17-bo‘lim

Nginx - statik fayllar va teskari proksi

server bloklari, location tartibi, proxy_pass, 502 xatosining sababi va veb-server darajasidagi himoya.

🕑 20 daqiqa o‘qish 📄 1 317 so‘z 👁 1 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Nima uchun ilova to'g'ridan-to'g'ri turmasin
  2. Sinov muhiti
  3. Sozlamani tekshirish
  4. Statik fayllar
  5. Teskari proksi
  6. Uzatiladigan sarlavhalar
  7. 502 Bad Gateway - eng ko'p uchraydigan xato
  8. Veb-server darajasidagi himoya
  9. Foydali sozlamalar
  10. Bir necha sayt
  11. Jurnallar
  12. Xulosa

Nginx serverda ikkita ish bajaradi: statik fayllarni juda tez uzatadi va ilovaga so'rovlarni yo'naltiradi. Ilova esa 127.0.0.1 da yashirinib turadi.

Nima uchun ilova to'g'ridan-to'g'ri turmasin #

VazifaIlova o'ziNginx orqali
Statik fayl uzatishSekinJuda tez
TLSHar ilovada alohidaBir joyda (18-bo'lim)
Bir necha domenQiyinserver bloklari
Sekin mijozlarIlova oqimini band qiladiNginx buferlaydi
Tezlik chekloviKodda yozasizlimit_req
Ilova qayta ishga tushgandaXato sahifaNginx 502 beradi
So'rov Nginx ichida qanday taqsimlanadi Brauzer 443-port Nginx 0.0.0.0:80, :443 location /rasm/ diskdan o'zi uzatadi location /api/ ilovaga uzatadi location ~ /\. deny all - .env, .git limit_req tezlik cheklovi /var/www statik fayllar diskda Ilova 127.0.0.1:8080 tashqaridan ko'rinmaydi MySQL 127.0.0.1:3306 Faqat Nginx tashqariga qaraydi - qolgan hamma narsa loopbackda
Bitta ochiq eshik, orqasida bir necha yopiq xizmat

Sinov muhiti #

Bu bo'limda Nginx alohida prefiks bilan, 127.0.0.1:8088 da ishga tushiriladi - tizimdagi Nginx sozlamasiga tegilmaydi.

Terminal
[ -f logs/nginx.pid ] && kill -QUIT "$(cat logs/nginx.pid)" 2>/dev/null
sleep 0.3
mkdir -p conf logs html temp api
echo "<h1>Statik sahifa</h1>" > html/index.html
echo "SIRLI_KALIT=12345" > html/.env
echo '{"holat": "ok"}' > api/holat.json

cat > conf/nginx.conf <<'EOF'
worker_processes 1;
error_log logs/error.log warn;
pid logs/nginx.pid;
events { worker_connections 64; }
http {
    access_log logs/access.log;
    client_body_temp_path temp;
    proxy_temp_path temp/proxy;
    fastcgi_temp_path temp/fastcgi;
    uwsgi_temp_path temp/uwsgi;
    scgi_temp_path temp/scgi;
    default_type text/html;

    server {
        listen 127.0.0.1:8088;
        server_name localhost;
        root html;

        location / {
            try_files $uri $uri/ =404;
        }

        location /api/ {
            proxy_pass http://127.0.0.1:8081/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }

        location ~ /\. {
            deny all;
        }
    }
}
EOF

Sozlamani tekshirish #

Terminal
nginx -p "$PWD" -c conf/nginx.conf -t 2>&1 | sed "s|$PWD/||g"
Natija
nginx: the configuration file conf/nginx.conf syntax is ok
nginx: configuration file conf/nginx.conf test is successful

Xato sozlama qanday ko'rinadi:

Terminal
printf 'events {}\nhttp { server { listen 8088 } }\n' > conf/yomon.conf
nginx -p "$PWD" -c conf/yomon.conf -t 2>&1 \
    | sed "s|$PWD/||g; s/^[0-9\/]* [0-9:]* //; s/[0-9]*#[0-9]*: //"
Natija
[emerg] unexpected "}" in conf/yomon.conf:2
nginx: configuration file conf/yomon.conf test failed

listen 8088 dan keyin nuqta-vergul tushib qolgan.

nginx -t siz reload qilmang

Agar sozlamada xato bo'lsa:

BuyruqNatija
systemctl reload nginxNginx eski sozlama bilan ishlashda davom etadi
systemctl restart nginxNginx butunlay to'xtaydi - sayt o'chadi

Ikkinchisi - kechqurun sayt yo'qolishining eng ko'p uchraydigan sababi.

Shuning uchun tartib doim shunday:

Terminal
sudo nginx -t && sudo systemctl reload nginx

&& muhim: nginx -t xato bersa, reload umuman bajarilmaydi.

Bu darslikdagi beshinchi "avval tekshir" buyrug'i: visudo -c, sshd -t, systemd-analyze verify, nft -c -f va nginx -t.

Statik fayllar #

Terminal
nginx -p "$PWD" -c conf/nginx.conf
sleep 1
curl -s http://127.0.0.1:8088/
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8088/mavjud-emas
nginx -p "$PWD" -c conf/nginx.conf -s quit 2>/dev/null
Natija
<h1>Statik sahifa</h1>
404
DirektivaVazifa
root htmlFayllar qayerdan olinadi
index index.htmlKatalog so'ralganda qaysi fayl
try_files $uri $uri/ =404Ketma-ket urinish, topilmasa 404
autoindex onKatalog ro'yxatini ko'rsatish - odatda kerak emas
root va alias farqi

Bu ikkisi juda o'xshash ko'rinadi, lekin boshqacha ishlaydi:

Natija
location /rasm/ {
    root /var/www/sayt;      # -> /var/www/sayt/rasm/logo.png
}

location /rasm/ {
    alias /var/www/rasmlar/; # -> /var/www/rasmlar/logo.png
}

root da location yo'li yo'lga qo'shiladi, alias da esa almashtiriladi.

Amaliy maslahat: iloji boricha root ishlating. alias bilan bitta klassik xato bor - oxirgi / ni unutish:

Natija
location /rasm {
    alias /var/www/rasmlar;   # XAVFLI
}

Bunda /rasm../etc/passwd kabi so'rov katalogdan tashqariga chiqishi mumkin. alias ishlatsangiz, location ham, alias ham / bilan tugasin.

Teskari proksi #

Terminal
(cd api && exec python3 -m http.server 8081 --bind 127.0.0.1 >/dev/null 2>&1) &
BE=$!
nginx -p "$PWD" -c conf/nginx.conf
sleep 1
curl -s http://127.0.0.1:8088/api/holat.json
nginx -p "$PWD" -c conf/nginx.conf -s quit 2>/dev/null
kill "$BE" 2>/dev/null
Natija
{"holat": "ok"}

So'rov 8088 ga keldi, Nginx uni 8081 dagi ilovaga uzatdi va javobni qaytardi.

proxy_pass da oxirgi / hamma narsani o'zgartiradi
Natija
location /api/ {
    proxy_pass http://127.0.0.1:8081/;    # / BOR
}

/api/holat.json → ilovaga /holat.json bo'lib boradi. /api/ qismi kesib tashlanadi.

Natija
location /api/ {
    proxy_pass http://127.0.0.1:8081;     # / YO'Q
}

/api/holat.json → ilovaga /api/holat.json bo'lib boradi. Yo'l to'liq uzatiladi.

Ikkalasi ham to'g'ri bo'lishi mumkin - bu ilova nimani kutayotganiga bog'liq. Lekin ularni chalkashtirish 404 xatolarining eng ko'p uchraydigan sababi.

Shubha bo'lsa, ilova jurnaliga qarang: u qaysi yo'lni olganini yozadi.

Uzatiladigan sarlavhalar #

proxy_set_header bo'lmasa, ilova mijoz haqida hech nima bilmaydi.

SarlavhaNima uchun kerak
Host $hostIlova qaysi domen so'ralganini biladi
X-Real-IP $remote_addrMijozning haqiqiy IP manzili
X-Forwarded-For $proxy_add_x_forwarded_forProksilar zanjiri
X-Forwarded-Proto $schemeHTTP mi, HTTPS mi
X-Forwarded-For ga ishonmang

Bu sarlavhani mijoz o'zi ham yubora oladi. Agar ilovangiz uni to'g'ridan-to'g'ri o'qisa, hujumchi istalgan IP ni ko'rsata oladi - va IP bo'yicha bloklash, tezlik cheklovi hamda jurnal ishonchsiz bo'lib qoladi.

To'g'ri yondashuv:

QadamNima qilinadi
Nginx sarlavhani o'zi qo'yadiX-Real-IP $remote_addr
Ilova faqat Nginx dan kelganiga ishonadiIlova 127.0.0.1 da tinglaydi
Bir necha proksi bo'lsaset_real_ip_from bilan ishonchli manbalarni sanang

Uchinchisi muhim: Cloudflare yoki yuk balanslagichi ortida turgan bo'lsangiz, faqat o'sha manzillardan kelgan sarlavhaga ishoning:

Natija
set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;

502 Bad Gateway - eng ko'p uchraydigan xato #

Terminal
nginx -p "$PWD" -c conf/nginx.conf
sleep 1
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8088/api/holat.json
nginx -p "$PWD" -c conf/nginx.conf -s quit 2>/dev/null
Natija
502

Backend ishga tushirilmagan - va Nginx 502 qaytardi.

Terminal
nginx -p "$PWD" -c conf/nginx.conf
sleep 1
curl -s -o /dev/null http://127.0.0.1:8088/api/holat.json
nginx -p "$PWD" -c conf/nginx.conf -s quit 2>/dev/null
sleep 0.3
grep -o 'connect() failed ([0-9]*: [^)]*)' logs/error.log | tail -1
Natija
connect() failed (111: Connection refused)
502, 504, 503 - uchta boshqa sabab
KodMa'noOdatiy sabab
502 Bad GatewayBackend javob bermadiIlova o'lgan yoki port noto'g'ri
504 Gateway TimeoutBackend juda sekinSo'rov proxy_read_timeout dan uzoq
503 Service UnavailableNginx o'zi rad etdilimit_req yoki upstream da server yo'q

Farqni bilish tashxisni tezlashtiradi:

KodQayerga qarash
502systemctl status ilova, ss -tlnp
504Ilova jurnali - qaysi so'rov osilib qolgan
503Nginx sozlamasi - cheklovlar

error.log dagi raqamli kod ham aniq aytadi: 111 - Connection refused (hech kim tinglamayapti), 110 - Connection timed out (javob yo'q).

Veb-server darajasidagi himoya #

Terminal
nginx -p "$PWD" -c conf/nginx.conf
sleep 1
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8088/.env
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8088/index.html
nginx -p "$PWD" -c conf/nginx.conf -s quit 2>/dev/null
Natija
403
200

.env fayli diskda bor, lekin Nginx uni bermadi.

.env va .git - internetdagi eng ko'p skanerlanadigan yo'llar

Avtomatik skanerlar har yangi domenni topgach, birinchi navbatda shu yo'llarni sinaydi:

Yo'lIchida nima bo'lishi mumkin
/.envMa'lumotlar bazasi paroli, API kalitlari
/.git/configOmbor manzili, ba'zan token
/.git/HEADButun manba kodini yuklab olish mumkin
/backup.sql, /dump.sqlTo'liq ma'lumotlar bazasi
/.DS_StoreFayllar ro'yxati

Ikkita qatlam himoya:

Natija
location ~ /\. {
    deny all;
    access_log off;
}

location ~* \.(sql|bak|old|log)$ {
    deny all;
}

Va eng muhimi: bu fayllar root katalogida umuman bo'lmasin. Ilova kodini /var/www/sayt ga, ochiq fayllarni esa /var/www/sayt/public ga qo'ying va root ni aynan public ga qarating.

Nginx qoidasi - ikkinchi himoya qatlami, birinchisi emas.

Foydali sozlamalar #

DirektivaVazifa
gzip onJavobni siqish - trafik kamayadi
client_max_body_size 20mYuklanadigan fayl chegarasi
proxy_read_timeout 60sBackend javobini kutish vaqti
expires 30dStatik fayllar uchun kesh
server_tokens offVersiya raqamini yashirish
limit_req_zoneTezlik cheklovi
add_header X-Frame-Options DENYXavfsizlik sarlavhalari
client_max_body_size - "413" xatosining sababi

Standart qiymat 1 MB. Foydalanuvchi 2 MB lik rasm yuklamoqchi bo'lsa, Nginx 413 Request Entity Too Large qaytaradi - ilova bu haqda umuman bilmaydi.

Bu xato ko'pincha ilovada qidiriladi, aslida esa Nginx darajasida hal qilinadi:

Natija
client_max_body_size 20m;

PHP ishlatilsa, uchta joyda birga oshirish kerak:

JoySozlama
Nginxclient_max_body_size
PHPupload_max_filesize
PHPpost_max_size

Uchtasidan eng kichigi amal qiladi. Bittasini oshirib, qolganini unutish - klassik vaqt yo'qotish.

Bir necha sayt #

Natija
server {
    listen 80;
    server_name softromeda.uz www.softromeda.uz;
    return 301 https://softromeda.uz$request_uri;
}

server {
    listen 443 ssl;
    server_name softromeda.uz;
    root /var/www/softromeda/public;
}

server {
    listen 443 ssl;
    server_name edu.softromeda.uz;
    root /var/www/edu/public;
}

Nginx Host sarlavhasiga qarab qaysi server blokini ishlatishni tanlaydi.

Standart server bloki - so'ralmagan domenlar uchun

Agar hech bir server_name mos kelmasa, Nginx birinchi blokni ishlatadi. Bu kutilmagan natija beradi: serveringizning IP manzilini bilgan har kim tasodifiy saytingizni ko'radi.

To'g'risi - aniq "hech kim" bloki qo'shish:

Natija
server {
    listen 80 default_server;
    listen 443 ssl default_server;
    server_name _;
    return 444;
}

444 - Nginx ning maxsus kodi: javob bermasdan ulanishni yopish. Skanerlar hech qanday ma'lumot olmaydi.

Sozlama fayllarini /etc/nginx/sites-available/ da saqlang va sites-enabled/ ga havola qo'ying - shunda saytni o'chirmasdan vaqtincha yopish mumkin:

Terminal
sudo rm /etc/nginx/sites-enabled/sayt
sudo nginx -t && sudo systemctl reload nginx

Jurnallar #

FaylIchida nima
/var/log/nginx/access.logHar so'rov
/var/log/nginx/error.logXatolar va ogohlantirishlar

3-bo'limdagi iboralar aynan shu yerda ishlaydi:

Natija
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
awk '$9 == 404 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
awk '$9 >= 500 {print}' /var/log/nginx/access.log | tail -20
Amaliy topshiriq
  1. Alohida prefiks bilan Nginx sozlamasi yozing.
  2. nginx -t bilan tekshiring, keyin ataylab xato kiriting.
  3. Statik faylni uzating va 404 ni oling.
  4. proxy_pass bilan backendga yo'naltiring.
  5. Backendni to'xtatib, 502 ni oling.
  6. error.log dan connect() failed satrini toping.
  7. location ~ /. bilan .env ni bloklang va 403 ni tasdiqlang.
  8. proxy_pass da oxirgi / bor va yo'q holatlarni solishtiring.
  9. default_server bloki bilan 444 qaytaring.
  10. access.log dan eng ko'p 404 bergan yo'llarni sanang.

Xulosa #

  • Nginx statikni tez uzatadi, ilovani 127.0.0.1 da yashiradi.
  • nginx -t && systemctl reload nginx - && ni tushirmang.
  • restart saytni o'chiradi, reload esa uzmaydi.
  • root yo'lni qo'shadi, alias almashtiradi.
  • proxy_pass dagi oxirgi / yo'lni kesadi - 404 larning tez-tez sababi.
  • X-Forwarded-For ga ishonmang; X-Real-IP ni Nginx o'zi qo'ysin.
  • 502 - backend o'lgan, 504 - sekin, 503 - Nginx rad etdi.
  • .env va .git ni bloklang, lekin ularni root ga umuman qo'ymang.
  • client_max_body_size standart holda atigi 1 MB.
  • default_server + return 444 - so'ralmagan domenlarga javob bermaslik.

Keyingi bo'limda HTTPS ni yoqamiz: sertifikatlar, Let's Encrypt va TLS sozlamalari.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.