Не допускайте вихідного трафіку, якщо підключення OpenVPN не активне за допомогою pf.conf на Mac OS X


19

Мені вдалося відхилити всі з'єднання із зовнішніми мережами, якщо моє з'єднання OpenVPN не активне за допомогою pf.conf. Однак я втрачаю підключення до Wi-Fi, якщо з'єднання розривається, закриваючи та відкриваючи кришку ноутбука або вимикаючи та знову вмикаючи Wi-Fi.

  • Я на Mac OS 10.8.1.
  • Я підключаюся до Інтернету через Wi-Fi (з різних місць, включаючи загальнодоступний Wi-Fi).
  • З'єднання OpenVPN налаштовано з в'язкістю.

У мене встановлені такі правила фільтра пакетів /etc/pf.conf

# Deny all packets unless they pass through the OpenVPN connection
wifi=en1
vpn=tun0

block all

set skip on lo
pass on $wifi proto udp to [OpenVPN server IP address] port 443
pass on $vpn

Я запускаю службу фільтра пакетів sudo pfctl -eі завантажую нові правила sudo pfctl -f /etc/pf.conf.

Я також відредагував /System/Library/LaunchDaemons/com.apple.pfctl.plistі змінив рядок <string>-f</string>для читання, <string>-ef</string>щоб фільтр пакетів запустився при запуску системи.

Це, здається, спочатку чудово спрацьовує: програми можуть підключатися до Інтернету лише у тому випадку, якщо підключення OpenVPN активне, тому я ніколи не пропускаю дані через незахищене з'єднання.

Але якщо я закрию і знову відкрию кришку ноутбука або вимкнути і знову ввімкнути Wi-Fi, з'єднання Wi-Fi втратиться, і я побачу знак оклику на значку Wi-Fi на панелі стану. Якщо натиснути значок Wi-Fi, з'явиться повідомлення "Попередження: Немає з'єднання з Інтернетом":

Немає повідомлення про підключення до Інтернету

Щоб відновити з'єднання, мені доведеться відключити та підключити Wi-Fi, іноді п’ять-шість разів, перш ніж повідомлення «Попередження: Немає з'єднання з Інтернетом» зникне, і я можу знову відкрити VPN-з'єднання. В іншому випадку сигнал Wi-Fi зникає за власним бажанням, знак оклику очищається, і я можу знову підключитися. У будь-якому випадку може знадобитися п’ять хвилин або більше, щоб знову встановити зв’язок, що може розчарувати.

Видалення лінії block allвирішує проблему (але дозволяє отримати небезпечні підключення), тому, здається, існує служба, яку я блокую, що потрібна Apple, щоб відновити та підтвердити з'єднання Wi-Fi. Я намагався:

  • Увімкнення icmp, додавши pass on $wifi proto icmp allв pf.conf
  • Увімкнення роздільної здатності DNS шляхом додавання pass on $wifi proto udp from $wifi to any port 53
  • Намагаюся дізнатися більше, записуючи заблоковані пакети (змінившись block allна block log all), але журнал, здається, вимкнено в ОС X, тому що для того, sudo tcpdump -n -e -ttt -i pflog0щоб побачити результати журналу в "tcpdump: pflog0: Такого пристрою не існує".

Ніщо з цього не допомагає швидше встановити з’єднання Wi-Fi.

Що ще я можу зробити, щоб визначити, яка послуга повинна бути доступною для відновлення підключення до Wi-Fi, або яке правило слід додати до pf.conf, щоб зробити з'єднання Wi-Fi надійнішими?


1
це може бути актуальним для тих, хто приходить після: sparklabs.com/support/preventing_network_and_dns_traffic_leaks
ptim

Відповіді:


14

Відслідковуючи мережеві з'єднання за допомогою Little Snitch, я виявив, що Apple використовує додаток mDNSResponder у фоновому режимі, щоб перевірити, чи є підключення Wi-Fi. mDNSResponder посилає пакети UDP серверам імен для перевірки підключення та вирішення імен хостів до IP-адрес.

Змінюючи правило UDP, я раніше мав дозволити всі пакети UDP через Wi-Fi, що дозволяє mDNSResponder підключатися, що означає, що Wi-Fi тепер підключається вперше після відключення. Якщо це допомагає іншим у майбутньому, мій останній pf.conf, включаючи правила за замовчуванням Apple для Mountain Lion, виглядає так:

#
# com.apple anchor point
#
scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"as
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"

#
# Allow connection via Viscosity only
#
wifi=en1 #change this to en0 on MacBook Airs and other Macs without ethernet ports
vpn=tun0
vpn2=tap0

block all

set skip on lo          # allow local traffic

pass on p2p0            #allow AirDrop
pass on p2p1            #allow AirDrop
pass on p2p2            #allow AirDrop
pass quick proto tcp to any port 631    #allow AirPrint

pass on $wifi proto udp # allow only UDP packets over unprotected Wi-Fi
pass on $vpn            # allow everything else through the VPN (tun interface)
pass on $vpn2           # allow everything else through the VPN (tap interface)

Це означає, що дані тепер можуть просочуватися через Wi-Fi через невелику кількість програм, які використовують протокол UDP, на жаль, такі як ntpd (для синхронізації часу) та mDNSResponder. Але це все ще здається кращим, ніж дозволяти даним подорожувати незахищеними через TCP, для чого використовується більшість додатків. Якщо у когось є якісь пропозиції щодо вдосконалення цього налаштування, коментарі або подальші відповіді вітаються.


Це те, що мене випадково цікавило, побачивши, що ваші результати надихнули мене піти додому та спробувати! Дякую!
jakev

@SixSlayer Це, здається, працює досить добре! У мене налаштована в'язкість для автоматичного підключення при запуску та на занепалих з'єднаннях, що робить цілу справу майже бездоганною. Головне зауважити, що pf.conf та com.apple.pfctl.plist після скидання оновлень ОС скидаються до стандартних, мабуть, тому варто зберігати резервну копію обох.
Нік

ІМХО, справа в УДП - це якийсь облом. Я не хлопець у мережі, але ця річ допомагає мені вчитися, і я захоплююсь контролем над такими деталями. Я витрачу деякий час на пошуки роботи навколо, але якщо хтось мене б’є, так само добре.
jakev

це дивовижно - саме те, що я шукав. Дякую!
keo

Чи, можливо, вам вдалося одночасно відкрити багато з’єднань OpenVPN і паралельно проходити через них? (щоб отримати та збільшити пропускну здатність)
keo

11

Вам не потрібно дозволяти всі UDP. 'M' в mDNS означає «багатоадресна передача», і він використовує конкретну IP-адресу для багатоадресної розсилки під назвою «локальна посилання багатоадресної пошти» та номер UDPпорту 5353.

Це означає, що у вашому рішенні вище, ви зайво дозволяєте трафіку на всі 65535 порти UDP на всі 3,7 мільярда маршрутизованих IP-адрес у світі, щоб обійти вашу VPN. Ви здивуєтеся, скільки програм використовує UDP, тому ви значно перемагаєте мету своєї оригінальної ідеї запобігти вихідному трафіку при зниженні VPN.

Чому б не використовувати це правило замість цього:

pass on $wifi proto udp to 224.0.0.251 port 5353

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

Якщо ви поміняєтеся вищезазначеним правилом і виявите, що початкова проблема Wi-Fi повертається, можливо, ваш PF блокує DHCP, протокол, який використовується для автоматичної настройки IP-адрес мережевих пристроїв. (у домашній мережі, як правило, ваш широкосмуговий маршрутизатор буде вашим сервером DHCP). Правилом, яким потрібно дозволити DHCP, було б:

pass on $wifi proto udp from 0.0.0.0 port 68 to 255.255.255.255 port 67

* Примітка: Ви , можливо , буде потрібно замінити 0.0.0.0на any. DHCPREQUESTПакет ваш комп'ютер посилає перший, має адресу джерела , 0.0.0.0тому що на цьому етапі, ваш комп'ютер не має IP - адреса ще.
Якщо чесно, я б більше схилявся до використання any. Інший варіант полягає в тому, щоб вирвати будь-яку специфікацію джерела, тобто pass on $wifi proto udp to 255.255.255.255 port 67, але це означає, що ми втрачаємо частину правила джерела-порту, і бути максимально конкретним завжди найбезпечнішим варіантом.

Сподіваюся, що це допомагає. Ось кілька корисних посилань:

mDNS: http://en.wikipedia.org/wiki/Multicast_DNS#Packet_structure

DHSP: http://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol#DHCP_discovery


1

Це дало мені достатню довідкову інформацію, щоб зробити великий стрибок і використовувати pf.conf. Ось що я використовую в моїй версії 10.8, щоб знов підключитися після падіння VPN-з'єднання:

(Я використовую лише Ethernet, але ви можете змінити $ lan на $ wifi, і він повинен працювати)

lan=en0
wifi=en1
vpn=tun0
block all
set skip on lo
pass on $lan proto { udp,tcp } to 8.8.8.8
pass on $lan proto tcp to vpn.btguard.com port 1194
pass on $vpn

1

Для того, щоб створити правила PF "простим" способом, ідентифікуючи існуючі активні інтерфейси, включаючи поточні (vpn) інтерфейси, ця невелика програма для Killswitch може використовуватися,

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

Приклад або вихід з використанням -iопції (info):

$ killswitch -i
Interface  MAC address         IP
en1        bc:57:36:d1:82:ba   192.168.1.7
ppp0                           10.10.1.3

public IP address: 93.117.82.123

Проходження ip сервера -ip:

# --------------------------------------------------------------
# Sat, 19 Nov 2016 12:37:24 +0100
# sudo pfctl -Fa -f ~/.killswitch.pf.conf -e
# --------------------------------------------------------------
int_en1 = "en1"
vpn_ppp0 = "ppp0"
vpn_ip = "93.117.82.123"
set block-policy drop
set ruleset-optimization basic
set skip on lo0
block all
pass on $int_en1 proto udp to 224.0.0.251 port 5353
pass on $int_en1 proto udp from any port 67 to any port 68
pass on $int_en1 inet proto icmp all icmp-type 8 code 0
pass on $int_en1 proto {tcp, udp} from any to $vpn_ip
pass on $vpn_ppp0 all

Це далеко не ідеально, але триває робота. Більше інформації та коду можна знайти тут: https://github.com/vpn-kill-switch/killswitch


0

- Як додаток -

Ви можете додати цей рядок:

pass on $wifi inet6 proto udp from any to FF02:0000:0000:0000:0000:0000:0000:00FB port 5353

щоб mDNS працював на ipv6

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.