Кожны радок у журнале доступу паказвае той жа адрас loopback, хаця старонка загружаецца і сертыфікат праходзіць праверку. Нішто не зламана ў сэнсе недаступнасці, і менавіта таму гэта цягнецца месяцы. Зламалася атрыбуцыя: вэб-бэкенд запісвае адрас кроку, які перанакіраваў злучэнне, і кожнае наступнае рашэнне, якое давярала журналу, атрымала ў спадчыну той жа няправільны адказ.

Праверкі ніжэй ідуць ад кабеля ўнутр. Спыніцеся на першай, якая тлумачыць значэнне, якое вы бачыце, бо кожны наступны крок мяркуе, што папярэднія ўжо праўдзівыя. Ні адна з іх не патрабуе здагадак пра канфігурацыю франтэнда.

Ідзіце за двума злучэннямі, а не за радком журнала

Port-Share мультыплексуе два пратаколы на адным слухачы TCP. OpenVPN правярае першыя байты ўваходнага злучэння, пакідае яго, калі той выглядае як яго ўласны пратакол, і перадае ўсё астатняе на другі адрас. Гэты адрас звычайна вэб-сервер на тым жа хасце, таму прыняты сокет вэб-сервера мае працэс OpenVPN у якасці суразмоўцы.

ss -ltnp 'sport = :443'
ss -tnp 'dport = :8080'

Першая каманда паказвае, хто валодае публічным слухачом. Другая паказвае злучэнні, якія прыходзяць на порт бэкенда, і іх адрас суразмоўцы — гэта той, што надрукуе журнал доступу. Калі гэты суразмоўца — loopback, журнал дакладны, і інфармацыя згубілася на ўзроўнем раней. Перайменаванне поля журнала або ўключэнне модуля IP кліента не верне адрас, які злучэнне ніколі не несла.

Гэта праверка вырашае ўсё астатняе. Калі суразмоўца бэкенда — адрас браўзера, то сумеснае выкарыстанне порта не ваша праблема, а фармат журнала.

Перадача транспарту — гэта не ўстаўка загалоўкаў

Перадатчык рухае байты. Ён не разбірае HTTP, таму не можа ўставіць загаловак у запыт, які ніколі не чытае як запыт, і не можа дадаць нічога ў паток TLS, які прапускае некранутым. Модуль, які чакае загаловак проксі, будзе чакаць таго, што не стварае ніводзін кампанент.

Адрас крыніцы могуць несці два механізмы, і абодва патрабуюць згоды з двух бакоў. Пратакол PROXY дадае невялікі загаловак у пачатак злучэння, і бэкенд павінен быць настроены яго чакаць; бэкенд, які яго не чакае, прыме гэтыя байты за пачатак запыту і пацерпіць няўдачу незразумелым чынам. Давераныя загалоўкі проксі, такія як X-Forwarded-For, працуюць, калі іх ставіць проксі, які разумее HTTP, а бэкенду паведамляюць, якія суразмоўцы могуць іх сцвярджаць.

Нішто з гэтага не аўтаматычнае і не бяспечнае па змаўчанні. Бэкенд, які верыць любому ўваходнаму перададзенаму загалоўку, дазваляе кліенту выбраць свой адрас, што ператварае недакладнасць у журнале ў абыход кантролю доступу. Запусціце дэманстрацыю адзін раз на тэставым хасце, перш чым давяраць любому загалоўку на прадукцыйным шляху.

curl -sS -H 'X-Forwarded-For: 127.0.0.1' https://site.example.com/health
grep -F '127.0.0.1' /var/log/nginx/access.log | tail -n 3

Апцыянальны каталог супастаўлення крыніц

Сумеснае выкарыстанне порта мае апцыянальны аргумент каталога, які запісвае супастаўленне паміж зыходным адрасам крыніцы і злучэннем перанакіравання, на платформах, дзе гэтая функцыя рэалізавана. Меркавана вэб-бок звяртаецца да гэтага супастаўлення; гэта не загаловак, і яно не ўстаўляецца ў запыт.

Гэты дызайн варта ведаць, бо ён тлумачыць, чаму некаторыя разгортванні паведамляюць рэальныя адрасы, а іншыя не, пры знешне аднолькавай канфігурацыі франтэнда. Розніца на баку атрымальніка, і звычайна яна жыве ў модулі або пачці, якую большасць пакаваных вэб-сервераў не ўключае па змаўчанні. Чытайце дакументацыю вашага вэб-сервера пра дакладны хук, які ён прапануе, і пацвердзіце, што модуль загружаны, а не прыняты за здагадку.

Калі вы пойдзеце гэтым шляхам, разглядайце гэта як інтэграцыю з дзвюх палоў: супастаўленне, якое запісвае перадатчык, і пошук, які выконвае бэкенд. Праверце абодва і пацвердзіце, што каталог перажывае перазапуск і не расце бязмежна на занятым слухачы.

Вырашыце, які кампанент ручаецца за адрас

Перш чым змяняць канфігурацыю, назавіце кампанент, якому дазволена сцвярджаць адрас кліента, і кампаненты, якім дазволена яму верыць. Адзіны запісаны адказ прадухіляе звычайны дрыфт, калі тры розныя ўзроўні давяраюць рознай крыніцы.

Тры дызайны пакрываюць большасць патрэб. Трымайце публічны слухач і вэб-слухач асобна, каб вэб-сервер бачыў сапраўдных суразмоўцаў і не было праблемы атрыбуцыі. Пастаўце наперад адваротны проксі, які разумее HTTP, завяршыце або разбярыце запыт там, і дайце яму вызначыць перададзены загаловак для бэкенда, які давярае толькі гэтаму проксі. Або пакіньце сумеснае выкарыстанне порта і прызнайце, што журналы паказваюць крок, з правіламі доступу, напісанымі супраць ідэнтычнасці праграмы, а не адраса.

Што не працуе — гэта стаўленне да перададзенага адрасу loopback як да доказу, што запыт узнік на гэтай машыне. Гэты вывад менавіта адваротны: адрас прысутнічае якраз таму, што лакальны кампанент стварыў злучэнне. Правіла, напісанае так, дапускае кожнага, хто можа дасягнуць слухача.

Праверце правіла, а не старонку

Старонка, якая загружаецца, даказвае, што шлях перанакіравання працуе, і нічога не кажа пра атрыбуцыю. Праверце спажыўца адрасу: правіла доступу, абмежаванне хуткасці, запіс аўдыту, геа-пошук.

curl -sS -o /dev/null -w '%{http_code}\n' https://site.example.com/
tail -n 5 /var/log/nginx/access.log
grep -c '' /var/log/nginx/access.log

Параўнайце дазволены знешні запыт з запісамі як франтэнда, так і бэкенда і пацвердзіце, што правіла, якое павінна адмаўляць, усё яшчэ адмаўляе, а тое, якое павінна дапускаць, усё яшчэ дапускае. Калі радок журнала правільны, але правіла ўсё яшчэ паводзіць сябе так, нібы ўсе лакальныя, то правіла чытае іншае поле, чым тое, якое вы выправілі.

Завяршыце, запісаўшы ланцуг атрыбуцыі ў нататкі разгортвання: які слухач, які перадатчык, які загаловак або супастаўленне і які бэкенд настроены яму давяраць. Наступнаму чалавеку, які прачытае радок журнала, спатрэбяцца ўсе чатыры, і менавіта адсутнасць гэтай нататкі робіць так, што той жа тыкет адкрываецца праз год. Трымайце яе побач з канфігурацыяй, а не ў потоцы чата.

Падобныя артыкулы