Squid відповідає на запит CONNECT першим відповідним рядком http_access, і цей рядок може бути відмовою. Саме цей факт пояснює, чому виняток для кінцевої точки VPN зазвичай не спрацьовує з першої спроби: запит ніколи не доходить до дозволу, який хтось додав у кінці. Вузька правка зберігає наявні захисти портів і вчить їх одному перевіреному джерелу, призначенню та порту. Усе інше на проксі поводиться точно так само, як раніше.

Як Squid вирішує запит CONNECT

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

Звичайні захисти відхиляють усе за межами Safe_ports і відхиляють CONNECT за межами SSL_ports. Ці назви — ACL, визначені у вашій власній конфігурації, тому їхній вміст належить вам, а не протоколу. Дистрибутив може дозволяти широкий діапазон портів як Safe_ports, окремо обмежуючи CONNECT. Прочитайте фактичні значення, перш ніж припускати, що порт заблокований за задумом.

Переконайтеся, що запит відхиляє саме проксі. 403 від Squid зовсім не схожий на попередження TLS від сервера VPN, і об'єднання двох проблем в одну коштує першої години. Перевірте рядок журналу доступу для запиту, бо він фіксує і дію, і правило, яке її спричинило.

Побудуйте один складений збіг замість трьох окремих ACL

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

Наведена нижче форма використовує діапазони з документації, які треба замінити перевіреними значеннями. Squid не резервує жодної з цих назв, тож вибирати їх і тримати узгодженими — ваша справа. Цей рецепт обмежено Squid 6 і 7, чия документована конфігурація підтримує групу all-of. Поточна довідка позначає ці директиви як недоступні в Squid 8, тому ставтеся до цього як до рецепта, прив'язаного до версії, а не як до шляху міграції, і звірте директиву з довідкою своєї версії перед застосуванням.

acl pvpn_src src 192.0.2.128/25
acl pvpn_dst dst 198.51.100.77/32
acl pvpn_port port 1194
acl pvpn_ok all-of CONNECT pvpn_port pvpn_dst pvpn_src

Група all-of збігається лише тоді, коли збігається кожен член, тобто джерело, призначення й порт перевіряються в одному рядку. Сама група нічого не дає, і запит, що збігається лише з двома з трьох фактів, не може її задовольнити. Ця властивість утримує виняток вузьким, коли хтось пізніше додає другий шлюз. Або нове призначення додають навмисно, або запит повертається до початкових захистів.

Зігніть захисти портів, не видаляючи їх

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

http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports

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

http_access deny CONNECT !SSL_ports !pvpn_ok
http_access deny !Safe_ports !pvpn_ok

Члени в одному рядку доступу об'єднуються, тому рядок тепер відхиляє лише ті запити, які не проходять і початкову перевірку, і виняток. Запит до схваленої кінцевої точки проходить, а кожен інший запит зберігає стару поведінку порту. Це вужче, ніж додати порт до глобального списку SSL_ports, що дозволило б цей порт кожному призначенню. Якщо порт уже є в цьому списку, цей ACL нічого не звужує, і старіший, ширший дозвіл далі діє для інших призначень, тому прочитайте живий список, перш ніж стверджувати, що виняток відкрив порт. Він також оборотний, бо два рядки повертаються до попередньої форми. Довідка з керування доступом описує порядок і звичайні захисти, на яких ґрунтується ця зміна.

Де виняток розміщувати не можна

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

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

Подумайте, чи кінцева точка взагалі TCP. Виняток CONNECT передає потоки TCP, а профіль OpenVPN, що використовує UDP, через нього недоступним і залишиться. Змінюйте профіль на TCP лише тоді, коли сервер так слухає й оператор приймає різницю в поведінці.

Перевірте межу парсером і реальним запитом

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

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

squid -k parse
squid -k reconfigure
curl -v -p -x http://proxy.lab.internal:3128 https://vpn.lab.internal:1194/ --max-time 5

Перевірте три випадки: схвалене джерело й обліковий запис, несхвалене джерело та інше призначення на тому самому порту. Третій випадок і доводить вузькість винятку, бо задіює порт без збігу призначення. Читайте журнал доступу для всіх трьох, а не покладайтеся на повідомлення клієнта. Успішний CONNECT встановлює потік TCP і нічого більше, тому рукостискання VPN залишається окремою перевіркою.

Схожі статті