14

We have dozens of embedded devices installed at customers, all calling home to our OpenVPN service. That works fine in general, but a few of our customers have severe path MTU issues. Our influence on the customers to fix their networks is limited, so we need OpenVPN to deal with it. In a nutshell, my question is:

How can i mitigate the low path MTUs of some clients on a per-client bases, that is without using global settings accommodating the worst case for all clients

Note that our worst case it pretty bad: path MTU 576, drops all fragments, doesn't fragment itself, doesn't honour DF-bit. You see why i'd prefer to not solve this issue globally.

The OpenVPN manpage offers a number of MTU related options, most notably --link-mtu, --tun-mtu, --fragment and --mssfix. But it also says

--link-mtu [...] It's best not to set this parameter unless you know what you're doing.

--tun-mtu [...] It's best to use the --fragment and/or --mssfix options to deal with MTU sizing issues.

So i started experimenting with --fragment and --mssfix but soon had to realize that at least the former must be set not only client-side, but also server-side. I then looked into server-side per-client config via --client-config-dir but it says

The following options are legal in a client-specific context: --push, --push-reset, --iroute, --ifconfig-push, and --config.

No mention of MTU options!

So here are my more specific questions:

  • Why exactly are link-mtu and tun-mtu discouraged? What are the potential problems with these options? Note that i am quite comfortable with low-level IP header munging.
  • Which of the options link-mtu tun-mtu fragment mssfix have to be mirrored on the server-side in order to work?
  • Which of the options link-mtu tun-mtu fragment mssfix can be used in client-config-dir?
  • In case all four options have to be mirrored server-side, and cannot be used inside client-config-dir: Are there any alternatives to combat low path MTU per client?

Notes:

  • Parts of my questions have already been asked 5 years ago here, But they haven't really been answered back then, hence i dare to duplicate them.
  • The OpenVPN server is currently 2.2.1 on Ubuntu 12.04. We are preparing an upgrade to 2.3.2 on Ubuntu 14.04
  • The OpenVPN clients are 2.2.1 on Debian 7.6
  • I am happy to determine a customer's path-MTU myself manually
  • Currently we cannot test much server-side. But we are building a complete separate test bed, should be ready soon.

I am thankful for any helpful advise.

  • 1
    576? Dear gawd. I haven't seen an MTU that low since the days of dialup. Is that going over an ancient serial link? – Michael Hampton Sep 13 '14 at 14:44
  • Could you run two OpenVPN servers? Maybe you could run both servers on the same public IP address and use port forwarding (or a routing policy) to direct clients to a different OpenVPN server depending on whether they are on a known problematic network or not (as determined by a list of client IP addresses). – kasperd Sep 13 '14 at 14:52
  • 1
    @MichaelHampton I wondered too. It's >600kbit/s and RTT ~30ms, doesn't look like ancient serial to me. Given that they have other stupid settings (e.g. not responding to DF with 'fragmentation needed'), i guess this is just another one. We told them, but haven't heard back yet. – Nils Toedtmann Sep 13 '14 at 14:54
  • @kasperd interesting idea. I could run multiple OpenVPN server instances. Would have to have maybe 3 or 4, for different MTU ranges. Server-side per-client NAT would not work (i cannot predict the dynamic public client IP addresses), but i would have to alter the client config anyway for the MTU settings (correct?), so i would simply configure the different port straight into the client. - But it would be a maintenance nightmare that i would prefer to avoid! – Nils Toedtmann Sep 13 '14 at 15:02
  • @NilsToedtmann Which criteria would you use to detect which clients are affected? One other approach could be to run a script on the server after a client has connected. The script can try to ping the client IP address with varying packet sizes to figure out which work and which do not. Then it can insert iptables rules to reduce the MSS on all SYN packets to or from that client IP address. – kasperd Sep 13 '14 at 15:09
3

I solved the problem on the client side by adding the option mssfix 1300 to the config file.

From the openvpn man page:

--mssfix max
    Announce to TCP sessions running over the tunnel that they should limit their send packet sizes such that after OpenVPN has encapsulated them, the resulting UDP packet size that OpenVPN sends to its peer will not exceed max bytes. 

Original idea for my solution came from personalvpn.org

  • 1
    So mssfix can be set client-side only? Well, that's something at least. It doesn't help with UDP packets though (which is why i was interested in the other options, but at least the recommended fragment needs to be set server-side too) – Nils Toedtmann Dec 22 '14 at 12:44
  • 2
    mssfix can be added on server as well as client. However the smaller value will be used in negotiation – Ahmed Jul 25 '16 at 22:45
2

Given the lack of answers, i am posting now a solution that is not very elegant, but simple: Run another OpenVPN instance on TCP for "bad clients"

proto tcp

and lower the TCP MSS on the client, e.g.

iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o ${OUT_DEV} -j TCPMSS --set-mss ${PATH-MTU-MINUS-40}

An advantage of this solution is that each client can set its individual MSS.

This is admittedly TCP-over-TCP, but that should perform well enough in many scenarios.

Note that I am still very interested solutions that don't require proto tcp, and i'll mark them as valid answer if they more or less fulfil my outlined requirements.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.