API NodeJ에서 DDoS 및 DDoS에 대한 설명

Quando criamos nossa API e disponibilizamos publicamente estamos sujeito a ataques como força bruta eDDoS .
As intenções desses ataques são sobrecarregar nosso servidor com múltiplas requisições e tornar nosso serviço indisponível na rede.
Para evitar tais ataques podemos limitar o número de requisições por IPs, isso vai deixar nosso serviço mais profissional e caso aconteça um ataque não fique indisponível.

1 – Criar Projeto e Instalar Bibliotecas



Crie um simples projeto que será nossa API publica, para isso siga os passos:
  • Crie um diretório:

  • mkdir brute_force 
    

  • Entre no diretório:

  • cd brute_force 
    

  • 프로젝트 NodeJ에 대한 구성으로 외침:

  • yarn init 
    

  • seguintes bibliotecas abaixo로 설치:

  • yarn add express
    yarn add @types/express -D
    yarn add express-async-errors
    



    yarn add typescript -D
    



    yarn add dotenv
    yarn add ts-node-dev -D
    yarn add tsconfig-paths -D
    yarn add cors
    yarn add @types/cors -D
    

    2 – API



    Nossa API será bem simples, pois o objetivo é tratar os problemas de multipllas requisições.
    Crie uma estrutura de projeto com segue na imagem abaixo:



    Antes de começar a codificação, execute o comando abaixo na raiz o projeto para criar as configurações para usar Typescript:

    yarn tsc --init
    


    a - 모델

    Nosso modelo é simples, cry o arquivo user.ts na 파스타 모델:

    export default class User{
      constructor(
        id: number, 
        name:String
        ){}
    }
    


    b - 컨트롤러

    요구 사항과 유사하게 메모리를 사용하여 목록을 제어하려면 usersController.ts를 파스타 컨트롤러에 저장해야 합니다.

    import { Request, Response } from 'express';
    
    import User from '../models/user';
    
    class UsersController {
      public async show(request: Request, response: Response): Promise<Response> {
    
        const users:User[] = [
          {id:1,name:'user 01'},
          {id:2,name:'user 02'},
          {id:3,name:'user 03'},
          {id:4,name:'user 04'},
          {id:5,name:'user 05'},
          {id:6,name:'user 06'},
          {id:7,name:'user 07'},
          {id:8,name:'user 08'},
          {id:9,name:'user 09'},
          {id:10,name:'user 10'},
        ];
    
        return response.status(200).json(users);
      }
    }
    
    export default UsersController;
    


    c - 경로

    Nossa rotas para o acesso a API, crie o arquivo index.ts dentro da 파스타 경로:

    import { Router } from 'express';
    
    import UsersController from '../controllers/usersController';
    
    const usersController = new UsersController();
    const routes = Router();
    
    routes.get('/users', usersController.show);
    
    export default routes;
    


    d - Erros Customizados

    Vamos criar uma classe para customizar os erros, cry o arquivo appError.ts dentro da 파스타 오류:

    class AppError {
      public readonly message: string;
    
      public readonly statusCode: number;
    
      constructor(message: string, statusCode = 400) {
        this.message = message;
        this.statusCode = statusCode;
      }
    }
    
    export default AppError;
    


    e - 서비더

    Crie o arquivo server.ts dentro da pasta src para podemos executar no servidor:

    import express, { Request, Response, NextFunction } from 'express';
    import 'express-async-errors';
    import cors from 'cors';
    
    import AppError from './errors/appError';
    import routes from './routes';
    
    const app = express();
    
    app.use(cors());
    app.use(express.json());
    app.use(routes);
    
    app.use((err: Error, request: Request, response: Response, _: NextFunction) => {
      if (err instanceof AppError) {
        return response.status(err.statusCode).json({
          status: 'error',
          message: err.message,
        });
      }
    
      return response.status(500).json({
        status: 'error',
        message: 'Internal server error',
      });
    });
    
    app.listen(3333, () => {
      console.log('Server started on port 3333');
    });
    


    f - API 실행

    API를 로드하고 터미널 없이 다음 명령을 실행합니다.

    yarn dev:server
    


    사이다:

    $ yarn dev:server
    yarn run v1.21.1
    $ ts-node-dev -r tsconfig-paths/register  --inspect --transpile-only --ignore-watch node_modules src/server.ts
    ts-node-dev ver. 1.0.0-pre.63 (using ts-node ver. 8.10.2, typescript ver. 4.0.3)
    Debugger listening on ws://127.0.0.1:9229/31789a56-8b3f-4628-944d-56aeb1a6f061
    For help, see: https://nodejs.org/en/docs/inspector
    Missing baseUrl in compilerOptions. tsconfig-paths will be skipped
    Server started on port 33
    


  • Para obter os dados da API, acesse a rota:

  • localhost:3333/users
    


    2 – 고속 속도 제한기



    Com nossa API criada e rodando, agora vamos a parte de limitação de multiplas requisições por IPs.
    Para isso temos que instalar as seguintes bibliotecas:

    a-rate-limiter-flexible .

    yarn add rate-limiter-flexible
    


    b-레디스

    vamos precisar de um lugar para guardar as requisições poderíamos usar a memória porém se nosso servidor reiniciar vamos perder as informações dos IPs e quantidades de requisições.
    Redis를 사용하여 문제를 해결할 수 있습니다.

    yarn add redis
    yarn add @types/redis -D
    


    3 – 미들웨어



    Vamos criar um middleware para receber as requisições e verificar se o IP que realizou tem múltiplas requisições de forma simultânea.
    파스타 미들웨어에 대해 rateLimiter.ts를 요청하십시오.

    import {Request, Response, NextFunction} from 'express';
    import redis from 'redis';
    import {RateLimiterRedis} from 'rate-limiter-flexible';
    
    const redisClient = redis.createClient({
      host: 'localhost',
      port:6379,
      password: undefined,
    });
    
    
    const limiter = new RateLimiterRedis({
      storeClient: redisClient,
      keyPrefix: 'rateLimiter',
      points: 5,//quantas requisições por IP
      duration: 5,//segundos
    });
    
    export default async function rateTimiter(request:Request, response:Response, next:NextFunction):Promise<any>{
      try{
        await limiter.consume(request.ip);
        return next();
      }catch(err){
        return response.status(429).json({message: 'Too many requests', code:429})
      }
    }
    


    No código, fiz a configuração que ser nossa API receber 5 requisições em um intervalo de 5 segundos do mesmo IP retornará uma resposta 429 ..
    Então caso o limite seja rompido será retornar a resposta.

    {
        "message": "Too many requests",
        "code": 429
    }
    


    server.ts 및 미들웨어 rateLimiter에 대한 액세스 권한이 있습니다.

    import express, { Request, Response, NextFunction } from 'express';
    import 'express-async-errors';
    import cors from 'cors';
    
    import AppError from './errors/appError';
    import routes from './routes';
    import rateLimiter from './middlewares/rateLimiter';
    
    const app = express();
    
    app.use(rateLimiter);
    app.use(cors());
    app.use(express.json());
    app.use(routes);
    
    app.use((err: Error, request: Request, response: Response, _: NextFunction) => {
      if (err instanceof AppError) {
        return response.status(err.statusCode).json({
          status: 'error',
          message: err.message,
        });
      }
    
      return response.status(500).json({
        status: 'error',
        message: 'Internal server error',
      });
    });
    
    app.listen(3333, () => {
      console.log('Server started on port 3333');
    });
    


    Github do projeto .

    좋은 웹페이지 즐겨찾기