This is a post from future me to past me, or at least to an intrepid Googler. I am working with an Xfinity gateway with “Advanced Security” enabled (via the Xfinity app) and a Raspberry Pi running UFW (Uncomplicated Firewall).
If UPnP is disabled on the router (via Advanced > Device Discover), Port Forwarding becomes required. But forwarding Plex’s default port 32400 from the router to the server (via the Xfinity app) will quickly surface “IP reputation” attacks against the server (which are really just port scans from questionable sources). To solve this problem, Plex merely needs to operate its public service on another port.
Although Plex allows you to manually specify a PUBLIC_PORT for the service (Plex Settings > Settings > Remote Access > Show Advanced > Manually Specify Public Port), it still relies on TCP port 32400 on the local network. But the simple Xfinity app does not allow you to do port mapping from one external port to a different internal one, meaning that even if you tell Plex to listen on PUBLIC_PORT, the server itself will only ever listen on 32400. Think of the “Manually specify public port” setting as telling the external Plex service where to find your server. It does NOT make the server itself start listening on that port because Plex server will ONLY listen on 32400.
Since TCP port 32400 will likely generate alerts with Advanced Security then, change it to any other available TCP port “in the 20,000 to 50,000 range” (source) and hope your new port is less popular. So pick a random number in that range (your new PUBLIC_PORT) and begin by forwarding it in the Xfinity app (Connect > [Network Name] > Advanced Settings > Port Forwarding) to the device on your Network hosting your Plex server (use a different port for each device if you have multiple servers). Then use the Plex web interface to “Manually specify public port” to the PUBLIC_PORT you just forwarded.
At this stage it is useful to employ a port checking tool, which right now should show connections to your server’s public IP address at the PUBLIC_PORT as closed. What you need to do on the server is somehow redirect the traffic it receives on PUBLIC_PORT to its listening local port 32400.
The easiest way to test that the instructions ahead will work is by creating a temporary SSH port tunnel which sounds more daunting than it is. On the server, merely run the following command in a terminal window, replacing PUBLIC_PORT with the port you selected and username@hostname with the same username/hostname you use to connect to SSH, and press Enter:
ssh -g -L PUBLIC_PORT:localhost:32400 -N username@hostname
(For parameter reference, -g allows connection from remote ports; -L specifies a local port; -N suppresses second Shell instance.)
You’ll be prompted for the SSH password, which will temporarily open a secure tunnel until you cancel the command. While open, an external port checker should now validate the port is open. After successful testing, press Ctrl+C in the terminal window to stop the process and close the tunnel.
If everything is working so far, you have a couple of options for what to do from here. SSH port tunneling as described above can be automated via autossh to survive reboots, or done with socat or netcat, systemd or iptables, but because I am already running ufw in my setup as a firewall, the easiest thing for me to “set and forget” is to route the traffic automatically alongside it which is so easy as to be anticlimactic.
Assuming Plex’s ports are already added in UFW (PUBLIC_PORT does NOT need to be allowed since it will be redirected to 32400), run the following command:
sudo nano /etc/ufw/before.rules
Then add the following lines to the top of the file (or at least above the *filter section):
*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport PUBLIC_PORT -j REDIRECT --to-port 32400
COMMIT
Make sure and set the PUBLIC_PORT in the code above! Press Ctrl+X to exit the editor (and Y to save your changes followed by Enter Enter). Finally, restart the firewall with:
sudo ufw reload
Now my local server can communicate with the Plex service and allow remote access persistently!
I am sure there are many easier ways I don’t know about to address this same issue, but this is what finally worked for me after a long week of problem solving. If it is not blatantly obvious, I know very little of what I am doing here and am unable to answer any questions so I will not be monitoring this thread after posting it. I just wanted to put it out there in case someone else could glean some value from my findings.
Thanks for reading!