你是否遇到过这样的困境?
- 一个关键服务的IP地址或端口需要变更,但无数应用程序的配置却无法立即修改?
- 在本地开发时,想将测试请求无缝转发到远程的测试服务器?
- 希望在不重启应用程序的情况下,实现流量的透明转发或负载均衡?
今天介绍一条iptables命令:
bash
sudo iptables -t nat -A OUTPUT ... -j DNAT ...
用于在各个场景下,不重启服务进行网络流量的重定向。
实战
这边结合一个Python Flask编写的HTTP服务端来描述该条命令的使用。
服务端
服务端Python代码如下:
python
from flask import Flask, jsonify
import socket
app = Flask(__name__)
@app.route("/ping")
def ping():
return jsonify(
{"message": "pong", "hostname": socket.gethostname()},
)
这个HTTP服务器在访问/ping时简单返回一条message和服务器的hostname。
网络拓扑
网络拓扑图如下:

此时在服务器1(192.168.11.1)和服务器2(192.168.11.135)上部署上述的Python HTTP服务器代码,访问结果如下:

访问 192.168.11.1:5000/ping 时,得到Windows服务器的hostname;
访问 192.168.11.135:5000/ping 时,得到Linux服务器的hostname。
iptables
使用iptables进行网络流量的重定向:
bash
#启用Linux内核的ipv4转发,这一步是必须的
sudo sysctl -w net.ipv4.ip_forward=1
# 将所有 192.168.11.1:5000 的流量重定向至 192.168.11.135:5000
sudo iptables -t nat -A OUTPUT -p tcp -d 192.168.11.1 --dport 5000 -j DNAT --to-destination 192.168.11.135:5000
此时我们再访问 192.168.11.1:5000 得到的结果如下:

相比较上图的结果,我们发现所有访问 192.168.11.1 的流量都被成功定向到 192.168.11.135。