Skip to main content

Port forward

socat TCP4-LISTEN:80,fork TCP4:www.yourdomain.org:8080

# 启用转发
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

# 本地
# eth0 192.168.1.2
# testnet 10.10.1.1
# 目标
# testnet 10.10.2.1
# eth0:80 -> testnet 10.10.2.1

# 允许新的链接 eth0:80 -> testnet
iptables -A FORWARD -i eth0 -o testnet -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT
# 允许链接通信 eth0 -> testnet 和 testnet -> eth0
iptables -A FORWARD -i eth0 -o testnet -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i testnet -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# 默认拒绝
iptables -P FORWARD DROP

# 从外部可以通过,但是本地是不可以的
curl 192.168.1.2

DNAT

  • 不同网口转发需要控制好 SNAT 地址
# 允许转发 - 实际使用时建议进行更精细化控制 - 防火墙
iptables -A FORWARD -j ACCEPT

# DNAT eth0:80 -> 10.10.2.1
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.10.2.1
# SNAT eth0:80 -> 10.10.2.1 from 10.10.1.1
iptables -t nat -A POSTROUTING -o eth0 -p tcp --dport 80 -d 10.10.2.1 -j SNAT --to-source 10.10.1.1

# 可以一个网口配置一个 SNAT - 所有出去的都是相同的 IP
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 10.10.1.1

# 如果是动态 IP 也可以直接使用 MASQUERADE
iptables -t nat -A POSTROUTING -j MASQUERADE

DNAT+SNAT

  • GUEST
    • 192.168.1.3/24
  • HOST
    • eth0 192.168.1.2/24
    • testnet 10.10.1.1
  • TARGET
    • testnet 10.10.2.1
# 准备
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -A FORWARD -j ACCEPT

# 调试
tcpdump -ni any 'port 2222 or (host 10.10.2.1 and port 22)'

# DNAT
# 192.168.1.3=>192.168.1.2:2222 -> 192.168.1.2=>10.10.2.1:22
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 2222 -j DNAT --to-destination 10.10.2.1:22
# 也可以
# iptables -t nat -A PREROUTING -d 192.168.1.2 -p tcp -m tcp --dport 2222 -j DNAT --to-destination 10.10.2.1:22

# SNAT
# 192.168.1.2=>10.10.2.1:22 -> 10.10.1.1=>10.10.2.1:22
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to-source 10.10.1.1
# 也可以
# iptables -t nat -A POSTROUTING -o testnet -j SNAT --to-source 10.10.1.1

以上规则转换为 nftables

# DNAT+SNAT
table ip nat {
chain PREROUTING {
type nat hook prerouting priority dstnat; policy accept;
iifname "eth0" meta l4proto tcp # xt_tcp counter packets 1 bytes 64 # xt_DNAT
}

chain INPUT {
type nat hook input priority 100; policy accept;
}

chain POSTROUTING {
type nat hook postrouting priority srcnat; policy accept;
oifname "testnet" counter packets 2 bytes 124 # xt_SNAT
}

chain OUTPUT {
type nat hook output priority -100; policy accept;
}
}
# 允许转发
table ip filter {
chain INPUT {
type filter hook input priority filter; policy accept;
}

chain FORWARD {
type filter hook forward priority filter; policy accept;
counter packets 9 bytes 509 accept
}

chain OUTPUT {
type filter hook output priority filter; policy accept;
}
}

本地端口转发

# 8001 -> 80
iptables -t nat -A PREROUTING -s 127.0.0.1 -p tcp --dport 8001 -j REDIRECT --to 80
iptables -t nat -A OUTPUT -s 127.0.0.1 -p tcp --dport 8001 -j REDIRECT --to 80
#  UDP 500, 4500
iptables -t nat -A PREROUTING -p udp --dport 500 -j DNAT --to-destination 192.168.1.100:500
iptables -t nat -A PREROUTING -p udp --dport 4500 -j DNAT --to-destination 192.168.1.100:4500

# 确保转发后的数据包可以返回客户端
iptables -t nat -A POSTROUTING -p udp --dport 500 -d 192.168.1.100 -j MASQUERADE
iptables -t nat -A POSTROUTING -p udp --dport 4500 -d 192.168.1.100 -j MASQUERADE