Hey, here is how you can route all plex traffic via wireguard out of another VPS, this can be used for any container but was inspired by the recent Hetzner block Plex put in place.
And no not all of us are using it for nefarious means, sometimes people don't have room for a home server.
Why docker? I prefer it as it keeps items separated and cleaned. It also allows for quickly moving configurations around from server to server if need be.
- Get yourself a VPS. ( If your VPS has a built in firewall like IONOS (but don't use Ionos), then you need to allow through the ports specified in the VPS docker compose)
- Install docker ( Do not use snap, follow their offical directions otherwise you may have docker related issues. )
- Create this
docker-compose.yml
version: '3'
services:
wireguard:
image: linuxserver/wireguard
container_name: wireguard
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- SERVERURL=111.111.111.111 # Replace with your server's public domain or IP
- SERVERPORT=51820
- PEERS=plexServer # Replace with peer names, this is chosen by you. Do not use any special characters like _
- PEERDNS=9.9.9.9
- INTERNAL_SUBNET=10.13.13.0
- LOG_CONFS=true
ports:
- "51820:51820/udp"
- "32400:32400"
volumes:
- /root/wireguard/config:/config
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
restart: unless-stopped
- Bring the docker container up once.
- Stop the container
- Update the main config
wg0.conf
so that under [Interface] but before [Peer] you include: - Update the --to-destination X.X.X.X to point to the Ip of the peer below.
[Interface]
Address = ...
etc...
PostUp = iptables -A FORWARD -i %i -j ACCEPT
PostUp = iptables -A FORWARD -o %i -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o eth+ -j MASQUERADE
PostUp = iptables -t nat -A PREROUTING -p tcp --dport 32400 -j DNAT --to-destination 10.13.13.2 # IP Of peer below
PostDown = iptables -D FORWARD -i %i -j ACCEPT
PostDown = iptables -D FORWARD -o %i -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth+ -j MASQUERADE
PostDown = iptables -t nat -A PREROUTING -p tcp --dport 32400 -j DNAT --to-destination 10.13.13.2 # IP Of peer below
[Peer]
- Update the 10.13.13.2 in the above to be the IP of your peer_plexServer. This will forward port traffic from 32400 to that internal peer.
- Visit
/root/wireguard/config
and find the.conf
file for theplexServer
peer. - Copy that information down.
- Bring the container back up with
docker cmpose up
- You're done for the VPS!
On the hetzner server
- Install docker
- Create a directory to hold the goods, in the below I created /home/shipka/PlexWireguard
- Create
/home/shipka/PlexWireguard/wireguard-client/wg_confs/wg0.conf
This file will be what is generated by the VPS you just need to add in the PostUp
, PreDown
, PostUp
and PreDown
[Interface]
Address = 10.13.13.2
PrivateKey =
ListenPort = 51820
DNS = 10.13.13.1
PostUp = iptables -t nat -A POSTROUTING -o wg+ -j MASQUERADE
PreDown = iptables -t nat -D POSTROUTING -o wg+ -j MASQUERADE
PostUp = FORWARDEDPORT=32400; iptables -A INPUT -i wg0 -p udp --dport $FORWARDEDPORT -j ACCEPT; iptables -A INPUT -i wg0 -p tcp --dport $FORWARDEDPORT -j ACCEPT;
PreDown = FORWARDEDPORT=32400; iptables -D INPUT -i wg0 -p udp --dport $FORWARDEDPORT -j ACCEPT; iptables -D INPUT -i wg0 -p tcp --dport $FORWARDEDPORT -j ACCEPT;
[Peer]
PublicKey =
PresharedKey =
Endpoint = END POINT OF VPS:51820
AllowedIPs = 0.0.0.0/0 # You might want to remove the , ::/0 if you have issues using IPv6
IPV6 ISSUES Remove the ", ::/0" in the allowed IPS
- Create the
docker-compose.yml
- Make sure your volumes in plex line up and the volumes for the wireguard line up.
services:
wireguard:
image: lscr.io/linuxserver/wireguard
container_name: wireguard
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
volumes:
- /home/shipka/PlexWireGuard/wireguard-client:/config
- /lib/modules:/lib/modules
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
ports:
- 32400:32400
restart: unless-stopped
plex:
image: linuxserver/plex
container_name: plex
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- VERSION=docker
- PLEX_CLAIM= #lasts 4 minutes get from plex.tv/claim
volumes:
- /home/shipka/PlexWireGuard/config:/config
- /data/tv:/tv
- /data/downloaded:/movies
network_mode: service:wireguard
restart: unless-stopped
And that should be it! Bring it up with docker compose up
and visit VPS:32400 and you’ll see your plex container. Finally make sure to manually specify port 32400
(Or which ever port you used in docker for plex) in the plex remote access settings.
Don't use it, they limit UDP rates so it drastically drops your speed. You can do a quick speed test by running the following:
docker run -it --network container:wireguard gists/speedtest-cli speedtest
Follow the steps below in order, post a comment saying where you get to if it fails. ( Like 2.a )
exec into the containers on Hetzner.
docker exec -it plex /bin/bash
a. Do curl localhost:32400 you should see some html coming back. If it's not plex isn't up. b. Do curl icanhazip.com to make sure it's returning the VPS ip. If it's not then your wireguard tunnel is not connected. c. Do curl 8.8.8.8 this should return active pings. If it does not there is not internet connection at all.
Repeat this for
docker exec -it wireguard /bin/bash
a. Do curl localhost:32400 you should see some html coming back. If it's not then the plex container is not connected to the wireguard container. b. Do curl icanhazip.com to make sure it's returning the VPS ip. If it's not then your wireguard tunnel is not connected. c. Do curl 8.8.8.8 this should return active pings. If it does not there is not internet connection at all.
Then on the VPS
docker exec -it wireguard /bin/bash
a. curl icanhazip.com to make sure that wireguard container is reaching the outside world you should see the VPS ip. b. Do curl 8.8.8.8 this should return active pings. If it does not there is not internet connection at all. c. curl localhost:32400 you should see the plex html. If you don't then you need to make sure you've done the forward ports part on the Hetzner.
On the VPS a. Outside of the docker instance, do wg show look to see if the peer has connected.
b. curl localhost:32400, you should see the plex html. If you don't then you need to forward the ports on the wg0.conf of the VPS.
On your home machine: a. Visit VPS:32400 you should get to plex, if you do not then on the VPS it's self you need to open the ports or make sure ufw etc is not blocking them.
Hey @sovajri7. I just followed your gist update. Its well written and very comprehensive. Unfortunately though Im still not able to get plex running. When I try to reach my VPS at port 32400 the connection times out. Through troubleshooting I can see that a from from within the plex container
curl icanhazip.com
throws:curl: (7) Couldn't connect to server
curling localhost:32400 returns xml data.
EDIT: From looking at the logs when starting wireguard I found an error:
RTNETLINK answers: Permission denied
Searching for it online, some was hinting that adding the following to /etc/sysctl.conf would solve the problem. In my case this did not help either: