Nginx priekšā, privāts aizmugurējais serveris aiz VPN
Pārlūks runā ar Nginx, un Nginx atver otru savienojumu tunelī. Maršrutē abus, pārbaudi abus sertifikātus un turi publiskos pāradresējumus publiskus.
Izseko vienu pieprasījumu no tālruņa vilcienā līdz aizmugurējam serverim, kas pastāv tikai privātā tīklā. Tālrunis atrisina publisku nosaukumu, izveido savienojumu ar publisku adresi portā 443 un pabeidz parastu TLS rokasspiedienu. Nginx pieņem šo savienojumu un pēc tam atver otru, pilnīgi atsevišķu savienojumu ar adresi, kuru tas sasniedz tikai caur VPN saskarni. Tālrunī nekas nemainās, un tālrunis nekad neuzzina, ka tunelis bija iesaistīts.
Izsekot vienam pieprasījumam cauri diviem savienojumiem
Ienākošā daļa ir publisks HTTP darījums. Tam ir publisks nosaukums, publisks sertifikāts un atbildes ceļš, kam jāstrādā jebkurai adresei, kāda apmeklētājam tobrīd ir. Jebkuras izmaiņas, kas traucē šo ceļu, vienlaikus salauž visus apmeklētājus. Tāpēc publiskā daļa ir tā, ar kuru tu gribi eksperimentēt vismazāk.
Izejošā daļa ir privāta. Nginx kļūst par klientu, atrisina iekšēju nosaukumu vai izmanto fiksētu adresi, un sasniedz pakalpojumu, kas atteiktos no savienojuma no interneta.
Public client -> frontend public address:443 (TLS, public name)
Frontend -> VPN private backend 10.40.0.20:8443 (TLS, private name)
Turi tos atsevišķi galvā, un konfigurācija kļūst acīmredzama. Sajauc tos, un tu beigās mēģināsi likt publiskam klientam piedalīties tunelī, un tieši no tā nāk lielākā daļa šī dizaina apjukuma. Privātā daļa drīkst būt trausla. Publiskā nedrīkst.
Pirms kaut ko no tā būvē, apstiprini, ka lietotnes publicēšana ir apzināta. Strādājošs starpniekserveris ir arī strādājoša pakļaušana riskam, un autentifikācijas modelim jābūt lēmumam, nevis blakusefektam.
Vārtejas nosaukumam jāiztur tunelis
Nosaukumu atrisināšanā slēpjas viltīgs slazds. Ja privātais DNS pārraksta to pašu nosaukumu, ko VPN profils izmanto savai vārtejai, atkārtots savienojums var beigās mēģināt sasniegt šo vārteju caur tuneli, kuru tam pašam vajadzētu izveidot. Klientam šis nosaukums jāatrisina pirms tuneļa pastāvēšanas. Kad tas tiek atrisināts tuneļa iekšienē, savienojumu vairs nevar izveidot.
Izmanto atšķirīgus apstiprinātus nosaukumus vārtejai un aizmugurējam serverim, un ierobežo atrisinātāja politiku tā, lai katrs nosaukums atrisinātos uz adresi, kura nepieciešama tā lietotājam. Lietotnes Host galvenes maiņa šeit nepalīdz, jo uzmeklēšanu veic VPN klients.
Pēc tam padomā par apjomu. Priekšgalam ir nepieciešams maršruts uz aizmugurējā servera adresi, un tam arī jāturpina atbildēt publiskiem klientiem. Pilns tunelis uz šī saimnieka var izpildīt pirmo prasību un salauzt otro.
Kur politika to atļauj, tunelis uz konkrētu galamērķi ir tīrākais dizains. Kur politika pieprasa pilnu tuneli, priekšgals pieder atsevišķā tīkla kontekstā, nevis tiek lāpīts ar ad hoc maršrutiem zināmiem apmeklētājiem.
Uzrakstīt servera bloku tā, lai abas daļas pārbaudītu
Pieņemsim, ka aizmugurējais serveris uzrāda sertifikātu nosaukumam backend.corp.example un atbild uz privātas adreses. Savienošanās ar adresi, pārbaudot nosaukumu, ir tieši tas, kam domātas starpniekservera moduļa SNI un nosaukuma opcijas.
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;
}
}
Katrs ceļš un adrese iepriekš ir vietturis. Svarīgas ir tās daļas, kas tur pārbaudi ieslēgtu: nosaukums, ko pārbaudīt, uzticības pakete, ar ko to pārbaudīt, un dziļums, kas atbilst apstiprinātajai ķēdei.
proxy_set_header Host app.example.com ir apzināta. Aizmugurējais serveris jākonfigurē, lai pieņemtu šo publisko izcelsmi, un tam jāuzticas pārsūtītajām galvenēm tikai no šī priekšgala. Pārrakstīt X-Forwarded-For ar klienta adresi ir pareizi vienam starpniekam un nepareizi ķēdei, tāpēc izvietojumam ar vairākiem starpniekiem nepieciešams savs uzticamo adrešu risinājums.
Panākt, lai publiskā izcelsme uzvestos kā tāda
Lietotnei jāizvada absolūti URL, pāradresācijas un sīkfaili publiskajai izcelsmei. Ja tā pāradresē apmeklētāju uz backend.corp.example, šis apmeklētājs tiek sūtīts uz nosaukumu, kuru tas nevar atrisināt.
Labo to ar lietotnes atbalstīto ārējā URL iestatījumu un pārskatītu pāradresācijas politiku, nevis pārrakstot saimniekdatoru nosaukumus atbilžu pamattekstos. Virkņu aizstāšana patvaļīgā saturā salauž parakstītas kravas un rada kļūdas, kuras grūti izsekot.
Sīkfaili pelna tādu pašu rūpību. Sīfails, kas saistīts ar privāto nosaukumu, nekad netiks nosūtīts no pārlūka, kas zina tikai publisko.
Apstiprini arī, ka Nginx patiešām var aizņemt publisko ligzdu. Esošam tīmekļa pakalpojumam portā 443 ir jāpārvietojas, vai arī priekšgalam jāatrodas citur, jo divi procesi nevar piesaistīt vienu un to pašu adresi un portu.
Pārbaudīt katru daļu tur, kur tā patiešām darbojas
Validē konfigurāciju ar instalēto parseri pirms katras pārlādes, lai drukas kļūda nenomestu klausītāju, kas pašlaik apkalpo.
Pēc tam pārbaudi aizmugurējo daļu no priekšgala saimnieka paša, tajā pašā tīkla kontekstā, ko izmanto Nginx. Ping caur tuneli pierāda sasniedzamību un neko par TLS, autorizāciju vai lietotni.
Visbeidzot izdari svaigu publisku pieprasījumu uz īsto saimniekdatora nosaukumu ar parastu sertifikāta pārbaudi, un vēro atbildes ceļu, nevis tikai atbildes pamattekstu.
Saglabā abus novērojumus kopā ar izvietoto konfigurāciju un pieraksti, kas notiek, kad tunelis nav pieejams. Priekšgalam jāatgriež kontrolēta augšupstraumes kļūda, nevis klusi jāpāriet uz citu aizmugurējo serveri, ko neviens nav dokumentējis. 502 ar skaidru žurnāla rindu ir labs rezultāts. Kešota lapa no nevēlamas izcelsmes tāda nav.