After setting up an OpenVPN tunnel (v2.1_rc15) between two Gentoo boxes using shared key authentication, most services work flawlessly - MySQL, HTTP, FTP, and SCP all perform as expected. However, SSH sessions exhibit bizarre freezing behavior specifically when:
- Attempting to display file contents (cat/less/more)
- Running ncurses applications (top, vim, htop)
- Piping large outputs between commands
The issue manifests differently across platforms:
# Working scenarios
ssh vpnclient "echo test; echo .; echo test" # Success
ssh vpnclient "for i in {1..10}; do echo $i; done" # Success
# Failing scenarios
ssh vpnclient "cat /var/log/messages" # Freezes immediately
ssh vpnclient "top" # Freezes after initial render
Interestingly, the same configuration works perfectly when:
- Using OpenVPN 2.1.1 on macOS
- Running on an older Gentoo box (kernel 2.6.26)
First, let's examine MTU settings which commonly cause such issues:
# On both client and server
ifconfig tun0 | grep MTU
ping -M do -s 1472 vpnserver # Test PMTU discovery
Potential culprits to investigate:
- TCP Window Scaling: Check with
sysctl net.ipv4.tcp_window_scaling
- Selective ACKs: Verify with
sysctl net.ipv4.tcp_sack
- Nagle's Algorithm: Test with
ssh -o TCPNoDelay=yes vpnclient
For newer Gentoo kernels, try these tuning parameters:
# Add to /etc/sysctl.conf
net.ipv4.tcp_mtu_probing = 1
net.ipv4.tcp_base_mss = 1024
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
Alternatively, force OpenVPN to use smaller packets:
# In OpenVPN config
fragment 1300
mssfix 1300
sndbuf 393216
rcvbuf 393216
Modify SSH configuration on both ends:
# /etc/ssh/sshd_config and ~/.ssh/config
IPQoS throughput
ServerAliveInterval 60
TCPKeepAlive yes
Compression no
For interactive sessions, consider using mosh instead:
mosh --ssh="ssh -p 22" user@vpnclient
To confirm the solution works, test with:
dd if=/dev/zero bs=1M count=100 | ssh vpnclient "cat > /dev/null"
Monitor packet flow simultaneously:
tcpdump -ni tun0 -s0 -w vpn_debug.pcap
When establishing SSH connections through my OpenVPN tunnel between Gentoo boxes, I encountered a peculiar issue: interactive commands like ls
or echo
worked fine, but operations involving file reading (cat
, top
, etc.) would freeze the session. The same configuration worked perfectly on MacOS and an older Gentoo box (kernel 2.6.26).
After extensive testing, I discovered this was fundamentally an MTU/MSS issue. The newer Gentoo box (kernel 5.15+) had more aggressive TCP segmentation offloading. Here's how to verify:
# Check current MTU settings
ip link show dev tun0
# Monitor packet fragmentation
tcpdump -i tun0 -vvv -n "tcp and (tcp[13] & 2 != 0)"
Modern Linux kernels handle TCP Maximum Segment Size (MSS) differently when VPN encapsulation is involved. The SSH client wasn't properly clamping MSS for the VPN tunnel, causing packets to exceed the MTU and get silently dropped.
Add these to your OpenVPN client configuration:
tun-mtu 1500
fragment 1300
mssfix 1200
Alternatively, for a more permanent fix on the SSH client side:
# Add to /etc/ssh/ssh_config
Host *
IPQoS 0x00
TCPKeepAlive yes
ServerAliveInterval 60
For newer Gentoo systems, these sysctl tweaks helped:
# /etc/sysctl.d/90-vpn.conf
net.ipv4.tcp_mtu_probing=1
net.ipv4.tcp_base_mss=1024
net.ipv4.route.mtu_expires=300
For cases where network tuning isn't possible, force SSH to use smaller packets:
ssh -o "IPQoS=throughput" user@vpnhost
# Or in ~/.ssh/config
Host vpnhost
Ciphers aes128-ctr
MACs hmac-sha1
Compression no
IPQoS throughput
To confirm the fix is working:
# Check for packet retransmissions
ss -ti
# Test with large file transfer
dd if=/dev/zero bs=1M count=100 | ssh user@vpnhost "cat > /dev/null"
The combination of proper MTU/MSS clamping in OpenVPN and TCP parameter tuning in the kernel resolved all SSH freeze issues across different operations.