У меня есть маршрутизатор. У него есть несколько интерфейсов. Один из них — VPN, называемый vpn0, один — маршрут по умолчанию к физическому интерфейсу, называемый out0, и входной интерфейс in0.
Пакеты из in0 с портом назначения 993 никогда не должны помещаться на out0. Я делаю это, помечая пакеты следующим образом:
iptables -t mangle -A PREROUTING -i in0 -p tcp --dport 993 -j MASK --set-mark 100
iptables -t mangle -A PREROUTING -i in0 -p tcp --dport 993 -j CONNMARK --save-mark
и чтобы отключить пересылку на out0 я делаю следующее:
iptables -A FORWARD -i in0 ! -o vpn0 --match-mark 100 -j DROP -m conntrack --ctstate NEW
Проблема, с которой я сталкиваюсь, заключается в выходных пакетах, которые приходят с хоста. Чтобы исказить пакеты из vpn0, у меня есть следующие правила:
iptables -t mangle -A OUTPUT --protocol tcp --dport 993 --jump MARK --set-mark 100
iptables -t mangle -A OUTPUT --protocol tcp --dport 993 --jump CONNMARK --save-mark
iptables -t mangle -A OUTPUT --protocol tcp --dport 993 --jump RETURN
Который работает довольно хорошо. Это происходит только когда vpn0 не работает. Я попробовал добавить правило:
iptables -A OUTPUT --protocol tcp --dport 993 -o out0 --match mark --mark 100 --jump DROP -m conntrack --ctstate NEW
Но это отбрасывает пакеты, которые вышли бы из VPN. Я проверил это, изменив DROP на LOG, а выходной интерфейс — out0, а не vpn0.
Что дает?