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 более надежным?

5 ответов5

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

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 "простым" способом, идентифицируя существующие активные интерфейсы, включая текущие (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.

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
0

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

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

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .