Дістатися до веб-інтерфейсу всередині контейнера VPN: виберіть власника порту
Застосунок ділить простір імен VPN, тому порт належить контейнеру VPN. Правильно прив’яжіть слухач, публікуйте на власнику й тримайте шлях вузьким.
Із застосунком усе гаразд, і з тунелем усе гаразд, а панель усе одно не завантажується. Коли служба працює з network_mode: service:vpn, вона ділить мережевий простір імен контейнера VPN, тобто її слухач і опубліковані порти належать цьому простору імен, а не службі. Звідси випливають три рішення: де прив’язується застосунок, який контейнер публікує порт і наскільки вузький шлях керування. Розставте їх у неправильному порядку, і кожне окреме налаштування виглядатиме правильним, хоча поєднання не може працювати.
Кому належить простір імен порту
У спільному просторі імен додавання запису ports: залежній службі нічого корисного не дає, а кілька мережевих параметрів для неї не підтримуються за задумом. Публікуйте натомість на контейнері, якому належить простір імен. Цей самий контейнер — той, чия адреса з’являється на хості, тому зіставлення читається як один запис, а не один на кожну службу.
services:
vpn:
image: vpn-client-image
cap_add: [NET_ADMIN]
ports:
- "127.0.0.1:8080:8080"
app:
network_mode: "service:vpn"
Зверніть увагу на адресу ліворуч від зіставлення. Прив’язка до 127.0.0.1 залишає опублікований порт на loopback хоста, що зазвичай і потрібно інтерфейсу керування. Прив’язка до 0.0.0.0 відкриває його на всіх інтерфейсах хоста, і це інше рішення щодо безпеки, а не зручність.
Змусьте застосунок слухати там, де простір імен цього чекає
Слухач, прив’язаний до 127.0.0.1 усередині простору імен, доступний лише зсередини цього простору. Опубліковані порти хоста надходять ззовні, тому застосунок має прив’язати ширшу адресу, щоб зіставлення працювало. На більшості серверів це зміна в один рядок, і саме цей крок пропускають після копіювання настанови зі зміцнення, написаної для розгортання без контейнерів.
docker compose exec app ss -lntp
docker port vpn
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/
Список слухачів усередині застосунку каже правду про адресу прив’язки, а docker port показує, що власник насправді опублікував. Якщо перший показує 127.0.0.1, а другий показує зіставлення на хості, ви знайшли невідповідність, не торкаючись конфігурації VPN.
Виберіть, як входить шлях керування
Є три розумні варіанти. Публікуйте на контейнері VPN і діставайтеся до нього з хоста або з локальної мережі. Поставте зворотний проксі перед простором імен і віддайте проксі єдиний відкритий порт. Або тримайте панель доступною лише зсередини простору імен через сеанс exec або тунель SSH, що дає найменше розкриття і найменше зручності.
Який підійде, залежить від того, кому і звідки потрібен інтерфейс. Одному адміністратору на тому самому хості достатньо прив’язки до loopback. Команді, яка дістається через VPN, потрібен продуманий шлях і названий власник. Вибір варіанта з проксі дає TLS і журнали доступу, але потребує ще одного компонента, який треба підтримувати актуальним.
Відкрийте порт керування, не відкриваючи все
Власна політика локального доступу або блокування клієнта VPN може відкинути вхідний запит керування, навіть коли вихідний тунель працює бездоганно. Дозвольте один задокументований виняток для потрібного джерела й порту, потім підтвердьте, що звичайний захист тунелю не змінився. Вимкнення аварійного вимикача заради завантаження панелі міняє реальний контроль на вкладку браузера.
Залиште власну автентифікацію застосунку ввімкненою. Перебування всередині стека, під’єднаного до VPN, не дає прав кожному локальному користувачеві й кожному пристрою, який може дістатися хоста, а панель адміністратора без автентифікації за тунелем залишається панеллю без автентифікації.
Перевірте з пристрою керування, а потім перевірте ще раз пізніше
Тестуйте з машини, яка справді керуватиме службою, а не з хоста, потім окремо перевірте потрібний застосунку шлях до інтернету. Успіх у керуванні доводить один напрямок і нічого не каже про вихідний трафік.
Перевірте знову після перестворення стека. Замінений власник мережі змінює простір імен, до якого під’єднується застосунок, і URL, що працював до оновлення, після нього може нікуди не вказувати. Запишіть опубліковане зіставлення й адресу прив’язки, щоб наступна перебудова була двохвилинною перевіркою, а не повторним розслідуванням.