Алдында Nginx, VPN артында жеке backend
Браузер Nginx-пен сөйлеседі, ал Nginx туннельге екінші қосылым ашады. Екеуін де бағытта, екі сертификатты да тексер және жалпыға ашық қайта бағыттауларды ашық күйде ұста.
Пойыздағы телефоннан тек жеке желіде ғана болатын backend-ке дейін бір сұранысты қадағала. Телефон жалпыға ашық атауды шешеді, 443 портындағы жалпыға ашық мекенжайға қосылады және қалыпты TLS қол алысуды аяқтайды. Nginx бұл қосылымды қабылдайды, содан кейін VPN интерфейсі арқылы ғана жететін мекенжайға екінші, толығымен бөлек қосылым ашады. Телефонда ештеңе өзгермейді және телефон туннельдің қатысқанын ешқашан білмейді.
Бір сұранысты екі қосылым арқылы қадағалау
Кіріс бөлігі — жалпыға ашық HTTP транзакциясы. Оның жалпыға ашық атауы, жалпыға ашық сертификаты және келушінің сол сәттегі кез келген мекенжайы үшін жұмыс істеуі керек жауап жолы бар. Бұл жолды бұзатын кез келген өзгеріс барлық келушілерді бірден бұзады. Сондықтан жалпыға ашық бөлік — тәжірибе жасауды ең аз қалайтын бөлік.
Шығыс бөлігі жеке. Nginx клиентке айналады, ішкі атауды шешеді немесе тіркелген мекенжайды пайдаланады және интернеттен келетін қосылымнан бас тартатын қызметке жетеді.
Public client -> frontend public address:443 (TLS, public name)
Frontend -> VPN private backend 10.40.0.20:8443 (TLS, private name)
Оларды санада бөлек ұста, конфигурация өзінен-өзі айқын болады. Егер біріктірсең, соңында жалпыға ашық клиентті туннельге қатыстыруға тырысасың, және бұл дизайндағы шатасудың көп бөлігі осыдан шығады. Жеке бөлік нәзік бола алады. Жалпыға ашық бөлік ондай болмауы керек.
Осының кез келгенін салудан бұрын қолданбаны жариялау әдейі екенін раста. Жұмыс істейтін прокси — бұл да жұмыс істейтін әшкерелеу, ал аутентификация моделі шешім болуы керек, жанама әсер емес.
Шлюз атауы туннельден аман өтуі керек
Атауларды шешуде нәзік тұзақ бар. Егер жеке DNS VPN профилі өз шлюзі үшін пайдаланатын сол атауды қайта жазса, қайта қосылу соңында өзі құруы тиіс туннель арқылы сол шлюзге жетуге тырысуы мүмкін. Клиентке бұл атау туннель пайда болмай тұрып шешілуі керек. Ол туннель ішінде шешілсе, қосылымды мүлде құру мүмкін емес.
Шлюз мен backend үшін бөлек бекітілген атауларды пайдалан және шешуші саясатын әр атау өз тұтынушысына қажет мекенжайға шешілетіндей шекте. Қолданбаның Host тақырыбын өзгерту мұнда ештеңе бермейді, өйткені іздеуді VPN клиенті жасайды.
Содан кейін ауқым туралы ойлан. Frontend-ке backend мекенжайына маршрут керек, сонымен қатар ол жалпыға ашық клиенттерге жауап беруді жалғастыруы керек. Сол хосттағы толық туннель бірінші талапты қанағаттандырып, екіншісін бұзуы мүмкін.
Саясат рұқсат еткен жерде нақты мақсатқа туннель таза дизайн. Саясат толық туннельді талап еткен жерде frontend бөлек желілік контекстке жатады, белгілі келушілер үшін уақытша маршруттармен жамалмайды.
Сервер блогын екі бөлік те тексеретіндей етіп жаз
Backend осы атауға сертификат ұсынады деп есептейік: backend.corp.example және жеке мекенжайда жауап береді. Атауды тексеріп отырып мекенжайға қосылу — прокси модулінің SNI және атау опцияларының дәл мақсаты.
upstream private_app {
server 10.40.0.20:8443;
}
server {
listen 443 ssl;
server_name app.example.com;
ssl_certificate /etc/nginx/tls/app-fullchain.pem;
ssl_certificate_key /etc/nginx/tls/app-key.pem;
location / {
proxy_pass https://private_app;
proxy_ssl_server_name on;
proxy_ssl_name backend.corp.example;
proxy_ssl_trusted_certificate /etc/nginx/trust/backend-ca.pem;
proxy_ssl_verify on;
proxy_ssl_verify_depth 3;
proxy_set_header Host app.example.com;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
Жоғарыдағы әр жол мен мекенжай — орын толтырғыш. Маңыздысы — тексеруді қосулы ұстайтын бөліктер: тексерілетін атау, оған қарсы тексеруге арналған сенім бумасы және бекітілген тізбекке сәйкес тереңдік.
proxy_set_header Host app.example.com әдейі. Backend осы жалпыға ашық шығу тегін қабылдайтындай конфигурациялануы керек және жіберілген тақырыптарға тек осы frontend-тен сенуі керек. Мынаны қайта жазу X-Forwarded-For клиент мекенжайымен бір прокси үшін дұрыс, ал тізбек үшін қате, сондықтан көп проксилі орналастыруға өзінің сенімді мекенжай реті керек.
Жалпыға ашық шығу тегін солай ұстауға мәжбүр ету
Қолданба жалпыға ашық шығу тегі үшін абсолютті URL-дер, қайта бағыттаулар және cookie-лер шығаруы керек. Егер ол келушіні мынаған бағыттаса: backend.corp.example, бұл келуші өзі шеше алмайтын атауға жіберіледі.
Мұны қолданбаның қолдайтын сыртқы URL параметрі және қаралған қайта бағыттау саясаты арқылы түзе, жауап денелерінде хост атауларын қайта жазбай. Кездейсоқ мазмұндағы жолдарды ауыстыру қол қойылған жүктемелерді бұзады және ізіне түсу қиын қателерді тудырады.
Cookie-лер де сол күтімге лайық. Жеке атауға шектелген cookie-ді тек жалпыға ашық атауды білетін браузер ешқашан жібермейді.
Nginx шынымен жалпыға ашық сокетке ие бола алатынын да раста. 443-тегі бар веб-қызмет көшуі керек немесе frontend басқа жерде тұруы керек, өйткені екі процесс бір мекенжай мен портты байлай алмайды.
Әр бөлікті ол шынымен жұмыс істейтін жерде тексер
Конфигурацияны орнатылған талдағышпен әр қайта жүктеу алдында валидацияла, теру қатесі қазір қызмет көрсетіп тұрған тыңдаушыны құлатпасын.
Содан кейін backend бөлігін frontend хостының өзінен, Nginx пайдаланатын сол желілік контексте сынап көр. Туннель арқылы ping қолжетімділікті дәлелдейді және TLS, авторизация немесе қолданба туралы ештеңе айтпайды.
Соңында нақты хост атауына қалыпты сертификат тексеруімен жаңа жалпыға ашық сұраныс жібер және тек жауап денесін емес, жауап жолын бақыла.
Екі байқауды да орналастырылған конфигурациямен бірге сақта және туннель қолжетімсіз болғанда не болатынын жаз. Frontend бақыланатын upstream қатесін қайтаруы керек, ешкім құжаттамаған басқа backend-ке үнсіз ауыспауы керек. Айқын журнал жолы бар 502 — жақсы нәтиже. Күтпеген дереккөзден кэштелінген бет ондай емес.