SSL/TLS Content Inspection with Remote Access

Alright everyone, here’s my first how-to guide!

To perform the SSL decryption for Plex, we need to extract the embedded certificate. This certificate expires every year, so the procedure will need to be repeated from time to time.

We will be using a small helper script called “plex2pem” that runs on nodejs and forge. Don’t do this on your production Plex server. In this example, we’re running Plex on Ubuntu 16.04 LTS and the helper script is being run on Ubuntu 18.04 LTS.

Preparation

Download nodejs, npm, and node-forge:

apt install nodejs npm
npm install node-forge

Create a script plex2pem:

#! /usr/bin/env node
var forge = require('node-forge'),
crypto = require('crypto'),
fs = require('fs');
var file = fs.readFileSync(process.argv[2], { encoding: 'base64' });
var hash = crypto.createHash('sha512');
hash.update('plex');
hash.update(process.argv[3])
var pass = hash.digest('hex');
var p12Der = forge.util.decode64(file);
var p12Asn1 = forge.asn1.fromDer(p12Der);
var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, pass);
process.stdout.write(forge.pki.privateKeyToPem(p12.safeContents[1].safeBags[0].key));
process.stdout.write(forge.pki.certificateToPem(p12.safeContents[0].safeBags[0].cert));

Get the Plex certificate and ProcessedMachineIdentifier

The machine certificate is located in Library/Application Support/Plex Media Server/Cache/certificate.p12

The ProcessedMachineIdentifier is one of the values in the Preferences.xml file (Library/Application Support/Plex Media Server/Preferences.xml)

Transfer the certificate to the server on which you will be running the helper script. We use the ProcessedMachineIdentifier value to compute the private key.

Export the certificate

Example with node.js version:

node plex2pem certificate.p12 your_processed_machine_identifier

Spit the output into a .key file and a .crt file using your favourite text editor.

Create a new .pfx file using openssl:

openssl pkcs12 -export -out newcert.p12 -inkey key.key -in cert.crt
Enter Export Password: iloveplex
Verifying - Enter Export Password: iloveplex
3 Likes

WORKING!! (see below screenshot from a Palo firewall, showing the “decrypted” box checked and associated plain text app identified!)
@c.megalodon - so this little script just ignores the password challenge for the key and then extracts it? Impressive!

1 Like

Glad to see I’m not the only one who is using a PAN firewall :slight_smile:

The script actually computes the key with the “ProcessedMachineIdentifier” value, which is unique to each Plex installation. (I didn’t write the script myself… can’t remember where I got it from.)

I’ve been having a few issues with the decryption, so I turned it off temporarily until I can troubleshoot.

My decryption rule basically hits everything on port 32400, and my security rule is allowing the applications plex, ssl, web-browsing, and websocket. I might set up an “any” application security rule on 32400 for testing.

@c.megalodon - I’ll save you some time :-), the application types needed for web, mobile, and game console apps are http-audio, plex, shoutcast, ssl, web-browsing, and websocket. I monitored plain text connections for awhile and was able to compile that list over about six days.

I get ‘decrypt-error’ problems pretty consistently, however it seems to have no effect on the functionality of the user experience. Remote access still shows “Not available outside your network” but the app works fine, plex.tv works fine, etc. If I turn off SSL/TLS inbound decryption, the remote access will ‘green up’ without issue and I get the “Fully accessible outside your network” or whatever the message is. Same ultimate result though - even when decryption is enabled - the user experience works as expected. Users are able to view/stream content remotely, and the PAN successfully decrypts 95% of the traffic.

Thus it would appear the decrypt errors below have no effect on user experience.

1 Like

I put a no-decrypt whitelist on for some known Plex cloud addresses (these are pretty big swaths of the Internet):

fqdn: my.plexapp.com
fqdn: plex.tv
34.192.0.0/10
52.0.0.0/8
54.0.0.0/8
63.32.0.0/14

That made the Remote Access light up in green and got the Plex relay working fine.

1 Like

You might wanna keep an eye on the list of IP’s linked on this page
https://support.plex.tv/articles/200931138-troubleshooting-remote-access/
This will contain an automatically updated list of IPs used for the connection tests.

1 Like

This thread is cooking now!!

With a little configuration - this list can be ingested into the PAN at a specific interval (external dynamic list feature) and used as a automagically updated no-decrypt whitelist!

https://s3-eu-west-1.amazonaws.com/plex-sidekiq-servers-list/sidekiqIPs.txt

AWESOME! And @c.megalodon - nice tip, after configuring the no-decrypt whitelist it greened right up!

1 Like

Much appreciated information in this thread, and thanks to all of you for sharing your steps. I stumbled upon this thread when I had troubles with Plex after enabling PAN’s DNS Security, totally unrelated, though.

I’m trying to get the cert on my PAN too. However, the script gave me an error:

root@temp:~$ node plex2pem certificate.p12 MY_processed_machine_identifier
/root/node_modules/node-forge/lib/pkcs12.js:475
throw new Error(‘PKCS#12 MAC could not be verified. Invalid password?’);
^

Error: PKCS#12 MAC could not be verified. Invalid password?
at Object.p12.pkcs12FromAsn1 (/root/node_modules/node-forge/lib/pkcs12.js:475:13)
at Object. (/root/plex2pem:12:24)
at Module._compile (module.js:652:30)
at Object.Module._extensions…js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:188:16)
at bootstrap_node.js:609:3
root@tem:~$

Do I need to change my MAC on the server to match the MAC on the plexserver? As per instructions above, I ran the script on a different server, not my plexserver.

Any guesses?

In the “MY_processed_machine_identifier”, you aren’t storing the identifier in a file right?

I didn’t have to clone MACs. Ran the script as dictated. All I changed was that I added the -g flag to the node-forge install line so it would install the package globally, instead of in the working directory. But that really doesn’t matter for script functionality.

Maybe special chars? ANSI or VTI encoding and the special chars are wonky?

MY_machine_identifier is just a copy and paste from the xml file, just a long string. :frowning:

Ugh. Wish I could help more. I promise it does work though. Maybe deploy a vanilla debian distro VM with nothing configured and see if that makes a difference?

No worries. That is a good idea though. I just realized that my /boot is full and apt-get purge isn’t working on my plex server. It is a good opportunity to create a new vm, try this and then migrate the library. All files are on a share anyways, so it isn’t a big deal.
Thanks again, I now have a weekend project! :slight_smile:

Even when I run it on the actual server, I get an error (different error though):

root@temp:~$ sudo node plex2pem certificate.p12 b9999a99-a9aa-9999-aaa9-9999999a99a9
internal/modules/cjs/loader.js:638
    throw err;
    ^

Error: Cannot find module '/home/root/plex2pem'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
    at Function.Module._load (internal/modules/cjs/loader.js:562:25)
    at Function.Module.runMain (internal/modules/cjs/loader.js:829:12)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
root@temp:~$

This topic was automatically closed after 90 days. New replies are no longer allowed.