Разрешение сетевых соединений в OS X только при подключенном VPN

Существует угроза утечки трафика через основное сетевое соединение до установления или при переподключении VPN-соединения. Поэтому возникает необходимость разрешения доступа в сеть только при подключенном VPN. В OS X это может быть осуществлено с помощью файерволла PF (PF доступен в системе, начиная с OS X Lion).

Настройка правил

Добавьте в конец файла /etc/pf.conf следующие строки:

anchor "org.vpnonly.pf"
load anchor "org.vpnonly.pf" from "/etc/pf.anchors/org.vpnonly.pf.rules"

Создайте файл /etc/pf.anchors/org.vpnonly.pf.rules со следующим содержимым:

# Options
set block-policy drop
set fingerprints "/etc/pf.os"
set ruleset-optimization basic
set skip on lo0

# Interfaces
vpn_intf = "{utun0 utun1 utun2 utun3}"

# Ports
allowed_vpn_ports = "{1:65535}"

# Table with allowed IPs
table <allowed_vpn_ips> persist file "/etc/pf.anchors/vpn.list" file "/etc/pf.anchors/custom.list"

# Block all outgoing packets
block out all

# Antispoof protection
antispoof for $vpn_intf

# Allow outgoing packets to specified IPs only
pass out proto icmp from any to <allowed_vpn_ips>
pass out proto {tcp udp} from any to <allowed_vpn_ips> port $allowed_vpn_ports

# Allow traffic for VPN interfaces
pass out on $vpn_intf all

С помощью allowed_vpn_ports можно ограничить список разрешенных портов для подключения. Например:

allowed_vpn_ports = "{22:443 50000:60000}"

для разрешения подключения только к портам в диапазонах 22-443 и 50000-60000.

Конфигурация списка разрешенных IP-адресов

Создайте файлы /etc/pf.anchors/vpn.list и /etc/pf.anchors/custom.list:

re_ip_addr='[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
vpn_servers=$(host -T -W 2 -t A -4 all.vpn.zorrovpn.com | grep 'has address' | grep -E -o "$re_ip_addr")
dns_servers=$(grep -s "nameserver" "/etc/resolv.conf" | grep -E -o "$re_ip_addr" | sort | uniq)
if [[ ! -z $vpn_servers ]]
then 
  echo "$vpn_servers" | sudo tee /etc/pf.anchors/vpn.list > /dev/null
else
  echo Error creating vpn.list
fi
[[ ! -z $dns_servers ]] && echo "$dns_servers" | sudo tee /etc/pf.anchors/custom.list > /dev/null

В файл /etc/pf.anchors/vpn.list добавьте список IP-адресов (адреса VPN-серверов), к которым будет разрешено подключение. Каждый адрес с новой строки, например:

22.0.0.1
33.0.0.1

В файл /etc/pf.anchors/custom.list можно добавить публичные DNS от Google или другие адреса, не являющиеся адресами VPN-серверов, к которым необходим доступ без установленного VPN-соединения:

8.8.8.8
8.8.4.4

Включение PF

sudo pfctl -e -f /etc/pf.conf

После включения PF с указанными правилами подключение к VPN-серверу по имени хоста (вместо IP-адреса) будет возможно, только если Вы добавили адреса системных DNS в файл custom.list. Но если в конфигурационном файле также есть подключение и по IP-адресу (справедливо для ZorroVPN), то после паузы в несколько секунд подключение к VPN-серверу будет произведено.

Для ZorroVPN при скачивании конфигурационного файла Вы можете отметить опцию "Не использовать имя хоста в дополнении к IP-адресу" для избежания какой-либо паузы при подключении в ситуации описанной выше.

Тестирование

ping -n -c 3 4.2.2.2
PING 4.2.2.2 (4.2.2.2): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
--- 4.2.2.2 ping statistics ---
3 packets transmitted, 0 packets received, 100.0% packet loss

Теперь доступ в сеть будет работать только при установленном соединение через VPN (например OpenVPN).

Отключение PF

После окончания работы с VPN-соединением можно вернуть систему в исходное состояние с помощью команды:

sudo pfctl -d

Запуск при старте системы

Для современных систем OS X (например El Capitan) с режимом "Rootless" необходимо сначала отключить данный режим. Посмотреть руководство для отключения можно здесь.

Затем откройте /System/Library/LaunchDaemons/com.apple.pfctl.plist и добавьте -e (включить) в качестве аргумента для pfctl:

<key>ProgramArguments</key>
<array>
    <string>pfctl</string>
    <string>-e</string>
    <string>-f</string>
    <string>/etc/pf.conf</string>
</array>

Выполните перезагрузку и возвратите режим "Rootless", если это необходимо, и загрузите систему. После данных действий PF будет запущен автоматически.


показать комментарии