LINUX.ORG.RU
решено ФорумAdmin

Не работает tor через TPROXY

 , ,


1

2

Всем хороших выходных! Пытаюсь настроить tor на маршрутизаторе OpenWRT (LEDE) через TPROXY, но оно не работает, не знаю, как дебажить такие вещи.

Конфиг тора:

AutomapHostsOnResolve 1
TransProxyType TPROXY
VirtualAddrNetworkIPv4 10.192.0.0/10
DNSPort 153 NoPreferIPv6Automap
TransPort 127.0.0.1:9040 NoPreferIPv6Automap

Он успешно слушает на локальном интерфейсе, на порту 9040:

root@openwrt:~# netstat -atpn|grep 9040
tcp        0      0 127.0.0.1:9040          0.0.0.0:*               LISTEN      23264/tor

Форвардинг настраиваю так:

ip route add local default dev lo table 100
ip rule add fwmark 1 lookup 100

iptables -t mangle -N DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT
iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
iptables -t mangle -A PREROUTING -p tcp -d 10.192.0.0/10 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 9040

Результат:

root@openwrt:~# ip rule show
0:      from all lookup local
32765:  from all fwmark 0x1 lookup 100
32766:  from all lookup main
32767:  from all lookup default
root@openwrt:~# ip route show table 100
local default dev lo
root@openwrt:~# iptables -t mangle -L -v
Chain PREROUTING (policy ACCEPT 141K packets, 46M bytes)
 pkts bytes target     prot opt in     out     source               destination
 7935 2433K DIVERT     tcp  --  any    any     anywhere             anywhere             socket
   28  1680 TPROXY     tcp  --  any    any     anywhere             10.192.0.0/10        TPROXY redirect 0.0.0.0:9040 mark 0x1/0x1

Chain INPUT (policy ACCEPT 18499 packets, 5939K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 130K packets, 42M bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 26325 packets, 8048K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 156K packets, 50M bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain DIVERT (1 references)
 pkts bytes target     prot opt in     out     source               destination
 7935 2433K MARK       all  --  any    any     anywhere             anywhere             MARK set 0x1
 7935 2433K ACCEPT     all  --  any    any     anywhere             anywhere

Проверяю с компьютера из внутренней сети:

[pythagoras@localhost ~]$ dig -p 153 flibustahezeous3.onion A

; <<>> DiG 9.10.4-P3-RedHat-9.10.4-2.P3.fc24 <<>> -p 153 flibustahezeous3.onion A
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35660
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;flibustahezeous3.onion.                IN      A

;; ANSWER SECTION:
flibustahezeous3.onion. 60      IN      A       10.210.74.75

;; Query time: 48 msec
;; SERVER: 192.168.1.1#153(192.168.1.1)
;; WHEN: Сб ноя 12 18:24:37 MSK 2016
;; MSG SIZE  rcvd: 56

[pythagoras@localhost ~]$ curl -v "http://10.210.74.75/"
*   Trying 10.210.74.75...
* connect to 10.210.74.75 port 80 failed: Connection timed out
* Failed to connect to 10.210.74.75 port 80: Connection timed out
* Closing connection 0
curl: (7) Failed to connect to 10.210.74.75 port 80: Connection timed out

Увеличивается счётчик пакетов в выводе iptables напротив правила TPROXY, но соединения не происходит. В логах тора ничего. В 'tcpdump -i lo' - тоже.

Как это вообще инвестигировать?

Просьба NAT не предлагать, так как в случае успеха собираюсь тот же подход распространить на IPv6.

Опытным путём выяснилось, что соединение устанавливается, если слушать не только lo, а все интерфейсы. Почему это так? Ведь «ip route add local default dev lo table 100» должен заворачивать из в lo, разве нет?

Pythagoras ★★ ()
Ответ на: комментарий от Pythagoras

Дело, полагаю, в -m socket, который и не срабатывает при прослушивании только lo.

anonymous ()
Ответ на: комментарий от anonymous

Не меняется. Ладно, оставлю tor слушать на всех интерфейсах, с этим можно жить.

Вообще, если честно, я не совсем понимаю эти правила. Если из всех этих пяти правил iptables только последнюю строчку (которая -j TPROXY) - всё вроде бы работает точно так же. Зачем тогда первые 4? И зачем там устанавливать маркировку (-j MARK --set-mark 1), если мы её устанавливаем позже в TPROXY (-j TPROXY --tproxy-mark 0x1/0x1)?

В трёх источниках, в которых я об этом читал (https://github.com/openwrt/bcm63xx-next/blob/master/Documentation/networking/..., http://wiki.squid-cache.org/Features/Tproxy4, https://ru.wikibooks.org/wiki/Iptables#.D0.A2.D0.B0.D0.B1.D0.BB.D0.B8.D1.86.D...), какие-то немного противоречивые вещи об этом написаны.

Pythagoras ★★ ()
Ответ на: комментарий от Pythagoras
iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT

Это проверяет отностся ли пакет к слушаемому/открытому локальному сокету.

В современных ядрах есть еще полезная опция --transparent (чтоб не срабатывало на нормальные локальные сокеты)

Это правило не срабатывает для первого пакета соедиения.

Отдельная цепочка divert нужна только из-за того, что MARK не умеет возвращать ACCEPT. А сделать нужно 2 действия MARK+ACCEPT

Схема следование пакета в ядре/iptables.

По этой марке оно на «routing decision» через «ip ru» станет локальным трафиком без NAT-a в явном виде :).

iptables -t mangle -A PREROUTING -p tcp -d 10.192.0.0/10 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 9040

Это хитрый аналог DNAT/REDIRECT с доп. действием - ставил марку + отмечает пакет как бы локальным.

Правило срабатывает только для первого пакета соедиения.

По метке и «ip ru» оно попадет в локальный трафик после «routing decision»

На счет биндинга на INANY - у TPROXY можно указать не только порт, но и адрес через --on-ip. Проблема в том, что ip адрес редиректа через TPROXY выбирается по интерфейсу через который пришел пакет.

Порт 9040 нужно прибиндить к какому-нибудь локальному адресу ( но не 127.0.0.1), а в TPROXY указать его явно, токгда не будет неопределенностей.

C "-j REDIRECT" такая же фигня с ip :(

vel ★★★★★ ()
Последнее исправление: vel (всего исправлений: 3)
Ответ на: комментарий от vel

Спасибо! Теперь гораздо понятнее, но есть ещё пара вопросов.

--transparent нужно использовать вместо -m socket, или одновременно?

Действительно ли у --tproxy-mark другой синтаксис (1 и 0x1/0x1), или тут ошибка? Собираюсь выбрать другую марку, так как эта, кажется, конфликтует с qos, который тоже через марки работает.

Чтобы эти правила работали для локалтьной машины тоже, мне их надо засунуть в -t mangle -A OUTPUT?

Pythagoras ★★ ()
Последнее исправление: Pythagoras (всего исправлений: 1)
Ответ на: комментарий от Pythagoras

"--transparent" - одновременно

"-tproxy-mark mark[/mask]" - mask необязательный параметр.

Для локальных вроде в mangle/OUTPUT, но это IMHO.

vel ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.