/ network

Source policy route on Ubuntu

被CDN了

部署系统时发现apt-get update失败了,更新某个source list的时候Packages Hash mismatch,一般来说都是运营商的缓存导致的,在服务器上wget那个Packages。gz或者Packages.bz2文件时会发现这个GET请求的response被重定向到了120.52.72.22,说好听一些这算是联通CDN,说难听点这应该算是联通的缓存服务,带宽怎么每年都可以提升?上缓存就好了。

然而这些缓存有时能够加速GET请求的速度,有时就很讨厌了,如果不按照正常时间过期,源内容已经更新了,但我们在末端的用户还是从缓存服务器中获取内容,问题可想而知。

服务器在获取Packages文件时于Release文件中记录的文件签名对比,无法匹配,所以出了那个错,但在我的开发环境下是正常的,因为我们用了两个外网出口。

服务器同时接入了内网和外网,分别在两块网卡上。系统启动时把外网的网关作为系统默认网关,所以在请求外部资源时,都走了外网出口,其实我们这边内网出口最终也可以出去,但有时又需要从公司外访问这台服务器,又不想在另一个出口上加DNAT到内网,于是需要修改系统默认网关为内网的网关。

修改的话用sudo ip route change default via 10.10.10.253就可以了。

这样默认网关就被修改了,但重启的话还有可能被设置成外网那个,所以我修改了interfaces文件,把外网的配置中gateway拿掉了,只保留内网的gateway 10.10.10.253,这样即便重启也会把默认网关设置成内网的。

外网不能用了

另一个问题又出现了,从公司外访问服务器失败了。系统不知道从外网进来的packet应该从外网的网关出去。(好吧,我没有给出网络拓扑图,空说的话不好想象,公司有多个网络接入,本文遇到的情况是两个网卡都分别接入了不同网络,其中一个质量不够好,要使用另一个作为默认)因为此时packet如果从另一个网关走的话,最终是没法正常通信的,举个栗子:我发送数据个foo,结果bar把响应给了我,我就会莫名其妙了,怎么不是foo给我呢?难道我的数据被bar劫持了么?

要想让来自某个IP的packet再从指定的gateway走就需要有一条路由规则,规则发现来自某个IP的packet后离开时走的gateway是我指定的。

Ubuntu等Linux系统中完成这个需要内核支持,内核配置项为:CONFIG_IP_ADVANCED_ROUTERCONFIG_IP_MULTIPLE_TABLES,正常情况下应该都开启了,检查方法可以看/boot/config-xxx文件,其中xxx是内核版本号,可以通过uname -r看到当前的版本号。

系统中有路由表和路由策略,路由表是具体的路由规则,路由策略是在某个条件时应用什么路由规则,所以我们可以先看系统中的路由策略是怎样的:ip rule show,大致如下:

0:	from all lookup local 
32766:	from all lookup main 
32767:	from all lookup default

没有什么条件,所有的流量(all)依次查询localmaindefault路由表中的规则执行。此时可以使用:ip route list table local来看local表的内容,我们这里需要添加一条规则:来自这个网络或者IP的流量,查询一张新的路由表,新路由表中定义默认网关为我们需要的那个。

在添加路由策略之前需要将用到的新路由表写入/etc/iptoute2/rt_tables中,两列,id和表名。(写入后可以添加路由策略)

这个是添加路由策略,来自124.x.x.x的packet使用from_external_rt表处理

sudo ip rule add from 124.x.x.x/24 table from_external_rt

from_external_rt表的内容只需要添加默认网关,sudo ip route add default via 124.x.x.254 table from_external_rt,如果表中已有default的话,可以先删掉或者用change命令,删掉的话:sudo ip route del default table from_external_rt

注意操作路由表时带上table为from_external_rt的参数,否则你是在修改main表的内容,还有就是策略在ip rule中,而路由在ip route中,希望不要看错(之前我看错了,怎么加都看不到策略)

最后

如果希望规则在系统启动时生效,请把这些写入interfaces文件中,写在具体的interface配置的地方,例如我的配置大致是这样:

auto em1
iface em1 inet static
	address 124.x.x.2
	netmask 255.255.255.0
	up ip route flush table from_external_rt
	up ip route add default via 124.x.x.254 table from_external_rt
	up ip rule add from 124.x.x.2/24 table from_external_rt
	down ip rule del from 124.x.x.2/24 table from_external_rt