Alter.Org.UA
 << Back Home UK uk   Donate Donate

GIF/GRE tunnels and MSS/MTU under FreeBSD

         +--------   [ Internet ]  ---------+
         |          via Internet too        |       
         |       /                    \     |
  [ Our Server ] --- [ GRE tunnel ] --- [ Client ] -- LAN -- [ Sub-clients ]
                                        

Simple. But the most important issue is missing from manuals. Google knows, but it would be better to avoid problem rather than fix it on-the-fly.

Just do this simple steps on both side and $my_tunnel_ip and $other_side_tunnel_ip become available on both sides. Note, do not forget to swap IPs on 2nd machine :)

Tunnel Server

 ifconfig create gif0 (or gre0)
 ifconfig tunnel $server_real_ip $other_side_real_ip
 ifconfig inet $server_tunnel_ip $other_side_tunnel_ip
 route add $client_net $other_side_tunnel_ip

Tunnel Client

 ifconfig create gif0 (or gre0)
 ifconfig tunnel $other_side_real_ip $server_real_ip
 ifconfig inet $other_side_tunnel_ip $server_tunnel_ip
 ping -c 1 $server_tunnel_ip
 ifconfig $lan_if $client_net_gw_ip/mask

Note: if the client is beyond NAT, you must run once ping from client side to server_tunnel_ip. You must use client's NAT'ad IP for other_side_real_ip in server config. But you must use fake local IP for other_side_real_ip on client's side in this case.

Tunnel Client

At some moment we discover that sub-client can't load some site(s) via tunnel. In our case they were github.com and slack.com. A bit later we find in tcpdump something like this

ICMP destination unreachable message for path MTU discovery, MTU 1280

This happens because

  • tunneled packets are forwarded via unknown networks with unknown MTU.
  • gif/gre doesn't fragment packets, thus MTU adjustment on the tunnel interface doesn't help. However, this must be done.
  • ICMP is filtered or not handled somewhere in the Intrnet. Or someboby sets no-frag flag.
  • client beyond the tunnel doesn't know about tunneling.

This can be fixed by changing MSS value on TCP connection setup. In this case server side will reduce packet size to the value, that can be transmitted via tunnel without fragmentation. Run the following on both sides of the tunnel

tcpmssd  -p 22200 -m 1280
ipfw add NNN divert 22200 tcp from any to any via gif0 out setup

Note: If you cannot do this on client side, do the following on the tunnel server:

tcpmssd -b -p 22200 -m 1280
ipfw add NNN divert 22200 tcp from any to any via gif0 setup

Note: -b tells tcpmssd to fix MSS not only for "outgoing" packets (those are sent via some interface), but for incoming too. This is required because packets going from client beyond the tunnel to the Internet are "incoming" for tunnel server, since the come in from gif/gre interface.


See also:

FB or mail alterX@alter.org.ua (remove X)   Share
<< Back designed by Alter aka Alexander A. Telyatnikov powered by Apache+PHP under FBSD © 2002-2024