Някой насочва публичен HAProxy хост към вътрешно приложение и пита защо браузърът не може да продължи. Проксито достига приложението през своя VPN, пренасочването връща заглавка Location и браузърът после опитва адрес, който съществува само в тунела. Отвън страницата просто забива. Решението е коя страна отваря втората връзка и точно това отличава пренасочването от бекенда.

Два пътя, които изглеждат еднакво в конфигурацията

Пренасочването приключва размяната с отговор. Клиентът чете Location и започва нова заявка от мястото, където се намира, тоест от мрежата, която никога не сте контролирали. Проксито вече не участва. Всичко след това зависи от DNS, маршрута и доверието на самия клиент, затова резултатът варира според това къде потребителят е отворил браузъра:

GET /app        client -> proxy
302 Location    proxy  -> client   (http://10.40.0.20:8080/)
GET /app        client -> 10.40.0.20:8080   client network, no route

Бекендът на проксито задържа втория етап от страната на сървъра. Проксито го отваря по пътя, който вече има, и клиентът продължава да говори с едно публично име. Ако тунелът падне, клиентът получава грешка вместо URL, който не може да последва. Тази разлика е и това, което прави повредата диагностицируема, защото грешката се появява там, където са журналите:

GET /app        client -> proxy
GET /app        proxy  -> 10.40.0.20:8080   over the VPN
response        proxy  -> client

Документацията за пренасочванията на HAProxy очертава точно тази граница: да отговориш на клиента с пренасочване е различно действие от препращането на заявката към бекенд. Двете директиви стоят на няколко реда една от друга в конфигурационен файл и се държат съвсем различно. Едната приключва заявката, другата започва втора, която принадлежи на проксито.

Какво е нужно на браузъра и какво VPN-ът на сървъра не му дава

Заявката на самия браузър се нуждае от четири неща, които може да няма: DNS отговор за частното име, маршрут до този адрес, разрешение да достигне слушащата услуга и доверие в сертификата, който тази услуга представя. Хостът на проксито притежава и четирите чрез своя тунел. Никое от тях не се прехвърля към клиент, който никога не е бил в този тунел, защото тунелът е свойство на хоста, а не на URL.

Тази разлика обяснява симптома почти работи. Първата заявка успява, адресната лента се променя и после връзката забива или се проваля, докато проксито е здраво през цялото време. В конфигурацията на проксито нищо не е счупено и настройката ѝ не помага на клиент, който няма път до 10.40.0.20. Или клиентът получава маршрут, или проксито трябва да осъществи връзката от негово име.

Когато само проксито може да достигне приложението

Премахнете действието за пренасочване и изпратете тези заявки към бекенд, който сочи към частния адрес. Фронтендът запазва публичното си име, докато бекендът решава накъде всъщност отива заявката. Нищо в пътя на клиента не се променя, защото проксито спира да описва дестинация и започва да бъде такава. За приложение, което умишлено слуша на вътрешния порт 8080, блокът на сървъра е кратък:

backend private_app
    mode http
    option httpchk GET /health
    server app1 10.40.0.20:8080 check

Четете този блок като твърдение за таблицата за маршрутизация на проксито: 10.40.0.20 трябва да е достъпен от самия хост на проксито, което тук означава през VPN интерфейса, а не през маршрута по подразбиране. Ключовата дума check само съобщава какво прави този маршрут и пътят за здраве трябва да съществува в приложението, иначе всяка проверка маркира сървъра като недостъпен. Успешната проверка не доказва нищо за клиента и не заменя политиката, която решава кой може да използва бекенда.

Фрагментът не е пълен фронтенд. Запазете слушателя, удостоверяването, избора на разрешени хост и път и правилото, което решава кой изобщо може да достигне приложението. Съгласувайте и протокола на бекенда, защото HTTPS бекендът изисква проверка на сертификата и конфигурация на идентичността на сървъра, а пропускането на тази проверка превръща частната връзка в непроверена.

Потвърдете обратния път в двете посоки, преди да обявите победа. Приложението вече вижда връзка от проксито, така че журналите му и всякакви метаданни за адреса на клиента описват проксито, освен ако не уредите друго. Решете как се обработват идентичността и препратените адреси и тествайте решението, вместо да го предполагате.

Собствените пренасочвания на приложението още сочат навътре

Препращането на първата заявка е само половината от интеграцията. Приложението може да издава абсолютни пренасочвания, твърдо кодирани URL на ресурси или бисквитки, ограничени до името, което познава вътрешно, и всяко от тях връща браузъра към адрес, който не може да достигне. Заглавка Location, сочеща към вътрешното име, изглежда идентична на първоначалния проблем, затова бива диагностицирана погрешно като повреда на проксито.

Задайте документирания външен URL на приложението и неговите опции за прокси, после съгласувайте заглавката Host с виртуалния хост и очакванията за сертификата. Бисквитка, ограничена до вътрешното име, няма да се върне през публичното име и цикълът на влизане, който следва, се чете като бъг в удостоверяването. Променете първо външния URL, тествайте отново от чист профил на браузъра и очаквайте полумигрирали настройки да дадат вход, който успява, и сесия, която умира веднага.

Доверявайте се на препратени метаданни само от определеното прокси. Заглавка, която всеки клиент може да зададе, никога не бива да става стойност за оторизация, иначе проксито се превръща в начин извикващият да претендира за чужда идентичност. Това правило е независимо от въпроса за пренасочването и оцелява при всеки следващ редизайн.

Решете кой дизайн всъщност имате

Ако всеки потребител вече има оторизиран VPN достъп, пренасочване към частен URL може да е съзнателен дизайн. Потвърдете това изискване изрично, вместо да го предполагате, защото двата дизайна обслужват напълно различни групи. Единият изобщо не работи от хотелска мрежа, а другият излага приложението на всеки, който може да зареди публичния URL. Това разграничение принадлежи в бележката за дизайна.

Изпълнете проверката от машина в мрежата на потребителите и проследете всеки скок на браузъра, не само първия отговор. Наблюдавайте адресната лента и всяка следваща заявка, защото един абсолютен URL в таг за ресурс е достатъчен да счупи поток, който първият скок е преминал. Влизането трябва да работи през публичното име и ресурсите, които трябва да бъдат отказани, трябва да останат отказани.

Публикуването на обратно прокси е отделно решение за достъп, а не прозрачно разширение на собствения VPN на проксито към всеки, който може да зареди публичния му URL. Двете изглеждат еднакво на диаграма и се различават по това кой е допуснат. Решаването на този въпрос след внедряването е начинът, по който вътрешно приложение случайно става публично.

Запишете кой от двата изградихте и защо. Следващият човек, който пипне конфигурацията, ще предположи другия. Едно пренасочване, добавено за удобство, е достатъчно да пресъздаде първоначалната повреда и симптомът ще изглежда точно като току-що поправения.

Подобни статии