路由其实是个很简单的事情,不知道为什么在实际运用中被很多人误解。首先,路由规则是个纯IP层的事情,和TCP没有关系。其次,路由和NAT没有关系。实际上,和这两个有关系的都是iptables。

路由表的大概概念就是,你家门口有三条路,有一张路径表。到上海市,走左边,北京市,走右边,西安市,走中间。因此路由表的概念是发出规则。当你收到一个包,如果目的地址是本地,那么就交给监听程序处理。如果没有监听程序,那么就拒绝报文。(注意,下文讨论的时候都略去了iptables)如果目的地址不是本地,则看是否允许转发。不允许,丢弃,允许,加入发出队列。路由表就是发出队列的选择规则。这个规则之所以存在,主要是因为多头主机的存在。如果一台机器只有一个发出设备,路由表是没有任何用处的。

发出规则计算很简单,首先取目标网络地址,还有包网络地址,然后分别和子网掩码求与(AND)。如果两者相等,那么就转发到这个规则所指定的接口上,如果不等,继续匹配。规则顺序也很简单,子网掩码距离越长,子网越小,规则越靠上。其中有两种特殊的子网掩码,一种是255.255.255.255,或者叫/32,用于指定主机。一种是0.0.0.0,或者叫/0。这个子网只有一个,叫做default。因为按照规则用这个掩码计算的结果,任何目标地址都可以匹配这一规则。

当然,根据上面的解释我们可以知道,路由表只管发出报文。如果目标设备需要返回一个报文,他必须保证返回路由的正确。因此在下面的openvpn讲解中,你在vps也必须配置路由。很幸运,这个问题openvpn已经帮我们做好了。

通常而言,我们拨号上网后应当有三条路由规则,第一条不解释。第二条通常是内网IP通过内网端口发出——这是当然的,否则内网包就暴露了。第三条通常是其他IP通过外网发出。当内网需要向外网发送数据的时候,会设定路由器作为网关。路由器会转发内网的包到他的上级路由器上。而当外网有数据要发送给内网的时候,情况则正好相反。注意,实际中一般是要进行NAT的,不是这么直接收发。

如果当你使用了openvpn的routed模式,那么你就有了两个内网——常规内网和虚拟内网。我们可以想像,首先需要配置的是两个内网的互通问题。在你本地的网关上,需要配置虚拟网络段发送到tun0设备上。而在远程,需要配置常规内网段发送到拨号上来的这个IP上。大致要配置这些东西。

-----------------vps-server.conf-------------------

client-config-dir /etc/openvpn/ccd

route 192.168.x.0 255.255.255.0

--------------------ccd/openwrt---------------------

iroute 192.168.x.0 255.255.255.0

这样,当openwrt这个用户拨号上来后,vps上就会添加一条路由,192.168.1.0网段通过刚刚拨号的地址来转发。

其次,哪些数据发送到拨号网络,哪些需要通过虚拟内网呢?这规则通常由你来定。不过千万注意,不要用tun0这个设备来发送到服务器的数据——这会引发循环。这个问题一个不是那么明显的例子是,你设定使用tun0来发送default,但是又没有特别指定vps的地址使用ppp0发送。