Між приватним сайтом та інтернетом стоять три незалежні рішення: який сокет приймає з'єднання, який шлях може його доставити і яким клієнтам HTTP відповідає вибраний сервер. Блок сервера ухвалює лише перше рішення. Ставтеся до двох інших як до окремих засобів контролю, інакше сайт виглядатиме приватним, поки старий вхід залишається відкритим. Більшість збоїв NGINX лише для VPN походить від перевірки лише першого рівня.

У прикладі використовується шлюз Linux OpenVPN за адресою 10.90.0.1 на tun0, клієнти в 10.90.0.0/24, збережені джерела та TCP 8443, зарезервований для цього входу. Налаштуйте значення, збережіть рівні.

Почніть із сокета, а не з імені хоста

Прив'яжіть слухач HTTPS до адреси тунелю та окремого порту. Конкретну адресу легше осмислити, ніж універсальний сокет із перевіркою імені, бо ядро не віддасть порт іншій локальній адресі.

server {
    listen 10.90.0.1:8443 ssl;
    server_name admin.corp.example;

    ssl_certificate     /etc/nginx/tls/admin-fullchain.pem;
    ssl_certificate_key /etc/nginx/tls/admin-key.pem;

    root /srv/private-site;

    allow 10.90.0.0/24;
    deny all;

    location / {
        try_files $uri $uri/ =404;
    }
}

Сертифікат має містити ім'я хоста служби, яке вводять клієнти, а приватне подання DNS має розв'язувати цей хост у прив'язану адресу. server_name лише вибирає віртуальний хост; він нікого не автентифікує. Відсутній запис DNS дає помилку сертифіката, схожу на збій TLS. Перевірте ім'я, перш ніж замінювати сертифікат.

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

Закрийте кожен інший слухач для цього вмісту

Перелічіть директиви listen і порівняйте корені, які вони обслуговують. Блок, доданий для іншого застосунку, може проксіювати на той самий upstream, а старий сервер за замовчуванням може й далі відповідати після встановлення нового. Цей вивід і є справжнім переліком, а не файл, який ви щойно редагували. Порівняйте кожен корінь, що обслуговує той самий вміст.

sudo nginx -T | grep -n "listen\|server_name\|root\|proxy_pass"

Перевірте обидві родини адрес. Прив'язка IPv4 залишає сокет IPv6 недоторканим, а новий запис A не відкликає стару відповідь AAAA, що досі вказує на публічний шлях.

Виведіть старий віртуальний хост окремою зміною. Видалення публічного двійника нового блока зазвичай і є кроком, який справді закриває вхід; приватний слухач лише додає потрібний.

Обмежте вхідний шлях на хості

Адреса прослуховування обмежує сокет, а не вхідний інтерфейс. Пакет, маршрутизований на цю адресу з іншого місця, все одно надходить як локальний ввід, тому міжмережевому екрану хоста потрібна власна заява про те, звідки може приходити з'єднання. Тому сама прив'язка рідко задовольняє аудит.

За політики вхідних за замовчуванням «заборонити» і без ширшого дозволу для цієї служби обмежене правило називає тунель, діапазон джерел, призначення та порт разом:

sudo ufw allow in on tun0 proto tcp from 10.90.0.0/24 to 10.90.0.1 port 8443

Прочитайте чинний порядок міжмережевого екрана перед застосуванням. Раніший широкий дозвіл може звести обмеження нанівець, а раннє остаточне відкидання може не дати дійти до цього дозволу. Не очищайте сторонні правила і не вимикайте міжмережевий екран, щоб приклад підійшов.

Це правило — вхід на хост, а не маршрут до іншої машини LAN, і зовнішній слухач OpenVPN шлюзу залишається окремою службою. Якщо сайт раніше був публічним, сплануйте, як виводиться старий вхід і як обробляються наявні сеанси.

Зберігайте список HTTP цілим, коли змінюються розташування

NGINX оцінює записи allow і deny по порядку, і список на рівні сервера вище пропускає оголошений пул до остаточного deny. Модуль доступу також фіксує, що розташування, яке визначає будь-який запис доступу, використовує власний список, а не батьківський. Порядок важливий не менше самих записів.

Це скидання — звичайна регресія. Нове розташування завантаження, API або здоров'я, що додає один запис, мовчки замінює обмеження на рівні сервера, і сайт стає ширшим на найновішому доданому шляху.

Перегляньте кожне розташування, псевдонім і альтернативний блок як частину однієї політики. Якщо перевірки IP поєднуються з автентифікацією NGINX, розберіться в satisfy: параметр any може пропустити клієнта через один механізм, поки інший не пройдено. Внесіть список доступу до контрольного списку розташувань.

Відмова HTTP відбувається після того, як з'єднання TCP досягає NGINX. Вона доповнює мережеве обмеження, а власна авторизація застосунку й далі діє для кожного користувача.

Перевірте живий шлях і випадок збою

Запустіть аналізатор конфігурації, огляньте слухаючі сокети, потім виконайте новий іменований запит від потрібного клієнта. Підтвердьте, що сертифікат проходить перевірку, ім'я DNS розв'язується в прив'язану адресу, а відповідь надходить із очікуваного кореня.

Далі перевірте виключене джерело та альтернативний вхід. Робочий дозволений запит нічого не каже про шляхи, які ви хотіли закрити, і саме на виключеній перевірці виявляється залишковий слухач або широкий дозвіл міжмережевого екрана.

Повторіть випадок завантаження або відновлення VPN. Якщо NGINX стартує раніше, ніж існує адреса тунелю, прив'язка може не вдатися навіть з ідеальним файлом. Узгодьте готовність адреси та тримайте локальний шлях відновлення, перш ніж змінювати спільний вебсервер.

Запишіть сокет, порт, діапазон джерел і список HTTP, які пройшли. Наступна зміна VPN або DNS може зсунути будь-який із них, і чотири іменовані значення порівнювати легше, ніж робочу вкладку браузера.

Схожі статті