1

Я установил клиент OpenVPN на моем домашнем маршрутизаторе. В тот момент, когда туннель поднимается, я больше не могу пропинговать свой роутер из интернета, используя его WAN_IP. Я хотел бы разрешить определенные входящие соединения (ping, ssh) через интерфейс WAN, когда туннель vpn включен. Я прочитал немного об этом, и я понимаю, что мне нужна маршрутизация на основе источника.

Я пытался реализовать это, но это не работает. Вот что я сделал:

# ip rule list
0:      from all lookup local 
32765:  from all fwmark 0x1 lookup 128 
32766:  from all lookup main 
32767:  from all lookup default
# ip route list table 128
default via WAN_IP dev vlan2
# iptables -t mangle -nvL PREROUTING
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 CONNMARK   all  --  br0    *       0.0.0.0/0            0.0.0.0/0           CONNMARK restore 
    0     0 CONNMARK   all  --  vlan2  *       0.0.0.0/0            0.0.0.0/0           CONNMARK set 0x1
# iptables -t mangle -nvL OUTPUT
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 CONNMARK   all  --  *      *       0.0.0.0/0            0.0.0.0/0           CONNMARK restore

Мое мышление было следующим. Пожалуйста, поправьте меня, если я что-то не так понял:

  • Когда пакет приходит на vlan2 (WAN iface), PREROUTING:2 устанавливает метку соединения 0x1
  • Пакет не имеет маркировки пакета на данный момент (это правильно?)
  • Пакет имеет маршрутизатор в качестве пункта назначения, поэтому он будет получен. Если бы это было DNATed, предыдущий пункт был бы решающим, потому что таблица 128 пропускает вещи LAN.
  • Ответный пакет генерируется локально.
  • ВЫХОД:1 установит метку пакета 0x1, используя метку соединения на ответном пакете
  • PREROUTING:1 будет делать то же самое для соединений DNAT в локальной сети (br0)
  • Ответный пакет с меткой 0x1 будет маршрутизирован с использованием таблицы 128.

К сожалению, это не работает, и я хотел бы понять, почему. С удаленного сервера, если я пингую WAN_IP, я не вижу никаких ответов. Я также включил удаленный доступ ssh на маршрутизаторе и не могу открыть порт с удаленного компьютера с помощью telnet WAN_IP SSH_PORT , так что это проблема не только icmp. Как отладить эти проблемы?

Обновление: я проверил rp_filter и он был установлен в 1. Я попытался установить его на 0, и теперь все работает как положено (2 тоже не сработало). Так как это интернет-роутер, я думаю, что ни один RPF не может быть хорошей идеей. Из того, что я понимаю, когда строгий RPF запускается на начальном пакете, ядро наблюдает, как маршрут к REMOTE_IP проходит через TUN_IF, в то время как пакет прибыл на WAN_IF, поэтому он отбрасывается. Это правильно? Я попытался MARK set 0x1 && CONNMARK save как mangle PREROUTING, надеясь, что ядро увидит метку во время RPF, но это не так.

2 ответа2

0

Проблема состоит в том, что шлюз по умолчанию изменяется OpenVPN, и это разрывает любое соединение, входящее на не-VPN интерфейс. Linux будет отправлять ответы на пакеты, которые поступают на реальном интерфейсе через интерфейс VPN! Вам нужно настроить соответствующие маршруты перед запуском OpenVPN.

То, что следует, работает для меня. Он использует iptables и ip (iproute2). Ниже предполагается, что интерфейсом шлюза по умолчанию перед запуском OpenVPN является "eth0". Идея состоит в том, чтобы при установлении соединения с eth0, даже если eth0 больше не является интерфейсом шлюза по умолчанию, ответные пакеты для соединения снова возвращаются на eth0.

Вы можете использовать один и тот же номер для метки соединения, метки межсетевого экрана и таблицы маршрутизации. Я использовал разные числа, чтобы сделать различия между ними более очевидными.

# set "connection" mark of connection from eth0 when first packet of connection arrives
sudo iptables -t mangle -A PREROUTING -i eth0 -m conntrack --ctstate NEW -j CONNMARK --set-mark 1234

# set "firewall" mark for response packets in connection with our connection mark
sudo iptables -t mangle -A OUTPUT -m connmark --mark 1234 -j MARK --set-mark 4321

# our routing table with eth0 as gateway interface
sudo ip route add default dev eth0 table 3412

# route packets with our firewall mark using our routing table
sudo ip rule add fwmark 4321 table 3412

===

ОБНОВИТЬ:

Вышесказанное прекрасно работает для меня в Debian Jessie. Но на более старой системе Wheezy я только что обнаружил, что мне нужно добавить "через" к записи таблицы маршрутизации:

# our routing table with eth0 as gateway interface
sudo ip route add default dev eth0 via 12.345.67.89 table 3412

Там "12.345.67.89" должен быть оригинальный шлюз не VPN.

0

Я не могу понять, почему вы должны использовать iptables для этого. Это простой случай PBR. Настройте две таблицы маршрутизации, основную настройку OpenVPN и другую, которая не включает VPN, затем добавьте правило

  ip rule from IP.Of.Your.Router table theother

и вы сделали.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .