既然是服务器, 那一般来说都是被访问的, 因此很多情况做源地址路由就够了, 即: 从哪里来, 往哪里回. (开发者需要注意: 对于TCP服务, 假如Listener是绑定到*或者0.0.0.0的, 那么Accept出来的socket会自动绑定到源网络接口, 不用担心数据走向. 对于UDP服务, 必须显式的绑定到特定网络接口, 否则回去的数据只会走默认路由). 假设一台机器两个网卡eth0, eth1. ip分别为192.168.1.2/24和192.168.2.2/24, 对应网关分别为192.168.1.1和192.168.2.1. 以下粗略的写下步骤 (注意, 以下所有操作仅针对redhat el 5/ centos 5以上的系统, 不保证其他系统也能工作)

1. 配置ip. 编辑/etc/sysconfig/network-scripts/ifcfg-ethX设置好两个eth接口的IP和掩码, 网关设一个就行, 设的那个即为默认网关. 这里假设默认网关是192.168.1.1

2. 新建一个路由表. 编辑/etc/iproute2/rt_tables, 加入一行

200 cnc

前面的200是路由表编号, 可以随便取, 只要不跟其他项冲突就行了. 后面的cnc是路由表名称, 按需求随便改.

3. 在新建的路由表中加入默认路由

ip ro add default via 192.168.2.1 table cnc

4. 添加源地址策略路由, 这是”从哪里来, 往哪里回”的关键

ip ru add from 192.168.2.2 table cnc

第3,4两个步骤的一般做法是加到rc.local, 实现开机自动运行. 但有个小问题, 就是当eth1因为某些原因断开链路时, cnc路由表里面的那条默认路由会丢失. 接下来将解决这个问题, 这也是写这篇文章的原因. 解决问题的关键在于如何在ifup的时候执行我们的命令. 仔细搜罗/etc/sysconfig/network-scripts/下的文件, 发现有个叫ifup-routes的脚本, 看看它的代码, 发现它会读取route-xxx和rule-xxx文件的内容, 并作为ip命令的参数, 就是这里了. network-scripts下并没有route-xxx 和rule-xxx文件, 需要手工创建, 后面的xxx表示网络接口名, 在这里就是eth1. 接下去就是

echo “default via 192.168.2.1 table cnc” > route-eth1

echo “from 192.168.2.2 table cnc” > rule-eth1

以这段代替前面3,4步骤. 这样就不用动rc.local了, 也不用担心路由丢失了.