Я хочу, чтобы соединения, поступающие на ppp0 на порт 8001, направлялись на 192.168.1.200 на eth0 на порт 8080.
У меня есть эти два правила
-A PREROUTING -p tcp -m tcp --dport 8001 -j DNAT --to-destination 192.168.1.200:8080
-A FORWARD -m state -p tcp -d 192.168.1.200 --dport 8080 --state NEW,ESTABLISHED,RELATED -j ACCEPT
и это не работает. Что мне не хватает?
Прежде всего - проверьте, разрешена ли вообще пересылка:
cat /proc/sys/net/ipv4/conf/ppp0/forwarding
cat /proc/sys/net/ipv4/conf/eth0/forwarding
Если оба вернутся 1
все нормально. Если нет, сделайте следующее:
echo '1' | sudo tee /proc/sys/net/ipv4/conf/ppp0/forwarding
echo '1' | sudo tee /proc/sys/net/ipv4/conf/eth0/forwarding
Второе - DNAT
может быть применен к nat
только таблица. Итак, ваше правило следует расширить, добавив также спецификацию таблицы (-t nat
):
iptables -t nat -A PREROUTING -p tcp -i ppp0 --dport 8001 -j DNAT --to-destination 192.168.1.200:8080
iptables -A FORWARD -p tcp -d 192.168.1.200 --dport 8080 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
Оба правила применяются только к TCP-трафику (если вы хотите изменить и UDP, вам необходимо предоставить аналогичные правила, но с -p udp
набор опций).
И последнее, но не менее важное - это конфигурация маршрутизации. Тип:
ip route
и проверьте, если 192.168.1.0/24
входит в число возвращенных записей маршрутизации.
Я думаю, что вам нужно:
iptables -A FORWARD -m state -p tcp -d 192.168.1.200 --dport 8080 --state
NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A PREROUTING -p tcp --dport 8001 -j DNAT --to-destination
192.168.1.200:8080
Вы забыли постмаршрутизацию исходного адреса SNAT 'ing:
sysctl net.ipv4.ip_forward=1
yours_wan_ip=101.23.3.1
-A PREROUTING -p tcp -m tcp -d $yours_wan_ip --dport 8001 -j DNAT --to-destination 192.168.1.200:8080
-A FORWARD -m state -p tcp -d 192.168.1.200 --dport 8080 --state NEW,ESTABLISHED,RELATED -j ACCEPT
-A POSTROUTING -t nat -p tcp -m tcp -s 192.168.1.200 --sport 8080 -j SNAT --to-source $yours_wan_ip
И не забудьте установить брандмауэр Linux в качестве шлюза по умолчанию на компьютере с адресом 192.168.1.200.
Для этого я создал следующий сценарий bash на моем маршрутизаторе Linux. Он автоматически определяет IP-адрес WAN и подтверждает ваш выбор перед продолжением.
#!/bin/bash
# decide which action to use
action="add"
if [[ "-r" == "$1" ]]; then
action="remove"
shift
fi
# break out components
dest_addr_lan="$1"
dest_port_wan="$2"
dest_port_lan="$3"
# figure out our WAN ip
wan_addr=`curl -4 -s icanhazip.com`
# auto fill our dest lan port if we need to
if [ -z $dest_port_lan ]; then
dest_port_lan="$dest_port_wan"
fi
# print info for review
echo "Destination LAN Address: $dest_addr_lan"
echo "Destination Port WAN: $dest_port_wan"
echo "Destination Port LAN: $dest_port_lan"
echo "WAN Address: $wan_addr"
# confirm with user
read -p "Does everything look correct? " -n 1 -r
echo # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]; then
if [[ "remove" == "$action" ]]; then
iptables -t nat -D PREROUTING -p tcp -m tcp -d $wan_addr --dport $dest_port_wan -j DNAT --to-destination $dest_addr_lan:$dest_port_lan
iptables -D FORWARD -m state -p tcp -d $dest_addr_lan --dport $dest_port_lan --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -D POSTROUTING -p tcp -m tcp -s $dest_addr_lan --sport $dest_port_lan -j SNAT --to-source $wan_addr
echo "Forwarding rule removed"
else
iptables -t nat -A PREROUTING -p tcp -m tcp -d $wan_addr --dport $dest_port_wan -j DNAT --to-destination $dest_addr_lan:$dest_port_lan
iptables -A FORWARD -m state -p tcp -d $dest_addr_lan --dport $dest_port_lan --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -p tcp -m tcp -s $dest_addr_lan --sport $dest_port_lan -j SNAT --to-source $wan_addr
echo "Forwarding rule added"
fi
else
echo "Info not confirmed, exiting..."
fi
Использование сценария простое: просто скопируйте и вставьте его в файл, а затем.
# chmod +x port_forward.sh
# ./port_forward.sh 192.168.1.100 3000
... confirm details ... press y
# Forwarding rule added
Чтобы удалить то же правило
# ./port_forward.sh -r 192.168.1.100 3000
... confirm details ... press y
# Forwarding rule removed
Я подумал, что это поможет кому-то сэкономить время на соответствующем роутере.
У меня была задача заставить MACHINE_A думать, что служба работает физически на MACHINE_B, но прозрачно перенаправлять все запросы на MACHINE_C.
Хитрость заключалась в том, чтобы использовать МАСКЕРАД.
sysctl net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -p tcp -d MACHINE_B --dport 443 -j DNAT --to-destination MACHINE_C
iptables -t nat -A POSTROUTING -s MACHINE_A -o INTERFACE_NAME -j MASQUERADE
Обратите внимание, что вы можете настроить команды:
Разрешить пересылку пакетов только на определенном интерфейсе. Например:
sysctl net.ipv4.conf.eth0.forwarding=1
Чтобы разрешить не только MACHINE_A, но и всем остальным использовать переадресацию портов, удалите:
-s MACHINE_A
Пытаться
echo "1" > /proc/sys/net/ipv4/conf/ppp0/forwarding
echo "1" > /proc/sys/net/ipv4/conf/eth0/forwarding
Эти файлы сообщают ядру, что разрешено пересылать пакеты между интерфейсами.
Эта команда у меня не работает:
-A POSTROUTING -t nat -p tcp -m tcp -s 192.168.1.200 --sport 8080 -j SNAT --to-source $yours_wan_ip
У меня есть 2 интерфейса LAN и работа FORWARD, когда я написал:
iptables -t nat -A POSTROUTING -o $LAN_IF -p tcp -m tcp --dport $FW_PORT -j SNAT --to-source $LAN_IP
ПРЕРУТИРОВКА и ВПЕРЕД тоже нужны, конечно :)
Принятое решение работает, когда целевой хост и шлюз находятся на тем же подсеть (как в вашем случае, оба находятся в eth0
192.168.1.0/24).
Ниже приведено общее решение, когда шлюз, источник и пункт назначения включены. разные подсети.
1) Включить переадресацию IP:
sysctl net.ipv4.conf.eth0.forwarding=1
sysctl net.ipv6.conf.eth0.forwarding=1
2) Добавьте 2 правила iptables для перенаправления определенного TCP-порта:
Чтобы переписать место назначения IP пакета (и обратно в ответном пакете):
iptables -A PREROUTING -t nat -p tcp -i ppp0 --dport 8001 -j DNAT --to-destination 192.168.1.200:8080
Чтобы переписать источник IP пакета на IP шлюза (и обратно в ответном пакете):
iptables -A POSTROUTING -t nat -p tcp -d 192.168.1.200 --dport 8080 -j MASQUERADE
3) Если у вас нет значения по умолчанию ACCEPT
правило брандмауэра, разрешить трафик к месту назначения:
iptables -A FORWARD -p tcp -d 192.168.1.200 --dport 8080 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
4) Протестируйте новую настройку. Если это работает, убедитесь, что изменения сохраняются после перезагрузки:
cat <<EOF > /etc/sysctl.d/99-forwarding.conf
sysctl net.ipv4.conf.eth0.forwarding=1
sysctl net.ipv6.conf.eth0.forwarding=1
EOF
iptables-save > /etc/network/iptables.up.rules
echo '#!/bin/sh' > /etc/network/if-pre-up.d/iptables
echo "`which iptables-restore` < /etc/network/iptables.up.rules" >> /etc/network/if-pre-up.d/iptables
chmod +x /etc/network/if-pre-up.d/iptables