Настройка Tor-роутера под BSD (transparent Tor-proxy как anonymizing middlebox)



Пример, приведённый в официальном Tor-faq[link1], на текущий момент не применим для OpenBSD PF из-за смены синтаксиса, и, на мой взгляд, содержит ряд неточностей. Ниже привожу пример настройки с дополнительным закручиванием гаек в PF. Цель — прозрачно выпускать несколько локальных подсетей в Tor, где каждая из них будет привязана к своему Tor-клиенту (в рассматриваемом примере две подсети).

Пусть выходной сетевой интерфейс — fxp0, а входные — vr0 и vr1. Тестировались только OpenBSD и NetBSD. При установке Tor из портов пользователь tor (_tor) и группа tor (_tor) создаются автоматически в NetBSD (OpenBSD). Далее с помощью vipw добавляем аналогичного юзера для второй подсети (достаточно сменить UID, сохранив ту же группу, имена пользователей для удобства можно упорядочить как, например, tor1 и tor2). Для tor-пользователей создаются конфигурационные файлы наподобие таких:
$ cat torrc_1 
SocksPort 9050 
SocksListenAddress 127.0.0.1 
RunAsDaemon 1
DataDirectory /tmp/tor_1
User tor1
AutomapHostsOnResolve 1
Log notice file /tmp/tor_1.log
VirtualAddrNetwork 10.192.0.0/10
TransPort 9060
DNSPort 5353
$ cat torrc_2 
SocksPort 8050 
SocksListenAddress 127.0.0.1 
RunAsDaemon 1
DataDirectory /tmp/tor_2
User tor2
AutomapHostsOnResolve 1
Log notice file /tmp/tor_2.log
VirtualAddrNetwork 172.16.0.0/12
TransPort 8060
DNSPort 5363
и кладутся в нужную директорию1. Автозапуск при загрузке системы делается прописыванием в /etc/rc.local строчек наподобие
/usr/local/bin/tor -f /path/to/torrc_1
/usr/local/bin/tor -f /path/to/torrc_2
для OpenBSD и
/usr/pkg/bin/tor -f /path/to/torrc_1
/usr/pkg/bin/tor -f /path/to/torrc_2
для NetBSD.

Вопреки сказанному в Tor-faq[link1], прав на чтение /dev/pf достаточно не только для OpenBSD, но и для NetBSD, потому назначаем:
# chgrp tor /dev/pf
# chmod g=r /dev/pf
Нижеследущий конфиг был проверен на работоспособность в NetBSD 5.0.2, NetBSD 5.1 и OpenBSD 4.52:
# переменные:
in0  = "vr0"
IPin0 = "IP_НА_vr0"
net0 = "СЕТЬ_НА_vr0"
TransPort0 = "9060"
DnsPort0 = "5353"
 
in1  = "vr1"
IPin1 = "IP_НА_vr1"
net1 = "СЕТЬ_НА_vr1"
TransPort1 = "8060"
DnsPort1 = "5363"
 
out0  = "fxp0"
IPout0 = "IP_НА_fxp0"
 
lh  = "localhost"
tor_users = "{ tor1, tor2 }"
 
# опции по вкусу:
scrub all no-df random-id min-ttl 128
 
# редиректы:
rdr on $in0 inet proto tcp from $net0 to ! $IPin0             -> 127.0.0.1 port $TransPort0
rdr on $in0 inet proto udp from $net0 to ! $IPin0 port domain -> 127.0.0.1 port $DnsPort0
 
rdr on $in1 inet proto tcp from $net1 to ! $IPin1             -> 127.0.0.1 port $TransPort1
rdr on $in1 inet proto udp from $net1 to ! $IPin1 port domain -> 127.0.0.1 port $DnsPort1
 
# фильтрация:
block all
block in quick from any os NMAP
antispoof log quick for {$in0,$in1,$out0}
 
pass in  on $in0  inet proto tcp from $net0   to $lh port $TransPort0 user root
pass in  on $in0  inet proto udp from $net0   to $lh port $DnsPort0   user root
 
pass in  on $in1  inet proto tcp from $net1   to $lh port $TransPort1 user root
pass in  on $in1  inet proto udp from $net1   to $lh port $DnsPort1   user root
 
pass out on $out0 inet proto tcp from $IPout0 to any                  user $tor_users
 
block inet6 all
Выше строки
block all
block in quick from any os NMAP
antispoof log quick for {$in0,$in1,$out0}
можно заменить на
block return log (all)
и тогда сниффер
# tcpdump -i pflog0 -n -e action block
покажет все пакеты, блокируемые PF (полезно для отладки). Критерий actions поддерживается только в OpenBSD. Кроме того, ввиду правила "block all" блокирование nmap и антиспуфинг, возможно, избыточны3.

Такая же конфигурация на OpenBSD 4.8 с учётом смены синтаксиса PF выглядит так4:
# редиректы:
match in on $in0 inet proto tcp from $net0 to ! $IPin0             rdr-to 127.0.0.1 port $TransPort0
match in on $in0 inet proto udp from $net0 to ! $IPin0 port domain rdr-to 127.0.0.1 port $DnsPort0
 
match in on $in1 inet proto tcp from $net1 to ! $IPin1             rdr-to 127.0.0.1 port $TransPort1
match in on $in1 inet proto udp from $net1 to ! $IPin1 port domain rdr-to 127.0.0.1 port $DnsPort1
 
# фильтрация:
block all
block in quick from any os NMAP
antispoof quick for {$in0,$in1,$out0}
 
pass in  on $in0  inet proto tcp from $net0   to $lh port $TransPort0 user unknown
pass in  on $in0  inet proto udp from $net0   to $lh port $DnsPort0   user unknown
 
pass in  on $in1  inet proto tcp from $net1   to $lh port $TransPort1 user unknown
pass in  on $in1  inet proto udp from $net1   to $lh port $DnsPort1   user unknown
 
pass out on $out0 inet proto tcp from $IPout0 to any                  user $tor_users
block inet6 all
Данные конфиги PF разрешают выход в сеть исключительно Tor-клиентам. Чтобы разрешить что-то ещё (входящие по ssh, например) добавьте правила по вкусу.

Замечания:

Указанная конфигурация легко заливается с помощью скрипта mklivecd на NetBSD LiveCD, что позволяет сделать бездисковый Tor-рутер из любого старого компьютера8. Конфиг будет работать и на одной сетевой с одним интерфейсом (надо будет для in0 и in1 указать тот же интерфейс).

P.S.: Конфигурацию с local redirection пока не настраивал, потому PF-аналог Linux-настройки[link2] привести не могу.


1Раздел /tmp целесообразно монтировать в память посредством mfs.
2В NetBSD 3.0 текущая версия Tor через pkgsrc собирается без поддержки прозрачной торификации (причины мне не известны), потому протестить не удалось.
3Если кто объяснит, где я не прав и как всё на самом деле, буду очень благодарен.
4Начало конфига до "опций" совпадает с предыдущим.
5Определялось экспериментально.
6Если вообще указывать опцию user, что в данной заметке делается по умолчанию.
7Например, user root для входящих pass in на ssh.
8Сколь-нибудь автоматизированных средств сборки OpenBSD LiveCD в сети не обнаружено, а все how-to написаны для довольно старых версий OpenBSD и не работают на 4.8 (ядро не влазит в отведённый размер boot при дискетоподобной системе загрузки LiveCD). Под FreeBSD есть средства автоматизированной сборки LiveCD, но я их не тестировал.

Ссылки
[link1] https://trac.torproject.org/projects/tor/wiki/TheOnionRouter/TransparentProxy#AnonymizingMiddlebox1

[link2] https://www.pgpru.com/faq/anonimnostj?p=5&show_comments=1#h41-11