背景:×××服务器是在Linux搭建的PPTP ×××服务,×××服务器在防火墙前端。

 问题:在外需要办公时,通过×××拨入对办公网资源进行访问,但是无法访问防火墙后端服务器(WEB服务),不通过×××拨入在办公室时进行访问正常。将服务器移至防火墙前端,×××拨入访问也正常。
 
解决过程:这个问题也比较怪,要是全不能访问那问题还好处理。首先在防火墙查看日志,×××拨入访问时防火墙是否丢弃了某些包,但是没有。最后防火墙都设置成允许所有IP包和PPTP(二层)包都通过还是不能访问。接下来在服务器上进行抓包:
09:21:16.394505 IP 172.20.4.226.3038 > 172.20.4.144.80: S 2073250562:2073250562(0) win 8192 <mss 1360,nop,nop,sackOK>
09:21:16.394628 IP 172.20.4.144.80 > 172.20.4.226.3038: S 4245157382:4245157382(0) ack 2073250563 win 5840 <mss 1460,nop,nop,sackOK>
09:21:16.733163 IP 172.20.4.226.3038 > 172.20.4.144.80: . ack 1 win 9520
09:21:16.853327 IP 172.20.4.226.3038 > 172.20.4.144.80: P 1:560(559) ack 1 win 9520
发现三次握手已成功,已经开始传输数据,但是为什么显示不了呢?经过咨询前辈最终确认是MTU的问题。
这是一个比较复杂的问题。首页拨入×××后,在×××服务器上能看到最PPP0的MTU是1396,通过上面的抓包能看到mms 最小的是1360(三次握手中协商小的mms为传输mms)。
ppp0接口的路径MTU为1396字节,也就是说如果一个数据包想要通过这个接口的话,一定不能大于1396字节,如果大于这个值,会出现两种结果:
1、如果这个数据包的IP头部没有设置不能分片(DF)的标志,那么×××主机就把这个数据包分片,使其数据包大小小于1396字节,然后允许其通过。
2、反之,如果这个数据包的IP头部设置不能分片(DF)的标志,那么×××主机就会返回一个ICMP不可达的差错报文。同时丢弃这个数据包。
你可能会说1396大于1360,数据包应该能通过的呀,但是还是20字节的tcp头部和20字节的IP报头这样数据包就会被丢弃了。
 
以下提供2种解决方法。
1、    修改防火墙的inside接口的MTU,将MTU设置成小于1396-20-20=1356 ,但是这种方法有一个缺点,需要在每一个防火墙上修改并且内部机器访问时MTU较小。
2、    直接在×××服务器上修改,因为mss是在TCP连接建立开始时,通过带有syn标志的IP数据包进行传输的,所以我们在iptables里面规定,在转发数据时,只要发现带有 syn标志并且源地址×××拨入分配的IP数据包时,将其mss设定为1356字节,这样就与ppp0接口的路径MTU向匹配了,数据自然就可以畅通无阻啦。

iptables -A FORWARD -p tcp --syn -s 10.1.107.0/24 -j TCPMSS --set-mss 1356