我正在努力建立一个基础设施,其中来自 Amazon RDS 实例的 MySQL 复制流量通过 OpenVPN 链接转发到第二台服务器。
有一个运行 OpenVPN 的 Ubuntu EC2 实例,并有一条通往另一个基础设施中的 MySQL 服务器的隧道。如果我理解iptables
正确的话,应该可以将端口 3306 上收到的流量转发到另一个 (远程) IP 上的端口 3306,并逆转返回流量的过程。
设置如下:
|<--------- VPC ---------->|<-- internet -->|<--- Datacenter --->|
RDS --> Public ip: 10.11.12.13
EC2 instance
VPC ip: 1.2.3.4
OpenVPN ==== tunnel ===> MySQL server
public ip: 9.10.11.12
vpn ip: 5.6.7.8
RDS 和 EC2 实例都在同一个 VPC 中,我可以通过 OpenVPN 链接从 EC2 实例连接到 MySQL 服务器,完全没有问题 - 因此 OpenVPN 部分似乎运行良好:
ssh [email protected]
mysql -uuser -p -h5.6.7.8
我尝试配置iptables
端口转发,但没有成功。我当前的规则如下:
$ iptables -L
Chain INPUT (policy ACCEPT)
num target prot opt source destination
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
Chain INET-PRIV (0 references)
num target prot opt source destination
和
$ iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306 to:5.6.7.8:3306
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306 to:5.6.7.8:3306
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT tcp -- 0.0.0.0/0 5.6.7.8 tcp dpt:3306 to:1.2.3.4
有人能指出我哪里做错了吗?
答案1
你的内核中是否启用了 IP 转发?
cat /proc/sys/net/ipv4/ip_forward
如果已启用,则返回 1;如果已禁用,则返回 0。如果为 0,则执行(以 root 身份执行)
echo 1 > /proc/sys/net/ipv4/ip_forward
另外,为什么针对同一目的地有两个 PREROUTING 规则(但这不应该是个问题)?
除此之外,您的规则是正确的,它可能会在您启用 ip_forward 后立即起作用。
另一个提示:仅出于测试目的在转发和输入中使用策略接受。
为了帮助您,此脚本应设置一些更安全的策略并包括您的转发。我保留了 SSH 以免将您锁定,并根据您的需要进行自定义(例如为您的 vpn 添加规则等)。
#!/bin/sh
# Enable IP-Forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
### DEFAULT FIREWALL SETTINGS
# Flush all tables
iptables -F
iptables -t nat -F
iptables -X
# Set default policy to drop
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
# Allow local process communication (optional, required for some services)
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Allow established and related connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow outgoing connections
iptables -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
### CUSTOM FIREWALL SETTINGS
# SSH (optional)
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
# MySQL Forwarding:
# Allow forwarding to 5.6.7.8 on port 3306
iptables -A FORWARD -p tcp --dport 3306 -d 5.6.7.8 -j ACCEPT
# Set NAT from 1.2.3.4:3306 to 5.6.7.8:3306
iptables -t nat -A PREROUTING -p tcp --dport 3306 -j DNAT --to-destination 5.6.7.8:3306
iptables -t nat -A POSTROUTING -p tcp -d 5.6.7.8 --dport 3306 -j SNAT --to-source 1.2.3.4
编辑:哦,如果您不使用 IPv6,请禁用它。
答案2
很抱歉让这篇旧帖再次活跃起来。
这项工作很棒。而且我还有另一套规则也适用于我的测试用例。
但是,除非您事先执行了 ssh localForward,否则我不想使用“中间”机器访问 SQL 服务器。否则,任何了解该“枢纽”的人都会获得对目的地的“访问权”。
那么,如何实现这一点......