Vissza a bloghoz

Hogyan tegyünk biztonságossá és skálázzunk egy Django alkalmazást Docker, Nginx és Let’s Encrypt segítségével

Hogyan tegyünk biztonságossá és skálázzunk egy Django alkalmazást Docker, Nginx és Let’s Encrypt segítségével

Felhasználók milliói lépnek fel az internetre, hogy információkat érjenek el különböző célokból, beleértve a tanulást, a szórakozást, a híreket és az életük’ alakulásának megosztását a barátaikkal. Ezért egy alkalmazás telepítésekor az Ön legfőbb érdeke, hogy rendkívül biztonságos és skálázható infrastruktúrát valósítson meg az alkalmazásához. A felhő különféle módokat kínál egy Django alkalmazás biztosítására és skálázására. A horizontális skálázás egy olyan módszer, amellyel az alkalmazás több példányát is futtathatja. Ez biztosítja, hogy az hibatűrőbb és magas rendelkezésre állású legyen. Emellett növeli a teljesítményét is, hogy egyszerre több kérést tudjon feldolgozni.

Egy Django alkalmazás horizontális skálázása

Egy Django alkalmazást horizontálisan skálázhat több olyan alkalmazásszerver üzembe helyezésével, amelyek a Django alkalmazást és annak WSGI HTTP szerverét futtatják (mint például a Gunicorn vagy uWSGI). Ezután be kell állítania egy infrastruktúrát a bejövő kérések elosztására ezen alkalmazásszerverek között. Egy terheléselosztó és egy olyan fordított proxy, mint az Nginx segíthet az infrastruktúrának a forgalom elosztásában. Az Nginx képes telepíteni SSL-tanúsítványokat, biztosítva a biztonságos kapcsolatokat az alkalmazásához HTTPS-en keresztül. Végül az Nginx a statikus tartalom gyorsítótárazását is biztosíthatja, hogy minimalizálja a szerver terhelését.

Ezeknek a különböző komponenseknek a külön-külön történő konfigurálása és a kommunikációjuk biztosítása ijesztő feladat lehet. Szerencsére a Docker használata leegyszerűsíti a konfigurációs folyamatot, és biztosítja, hogy a különböző komponensek ugyanúgy viselkedjenek, függetlenül attól, hogy hol vannak telepítve.

Mit fog tenni ebben az útmutatóban

Ebben az útmutatóban megtanulhatja, hogyan skálázhat horizontálisan egy konténerizált Django alkalmazást, amelyet egy Gunicorn WSGI HTTP szerver szolgál ki. Két alkalmazásszervert fog üzembe helyezni, amelyek mindegyikére telepítve van a Docker, és a Django és Gunicorn alkalmazáskonténer ugyanazon másolatát futtatják.

Az alkalmazását egy Let’s Encrypt SSL-tanúsítvánnyal is biztosítani fogja egy harmadik proxyszerver üzembe helyezésével és konfigurálásával, amely egy Nginx fordított proxy konténert és egy Certbot klienskonténert fog futtatni. A Certbot egy olyan csomag, amely segít a Let’s Encrypt tanúsítványkiosztó hatóságtól származó SSL-tanúsítványok kezelésében. Lekéri a tanúsítványt, konfigurálja az Nginx szerverblokkokat a tanúsítvány helyével, és kezeli az automatikus megújításokat. Ezt egy cron feladat konfigurálásával éri el, amely rendszeresen ellenőrzi, hogy a tanúsítvány hamarosan lejár-e, és meg kell-e újítani. Az SSL-tanúsítvány naprakészen tartásával webhelye mindig magas biztonsági minősítéssel fog rendelkezni az SSL Labs.

A harmadik proxyszerver az elosztott architektúra előtt helyezkedik el, és fogadja az összes bejövő külső forgalmat. Ezután elosztja a forgalmat az alkalmazásszerverek között. Az alkalmazásszerverek egy tűzfal mögött találhatók, amely csak a proxyszerver számára engedélyezi a hozzáférést.

Ez az oktatóanyag a második a Django, Docker és Kubernetes rendszerekkel foglalkozó háromrészes oktatóanyag-sorozatból. Először kövesse a Django és Gunicorn alkalmazás építése Dockerrel Ubuntun című oktatóanyagban leírt lépéseket. Ebben az oktatóanyagban beállítottuk az alapvető projektkódot, egy Dockerfile-t, és csatlakoztattuk az alkalmazást a MinIo Simple Storage Service (S3) szolgáltatáshoz a statikus fájljaink kiszolgálása érdekében.

Előfeltételek

Az oktatóanyag követéséhez a következőkre lesz szüksége:

  1. Négy Ubuntu 20.04 szerver:

Ha követte az előfeltételként megjelölt oktatóanyag lépéseit (Django és Gunicorn alkalmazás építése Dockerrel Ubuntun), akkor a négy szerverből már kettővel rendelkezik:

  1. A Dockert telepíteni kell a két alkalmazásszerverre és a proxy szerverre.

    Miután követte a lépéseket az előfeltétel útmutatóban, a Dockernek már telepítve kell lennie az egyik szerveren. Követheti a Docker telepítéséről és üzemeltetéséről szóló útmutatónk 1., 2. és 3. lépését. Ne felejtse el hozzáadni a fent létrehozott sudo felhasználót a Docker csoporthoz.

  2. Szerezzen be egy regisztrált domain nevet és állítsa be a DNS-rekordjait, hogy a proxy szerver nyilvános IP-címére mutassanak. Bemutató céljából a következőt fogjuk használni: example_domain.com.
  1. S3 objektumtárhely-szolgáltatás beállítása. A MinIO-t használtuk tárhelyszolgáltatásként az előfeltétel útmutatóban. Ezért kövesse a magyarázatokat az 5. lépésben az előfeltétel útmutatóból, hogy beállítsa a MinIO tárhelygyűjtőjét (bucket).

1. lépés: Az első Django alkalmazásszerver működésének ellenőrzése

Ahogy az Előfeltételek részben le van írva, ez az útmutató a Django és Gunicorn alkalmazás építése Dockerrel Ubuntu-n útmutató után következik. Ha abból az útmutatóból érkezik, és már végrehajtotta a lépéseket, akkor az első szervernek már futnia kell. Az alkalmazás kódja a Django dokumentációjának Szavazó alkalmazás útmutatóján alapul. Fontos, hogy végigolvassa azokat a lépéseket, hogy megértse a kezdeti beállításokat. Ha már végrehajtotta az útmutató lépéseit, kihagyhatja ezt az első lépést.

Ellenkező esetben egyszerűen klónozhatja a Dockerizált ágat a szerverére. Kezdje azzal, hogy bejelentkezik az első alkalmazásszerverére, és futtatja a következő git parancsot a django-polls-docker ágának klónozásához a django-polls tárolóból (repository):

Ezután lépjen be a django-polls könyvtárba:

cd django-polls

Ebben a könyvtárban talál egy Dockerfile fájlt, amelyet a Docker használ az alkalmazáskép (image) felépítéséhez, egy django-polls könyvtárat, amely a Python alkalmazáskódot tartalmazza, valamint egy env fájlt, amely a környezeti változók listáját tartalmazza, amelyek indításkor átadásra kerülnek a konténernek a működésének módosítására. A Dockerfile fájlban a Django csomagfüggőségeket a requirements.txt fájlon keresztül határozzuk meg. Ezenkívül deklarálnunk kell egy portot 8000 a bejövő forgalom fogadására, és be kell állítanunk, hogy egy gunicorn szervert futtasson 3 workerrel. Ha többet szeretne megtudni a Dockerfile utasításokról, kérjük, tekintse meg a Step 7 of the tutorial Building a Django and Gunicorn Application with Docker on Ubuntu.

A Docker képet a következő paranccsal építheti fel:

docker build -t django-polls:v1 .

Miután a Docker felépítette a képet, a következő paranccsal listázhatja a szerveren elérhető képeket:

docker images

Íme a kimenet, amikor futtattuk a parancsot:

Django Application scrn 1

Ezután módosítanunk kell a futtató környezet konfigurálására használt env fájlt. Ez a fájl átadásra kerül a Docker run konténernek a konténer indításakor. Nyissa meg az env fájlt a nano szerkesztővel:

A env fájl tartalmaz néhány helyőrző szöveget, amelyet módosítania kell, és ki kell töltenie a helyes értékekkel:

  • DJANGO_SECRET_KEY: Generáljon egy egyedi, kiszámíthatatlan értéket, ahogyan azt a Django dokumentáció magyarázza. Ezzel a paranccsal generálhat egy véletlenszerű karakterláncot, és beállíthatja azt a változóhoz:  python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'.

  • DJANGO_ALLOWED_HOSTS: ez az érték arra szolgál, hogy megvédje alkalmazását a HTTP Host Header támadásoktól. Beállíthatja a következőre: *, ami fejlesztői módban minden gazdagépre illeszkedik (helyettesítő karakter). Amikor éles környezetbe telepíti az alkalmazást, állítsa ezt a regisztrált domain nevére. A mi bemutatónkban ez a következő: example_domain.com.

  • DB_DATABASE: állítsa ezt a PostgreSQL adatbázis nevére, amelyet a Előfeltételek szakaszban hozott létre, a mi esetünkben ez a polls_db.

  • DB_USERNAME: állítsa ezt az adatbázishoz választott felhasználónévre.

  • DB_PASSWORD: állítsa ezt az adatbázishoz választott jelszóra.

  • DB_HOST: állítsa ezt az adatbázis-példányt futtató gazdagépre, ahogyan azt a Előfeltételek szakaszban beállította. Ezt a Building a Django and Gunicorn Application with Docker on Ubuntu oktatóanyag 1. és 2. lépése magyarázza el az adatbázis beállításához.

  • DB_PORT: állítsa ezt az adatbázis portjára.

Save and close the file once you finish editing. With our database credentials in place, we can create the database schema by running the container and overriding the CMD command set in the Dockerfile. You can find more information on the hivatalos dokumentáció Dockerfile belépési pontjáról szóló részében. Ezután futtassa a következő parancsot:

Ebben a parancsban a django-polls:v1 képet futtatjuk, és átadjuk a korábban módosított env fájlt. A sh -c "python manage.py makemigrations && python manage.py migrate rész létrehozza az alkalmazáskód által meghatározott adatbázis-sémát. Ha először futtatja a parancsot, egy hasonló kimenetet kell látnia, amely az adatbázis-séma létrehozását jelzi:

Django Application scrn 2

Miután létrehoztuk a sémát, létrehozhatjuk a Django szuperfelhasználót (superuser). Futtassa a következő parancsot a konténer interaktív shell-lel történő elindításához:

A parancs elindítja a konténert egy shell parancssorral, amelyet a Python shell-lel való interakcióra használhat. Hozzunk létre egy felhasználót a következő paranccsal:

Kövesse a felszólításokat a felhasználónév, e-mail cím és jelszó megadásához. Írja be újra a jelszót, majd nyomja meg az Entert a felhasználó létrehozásához. Lépjen ki a shellből és állítsa le a konténert a következő billentyűkombinációval: CTRL+D.

Ezután újra le kell futtatnunk a konténert, felülbírálva az alapértelmezett parancsot a collectstatic Django paranccsal. A parancs létrehozza az alkalmazás statikus fájljait, és feltölti azokat a MinIO Cloud Storage-ba:

A parancs létrehozza és feltölti a fájlt a konfigurált objektumtároló szolgáltatásba. Íme a kimenet:

object storage

Most már futtathatja az alkalmazást anélkül, hogy bármilyen további parancsot megadna a Dockerfile-ban meghatározott alapértelmezett CMD parancs felülbírálására:

Django Application scrn 3

A Docker futtatja a Dockerfile-ban meghatározott alapértelmezett parancsot, elindítja a konténert a gunicorn szerverrel, elérhetővé teszi a konténer 8000 portját, és leképezi azt az Ubuntu 80 portjára. Most már megtekintheti az alkalmazás felületét a böngészőjében, ha beírja az első szerver IP-címét a címsorba: http://FIRST_SERVER_IP.

Egy 404 Page Not Found hibaüzenetet fog kapni, mert semmit sem határoztunk meg a / útvonalat. Navigáljon a http://FIRST_SERVER_IP/polls címre a Szavazás (Polls) felület megtekintéséhez:

Django Application image 1

Látogasson el az adminisztrációs felületre néhány szavazás létrehozásához: http://FIRST_SERVER_IP/admin:

polls

Adja meg a fenti createsuperuser paranccsal beállított hitelesítési adatokat az adminisztrációs felület eléréséhez:

polls administration

Ha megnézi az oldal forrását, láthatja, hogy a statikus fájlok a meghatározott módon a tárhely-gyűjtőből (storage bucket) töltődnek be. Miután megbizonyosodott arról, hogy a konténer a várt módon kiszolgálja az alkalmazást, leállíthatja a konténert a CTRL+C billentyűkombinációval a terminálban.

Ezután a konténert detached (leválasztott) módban kell futtatnunk, hogy kiléphessünk az első szerver SSH-munkamenetéből. Ezáltal a konténer a háttérben fut tovább. Futtassa a következő parancsot:

A -d jelző elindítja a konténert detached (leválasztott) módban, így az a háttérben futhat tovább. A --rm jelző törli a konténer fájlrendszerét a konténerből való kilépés után. Adunk a konténernek egy nevet, a polls, hogy láthassuk, amikor listázzuk a konténereket.

Lépjen ki az első szerver SSH-munkamenetéből, és navigáljon a http://FIRST_SERVER_IP/polls címre a böngészőjében, hogy ellenőrizze, a várt módon fut-e. Ha látja a szavazás felületét, akkor az első alkalmazásszerver sikeresen be van állítva. A következő lépésben állítsuk be a második alkalmazásszervert.

2. lépés: A második alkalmazásszerver beállítása

A Building a Django and Gunicorn Application with Docker on Ubuntu oktatóanyagban létrehozott alkalmazás dockerizált ágát fogjuk klónozni. Az itt használt parancsokról további részleteket talál abban az oktatóanyagban, vagy az összefoglaló verziót a Step 1.

Már futnia kell a második szervernek, hozzá kell adnia egy nem-root sudo felhasználót, és telepítenie kell a Dockert az Prerequisites szakaszban leírtak szerint.

A következő lépés a szerver konfigurálása a PostgreSQL szerverpéldányhoz való csatlakozáshoz. Amint azt a Building a Django and Gunicorn Application with Docker on Ubuntu oktatóanyag 1. lépésében kifejtettük, engedélyeznie kell a második szerver IP-címét a ufw és a PostgreSQL konfigurációkon keresztül.

Először jelentkezzen be a PostgreSQL adatbázis-szerver példányba a nem-root sudo felhasználójával. Az ufw szabály hozzáadásához futtassa a következő parancsot:

Ezután futtassa ezt a parancsot, és adja hozzá a második szerver IP-címét a PostgreSQL kliens-hitelesítési fájljához:

Olvassa el a megjegyzéseket, hogy jobban megértse a konfigurációkat. Ezután adja hozzá ezt a sort a hosts szakasz alá, megadva az IP-címét:

Save and close the file when you finish editing.

Ezután indítsa újra a PostgreSQL szolgáltatást a változtatások érvénybe léptetéséhez:

Jelentkezzen ki a PostgreSQL adatbázis-szerver példányból, és folytassa a második alkalmazásszerver-példány konfigurálásával.

Jelentkezzen be a second app server with ssh. Then clone the django-polls-branch of the django-polls repository with the following command:

Lépjen be a django-polls könyvtárba:

Ezt követően építse fel a lemezképet a következő paranccsal:

Miután a lemezkép felépítése befejeződött, módosítsa az env fájlt a konfigurációs értékekkel az Step 1. Nyissa meg a fájlt a nano segítségével:

Cseréld ki a helyőrző szövegeket a(z) 1. lépésben hozzáadott tényleges értékekre. Ne felejtsd el megfelelően módosítani a DJANGO_ALLOWED_HOSTS változót. Mentsd el és zárd be a fájlt, ha kész vagy. Frissítsd a MinIO hitelesítési adataidat a env fájlban, ahogy az előző lépésben tetted.

Most már futtathatod az alkalmazáskonténert leválasztott (detached) módban a következő paranccsal:

A parancs elindítja a konténert, és a háttérben futtatja. Lépj ki a második alkalmazásszerver ssh-munkamenetéből, és navigálj a http://SECOND_SERVER_IP/polls címre a böngésződben, hogy ellenőrizd, az elvárásoknak megfelelően fut-e. Ha minden a tervek szerint alakult, látnod kell a polls felületét.

Most már két alkalmazásszerver futtatja az alkalmazásod ugyanazon másolatát. A következő lépésben beállítod az Nginx konténert, hogy fordított proxyként (reverse proxy) működjön.

3. lépés: Az Nginx Docker konténer beállítása

Nginx a világ egyik legnépszerűbb nyílt forráskódú webszerver-szoftvere. Ez felelős az internet legnagyobb forgalmú webhelyeinek elérhetőségéért és skálázhatóságáért. Garantálja a biztonságot, és rendkívül sokoldalú. Használhatod fordított proxyzáshoz, gyorsítótárazáshoz és terheléselosztáshoz. Az alkalmazásunkat úgy állítottuk be, hogy egy külön objektumtároló szolgáltatást használjon a statikus és médiafájlok kezelésére. Ezért nem fogjuk használni az Nginx gyorsítótárazási funkcióit. Ehelyett az Nginx fordított proxy és terheléselosztási képességeit fogjuk használni. Az Nginx kiszolgáló fogadja a bejövő forgalmat, és elosztja azt a háttér-alkalmazásszerverek között. Ezután biztonságos kommunikációt biztosít a kliens és a szerver között azáltal, hogy a forgalmat a Let’s Encrypt.

Az Nginx fordított proxyzás és terheléselosztás megvalósításának számos módja van. Az egyik módszer az, hogy az Nginx fordított proxyt a háttér-alkalmazásszervertől elkülönítve állítjuk be, ahogy ebben az útmutatóban is tettük. Ez a felépítés rugalmas, és lehetővé teszi mind az Nginx proxyréteg, mind az alkalmazásréteg skálázását. Hozzáadhatsz több Nginx proxyt, vagy bevezethetsz egy felhőalapú terheléselosztót. A fordított proxyzás megvalósításának egy másik módja, ha az egyik háttér-alkalmazásszervert használod Nginx proxyként. Ekkor a bejövő kéréseket helyben és a többi alkalmazásszerver felé is proxyzhatod. Opcionálisan konfigurálhatsz egy Nginx konténert az összes háttér-alkalmazásszerveren, és beállíthatsz egy elé helyezett felhőalapú terheléselosztót a bejövő forgalom fogadására és a háttér-alkalmazásszerverek közötti elosztására.

Kezdjük el a proxyszerver konfigurálását. Jelentkezz be a negyedik Ubuntu szerverre, amelyet Nginx proxyként való használatra állítottál be, és hozz létre egy konfigurációs könyvtárat:

Nyiss meg egy konfigurációs fájlt a nano segítségével a könyvtáron belül:

Ezután add hozzá a következő konfigurációt a fájlhoz:

Ebben a konfigurációs fájlban megadjuk a server, upstream, és a location blokkokat, hogy utasítsuk az Nginx-et a HTTP kérések HTTPS-re történő átirányítására, és a kérések elosztására a két alkalmazásszerver között, amelyeket a 1. lépésben és a 2. lépésben állítottunk be. Általános információkat találhat az Nginx konfigurációs fájl szerkezetéről a hivatalos dokumentációjukban.

Tanulmányoztuk a Docker Hub Nginx image dokumentációja, Certbot, és a Gunicorn által biztosított konfigurációs fájljait ahhoz, hogy összeállítsuk ezt a minimális Nginx konfigurációs fájlt. Bár ez csak bemutató célokat szolgál, és arra, hogy működésre bírjuk a rendszerünket, bátran felfedezheti és kísérletezhet más konfigurációkkal az Nginx útmutatóit követve.

Az upstream blokk a beérkező kéréseket feldolgozó szerverek csoportjának meghatározására szolgál. Egy név kerül hozzárendelésre a csoporthoz, amelyet a proxy_pass direktíva hív meg. A blokkot a következőképpen neveztük el: django és megadtuk a két háttéralkalmazás-szerver IP-címét:

Meghatároztunk továbbá 3 szerverblokkot. Az első szerverblokk elkap minden olyan kérést, amely nem egyezik meg a doménnel, és egy 444 kódot ad vissza (lezarja a kapcsolatot anélkül, hogy választ küldene az ügyfélnek, ezáltal elutasítva a rosszindulatú vagy hibás kéréseket). A szerver IP-címére érkező közvetlen HTTP-kérést ez a blokk kezeli, mivel ez van meghatározva mint default_server:

A második szerverblokk kezeli a bejövő HTTP (port: 80) kéréseket, és átirányítja azokat HTTPS-re (port: 443) a következő használatával: HTTP 301 átirányítás:

A harmadik szerverblokk kezeli most a kéréseket. Számos direktívát tartalmaz, amelyek fontosságát az alábbiakban határozzuk meg.

Két direktívánk van, amelyek meghatározzák a Certbot által biztosított TLS-tanúsítvány és kulcs elérési útját. A tanúsítványok az Nginx konténerbe kerülnek csatolásra annak indításakor:

Ezután a Certbot által javasolt alapértelmezett SSL-biztonsági beállítások következnek. További információkat az Nginx hivatalos dokumentációjában talál az ngx_http_ssl_module modulról. A Mozilla szintén nyújt további információkat a szerveroldali biztonságról. A ssl_ciphers érték a conf fájlban a Mozilla oldaláról származik:

A következő két direktívában meghatározzuk az ügyfél kéréstörzsének maximálisan megengedett méretét, és beállítjuk az időtúllépést a keep-alive kapcsolatokhoz az ügyféllel. Az Nginx lezárja a kapcsolatot az ügyféllel a keepalive_timeout direktívában beállított másodpercek letelte után. További információkat talál a Gunicorn telepítéséhez szükséges Nginx konfigurációkról a hivatalos dokumentációban:

A konfigurációs fájlban két location blokkot is meghatároztunk. Az első blokk a kérések proxyzását kezeli a proxy direktívákban meghatározottak szerint. A bejövő kérések a korábban meghatározott upstream django szerverekhez lesznek továbbítva:

További információt a proxy direktívákról itt talál: Nginx Module ngx_http_proxy_module és a dokumentációban erről: Gunicorn szerver telepítése.

A második location blokkban egy útvonalat határozunk meg: /well-known/acme-challenge/. Ezt általában a Certbot használja a domain név Let’s Encrypt segítségével történő ellenőrzésére az SSL-tanúsítvány kiállítása vagy megújítása előtt:

Ez minden az Nginx konfigurációs fájlhoz. A szerkesztés befejezése után elmentheti és bezárhatja a fájlt.

Az imént meghatározott konfigurációs fájl használható egy Nginx konténer futtatására. Ez azonban sikertelen lesz, mivel még nem szereztük be az SSL-tanúsítványokat a Let’s Encrypt-től. Ebben az útmutatóban az nginx:1.20.2 Docker-rendszerkép 1.20.2-es verzióját fogjuk használni a hivatalos Nginx képfájl-tárolóból a Docker Hubon.

Az alábbi parancs futtatásával letöltheti a rendszerképet, és ellenőrizheti, hogy minden megfelelően működik-e:

Ez a parancs létrehoz egy nginx nevű konténert, és leképezi a 80 és 443 portokat a gazdarendszer és a konténer között. Az --rm jelző eltávolítja az átmeneti konténereket a sikeres felépítés után. A -v jelzőt használjuk a konfigurációs fájl felcsatolására a konténerbe a /etc/nginx/conf.d/nginx.conf helyre, amely az alapértelmezett Nginx konfigurációs könyvtár. Ez írásvédett módban van felcsatolva a ro jelzővel, hogy megakadályozzuk az Nginx konténert annak módosításában. Beállítjuk az alapértelmezett webroot könyvtárat, és felcsatoljuk mint /var/www/html. Végezetül utasítjuk a Dockert, hogy használja a nginx:1.20.2 rendszerképet ehhez a buildhez. A következő lépésben szerezzük be a TLS/SSL tanúsítványt és kulcsot a Let’s Encrypt-től.

4. lépés: SSL/TLS tanúsítvány beszerzése a Let’s Encrypt-től és a Certbot automatikus megújításának konfigurálása

Certbot segít ingyenes TLS-tanúsítványok beszerzésében a Let’s Encrypt szolgáltatástól, valamint kezeli azok automatikus megújítását a lejárati idő előtt. Ez növeli a webhelyek biztonságát, és biztosítja, hogy HTTPS-en keresztül legyenek kiszolgálva. Összhangban azzal, hogy architektúránkat konténerizálva tartsuk, a Certbot Docker-rendszerképet fogjuk használni az SSL/TLS-tanúsítványok lekéréséhez és az automatikus megújítás konfigurálásához. Győződjön meg róla, hogy a Docker telepítve van a proxyszerverén az Előfeltételek utasításai szerint.

Rendelkeznie kell egy DNS A-rekorddal is a regisztrált domain nevéhez, amely a proxyszerver IP-címére mutat. Ezt ellenőrizheti a certbot Docker-rendszerkép futtatásával és a --staging jelző átadásával:

A parancs letölti a Certbot rendszerképet, és interaktív módban futtatja. Ez azt jelenti, hogy egy parancssorral fog rendelkezni, amely lehetővé teszi bizonyos adatok megadását. Leképezi a gazdagép 80 portját a konténeren belüli 80 portra. A -v jelzőt használjuk két gazdakönyvtár felcsatolására a konténerbe: /etc/letsencrypt/ és /var/lib/letsencrypt/. A --standalone jelző azt határozza meg, hogy a Certbot image-et az Nginx használata nélkül szeretnénk futtatni. Végül itt van a --staging jelző, amelynek hatására a Certbot a staging szervereken fog futni, és ellenőrzi a domain nevét.

Adja meg az e-mail-címét, és fogadja el a Szolgáltatási feltételeket, amikor a rendszer kéri. A sikeres ellenőrzés kimenete a következő:

KÖVETKEZŐ LÉPÉSEK:

A tanúsítványt lejárta előtt meg kell újítani. A Certbot automatikusan meg tudja újítani a tanúsítványt a háttérben, de előfordulhat, hogy lépéseket kell tennie a funkció engedélyezéséhez. Tekintse meg ezt a linket az utasításokért.

A tanúsítványt a következő paranccsal tekintheti meg: cat parancs:

A fenti parancsnak meg kell jelenítenie a tanúsítványt a terminálban. Miután megbizonyosodott arról, hogy a Certbot kiállította a tanúsítványt, tesztelheti a(z) 3. lépésben létrehozott Nginx konfigurációt. Futtassa az alábbi Docker parancsot az Nginx konténer elindításához:

Ebben a parancsban a -v jelzőt használtuk a Let’s Encrypt SSL/TLS tanúsítványok könyvtárainak csatolásához.

Amikor a konténer fut, nyissa meg a weboldalt a böngészőjében: http://example_domain.com. Valószínűleg egy figyelmeztetést fog látni arról, hogy a webhely nem biztonságos:

Ez azért van, mert csak staging/teszt tanúsítványokat igényeltünk, és nem éles tanúsítványokat a Let’s Encrypt-től. Szerezzük be az éles tanúsítványokat a következő Certbot parancs futtatásával a --staging jelző nélkül:

A felszólításban erősítse meg, hogy szeretné megújítani és lecserélni a meglévő tanúsítványt a 2 beírásával, majd nyomja meg az ENTER billentyűt. Ez egy éles használatra kész tanúsítványt fog biztosítani. Most már futtathatja az Nginx konténert, és mindennek jól kell működnie:

Miután a konténer elindult és fut, nyissa meg újra a weboldalt a böngészőjében: http://example_domain.com újra. Vegye figyelembe, hogy a böngésző átirányít a HTTPS-re, még akkor is, ha HTTP-t ír be. Ez azt jelenti, hogy az Nginx konfigurációban lévő szerverünk, valamint a kiállított SSL/TLS tanúsítványok is jól működnek. Navigáljon a polls  útvonalra http://example_domain.com/polls, mivel nincs útvonal meghatározva a kezdőlap elérési útjához /. Látnia kell a szavazási felületet:

Eddig sikeresen konfigurált egy éles környezetre kész architektúrát. Két háttérkiszolgálót valósított meg, amelyek a proxy szerverről továbbított bejövő kéréseket fogják feldolgozni. A proxy szerver kezeli majd a terheléselosztást és a forgalom biztosítását a kiosztott TLS-tanúsítványok segítségével.

Azonban tartsa szem előtt, hogy a Let’s Encrypt tanúsítványok 90 nap után lejárnak. Ezért a 90 napos határidő előtt meg kell újítania őket. Mivel az Nginx konténer futni fog, a webroot módot kell használnia a standalone mód helyett, amikor végrehajtja a certbot parancsot a tanúsítvány megújításához. Emlékezzen, hogy megadta a /var/www/html/.well-known/acme-challenge/ könyvtárat az Nginx konfigurációs fájljában a Step 3-ben. A Certbot ezt az útvonalat fogja használni az ellenőrző fájlok tárolására. Emellett a Let’s Encrypt kliens is ezt az útvonalat fogja hívni ellenőrzési kérésekkel, amikor megpróbálja megújítani a tanúsítványokat. Amint a megújítási parancs végrehajtása befejeződött, újratöltheti az Nginx-et a változtatások érvénybe léptetéséhez.

Állítsa le a konténert a CTRL+C billentyűkombinációval a terminálban, majd indítsuk el újra háttér módban a -d flag használatával:

Ez az Nginx konténert a háttérben hagyja futni. Teszteljük a tanúsítvány megújítási folyamatát a --dry-run flag használatával az alábbi parancs végrehajtásával:

Ebben a parancsban megadtuk a --webroot bővítményt, valamint az ellenőrzési kérésekhez használandó útvonalat a -w flag segítségével. Megadjuk továbbá a --dry-run flaget is, hogy ellenőrizzük az automatikus megújítási folyamatot anélkül, hogy ténylegesen tanúsítványt igényelnénk.

Sikeres szimuláció esetén hasonló kimenetet kell látnia:

Amikor megújít egy tanúsítványt a futó alkalmazásához, újra kell töltenie az Nginx-et, hogy a konténer elkezdhesse használni az új tanúsítványt. A következő Docker parancs újratölti a nginx konténert (ne feledje, hogy a konténert nginx-nek neveztük el):

A parancs egy HUP Unix szignált küld az Nginx folyamatnak, amely a nginx Docker konténerben fut. Ez arra készteti az Nginx-et, hogy újratöltse a konfigurációit, és elkezdje használni a megújított tanúsítványokat.

Mivel a proxy szerverünkön telepítve van a TLS/SSL, és a weboldalunk HTTPS-en keresztül érhető el, most meg kell védenünk a háttéralkalmazás-szervereinket, hogy csak a proxy szerverről érkező kéréseket engedélyezzék.

5. lépés: A háttér Django szerverek biztosítása a külső hozzáféréssel szemben

Az ebben az útmutatóban megvalósított proxy szerver kezeli az SSL-terminációt, ahol dekódolja az SSL-kapcsolatot, és a titkosítatlan csomagokat továbbítja a háttéralkalmazás-szervereknek. Mivel a háttérszervereket biztosítani fogjuk a külső hozzáféréssel szemben, ennek a biztonsági szintnek a legtöbb esetben működnie kell. Ha azonban olyan alkalmazásokat telepít, amelyek érzékeny adatokat, például banki információkat vagy egészségügyi adatokat továbbítanak, akkor implementálnia kell a(z) végpontok közötti titkosítást.

Ebben az útmutatóban a háttérben lévő Gunicorn szervereket az Nginx védi, mivel nem arra szolgálnak, hogy közvetlenül elérhetők legyenek az internetről. Az Nginx proxy szerver olyan, mint egy átjáró a háttérszerverekhez, megakadályozva, hogy a külső kliensek közvetlenül hozzáférjenek a háttéralkalmazás-szerverekhez. Gondoskodnia kell arról, hogy minden kérés a proxy szerveren keresztül menjen. Ennek ellenére a Dockernek van egy olyan hibája, hogy megkerüli az ufw tűzfalszabályait, és külsőleg nyit meg portokat, ami védtelenné teheti az infrastruktúrát. Ez valójában nyilvánvaló, mivel az alkalmazásszervereinket az 1. lépésben és a 2. lépésben állítottuk be anélkül, hogy engedélyeztük volna a(z) 80 portot a(z) ufw szabályokban. Ennek ellenére továbbra is elérheti a weboldalakat, ha a böngészőben meglátogatja a szerverek bármelyik nyilvános IP-címét. Ennek a problémának az egyik megoldása, ha közvetlenül az iptables eszközt használja, anélkül, hogy a(z) ufw szabályozáson menne keresztül. További információért elolvashatja a Docker és iptables hivatalos dokumentációit. Egy másik javasolt módszer a felhőalapú tűzfalak használata.

Módosítsuk az UFW konfigurációit, hogy blokkoljuk a külső hozzáférést minden olyan porthoz, amelyet a Docker megnyithatott. Amikor a gazdagép 80 portját a Docker-konténer 8000 portjához rendeltük a Docker parancs -p 80:8000 jelzőjével, akaratlanul is megnyitottuk a(z) 80 portot a gazdagépen. Ezt a hozzáférést letilthatja az UFW konfigurációjának módosításával, a(z) ufw-docker repozitórium README fájljában leírtak szerint.

Végezzük el a változtatást az első Django alkalmazásszerveren. Jelentkezzen be a szerverre, és nyissa meg a /etc/ufw/after.rules fájlt a nano segítségével sudo felhasználóként:

A fájl a következő ufw szabályokat tartalmazza:

Adja hozzá a következő UFW konfigurációs sorokat a fájl aljához:

A hozzáadott szabályok megakadályozzák a nyilvános hozzáférést a Docker által megnyitott portokhoz. Továbbá lehetővé teszik a hozzáférést a 10.0.0.0/8, 172.16.0.0/12, és 192.168.0.0/16 magán IP-címtartományokból. A szabályokról további részleteket olvashat a ufw-docker README fájlból. Mentse el és zárja be a fájlokat, ha végzett a szerkesztéssel. Ez a beállítás akkor működne, ha beállított volna egy virtuális magánfelhő-hálózatot (VPC), amelyben mindhárom szervere a VPC-ben található, majd megadta volna a Django szerverek privát IP-címeit az Nginx config fájljának upstream direktívájában.

Azonban mi nyilvános IP-címeket használtunk, és előfordulhat, hogy nem rendelkezünk VPC-vel. Ezért hozzá kell adnia egy szabályt a ufw eszközhöz, hogy engedélyezze a forgalmat az Nginx proxy szerverről a 80 porton keresztül mindkét Django alkalmazásszerver esetében. Hozzáadhat egy engedélyezési szabályt a ufw eszközhöz, megadva a küldő szerver IP-címét a 80 port felé a következő paranccsal:

Miután végzett a módosításokkal, indítsa újra a Django alkalmazásszervert, hogy a változtatások érvénybe lépjenek, mivel a sudo ufw reload futtatása úgy tűnik, nem lépteti életbe a változtatásokat:

Miután a szerver újraindult, indítsa el a konténert úgy, ahogy azt a 1. lépésben vagy a 2. lépésben:

Ezután próbálja meg megnyitni az első Django szerver IP-címét a böngészőben, hogy ellenőrizze, megjelenik-e a Polls felület: http://FIRST_SERVER_IP/polls. Ez sikertelen lesz. Most jelentkezzen ki az első szerverről, és ismételje meg az itt elvégzett lépéseket a második szerverre is. Nyissa meg a /etc/ufw/after.rules fájlt a nano segítségével sudo felhasználóként:

Ahogy korábban is tette, görgessen az aljára, és adja hozzá az UFW konfigurációs blokkot:

Mentse el és zárja be a fájlt, miután hozzáadta a fenti blokkot.

Ezután adjon hozzá egy engedélyezési szabályt a ufw megadva a forrás szerver IP-címet a porthoz80 a következő paranccsal:

Indítsa újra a szervert a változtatások érvénybe lépéséhez:

Amikor a szerver újra elindul, indítsa el újra a konténert a következő paranccsal:

Tesztelje, hogy meg tudja-e tekinteni a szavazási felületet közvetlenül a második szerver IP-címére lépve: http://SECOND_SERVER_IP/polls. Ennek is sikertelennek kell lennie.

Ez az architektúra most már készen áll a tesztelésre. Látogasson el a https://example_domain_here/polls címre a default Polls felület megtekintéséhez a böngészőjéből. Ez azt jelenti, hogy az Nginx proxy szerver továbbra is hozzáfér a Django háttérszerverekhez.

Összegzés

Ebben az útmutatóban bemutattuk, hogyan valósítson meg egy skálázható infrastruktúrát Docker konténerek használatával. Az infrastruktúra tartalmaz egy különálló PostgreSQL adatbázis-szervert, két háttéralkalmazás-szervert és egy Nginx proxy szervert a terheléselosztáshoz és a forgalom megosztásához a két szerver között. Bár az alkalmazásunkat a Django Polls alkalmazásra alapoztuk, ezt az architektúrát testre szabhatja különféle alkalmazásokhoz más keretrendszerek használatával is, mint például a Node.js, Laravel, stb.

Ez egy alapvető útmutató a kezdéshez. Néhány fejlesztési lehetőség, amit hozzáadhat, hogy a lemezképet egy olyan tárolóban hosztolja, mint a Docker Hub, ami lehetővé teszi a lemezkép egyszerű terjesztését több szerverre. Hozzáadhat folyamatos integrációs és telepítési folyamatokat (CI/CD) is, hogy automatikusan felépítse, tesztelje és telepítse a lemezképeket az alkalmazásszerverekre, amikor egy esemény történik. Például egy esemény lehet az új kód feltöltése egy git tároló meghatározott ágára. Érdemes lehet automatizálni azt is, hogy mi történjen, ha a konténer hibába ütközik. A Docker hivatalos dokumentációja jó útmutatást nyújt a Konténerek automatikus indítása témakörben hibák vagy rendszerújraindítás esetén.

Kellemes kódolást!

author

Hark Labs

Szerző · CloudSigma

Preslav Dobrev a CloudSigma kreatív tervezője, aki hagyományos és innovatív marketingcsatornák segítségével következetes vállalati identitás kialakítására összpontosít. Kiemelkedően képes ötvözni a művészi látásmódot a stratégiai marketinggel, hogy hatásos márkatörténeteket hozzon létre.

Hozzászólások

Még nincsenek hozzászólások. Legyen Ön az első.