Alter.Org.UA
 << Back Home EN en   Donate Donate

GIF/GRE тунели и MSS/MTU под FreeBSD

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

Все просто. Хотя про самый важный и не самый очевидный момент в manual'ах не написано. Google, конечно, знает ответ, но было бы здорово сделать сразу правильно, а не фиксить на рабочей системе.

По обе стороны делается простая операция и пакеты побежали между my_tunnel_ip и other_side_tunnel_ip. На всякий случай - на 2й стороне адреса меняются местами :)

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: Если клиент находится за NAT'ом - для подъема тунеля и формирования правила трансляции в NAT'е обязательно нужно сделать один ping с клиентской стороны. В качестве other_side_real_ip на сервере указывается ваш реальный IP. А на клиентской в качестве other_side_real_ip - получаемый внутренний IP.

Tunnel Client

И вдруг оказывается, что у суб-клиентов какой-то сайт не грузиться сквозь тунель и говорит timeout. В нашем случае это были github.com и slack.com. В tcpdump'е через некоторое время обнаруживаем что-то такое

ICMP destination unreachable message for path MTU discovery, MTU 1280

А все потому, что

  • тунель идет неизвстными нам путями и MTU может быть каким угодно.
  • gif/gre не фрагментируют и не пересобирают пакеты, поэтому уменьшение MTU на самом тунеле особо не спасает, хотя и необходимо.
  • где-то в интернете ICMP порезали или не обработали. Или запретили фрагментацию.
  • клиент за тунелем о существовании тунеля вообще не догадывается.

Cитуация может быть исправлена изменением MSS при инициализации соединения. Тогда серверная сторона уменьшит размер пакета и фрагментация на тунеле не потребуется. Влиять на клиента мы не можем, но можем перехватить SYN пакеты и изменить значение MSS. На обоих концах тунеля делаем

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

Note: Если нет возможности сделать такое на клиентской стороне тунеля, делаем на серверной немного иначе:

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

Note: -b говорит tcpmssd, что надо править MSS не не только у "исходящего" трафика (т.е. улетающего в некий интерфейс), но и у входящего. На стороне сервера пакеты, идущие от клиента (который за тунелем) в интернет как раз будут считаться входящими, т.к. приходят из тунеля.


См. также:

FB or mail alterX@alter.org.ua (remove X)   Share
<< Back Автор: Alter (Александр А. Телятников) Сервер: Apache+PHP под FBSD © 2002-2024