Дазволіць праходнае TLS-злучэнне ў кантэксце stream NGINX
NGINX можа адхіліць перадачу TCP TLS, не спыняючы TLS. Змясціце правіла дазволу ў stream, а не ў HTTP location, і праверце, які адрас партнёра прыходзіць.
Перадача зашыфраваных байтаў без захоўвання сертыфіката — гэта тое, што робіць рэлей праходжання TLS, і такая схема зручная і крыху заблытаная. Паколькі нічога не дэшыфруецца, няма нічога ў форме HTTP, што можна было б фільтраваць, таму звычайны блок location і яго правілы доступу тут не дапамогуць. Рашэнне, даступнае NGINX, тычыцца самога злучэння: які сеткавы партнёр пастукаў і ці трэба яго наогул прапускаць.
Рашэнне належыць stream, а не HTTP
У кантэксце stream NGINX працуе з TCP-сесіямі. Ён бачыць адрас партнёра злучэння і можа прымяніць да яго ўпарадкаваныя правілы allow і deny, перш чым любы байт дасягне backend. Гэта поўнае рашэнне аб допуску, і яно не патрабуе прыватнага ключа, сертыфіката і разбору HTTP.
| Mechanism | What it decides | Where it lives |
|---|---|---|
| stream allow/deny | Whether this TCP peer is relayed | stream server block |
| ssl_preread map | Which backend a named connection goes to | stream, with the preread module |
| HTTP location rule | Whether an HTTP request is served | http server block |
Гэтыя тры радкі ніколі не замяняюць адзін аднаго. Капіраванне дырэктывы доступу HTTP у любы файл, дзе згадваецца порт 443, нічога не зменіць, бо сервер stream ніколі не чытае кантэкст http.
Дазвольце злучэнне перад яго перадачай
Меркавана ёсць існуючая ўстаноўка з даступнымі модулямі stream і stream-access, VPN-кліенты трымаюць адрасы крыніцы ў 10.90.0.0/24, а backend на 192.168.50.20:443 ужо прадстаўляе патрэбную ідэнтычнасць HTTPS.
stream {
server {
listen 443;
allow 10.90.0.0/24;
deny all;
proxy_pass 192.168.50.20:443;
}
}
Чытайце гэта як фрагмент новага listener, а не як прамую замену працоўнай канфігурацыі. Спачатку праглядзіце існуючыя listener і include, бо другі listener на ўжо занятым порце падае пры reload, а не ў момант запыту.
Звярніце ўвагу, чаго няма: listen ... ssl няма, дырэктывы сертыфіката няма. NGINX перадае зашыфраваны паток, а backend спыняе TLS і прадстаўляе сертыфікат, які правярае кліент. Кліент, які не прайшоў allowlist, атрымлівае адхіленне TCP-сесіі, а не старонку HTTP 403, і любы інструмент, які чакае код стану, паведаміць нешта бескарыснае.
Што ахоплівае allowlist і што не
Калі рэлей ужо выбірае backend па імені сервера, ssl_preread і map могуць працягваць гэтую працу, калі модуль даступны. Імя ўсё яшчэ падае кліент, і нішто ў прадстаўленні імя не даказвае, што кліент далучыўся да VPN.
Правіла з прыкладу ахоплівае ўвесь listener stream. Гэта робіць яго непрыдатным для адной кропкі ўваходу, якая абслугоўвае сумесь публічных сайтаў і сайтаў толькі для VPN, дзе спатрэбілася б выключэнне для кожнага імя; асобныя listener звычайна зразумелейшыя за залежную ад імя палітыку, якую ніхто не можа прачытаць.
Варта назваць яшчэ дзве прагалы. Супадзенне прэфікса нічога не кажа пра тое, праз які інтэрфейс прыйшоў пакет, а правіла HTTP у іншым месцы не можа абмежаваць гэты listener. Абедзве прычыны трымаць палітыку ўваходу на ўзроўні хоста ў полі зроку, а не лічыць адзін радок allow усёй мяжой. Запішыце мяжу як два кантролі, якія павінны супадаць, каб змена любога з іх праглядалася.
Чый адрас NGINX насамрэч бачыць?
Балансіроўшчык нагрузкі, іншы proxy або source NAT могуць паставіць пасярэдніка перад NGINX, таму партнёр, якога ён бачыць, не ёсць унутраным адрасам VPN-кліента. Праверце рэальны шлях перад выбарам прэфікса, бо allowlist, напісаны для няправільнага адраса, альбо пускае ўсіх за транслятарам, альбо нікога.
Пратакол PROXY і апрацоўка рэальнага IP — законныя адказы, і іх трэба наладжваць толькі для сумяшчальных, яўна давераных адпраўнікоў. Абодва механізмы вераць таму, што кажа адпраўнік, і менавіта таму спіс адпраўнікоў павінен быць кароткім. Давер да загалоўка ідэнтычнасці ад любога інтэрнэт-кліента не робіць звесткі пра крыніцу зноў надзейнымі; ён ператварае правільную адмову ў падроблены допуск.
Праверце абодва вынікі перад reload
Праверце канфігурацыю, зрабіце reload, затым праверце двойчы: новую дазволеную сесію, якая павінна працаваць, і адхіленую, якая не павінна. Пакіньце звычайную праверку сертыфіката backend у дазволеным тэсце, бо рэлей, які злучаецца, але не можа праверыць backend, выправіў адну праблему і стварыў іншую.
nginx -t
ss -tnp | grep ':443'
Праверце маршрут да backend і адказ асобна. Праходжанне allowlist даказвае толькі тое, што NGINX прыняў сесію; яно не можа прымусіць недасяжны backend адказаць і не можа аднавіць зваротны шлях, якога не было да пачатку.