Background: I have a cellular ISP and therefore cannot configure the CGNAT. After burning through some dumb ideas (free reverse proxy, docker) I realized I could just use my paid VPN.

My setup is as follows: on the VPN server create a tunnel to AirVPN and start the openvpn daemon. This creates tun0 and tun1 with their own 10.x.x.x/24 subnets. The home network has 192.168.12.0/24.

It’s possible to troubleshoot the MTU with ping -M do -s xxxx y.y.y.y to the VPN public address and test TCP/UDP sockets with nc -l -u -p 1194 .

I’m not sure if the MTU is variable across servers, but for the server I am on now ping -M do -s 1432 x.x.x.x is the biggest I can get a response from. 1432+20+8=1460 bytes.

Regardless, connecting to the home VPN through the AirVPN link still causes breakage. Discord seems to be what isn’t working, mostly. Everything else has 200 ms latency as expected and not everything pings correctly. Rarely it will tell me the MTU has to be adjusted, sometimes tells me “message too long” and mostly just ignores my ping.

Can someone give me a recommendation for what MTU to be setting in my local OpenVPN server? Should I use mssfix or tun-mtu? Should I lower the MTU of the AirVPN connection? What else can I do?

Diagram:

Home -> AirVPN <- (1460 MTU) -> OpenVPN Client & server -> (1300 MTU) -> Home -> Outside World

client configuration
dev tun
proto udp
remote A.B.C.D 34183
tun-mtu 1300
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
mute-replay-warnings
remote-cert-tls server
key-direction 1
cipher AES-256-CBC
data-ciphers AES-256-CBC
verb 3
server configuration
proto udp
dev tun
ca /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/server.crt
key /etc/openvpn/easy-rsa/pki/private/server.key
dh /etc/openvpn/easy-rsa/pki/dh.pem
topology subnet
tun-mtu 1300
server 10.9.8.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 192.168.12.0 255.255.255.0"
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 1.1.1.1"
keepalive 10 120
tls-server
tls-auth /etc/openvpn/server/ta.key 0
auth-nocache
user nobody
group nogroup
cipher AES-256-CBC
data-ciphers AES-256-CBC
status /var/log/openvpn/openvpn-status.log
persist-tun
persist-key
verb 3
client-to-client
explicit-exit-notify 1
AirVPN client configuration
dev tun
remote [spoiler].vpn.airdns.org 443
resolv-retry infinite
nobind
tun-mtu 1460
persist-key
persist-tun
auth-nocache
verb 3
explicit-exit-notify 5
push-peer-info
setenv UV_IPV6 yes
remote-cert-tls server
comp-lzo no
data-ciphers AES-256-GCM:AES-256-CBC:AES-192-GCM:AES-192-CBC:AES-128-GCM:AES-128-CBC
data-ciphers-fallback AES-256-CBC
proto udp
auth SHA512

In the process of doing this I somehow shut my house’s WiFi down…

  • dirtycrowOP
    link
    fedilink
    English
    arrow-up
    2
    ·
    edit-2
    6 days ago

    Couldn’t end up getting this to work for Discord (everything else works). Turns out, my IPv4 traffic leaving through wlp3s0 has a MTU of 1460. And I measured a MTU of 1407 for traffic going through the AirVPN tun (implying 53 bytes of overhead, or 25 bytes of OpenVPN overhead). I ended up just saying the VPN overhead was 40 bytes. Here’s my napkin math:

    1460 <- ISP MTU
    - 28 cost of IP/UDP <- ISP MSS
    - 40 cost of OpenVPN <- AirVPN MTU
    1392
    - 28 cost of IP/UDP <- AirVPN MSS
    1364
    - 40 cost of 2nd OpenVPN <- Home VPN MTU
    1339
    - 40 cost of IP/TCP
    1299 <- Home VPN MSS
    

    For Home and AirVPN I set those in the configs (tun-mtu and mssfix), then mirrored it on the client.

    • TauZero@mander.xyz
      link
      fedilink
      English
      arrow-up
      1
      ·
      5 days ago

      Yep, that’s how the calculation goes! You only need mssfix on the innermost tunnel, and the outer tunnel will stay under the limit naturally. Mssfix only works on TCP, so it wouldn’t work on the VPN packets themselves anyway, inside the outer tunnel. OpenVPN/wireguard use UDP. By the way, does Discord use UDP at all? I don’t know what’s the proper way to limit the size of UDP packets in a situation where pathway mtu discovery is the problem/issue. I only know the trick with TCP and clamp-mss. Is there a way to tell discord to force use TCP only? Also, can you be sure that Discord service itself doesn’t block your commercial VPN?