Skip to content

Instantly share code, notes, and snippets.

@ShipkaChalk
Last active April 24, 2024 22:10
Show Gist options
  • Star 26 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save ShipkaChalk/629fdc42dad781776d2007fc502188f3 to your computer and use it in GitHub Desktop.
Save ShipkaChalk/629fdc42dad781776d2007fc502188f3 to your computer and use it in GitHub Desktop.
Plex Hetzner workaround using Docker.

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.

  1. Get yourself a VPS
  2. Install docker
  3. 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
  1. Bring the docker container up once.
  2. Stop the container
  3. Update the main config wg0.conf so that under [Interface] but before [Peer] you include:
  4. 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]

  1. 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.
  2. Visit /root/wireguard/config and find the .conf file for the plexServer peer.
  3. Copy that information down.
  4. Bring the container back up with docker cmpose up
  5. You're done for the VPS!

On the hetzner server

  1. Install docker
  2. Create a directory to hold the goods, in the below I created /home/shipka/PlexWireguard
  3. 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
  1. Create the docker-compose.yml
  2. 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.

Trouble Shooting

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.

@SecondaryH
Copy link

Facing the same exact errors as the guy above

@sovajri7
Copy link

sovajri7 commented Nov 3, 2023

Ok, now VPN is working, I cleaned the IONOS VPS and then installed Wireguard Server using this script :
https://github.com/angristan/wireguard-install

$ curl -O https://raw.githubusercontent.com/angristan/wireguard-install/master/wireguard-install.sh
$ chmod +x wireguard-install.sh
$ ./wireguard-install.sh
Welcome to the WireGuard installer!
The git repository is available at: https://github.com/angristan/wireguard-install

I need to ask you a few questions before starting the setup.
You can keep the default options and just press enter if you are ok with them.

IPv4 or IPv6 public address: IONOS_IP
Public interface: ens6
WireGuard interface name: wg0
Server WireGuard IPv4: 10.13.13.1 #MODIFY DEFAULT TO THIS
Server WireGuard IPv6: fd42:42:42::1
Server WireGuard port [1-65535]: 51820
First DNS resolver to use for the clients: 1.1.1.1
Second DNS resolver to use for the clients (optional): 1.0.0.1

The client name must consist of alphanumeric character(s). It may also include underscores or dashes and can't exceed 15 chars.
Client name: PlexNew
Client WireGuard IPv4: 10.13.13.2
Client WireGuard IPv6: fd42:42:42::2

Open the PlexNew.conf created by the automatic Wireguard installer and then on the Hetzner modify the client.conf (here I renamed mine wg0.conf) so wg0.conf on Hetzner looks like this, juste paste the PRIVKEY, PUBKEY, PREKEY from PlexNew.conf to the wg0.conf on Hetzner :

[Interface]
Address = 10.13.13.2
PrivateKey = PRIVKEY #MODIFY
ListenPort = 51820
DNS = 1.1.1.1,1.0.0.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 = PUBKEY #MODIFY
PresharedKey = PREKEY #MODIFY
Endpoint = IONOS_IP:51820 #MODIFY
AllowedIPs = 0.0.0.0/0

I didn't touched the Wireguard Server conf but now I'm at the same point as the tutorial above, ping are ok, but I'm now stuck here :
image

When I go to IONOS_IP:32400 : I get IONOS_IP does not allow the connexion

Hetzner :
docker exec -it plex /bin/bash
curl localhost:32400 : HTML OK but I get 401 Unauthorized
curl icanhazip.com : IONOS_IP
curl 8.8.8.8 : fail but I thik it's normal as it don't work IONOS too
docker exec -it wireguard /bin/bash
curl localhost:32400 : HTML OK but I get 401 Unauthorized
curl icanhazip.com : IONOS_IP
curl 8.8.8.8 : fail but I thik it's normal as it don't work IONOS too

IONOS VPS :
IDK how to test on it as it do not create container

root@ubuntu:~# wg show
interface: wg0
  public key: KEY
  private key: (hidden)
  listening port: 51820

peer: KEY
  preshared key: (hidden)
  endpoint: HETZNER_IP:51820
  allowed ips: 10.13.13.2/32, fd42:42:42::2/128
  latest handshake: 11 seconds ago
  transfer: 8.29 MiB received, 157.60 MiB sent

curl localhost:32400 : curl: (7) Failed to connect to localhost port 32400 after 0 ms: Connection refused

Just to be sure, my ufw status : inactive on both

@ShipkaChalk
Copy link
Author

So it looks like you've got to plex? That screenshot is from the IONOS:32400?

@sovajri7
Copy link

sovajri7 commented Nov 3, 2023

So it looks like you've got to plex? That screenshot is from the IONOS:32400?

no, if I go to IONOS:32400 : IONOS_IP does not allow the connexion

the screenshot was from this command (I created a tunnel) : ssh root@HETZNER_IP -L 8888:localhost:32400

@SecondaryH
Copy link

When I try to run the docker compose up, it shows that port 32400 is used by my plexmedia server

ERROR: for a28edff848c9_wireguard Cannot start service wireguard: driver failed programming external connectivity on endpoint wireguard (15e3aeea3f62afbde25c12bc57baa61e531b76982e43e89302a6b737279465c0): Error starting userland proxy: listen tcp4 0.0.0.0:32400: bind: address already in use ERROR: for wireguard Cannot start service wireguard: driver failed programming external connectivity on endpoint wireguard (15e3aeea3f62afbde25c12bc57baa61e531b76982e43e89302a6b737279465c0): Error starting userland proxy: listen tcp4 0.0.0.0:32400: bind: address already in use ERROR: Encountered errors while bringing up the project

Seems like my plex media server is using that port according to:
sudo netstat -peanut | grep ":32400" tcp6 0 0 :::32400 :::* LISTEN 998 297594579 226669/Plex Media S

Can I just use fill in another port on the docker-compose file (hetzner server)

Also another question, how do I actually view my downloaded movies etc? Do I need to manually add all the libraries again? And if so how do I actually make the content pop up because whenever I add a folder and scan it for media files it stays empty.

Thankyou

@sovajri7
Copy link

sovajri7 commented Nov 3, 2023

Ok just added that I forgot to add due to trouble shooting tries :

PostUp = iptables -t nat -A PREROUTING -p tcp --dport 32400 -j DNAT --to-destination 10.13.13.2 # IP Of peer 
PostDown = iptables -t nat -A PREROUTING -p tcp --dport 32400 -j DNAT --to-destination 10.13.13.2 # IP Of peer 

On the wg0.conf on IONOS and now Plex is OK !

Just to resume, I've followed the tutorial above for the client but for the server I've used this : https://github.com/angristan/wireguard-install
wg0.conf of this tutorial is located here : /etc/wireguard/wg0.conf

@sovajri7
Copy link

sovajri7 commented Nov 3, 2023

When I try to run the docker compose up, it shows that port 32400 is used by my plexmedia server

ERROR: for a28edff848c9_wireguard Cannot start service wireguard: driver failed programming external connectivity on endpoint wireguard (15e3aeea3f62afbde25c12bc57baa61e531b76982e43e89302a6b737279465c0): Error starting userland proxy: listen tcp4 0.0.0.0:32400: bind: address already in use ERROR: for wireguard Cannot start service wireguard: driver failed programming external connectivity on endpoint wireguard (15e3aeea3f62afbde25c12bc57baa61e531b76982e43e89302a6b737279465c0): Error starting userland proxy: listen tcp4 0.0.0.0:32400: bind: address already in use ERROR: Encountered errors while bringing up the project

Seems like my plex media server is using that port according to: sudo netstat -peanut | grep ":32400" tcp6 0 0 :::32400 :::* LISTEN 998 297594579 226669/Plex Media S

Can I just use fill in another port on the docker-compose file (hetzner server)

Also another question, how do I actually view my downloaded movies etc? Do I need to manually add all the libraries again? And if so how do I actually make the content pop up because whenever I add a folder and scan it for media files it stays empty.

Thankyou

You're missing something on the tutorial so because wireguard and plex have to be launched together using docker-compose.

When creating a new plex server yes you need to add libraries again, if nothing pop :
Check if when you add the folder to PMS, he can see the files if yes, just let him cook
If not, check folder permissions
Check if you added correctly the folder to docker-compose too.

@SecondaryH
Copy link

You're missing something on the tutorial so because wireguard and plex have to be launched together using docker-compose.

When I changed all the "32400" fields to "31400" I did get it working and plex launched. But I couldn't get it to recognize videos even though the correct folders were selected with correct permissions

@sovajri7
Copy link

sovajri7 commented Nov 3, 2023

You're missing something on the tutorial so because wireguard and plex have to be launched together using docker-compose.

When I changed all the "32400" fields to "31400" I did get it working and plex launched. But I couldn't get it to recognize videos even though the correct folders were selected with correct permissions

This a Plex problem now, go on their support forum.

@SecondaryH
Copy link

I started everything from scratch again but I still can't get it working on port 32400. I've tried killing the process running on that port but that just disables PMS all together.

Error response from daemon: driver failed programming external connectivity on endpoint wireguard (4daf05049ae5dbef5eb76a3ff145c8f4659ce452e95fafe52d06ae422e5e0cd3): Error starting userland proxy: listen tcp4 0.0.0.0:32400: bind: address already in use

This is the error I keep getting

@SecondaryH
Copy link

I started everything from scratch again but I still can't get it working on port 32400. I've tried killing the process running on that port but that just disables PMS all together.

Error response from daemon: driver failed programming external connectivity on endpoint wireguard (4daf05049ae5dbef5eb76a3ff145c8f4659ce452e95fafe52d06ae422e5e0cd3): Error starting userland proxy: listen tcp4 0.0.0.0:32400: bind: address already in use

This is the error I keep getting

I managed to fix this. I was using swizzin before so plexmediaserver kept running in the background and using the 32400 port.

For future readers you can fix this error by;
sudo service plexmediaserver stop

@ShipkaChalk
Copy link
Author

If you're using swizzin you should use their box commands to control it. I believe turning off the service will also work, but if can also just do sudo box uninstall plex. Then it's removed properly based on how you installed it.

@refreshcodee
Copy link

set PEERDNS=auto, it didn't work for me without it.

@Dokw0N
Copy link

Dokw0N commented Nov 17, 2023

Thank you for offering your help. I followed your instructions, but Im not yet able to connect to plex. Going through the troubleshooting, Im running into problems starting at 1.

1.a I am getting xml data instead of html

<?xml version="1.0" encoding="UTF-8"?>
<MediaContainer size="24" allowCameraUpload="0" allowChannelAccess="1" allowMediaDeletion="1" allowSharing="1" allowSync="0" allowTuners="0" backgroundProcessing="1" companionProxy="1" countryCode="" diagnostics="logs,databases,streaminglogs" eventStream="1" friendlyName="66633dcda674" hubSearch="1" itemClusters="1" livetv="7" machineIdentifier="a7d10623cf088b7eaebbc422c8e95afc8f9c59ed" mediaProviders="1" multiuser="1" musicAnalysis="2" myPlex="1" myPlexMappingState="unknown" myPlexSigninState="none" myPlexSubscription="0" platform="Linux" platformVersion="5.15.0-86-generic" pluginHost="1" pushNotifications="0" readOnlyLibraries="0" streamingBrainVersion="2" sync="1" transcoderActiveVideoSessions="0" transcoderAudio="1" transcoderLyrics="1" transcoderPhoto="1" transcoderSubtitles="1" transcoderVideo="1" transcoderVideoBitrates="64,96,208,320,720,1500,2000,3000,4000,8000,10000,12000,20000" transcoderVideoQualities="0,1,2,3,4,5,6,7,8,9,10,11,12" transcoderVideoResolutions="128,128,160,240,320,480,768,720,720,1080,1080,1080,1080" updatedAt="1700222866" updater="1" version="1.32.7.7621-871adbd44" voiceSearch="1">
<Directory count="1" key="actions" title="actions" />
<Directory count="1" key="activities" title="activities" />
<Directory count="1" key="butler" title="butler" />
<Directory count="1" key="channels" title="channels" />
<Directory count="1" key="clients" title="clients" />
<Directory count="1" key="devices" title="devices" />
<Directory count="1" key="diagnostics" title="diagnostics" />
<Directory count="1" key="hubs" title="hubs" />
<Directory count="3" key="library" title="library" />
<Directory count="3" key="livetv" title="livetv" />
<Directory count="3" key="media" title="media" />
<Directory count="3" key="metadata" title="metadata" />
<Directory count="1" key="neighborhood" title="neighborhood" />
<Directory count="1" key="playQueues" title="playQueues" />
<Directory count="1" key="playlists" title="playlists" />
<Directory count="1" key="resources" title="resources" />
<Directory count="1" key="search" title="search" />
<Directory count="1" key="server" title="server" />
<Directory count="1" key="servers" title="servers" />
<Directory count="1" key="statistics" title="statistics" />
<Directory count="1" key="system" title="system" />
<Directory count="1" key="transcode" title="transcode" />
<Directory count="1" key="updater" title="updater" />
<Directory count="1" key="user" title="user" />
</MediaContainer>

1.b
curl: (6) Could not resolve host: icanhazip.com

1.c
curl 8.8.8.8 returns nothing. Prompt does not return unless I ctrl-c

@sovajri7
Copy link

Thank you for offering your help. I followed your instructions, but Im not yet able to connect to plex. Going through the troubleshooting, Im running into problems starting at 1.

1.a I am getting xml data instead of html

<?xml version="1.0" encoding="UTF-8"?>
<MediaContainer size="24" allowCameraUpload="0" allowChannelAccess="1" allowMediaDeletion="1" allowSharing="1" allowSync="0" allowTuners="0" backgroundProcessing="1" companionProxy="1" countryCode="" diagnostics="logs,databases,streaminglogs" eventStream="1" friendlyName="66633dcda674" hubSearch="1" itemClusters="1" livetv="7" machineIdentifier="a7d10623cf088b7eaebbc422c8e95afc8f9c59ed" mediaProviders="1" multiuser="1" musicAnalysis="2" myPlex="1" myPlexMappingState="unknown" myPlexSigninState="none" myPlexSubscription="0" platform="Linux" platformVersion="5.15.0-86-generic" pluginHost="1" pushNotifications="0" readOnlyLibraries="0" streamingBrainVersion="2" sync="1" transcoderActiveVideoSessions="0" transcoderAudio="1" transcoderLyrics="1" transcoderPhoto="1" transcoderSubtitles="1" transcoderVideo="1" transcoderVideoBitrates="64,96,208,320,720,1500,2000,3000,4000,8000,10000,12000,20000" transcoderVideoQualities="0,1,2,3,4,5,6,7,8,9,10,11,12" transcoderVideoResolutions="128,128,160,240,320,480,768,720,720,1080,1080,1080,1080" updatedAt="1700222866" updater="1" version="1.32.7.7621-871adbd44" voiceSearch="1">
<Directory count="1" key="actions" title="actions" />
<Directory count="1" key="activities" title="activities" />
<Directory count="1" key="butler" title="butler" />
<Directory count="1" key="channels" title="channels" />
<Directory count="1" key="clients" title="clients" />
<Directory count="1" key="devices" title="devices" />
<Directory count="1" key="diagnostics" title="diagnostics" />
<Directory count="1" key="hubs" title="hubs" />
<Directory count="3" key="library" title="library" />
<Directory count="3" key="livetv" title="livetv" />
<Directory count="3" key="media" title="media" />
<Directory count="3" key="metadata" title="metadata" />
<Directory count="1" key="neighborhood" title="neighborhood" />
<Directory count="1" key="playQueues" title="playQueues" />
<Directory count="1" key="playlists" title="playlists" />
<Directory count="1" key="resources" title="resources" />
<Directory count="1" key="search" title="search" />
<Directory count="1" key="server" title="server" />
<Directory count="1" key="servers" title="servers" />
<Directory count="1" key="statistics" title="statistics" />
<Directory count="1" key="system" title="system" />
<Directory count="1" key="transcode" title="transcode" />
<Directory count="1" key="updater" title="updater" />
<Directory count="1" key="user" title="user" />
</MediaContainer>

1.b curl: (6) Could not resolve host: icanhazip.com

1.c curl 8.8.8.8 returns nothing. Prompt does not return unless I ctrl-c

Hi, I've written a gist update of this because I was unable to get this working using wireguard container on server machine, you should take a look and lmk if still not working : https://gist.github.com/sovajri7/856f75833f3d8764c5dc36e19ff5d0aa

@Dokw0N
Copy link

Dokw0N commented Nov 18, 2023

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:

net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 0

@Dokw0N
Copy link

Dokw0N commented Nov 19, 2023

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.

Just to make sure, are we talking about the public, or the internal IP address @ShipkaChalk?

@parnexcodes
Copy link

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.

Just to make sure, are we talking about the public, or the internal IP address @ShipkaChalk?

It's the IP address in your peer config.
Try connecting with your peer config on your windows/mac wireguard client.

Your ports are probably blocked. Send all the configs here.

@Dokw0N
Copy link

Dokw0N commented Nov 19, 2023

Thanks @parnexcodes
Here are my configs:

VPS (Server)
compose

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=HETZNER_IP # 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:
      - /home/user/repos/plexwireguard/config:/config
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    restart: unless-stopped

wg0

[Interface]
Address = 10.13.13.1
ListenPort = 51820
PrivateKey = ServerPrivateKey

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]
# peer_plexServer
PublicKey = HetznerPublicKey
PresharedKey = PresharedKey
AllowedIPs = 10.13.13.2/32

Hetzner (Client)
compose

services:
  wireguard:
    image: lscr.io/linuxserver/wireguard
    container_name: wireguard
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Berlin
    volumes:
      - /home/user/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=Europe/Berlin
      - VERSION=docker
      - PLEX_CLAIM= #lasts 4 minutes get from plex.tv/claim
    volumes:
      - /home/user/plexwireguard/plex/config:/config
      - /mnt/gmedia:/gmedia
    network_mode: service:wireguard
    restart: unless-stopped

wg0

[Interface]
Address = 10.13.13.2
PrivateKey = HetznerPrivateKey
ListenPort = 51820
DNS = 8.8.8.8

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 = ServerPublicKey
PresharedKey = PresharedKey
Endpoint = VPS_SERVER_IP:51820
AllowedIPs = 0.0.0.0/0

I basically cannot reach the internet from within the containers. Neither icanhazip nor 8.8.8.8 can successfully be curled.

@ShipkaChalk
Copy link
Author

If you can't reach the internet from within the Wireguard container on the VPS then you have a problem as this should always get out to the internet. Looks like an issue on step 3 of the troubleshooting.

If you're on a box with other items on, make sure you don't have any firewalls etc breaking it. I'd recommend spinning up a quick box on something like digital ocean and test if you can get it working there.

@Dokw0N
Copy link

Dokw0N commented Nov 19, 2023

No sorry I should have described this better. Wireguard on the VPS can reach the internet from within Docker without an issue.
My problems are on the Hetzner side. As VPS:32400 (from my home computer) leads to a timeout I tend to check the Plex container on Hetzner to curl domains and IPs for troubleshooting.

EDIT: Are we actually talking about pinging or curling 8.8.8.8 (from within VPS wg container)?
The latter just waits for further input it seems, pinging is successful with 0% packets lost.

@ShipkaChalk
Copy link
Author

I don't know enough about DNS's but it's possible that as you're using PEERDNS=9.9.9.9 it won't let you hit 8.8.8.8. Did you try with PEERDNS=auto? If you can ping Icanhazip and you get the IP back then your VPS Should be okay.

What you need to do now is check that the wireguard on your home machine is connected with the VPS. You can do this by going to the VPS and exec'ing into the container, sudo wg show wg0 should then hopefully show your home vps trying to connect, if you see nothing then it looks like it's just not being connected to.

What you can try for debugging if connecting directly to the vps from your home machine using the wire guard client you can either create a new config with PEERS=plexServer,homeMachine or try and use the plex server config.

If your home machine can connect and your ip is changed to the VPS then we can narrow down the issue to the docker containers on your home machine.

@Dokw0N
Copy link

Dokw0N commented Nov 21, 2023

Okay, so I tried to connect to wg from my home computer with windows: as soon as I connect to the network my internet connection is gone.
Apart from that I found out that ionos has a hardware firewall in place that you need to configure via the cloudpanel. I did, however I am still now able to connect to plex via browser at ionos_ip:32400.
Troubleshooting throught your points @ShipkaChalk I am now only left with one problem on the VPS side (3c): if I exec into the wg container on the vps, I cannot curl localhost:32400. Getting a curl: (7) Failed to connect to localhost port 32400 after 0 ms: Couldn't connect to server.
When Im testing, I actually uninstall ufw, and allow all traffic through iptables, flushing any residual rules. So at this point I have no idea why port 32400 is not accessible.

@ShipkaChalk
Copy link
Author

Well if you connected to wg from your home machine and lost internet connection then it means your WG on the VPS is not working.

Please try on another VPS, you can spin up a digital ocean for an hour for pennies.

@dmnchild
Copy link

Can anyone comment on upgrading? I thought it was as simple as stopping and starting the container but that didnt work. I did the docker pull and it seems to have grabbed the latest but doesnt seem to be using it. Looks like there was a 2/24/2024 update im not able to apply.

@ShipkaChalk
Copy link
Author

@dmnchild
run

docker compose pull

docker compose down

docker compose up

It can take a few minutes for plex to come back due to the reconnection with the wireguard.

@dmnchild
Copy link

dmnchild commented Feb 18, 2024

@ShipkaChalk
edit: docker compose -p plex pull worked. seems all good, thanks for setting me in right direction!

@Iliannnn
Copy link

Iliannnn commented Mar 9, 2024

Hey, I have some questions. I've never done something like this.

So, in step three:

  • What should SERVERURL be set to? Should this be set to the VPS IP or the Hetzner server IP?
  • Should INTERNAL_SUBNET=10.13.13.0 be changed to another value because this IP gets copied over in the wg0.conf file, if yes to which IP?

In step four:

  • What IP should come after --to-destination? The VPS IP or the Hetzner IP?
  • The following PostUp and PostDown lines are in the wg0.conf file by default under PrivateKey, should those be replace by the ones mentioned in step four or should those stay there?
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth+ -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth+ -j MASQUERADE

Thank you for the help in advance

@sovajri7
Copy link

sovajri7 commented Mar 9, 2024

@Iliannnn maybe my gist will help you better as I modified it a little bit to be easier for beginners, just copy/paste and fill your informations : https://gist.github.com/sovajri7/856f75833f3d8764c5dc36e19ff5d0aa

@Iliannnn
Copy link

Iliannnn commented Mar 9, 2024

@Iliannnn maybe my gist will help you better as I modified it a little bit to be easier for beginners, just copy/paste and fill your informations : https://gist.github.com/sovajri7/856f75833f3d8764c5dc36e19ff5d0aa

I will check it out, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment