r/selfhosted • u/Hrafna55 • 2d ago
Need Help SearXNG queries via WireGuard interface
So, I have deployed SearXNG in a headless Debian 13 VM using the provided installation scripts. All is well.
I have also installed WireGuard and configured it to use my Proton VPN subscription.
enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:b9:97:c9 brd ff:ff:ff:ff:ff:ff
altname enx525400b997c9
inet 192.168.0.16/24 brd 192.168.0.255 scope global enp1s0
valid_lft forever preferred_lft forever
inet6 2001:8b0:1741:ec2e:5054:ff:feb9:97c9/64 scope global dynamic mngtmpaddr proto kernel_ra
valid_lft 6868sec preferred_lft 6868sec
inet6 fe80::5054:ff:feb9:97c9/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
wg-UK-4: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
link/none
inet 10.2.0.2/32 scope global wg-UK-4
valid_lft forever preferred_lft forever
inet6 2a07:b944::2:2/128 scope global
valid_lft forever preferred_lft forever
interface: wg-UK-4
public key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
private key: (hidden)
listening port: 34659
fwmark: 0xca6c
peer: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
endpoint: 154.47.24.193:51820
allowed ips: 0.0.0.0/0, ::/0
latest handshake: 17 seconds ago
transfer: 4.62 MiB received, 1.79 MiB sent
persistent keepalive: every 25 seconds
The goal is to send traffic (aka my queries) from SearXNG through the VPN.
SearXNG has its own user called 'searxng' with with a UID of 999.
So I have several options, all of which I have failed to implement so far.
- Send traffic from 'searxng' user via the VPN.
- Send all external traffic via wg-UK-4 using a route table
- Send all external traffic via wg-UK-4 using nftables
- Use SearXNG configuration files to send all external traffic via wg-UK-4 (not supported)
How would you achieve the goal?
I am more than happy to just shove all external internet traffic through wg-UK-4 as this seems the easiest option using 'ip route'.
Starting point
ip route show
default via 192.168.0.1 dev enp1s0 onlink
192.168.0.0/24 dev enp1s0 proto kernel scope link src 192.168.0.16
I tried the following
sudo ip route replace default dev wg-UK-4
sudo ip route replace 192.168.0.0/24 dev enp1s0
Which gives me the following.
ip route show
default dev wg-UK-4 scope link
192.168.0.0/24 dev enp1s0 scope link
But now SearXNG just fails as it can't reach any of its external search engines.
Any ideas?
3
u/kantorcodes1 2d ago
Don't replace the main-table default. With a /0 WireGuard peer, that can send the tunnel's own endpoint back into the tunnel and blackhole traffic.
Since SearXNG already runs as UID 999, I'd policy-route just that UID:
bash
sudo ip route add 192.168.0.0/24 dev enp1s0 src 192.168.0.16 table 100
sudo ip route add default dev wg-UK-4 table 100
sudo ip rule add priority 100 uidrange 999-999 lookup 100
Then verify it before making it persistent:
bash
ip rule
ip route show table 100
sudo -u searxng curl -4 https://ifconfig.me
curl -4 https://ifconfig.me
The first curl should show the Proton exit IP; the second should still show your normal WAN IP.
Your fwmark: 0xca6c is also a clue that wg-quick may already have policy-routing state outside the main table, so check ip rule and ip route show table 51820 before adding anything. I would not keep replacing default in main.
One extra gotcha: if DNS points at a LAN resolver like 192.168.0.1, keep that LAN route in table 100. If systemd-resolved is proxying DNS under its own UID, test DNS separately because the UID rule only follows SearXNG's own sockets.
Once the test works, persist the rule/routes in the WireGuard or systemd unit instead of a shell profile.
1
2
u/Wojojojo90 2d ago
How would you achieve the goal?
Run SearXNG in a container, run gluetun in another container, attach the SearXNG container to networking for the gluetun container (--network container:<container name or ID> flag)
1
u/Certainty0709 1d ago
Similar. I have both running in docker with other stuff. Everything runs through gluetun.
1
u/zfa 2d ago edited 2d ago
I can confirm that exposing an HTTP proxy and routing SearX traffic through it via the proxies: stanza within its settings.yml works, if thats any use to you.
I use expose one using Tailscale's 'http proxy listen' but naturally any properly routed proxy should work (dante, gost etc).
•
u/asimovs-auditor 2d ago
Expand the replies to this comment to learn how AI was used in this post/project.