0

I have OpenVPN Server on a Raspberry Pi connected to my home broadband but it's behind a carrier-grade NAT. What's the best way of remote UDP port forwarding to get UDP working on OpenVPN when the server is behind a NAT? The first thing I tried is port forwarding on the router but doesn't work due to the CGNAT.

The main reason for this VPN is so I can route internet traffic through my home broadband connection when out and about such as when on public WiFi.

I have a VPS and currently using $ ssh -R :1194:localhost:1194 ubuntu@myvps on the Raspberry Pi with GatewayPorts yes in the SSH server config to port forward. This works when the OpenVPN server protocol is configured so it's on TCP but not UDP.

I tried socat

VPN server side: $ socat tcp4-listen:1190,reuseaddr,fork UDP:localhost:1194
VPS side: $ socat udp4-listen:1194,reuseaddr,fork tcp:localhost:1190

and $ ssh -R :1190:localhost:1190 ubuntu@myvps but the OpenVPN client just times out after a minute of trying to connect and got:

pi ovpn-server[81373]: ues/127.0.0.1:35092 tls-crypt unwrap error: packet replay
pi ovpn-server[81373]: ues/127.0.0.1:35092 TLS Error: tls-crypt unwrapping failed from [AF_INET]127.0.0.1:35092
pi ovpn-server[81373]: ues/127.0.0.1:35092 tls-crypt unwrap error: bad packet ID (may be a replay): [ #3 / time = (1628117978) Wed Aug  4 23:59:38 2021 ] -- see the man page entry for --no-replay and --replay-window for more info or silence this warning with --mute-replay-warnings

several times in the OpenVPN server log.

I then tried SSF - Secure Socket Funneling

OpenVPN side: $ ./ssf -V :1194:127.0.0.1:1194 -g myvps
VPS side: $ ./ssfd -g

and it works but it's slower than TCP and the ssf process uses high CPU on my Pi when there's VPN activity. I suspect this is something to do with the encryption SSF uses and isn't efficient.

Is there a better way of UDP remote port forwarding so I can get the fastest possible connection? The tunnel doesn't necessarily need encryption because OpenVPN uses encryption anyway.

[PiVPN Server] <- [CGNAT] <- [VPS] <- [client devices (Windows, Android, iOS, etc)]

7
  • Why not just turn the vps into the server and your Pi into the VPN client? That way the Pi xann initiate the connectiin and nat traversal can work seemlessly.
    – davidgo
    Commented Aug 5, 2021 at 19:23
  • @davidgo The problem with doing that is that some websites block VPS IP addresses and Google also keeps asking for a captcha. So it's not a viable solution.
    – Aenfa
    Commented Aug 5, 2021 at 20:43
  • 2
    @Aenta I think your understanding of VPN's is flawed. A VPN does not need to have a default route, and can be used for site to site communication only, leaving general traffic to go out the regular connection - or even having the VPS send its default through your home connection. The only difference between what I proposed and your current setup is which end initiates the connection and a few configuration options.
    – davidgo
    Commented Aug 5, 2021 at 22:43
  • @davidgo I do want general internet traffic to go through the VPN. How do I go about setting it up?
    – Aenfa
    Commented Aug 6, 2021 at 0:19
  • Your answers are confusing. You say "The problem with doing that is that some websites block VPS IP addresses and Google also keeps asking for a captcha. So it's not a viable solution." implying you DONT want general traffic going through the VPN, then you say you DO want it to. Have you set up a VPN on your VPS or are you reliant on SSH? Can you provide a network diagram of what you are trying to do?
    – davidgo
    Commented Aug 6, 2021 at 4:06

1 Answer 1

0

I have found a solution to the problem by using ssh -w and using iptables to port forward. The SSH server will need:

 PermitTunnel yes

in sshd_config.

Then on the Pi, run:

sudo ip tuntap add dev tun1 mode tun user pi group pi
sudo ip link set tun1 up
sudo ip addr add 10.0.0.200/32 peer 10.0.0.100 dev tun1

On VPS:

sudo ip tuntap add dev tun1 mode tun user <username> group <usergroup>
sudo ip link set tun1 up
sudo ip addr add 10.0.0.100/32 peer 10.0.0.200 dev tun1

sudo iptables -I FORWARD -d 10.0.0.200 -m comment --comment "Accept to forward VPN traffic" \
 -m udp -p udp --dport 1194 -j ACCEPT
sudo iptables -I FORWARD -m comment --comment "Accept to forward VPN return traffic" \
 -s 10.0.0.200 -m udp -p udp --sport 1194 -j ACCEPT
sudo iptables -t nat -I PREROUTING -m udp -p udp --dport 1194 -m comment \
 --comment "redirect pkts to VPN server" -j DNAT --to-destination 10.0.0.200:1194
sudo iptables -t nat -I POSTROUTING -m comment --comment "NAT the src ip" \
 -d 10.0.0.200 -o tun1 -j MASQUERADE

Then finally on the Pi, run:

ssh -w 1:1 -fN username@myvps

Now I have OpenVPN working on UDP. This also works with WireGuard so now I have them both up and running.

1
  • Isn't that a bit redundant? You're pretty much putting a VPN inside another VPN. And if SSH can connect outwards to the VPS... why not set up OpenVPN to do the same thing in the first place? Commented Aug 15, 2021 at 0:10

You must log in to answer this question.

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