
Я маршрутизирую HTTPS-соединения по SSH-туннелю (-w) с помощью iptables
меток и iproute2
правил. Причины, по которым мне нужно делать это таким образом, мягко говоря, надуманы, поэтому большинство альтернативных решений могут вообще не сработать у меня.
Устройство tun0 существует и работает так, как мне нужно, и маршрутизация работает, когда я применяю MARK в цепочке OUTPUT, но по какой-то причине правило маршрутизации не работает, если MARK применяется в цепочке FORWARD.
ОС — CentOS 6.7 с ядром 2.6.32 и iptables 1.4.7. iptables
Маркировка и логирование:
# iptables -t mangle -A FORWARD -p tcp --dport 443 -j MARK --set-mark 1
# iptables -t mangle -A OUTPUT -p tcp --dport 443 -j MARK --set-mark 1
# iptables -t mangle -A POSTROUTING -m mark --mark 1 -j LOG --log-prefix "marked: "
Настройка правила iproute2
:
# cat 201 tunneled >> /etc/iproute2/rt_tables
# ip rule add fwmark 1 table tunneled
# ip route add default via 192.168.100.1 dev tun1 table tunneled
И небольшой фрагмент из журнала, демонстрирующий результаты:
Feb 17 19:11:35 nhopm kernel: marked: IN= OUT=eth0 SRC=192.168.82.2 DST=69.30.217.90 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=16734 DF PROTO=TCP SPT=34619 DPT=443 WINDOW=29200 RES=0x00 SYN URGP=0 MARK=0x1
Feb 17 19:12:00 nhopm kernel: marked: IN= OUT=tun1 SRC=192.168.81.8 DST=69.30.217.90 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=62747 DF PROTO=TCP SPT=55349 DPT=443 WINDOW=14600 RES=0x00 SYN URGP=0 MARK=0x1
У хоста есть 2 сетевых карты eth0
: 192.168.81.8, где 192.168.81.1 является шлюзом по умолчанию, а eth1
192.168.82.8 действует как шлюз по умолчанию для 192.168.82.0/24 — с этой настройкой проблем нет, все работает как и ожидалось. Туннель tun0 имеет 192.168.100.1 на дальнем конце.
Я попытался сузить это до самой простой ситуации, которая иллюстрирует проблему, не перегружая ее подробностями, но предоставлю столько подробностей, сколько посчитаю необходимым, чтобы попытаться найти, где находится проблема. Пожалуйста, спрашивайте в комментариях, если что-то может быть полезным. Надеюсь, я просто неправильно понял небольшую часть того, как это работает.
Обходной путь
Моя попытка сделать вышеизложенное основывалась на следующей iptables
блок-схеме:
из iptables.info
Который скрывает тот факт, что тот же наборРешение о маршрутизациине применяются к пакетам, поступающим из цепочки OUTPUT, как к пакетам, поступающим из цепочки FORWARD.
Чтобы это сработало, мне нужно было заменить маркировку, сделанную в цепочке FORWARD, аналогичной записью в цепочке PREROUTING.
iptables -t mangle -A PREROUTING -p tcp --dport 443 ! -d 192.168.0.0/16 -j MARK --set-mark 1
Что на самом деле даже лучше соответствует моим потребностям.
Я пока не буду давать на это ответ, поскольку не нашел соответствующей документации. Если найду, то дам ответ, если только меня кто-нибудь не опередит.