Предотвращение исходящего трафика, если соединение 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), но журналирование кажется отключенным в OS 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 без защиты, что и используется большинством приложений. Если у кого-либо есть какие-либо предложения по улучшению этой настройки, приветствуются комментарии или дальнейшие ответы.

Ник
источник
Это то, что меня заинтересовало, потому что ваши результаты вдохновили меня пойти домой и попробовать! Благодарность!
января
@SixSlayer Кажется, это работает очень хорошо! У меня есть Вязкость, настроенная для автоматического подключения при запуске и при обрыве соединений, что делает все это в значительной степени плавным. Главное, что следует отметить, это то, что pf.conf и com.apple.pfctl.plist после обновлений ОС сбрасываются до значений по умолчанию, поэтому стоит сохранить резервные копии обоих.
Ник
ИМХО УДП вещь вроде облом. Я не сетевой парень, но это помогает мне учиться, и у меня есть восхищение тем, что я могу контролировать такие детали. Я потрачу некоторое время на поиски работы вокруг, но если кто-то и побьет меня, точно так же.
января
это потрясающе - именно то, что я искал. Спасибо!
Кео
Может быть, вам удалось одновременно открыть много 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

smashingly
источник
1

Это дало мне достаточно информации, чтобы сделать большой скачок и использовать pf.conf. Вот что я использую на своем 10.8, чтобы восстановить соединение после разрыва VPN-соединения:

(Я использую только Ethernet, но вы можете изменить $ LAN на $ Wi-Fi, и это должно работать)

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

nbari
источник
0

- Как дополнение -

Вы можете добавить эту строку:

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

разрешить mDNS работать на ipv6

user263367
источник