Урд талд 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 бол сайн үр дүн. Санаандгүй эх сурвалжаас кэшлэгдсэн хуудас тийм биш.