好的,我仍在努力创建一个 dmz 的 http 服务器
所以现在我有一个使用 ssh -w 0:0 的以太网隧道,并且两端都有可以相互通信的接口:
所以现在我正在努力让这个 http 服务器对外部网络可见。以下是完整的设置
因此我创建了一个新的 ec2 实例并运行设置:
源 ./HOST scp -i green.pem 服务器/* root@$HOST: ssh -i green.pem root@$HOST./setup
它依次在远程机器上运行设置:
apt-get 更新 apt-get 安装 telnet echo 1 | tee /proc/sys/net/ipv4/ip_forward 回显“PermitTunnel yes”>> /etc/ssh/sshd_config /etc/init.d/ssh 重启
然后我启动 ssh 连接:
sudo./运行服务器$HOST:
主机=$1 ssh -i green.pem root@$HOST -w 0:0 -o Tunnel=ethernet -o ServerAliveInterval=60
然后在 ssh 术语中我开始路由 iptables 转发:
##### # 服务器路由 # 打开水龙头 ifconfig tap0 启动 # 通过它路由 192.168.2.* 的所有流量 ip 路由添加 192.168.2.0/24 dev tap0 ##### # 服务器 iptables 远程内部 IP=$1 iptables -F iptables -t nat -F ### 结束初始化防火墙.. 启动 DMZ 内容 #### # 在 DMZ 和 LAN 之间转发流量 iptables -A FORWARD -i eth0 -o tap0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -i tap0 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT # 将传入端口路由到 DMZ 服务器 192.168.2.1 iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 8000 -j DNAT --to-destination 192.168.2.1:8000 iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to $REMOTE_INTERNAL_IP ### 结束 DMZ .. 添加其他规则 ###
最后在客户端我添加了路由和端口转发
########## # 客户 主机=$1 # 打开水龙头 ifconfig tap0 启动 # 在上面放一个 IP 以便我们能监听 ifconfig tap0 192.168.2.1 # 为我们的 ssh 添加一条明确的路由 ip route 通过 192.168.1.1 dev eth0 添加 $HOST # 将 tap 设为默认路由 ip route 替换默认 dev tap0 # 删除默认链接 #ip route del 192.168.2.0/24 dev tap0 proto 内核范围链接 src 192.168.2.1
然后我启动网络服务器
python-m 简单HTTP服务器
当我从任一服务器执行 telnet 192.168.2.1 时,它都能顺利通过。但如果我执行 telnet 到 $THE_REAL_IP,它就不起作用。
如果我设置 MASQUERADE iptables 规则,那么它就可以正常工作,但我这样做是为了避免 MASQUERADE。我希望原始 IP 保留在数据包上。
知道我做错了什么吗?
-----
更多信息
-----
好吧,现在我已经尝试了很多次了。但仍然没有任何效果。
我认为可能有效的是将其添加到客户端:
# 这些应该将数据包路由回tap0 从 192.168.2.0/24 表 42 添加 ip 规则 ip 路由添加默认 dev tap0 表 42
因为这应该为 192.168.2.1 写入的所有内容设置强制规则,应该通过该 tap0 接口返回。但不幸的是,它不起作用。
我还尝试将 IP 与远端的 tap0 关联起来。
ifconfig tap0 192.168.2.5
这看起来很有趣,因为现在我不需要设置路由,系统似乎几乎自动完成:
##### # 服务器路由 # 打开水龙头 ifconfig tap0 192.168.2.5 ifconfig tap0 启动 # 通过它路由 192.168.2.* 的所有流量 ip 路由添加 192.168.2.0/24 dev tap0 ##### # 服务器 iptables iptables -F iptables -t nat -F # 在 DMZ 和 LAN 之间转发流量 iptables -A FORWARD -i eth0 -o tap0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -i tap0 -o eth0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT # 将传入端口路由到 DMZ 服务器 192.168.2.1 iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 8000 -j DNAT --to-destination 192.168.2.1:8000 iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE ### 结束服务器 #### ################################ ################################ ########## # 客户 echo 1 | tee /proc/sys/net/ipv4/ip_forward # 打开水龙头 ifconfig tap0 启动 # 在上面放一个 IP 以便我们能监听 ifconfig tap0 192.168.2.1 # 这些应该将数据包路由回tap0 # 但实际上它们并没有什么区别 #从 192.168.2.0/24 表 42 添加 ip 规则 #ip route 添加默认 dev tap0 表 42
答案1
我知道您说过要让原始 IP 地址继续访问您的 Python 服务器,但您可能采取了错误的方法。标准做法是通过 X-Forwarded-For 标头中的 HTTP 传递原始 IP 地址。大多数 Web 框架都会拾取此标头并用它来代替原始 IP 地址(如果指定)。
如果您想走这条路,您只需要一个前端 Web 服务器。无论如何,拥有前端是个好主意:它更安全,因为没有人可以直接访问您的应用服务器,并且您可以轻松实现 HTTPS 和缓存等服务,而无需在应用服务器上占用更多 CPU 周期。像 Nginx 这样的工具可以完美地完成这个任务。
答案2
如果您使用DNAT
而不是,MASQUERADE
那么您应该保持传入数据包上的源 IP 地址不变。
当然,使用 DNAT 时,由于源地址不会被改变,您需要小心确保另一端知道以相同的方式发送响应数据包 - 在您的情况下,沿着隧道发送回,而不是通过作为默认网关的公共接口。