Saját szerverek
nginx
Az nginx HTTP-szerver és fordított proxy, amely hosztnév és útvonal szerint osztja el a kéréseket, és itt végzi el a TLS-terminálást a szolgáltatásaink előtt.
Az nginx egy HTTP-szerver, amely fordított proxyként is működik: statikus fájlokat szolgál ki, TLS-t bont, és a kéréseket a hosztnév és az útvonal alapján továbbítja a háttérben futó szolgáltatásokhoz. Nálunk ez a réteg áll minden saját üzemeltetésű szolgáltatás előtt, konténerben, Windows és Linux gazdagépen egyaránt.
A működés eseményvezérelt. A master process olvassa és értékeli a konfigurációt, és felügyeli a worker processeket, amelyek a kéréseket feldolgozzák; a workerek számát a worker_processes direktíva adja meg, ami igazodhat az elérhető CPU magokhoz is.
A konfigurációs modell
A beállítás egyetlen fájlban él, a direktívák egymásba ágyazott kontextusokba kerülnek: main, events, http, server, location. Az öröklés lefelé halad, a szűkebb kontextus felülírja a tágabbat.
- A server blokk egy hosztnévhez rendelt virtuális szerver. A kérést először az IP-cím és a port dönti el a listen direktívával, ezután a Host fejléc illeszkedik a server_name értékekhez.
- A server_name illesztése kötött sorrendben történik: pontos név, majd a csillaggal kezdődő leghosszabb helyettesítő név, aztán a csillaggal végződő leghosszabb, végül az első illeszkedő reguláris kifejezés a fájl sorrendje szerint.
- Ha egyetlen név sem illeszkedik, a kérést a port default szervere kapja meg; a default_server a listen port tulajdonsága, nem a szerver nevéé.
- A location blokkok az útvonalat bontják tovább: a pontos egyezés kerül előre, majd a leghosszabb prefix tárolódik, és csak akkor marad, ha egyetlen reguláris kifejezés sem illeszkedik. Az illesztés mindig a kérési URI-ra vonatkozik, az argumentumokra nem.
Kérések továbbítása és upstream
A proxy_pass a location belsejében adja meg a célt: hosztnevet, IP-címet porttal, Unix socketet vagy egy upstream csoport nevét. A viselkedés az utolsó perjelen múlik: URI nélkül a teljes kérési URI megy tovább, URI-val viszont az illeszkedő location prefix cserélődik le, ezért a záró perjel gyakori hibaforrás.
Az upstream blokk több hátteret fog össze egy név alá. Az alapértelmezett elosztás a round-robin, a least_conn a legkevesebb aktív kapcsolattal rendelkező szervert választja, az ip_hash pedig az ügyfél IP-címe szerint rögzíti a hozzárendelést. A weight súlyoz, a max_fails és a fail_timeout passzív állapotellenőrzést ad: a hibázó hátteret az nginx egy időre kihagyja.
TLS és proxy alapok
A TLS-hez a listen direktívában kell megadni az ssl paramétert, valamint a tanúsítvány és a privát kulcs útvonalát. A tanúsítványláncot egy fájlba fűzve kell átadni, a szerver tanúsítványával az élen, különben egyes kliensek nem tudják kiépíteni a kapcsolatot. A privát kulcs szűk jogosultsággal tárolható, de az nginx master processének olvasnia kell.
A proxyn átmenő kéréseknél az nginx alapértelmezésben a Host fejlécet a $proxy_host értékére állítja, a Connection fejlécet pedig close-ra, ezért az eredeti hosztot és az ügyfél címét külön kell átadni a proxy_set_header direktívával. A válaszok alapból belső bufferbe kerülnek, és csak teljes beérkezésük után mennek tovább; streamelő végpontoknál a proxy_buffering off adja a kívánt viselkedést.
Üzemeltetés: reload, munkafolyamatok, naplók
A konfiguráció módosítása nem él, amíg nem történik reload vagy restart. Az nginx -s reload hatására a master process ellenőrzi az új fájl szintaxisát, és siker esetén új workereket indít, a régieket pedig leállásra kéri: azok már nem fogadnak új kapcsolatot, de a folyamatban lévő kéréseket befejezik. Hibás fájl esetén a master visszaáll a korábbi állapotra. Az nginx -s quit szabályos leállás, a stop azonnali, a reopen pedig rotáció után nyitja újra a naplófájlokat.
TLS esetén a kézfogás CPU-igényes, ezért a dokumentáció több worker process futtatását és megosztott munkamenet-gyorsítótárat javasol, amelyet az ssl_session_cache állít be. Az error_log szintje alapból error, az access_log a combined formátumot használja; saját formátumban érdemes rögzíteni a $request_time és a $upstream_response_time értékét, mert ezekből látszik, hogy a lassulás a proxynál vagy a háttérben keletkezett.
Amire figyelni kell
- A nem illeszkedő hosztnevű kérések a port default szerverére esnek, ezért a nem kívánt forgalmat érdemes külön default_server blokkban kezelni, vagy üres server_name mellett eldobni.
- A proxy_buffering on állapotában a háttér gyorsan megszabadul a választól, de a kliens lassan kapja meg; interaktív és streamelő végpontoknál ez nem kívánatos.
- A szintaktikailag érvényes, logikailag rossz szabály csendben rossz helyre irányít, ezért a szabálymódosítás külön tesztelést érdemel.
Előttünk a Cloudflare áll, mögöttünk Docker konténerek futnak Linux gazdagépen, így a hosztnév szerinti szabályok egy helyen, az nginx konfigurációjában élnek. A CyberElectro minden saját üzemeltetésű szolgáltatása ezen a rétegen keresztül érhető el: a TLS itt terminálódik, a forgalmat pedig a hosztnév szerinti proxy szabályok osztják el.
Tovább olvasás
- Beginner’s Guide - indítás, leállítás, reload, valamint a konfigurációs fájl szerkezete.
- NGINX Reverse Proxy - a proxy_pass működése, a fejlécek átadása és a válaszok bufferelése.
- Server names - a szervernevek illesztési sorrendje, helyettesítő nevek és reguláris kifejezések.