1

We have some secured web services, including websites, that are only accessible when connected to a VPN provided by the service owner, and since the VPN account is only allowed to be connected by one user at a time, we planned to configure one of our machines in our LAN to be the gateway to handle the traffic towards the secured service:

  1. The VPN is connected via OpenConnect client on a machine running Ubuntu 18.04 bionic.

    • It was verified the proper route was added automatically after VPN is connected, as we can get ping responses from the secured server address, and we can also curl the content of the secured website.
  2. To enable LAN forward, we run:

    sysctl net.ipv4.ip_forward
    
    # tun0: VPN | eth0: LAN
    iptables -A INPUT    -i tun0         -m conntrack --ctstate ESTABLISHED,RELATED          -j ACCEPT
    iptables -A FORWARD  -i eth0         -o tun0                                             -j ACCEPT
    iptables -A FORWARD  -i tun0         -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED  -j ACCEPT
    iptables -t nat      -I POSTROUTING  -o tun0 -d <secured_host>                           -j MASQUERADE
    
  3. We added a static route on our router, to the machine running the VPN, to set the next-hop of traffic to the secured service.
  4. When testing from other machines in the LAN, we can now get ping responses from the secured server, but we cannot open the website in a browser, and if we try to curl from the secured Windows server, we get:
    curl: (35) schannel: failed to receive handshake, SSL/TLS connection failed
    
  5. Checking tcpdump on the machine running the VPN shows:

    sudo tcpdump net <secured_host> -i eth0
      sudo:     unable to resolve host VpnGateway: Resource temporarily unavailable
      tcpdump:  verbose output suppressed, use -v or -vv for full protocol decode
    
      listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
      04:42:56.343467 IP <LAN_machine>.54061 > <secured_host>.https: Flags [SEW], seq 1815972292, win 64240, options [mss 1418,nop,wscale 8,nop,nop,sackOK], length 0
      04:42:56.358208 IP <secured_host>.https > <LAN_machine>.54061: Flags [S.], seq 916191674, ack 1815972293, win 4254, options [mss 1460,sackOK,eol], length 0
      04:42:56.359305 IP <LAN_machine>.54061 > <secured_host>.https: Flags [.], ack 1, win 64240, length 0
      04:42:56.361243 IP <LAN_machine>.54061 > <secured_host>.https: Flags [P.], seq 1:190, ack 1, win 64240, length 189
      04:42:56.388369 IP <secured_host>.https > <LAN_machine>.54061: Flags [.], ack 190, win 4443, length 0
      04:43:06.388820 IP <secured_host>.https > <LAN_machine>.54061: Flags [R.], seq 5583, ack 190, win 0, length 0
      04:43:06.391505 IP <LAN_machine>.54061 > <secured_host>.https: Flags [.], ack 1, win 64240, length 0
      04:43:06.405569 IP <secured_host>.https > <LAN_machine>.54061: Flags [R.], seq 1, ack 190, win 0, length 0
    
      8  packets captured
      10 packets received by filter
      0  packets dropped by kernel
    
    sudo tcpdump net <secured_host> -i tun0
      tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    
      listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
      04:42:56.343504 IP <tun0_net>.54061 > <secured_host>.https: Flags [SEW], seq 1815972292, win 64240, options [mss 1418,nop,wscale 8,nop,nop,sackOK], length 0
      04:42:56.358199 IP <secured_host>.https > <tun0_net>.54061: Flags [S.], seq 916191674, ack 1815972293, win 4254, options [mss 1460,sackOK,eol], length 0
      04:42:56.359329 IP <tun0_net>.54061 > <secured_host>.https: Flags [.], ack 1, win 64240, length 0
      04:42:56.361251 IP <tun0_net>.54061 > <secured_host>.https: Flags [P.], seq 1:190, ack 1, win 64240, length 189
      04:42:56.388362 IP <secured_host>.https > <tun0_net>.54061: Flags [.], ack 190, win 4443, length 0
      04:43:06.388779 IP <secured_host>.https > <tun0_net>.54061: Flags [R.], seq 5583, ack 190, win 0, length 0
      04:43:06.391523 IP <tun0_net>.54061 > <secured_host>.https: Flags [.], ack 1, win 64240, length 0
      04:43:06.405552 IP <secured_host>.https > <tun0_net>.54061: Flags [R.], seq 1, ack 190, win 0, length 0
    
      8 packets captured
      8 packets received by filter
      0 packets dropped by kernel
    

What else should I do to make things work?

1 Answer 1

1

A common issue with routed VPNs is MTU. Your tun0 interface has a lower MTU (below the normal 1500) due to VPN encapsulation, and locally initiated connections know this and adjust the advertised TCP MSS (maximum segment size) accordingly. But software on your other LAN hosts doesn't know this (those hosts only know their own Ethernet interfaces) and still makes TCP connections with MSS still based on the full 1500 byte MTU.

Normally, this wouldn't be a problem – whenever the HTTPS server tried to send you a larger packet, the remote VPN gateway would respond with ICMP "Packet Too Big" and the server would adjust. But if the remote network has misconfigured firewalls which block "unusual" ICMP packets, that doesn't happen and the server just keeps trying to retransmit the same large packet forever.

There are client-side workarounds – you can use iptables to edit the TCP handshake on the fly:

-t mangle -A POSTROUTING -o tun0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1400
3
  • Yes, that worked. After setting TCPMSS a value smaller than MTU(1200, in my case), everything started working. Thank a lot.
    – Shaun Chen
    Commented Jun 8, 2020 at 7:56
  • Huh, why is your MTU so small? I'd expect at least 1350–1400 even for the worst VPNs... (IPv6 requires a MTU of at least 1280.) Commented Jun 8, 2020 at 8:08
  • What I got is 1199, which should be OK as it is mainly used for SOAP requests and exchanging small XML files via FTP.
    – Shaun Chen
    Commented Jun 8, 2020 at 23:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .