Kako omejiti število povezav (zahtev) v NGINX


NGINX je opremljen z različnimi moduli, ki uporabnikom omogočajo nadzor prometa na svojih spletnih mestih, spletnih aplikacijah in drugih spletnih virih. Eden od ključnih razlogov za omejevanje prometa ali dostopa je preprečevanje zlorab ali napadov določenih vrst, kot so napadi DoS (Denial of Service).

Obstajajo trije glavni načini omejevanja uporabe ali prometa v NGINX:

  1. Omejevanje števila povezav (zahtev).
  2. Omejevanje števila zahtev.
  3. Omejevanje pasovne širine.

Zgornje pristope upravljanja prometa NGINX, odvisno od primera uporabe, je mogoče konfigurirati za omejitev na podlagi definiranega ključa, najpogostejši je odjemalčev IP naslov. NGINX podpira tudi druge spremenljivke, kot je piškotek seje in še veliko več.

V tem prvem delu naše tridelne serije bomo razpravljali o tem, kako omejiti število povezav v NGINX, da zaščitite svoja spletna mesta/aplikacije.

  • Kako omejiti število povezav (zahtev) v NGINX – 1. del
  • Kako omejiti hitrost povezav (zahtev) v NGINX – 2. del
  • Kako omejiti uporabo pasovne širine v NGINX – 3. del

Upoštevajte, da bo NGINX upošteval povezavo za omejitev samo, če ima zahtevo, ki jo strežnik obdeluje in je bila celotna glava zahteve že prebrana. Zato se ne štejejo vse odjemalske povezave.

Omejitev števila povezav v NGINX

Najprej morate definirati območje pomnilnika v skupni rabi, ki shranjuje meritve povezave za različne ključe z uporabo direktive limit_conn_zone. Kot smo že omenili, je ključ lahko besedilo, spremenljivka, kot je oddaljeni naslov IP odjemalca, ali kombinacija obojega.

Ta direktiva, ki je veljavna v kontekstu HTTP, ima dva parametra: ključ in območje (v formatu ime_območja: velikost).

limit_conn_zone $binary_remote_addr zone=limitconnbyaddr:20m;

Če želite nastaviti kodo stanja odgovora, ki se vrne zavrnjenim zahtevam, uporabite direktivo limit_conn_status, ki vzame statusno kodo HTTP kot parameter. Velja v kontekstih HTTP, strežnika in lokacije.

limit_conn_status 429;

Če želite omejiti povezave, uporabite direktivo limint_conn, da nastavite uporabljeno pomnilniško območje in največje število dovoljenih povezav, kot je prikazano v naslednjem konfiguracijskem odrezku. Ta direktiva je veljavna v kontekstih HTTP, strežnika in lokacije.

limit_conn   limitconnbyaddr  50;

Tukaj je celotna konfiguracija:

upstream api_service {
    server 127.0.0.1:9051;
    server 10.1.1.77:9052;
}
limit_conn_zone $binary_remote_addr zone=limitconnbyaddr:20m;
limit_conn_status 429;

server {
    listen 80;
    server_name testapp.linux-console.net;
    root /var/www/html/testapp.linux-console.net/build;
    index index.html;

    limit_conn   limitconnbyaddr  50;

    #include snippets/error_pages.conf;
    proxy_read_timeout 600;
    proxy_connect_timeout 600;
    proxy_send_timeout 600;
    location / {
        try_files $uri $uri/ /index.html =404 =403 =500;
    }
    location /api {
        proxy_pass http://api_service;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
   }
}

Shranite datoteko in jo zaprite.

Nato preverite, ali je konfiguracija NGINX v redu, tako da zaženete naslednji ukaz:

$ sudo nginx -t

Nato znova naložite storitev NGINX, da uveljavite nedavne spremembe:

$ sudo systemctl reload nginx

Preverjanje omejitve povezave Nginx

Ko odjemalec preseže največje dovoljeno število povezav, NGINX vrne odjemalcu napako »429 Preveč zahtev« in v datoteko dnevnika napak registrira vnos, kot je spodnji:

2022/03/15 00:14:00 [error] 597443#0: *127 limiting connections by zone "limitconnbyaddr", client: x.x.x.x, server: testapp.tecmimt.com, request: "GET /static/css/main.63fdefff.chunk.css.map HTTP/1.1", host: "testapp.tecmimt.com"

Omejitev števila povezav Nginx z aplikacijo

Prav tako lahko omejite število povezav za dani strežnik z uporabo spremenljivke $server_name:

upstream api_service {
    server 127.0.0.1:9051;
    server 10.1.1.77:9052;
}
limit_conn_zone $server_name zone=limitbyservers:10m;
limit_conn_status 429;

server {
    listen 80;
    server_name testapp.linux-console.net;
    root /var/www/html/testapp.linux-console.net/build;
    index index.html;

     limit_conn  limitbyservers  2000;

    #include snippets/error_pages.conf;
    proxy_read_timeout 600;
    proxy_connect_timeout 600;
    proxy_send_timeout 600;
    location / {
        try_files $uri $uri/ /index.html =404 =403 =500;
    }
    location /api {
        proxy_pass http://api_service;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
   }
}

Ta konfiguracija omogoča NGINX, da omeji skupno število povezav z navideznim strežnikom, ki poganja aplikacijo testapp.linux-console.net, na 2000 povezav.

Opomba: omejevanje povezav na podlagi odjemalčevega IP-ja ima slabo stran. Morda boste na koncu omejili povezave za več kot samo enega uporabnika, še posebej, če je veliko uporabnikov, ki dostopajo do vaše aplikacije, v istem omrežju in delujejo za NAT – vse njihove povezave bodo izvirale iz istega naslova IP.

V takem scenariju lahko uporabite eno ali več spremenljivk, ki so na voljo v NGINX, ki lahko identificirajo odjemalca na ravni aplikacije, primer je piškotek seje.

Morda vam bodo všeč tudi naslednji članki, povezani z Nginxom:

  • Kako ustvariti stran z napako 404 po meri v NGINX
  • Kako nadzorovati dostop na podlagi naslova IP odjemalca v NGINX
  • Kako predpomniti vsebino v NGINX
  • Kako omogočiti HTTP/2.0 v Nginxu
  • Kako uporabiti Nginx kot HTTP Load Balancer v Linuxu

To je to zaenkrat! V naslednjem delu te serije bomo obravnavali še eno uporabno tehniko upravljanja prometa v NGINX – omejevanje stopnje zahtev. Do takrat pa ostani z nami.