What's new

How to allow incoming WAN connections for WireGuard clients?

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

arkywein

Occasional Visitor
Hi all,

I'm having an issue that I can't seem to figure out, and I was hoping someone here might be able to help.

Here's my setup:

  • I have a Raspberry Pi running within my local network.
  • The Raspberry Pi is behind a WireGuard VPN, which is configured on my router.
  • I'm running a Shadowsocks server on the Raspberry Pi that's supposed to accept incoming connections from the WAN and then reroute the traffic through the VPN's exit IP.
The problem:

  • The Shadowsocks clients are unable to connect to the server as long as the Raspberry Pi is behind the VPN.
  • If I add a rule to the VPN Director to take the Raspberry Pi off the VPN, everything works perfectly—the clients can connect without any issues.
  • However, when I do this, the outgoing traffic from the Raspberry Pi is no longer routed through the VPN, which exposes it to the public network.
Has anyone faced a similar issue or have any suggestions on how I can get this working? Ideally, I want the Raspberry Pi to remain behind the VPN while still allowing Shadowsocks to accept incoming connections from the WAN.

Thanks in advance for any advice!
 
Hi all,

I'm having an issue that I can't seem to figure out, and I was hoping someone here might be able to help.

Here's my setup:

  • I have a Raspberry Pi running within my local network.
  • The Raspberry Pi is behind a WireGuard VPN, which is configured on my router.
  • I'm running a Shadowsocks server on the Raspberry Pi that's supposed to accept incoming connections from the WAN and then reroute the traffic through the VPN's exit IP.
The problem:

  • The Shadowsocks clients are unable to connect to the server as long as the Raspberry Pi is behind the VPN.
  • If I add a rule to the VPN Director to take the Raspberry Pi off the VPN, everything works perfectly—the clients can connect without any issues.
  • However, when I do this, the outgoing traffic from the Raspberry Pi is no longer routed through the VPN, which exposes it to the public network.
Has anyone faced a similar issue or have any suggestions on how I can get this working? Ideally, I want the Raspberry Pi to remain behind the VPN while still allowing Shadowsocks to accept incoming connections from the WAN.

Thanks in advance for any advice!
There are several things that would prevent this from working. Rp_filter is one thing, general routing another.

There is no way I am aware of to make this work in the gui, one must create the nessisary firewall rules and routing rules manually.

I'm guessing you are using port forward to forward a port from wan to the rpi for incoming connections?

There are several ways of doing this but I would probably attempt to setup a firewall rule to make a connmark on incoming new connections from wan and then use restore mark to transfer this on all packets related to this connection. And set the src_valid_mark bit to keep rp_filter happy. Then create a routing rule to wan for this fw mark. I have never done exactly this before, but it should work. Here are some inspiration: https://www.snbforums.com/threads/e...to-vpn-policy-based-routing.71993/post-785284
some bits are missing though...
 
While I understand your intent (I think), the way you're trying to do it won't work.

What the VPN Director does is determine what will be the default gateway for a given source/remote IP (typically the WAN or one of the VPN clients). But you've created a situation in which the Shadowsock clients need the WAN as their default gateway, while the RPi itself needs the local WG client as its default gateway. But you can't have more than one default gateway for a given device! That makes no sense. The default gateway is, by definition, the *one* route of last resort when there is no other known specific route for the destination. IOW, there can only be *one* default gateway for a given source IP.

The best way to illustrate what does work is to examine the case of a local OpenVPN server rather than a Shadowsocks server.

The remote clients of the OpenVPN server have a specific route defined on the tunnel (e.g., 10.8.0.0/24). So even if those clients access a device on the local network like the RPi that is itself bound to the local Wireguard client, they still get routed back appropriately because they are NOT dependent on the default gateway for routing purposes. But your Shadowsocks clients *are* dependent on the default gateway since they have (presumably) a *public* IP!

IOW, you're trying to route some public IPs via the WAN, some via the VPN, and do it w/ a single default gateway, when the VPN Director can NOT split tunnel any finer than the source/remote IP.

You either have to change the configuration such that there are specific routes for both the Shadowsocks clients and the RPi, or a specific route for one and a default gateway for the other (like the OpenVPN server example above). But you can NOT resolve both through a common default gateway using the VPN Director.
 
Thanks for the input, everyone! While I'm not an expert in networking, your explanations made a lot of sense. After thinking it over, I came up with a workaround that seems to do the trick. For anyone else facing a similar issue, here's what I'm planning to do:

  1. Run a Gluetun container on Docker: This is a lightweight VPN client that also includes a built-in Shadowsocks server.
  2. Connect the Gluetun container to a VPN of my choice: I'll set up the Shadowsocks server within the container on a specific port.
  3. Forward the port from WAN to the Raspberry Pi: This will allow the Shadowsocks server inside the Gluetun container to accept incoming connections from the WAN.
With this setup, the Raspberry Pi's default gateway will remain the WAN, but any clients connected to the Shadowsocks server will be routed through the VPN. It's not a perfect solution, but it meets my needs.

Thanks again for the help @ZebMcKayhan @eibgrad!
 
Thanks for the input, everyone! While I'm not an expert in networking, your explanations made a lot of sense. After thinking it over, I came up with a workaround that seems to do the trick. For anyone else facing a similar issue, here's what I'm planning to do:

  1. Run a Gluetun container on Docker: This is a lightweight VPN client that also includes a built-in Shadowsocks server.
  2. Connect the Gluetun container to a VPN of my choice: I'll set up the Shadowsocks server within the container on a specific port.
  3. Forward the port from WAN to the Raspberry Pi: This will allow the Shadowsocks server inside the Gluetun container to accept incoming connections from the WAN.
With this setup, the Raspberry Pi's default gateway will remain the WAN, but any clients connected to the Shadowsocks server will be routed through the VPN. It's not a perfect solution, but it meets my needs.

Thanks again for the help @ZebMcKayhan @eibgrad!
Great! Yes, this is probably a better way if you can get it to work.

If you end up going back for some reason, this is what I was thinking could be done on the router:
Code:
#mark new packets incoming on wan:
WAN_IF=$(ip route | awk '/^default/{print $NF}')
iptables -t mangle -I PREROUTING -i "$WAN_IF" -m state --state new -j CONNMARK --set-mark 0x8000/0x8000

#restore connmark to fwmark:
iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark

#make rp_filter use fwmark:
echo 1 > /proc/sys/net/ipv4/conf/eth0/src_valid_mark

#add rule for marked packets to main table:
ip rule add from 0/0 fwmark 0x8000/0x8000 table main prio 110
ip route flush cache
My intention is that your rpi would use the VPN normally via vpn Director. But for new connections from wan these will recieve a mark which, via conntrack will be added to all packets relating to this connection, even reply packets. The marked packets will be set to use wan. This way connections initiate from wan will continue to be on wan and connection initiate from rpi will be on vpn.
I didn't test it so I have no idea if it works but I'm leaving it here for someone to test and Hopefully report back if it's working or not.
for the rules to be persistent they should be put in nat-start script:
https://github.com/RMerl/asuswrt-merlin.ng/wiki/User-scripts#nat-start
 
Last edited:
Another possibility here is to simply define static routes that bind the public IP of the Shadowsocks clients to the WAN. Granted, that assumes those public IPs will be known ahead of time (perhaps NOT likely). But if it happens to be the case (e.g., you always access from your workplace), it's by far the simplest solution.

Come to think of it, I wrote a script several years ago that uses DDNS in reverse. You define a DDNS domain name that the client keeps updated w/ its own public IP as it roams. The script then monitors that DDNS domain-name for changes and keeps that public IP bound to the WAN on the router.


Granted, I wrote it specifically for DD-WRT, but it should work, in principle, for any router.

So there are numerous ways to approach the problem. What will work best just depends on your particular circumstances.
 

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top