{"id":1922,"date":"2017-05-13T18:18:10","date_gmt":"2017-05-13T16:18:10","guid":{"rendered":"https:\/\/www.npcglib.org\/~stathis\/blog\/?p=1922"},"modified":"2020-11-20T00:49:33","modified_gmt":"2020-11-19T22:49:33","slug":"plex-media-server-over-https-with-letsencrypt-certificates","status":"publish","type":"post","link":"https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/","title":{"rendered":"Plex Media Server over HTTPS with Letsencrypt Certificates"},"content":{"rendered":"<p>This is a guide useful for anyone using Plex Media Server on Gentoo and seeking to encrypt\/secure their connections with TLS for the Plex Web UI. The instructions can be easily adapted to other distros and should work with minor modifications. I have written these notes using <code>media-tv\/plex-media-server-1.5.5<\/code> and <code>app-crypt\/certbot-apache-0.13.0<\/code>.<br \/>\nYou&#8217;ll need root in order to perform most of these steps. <\/p>\n<h3>Installing Plex Media Server and Letsencrypt client<\/h3>\n<p>Installing Plex Media Server on Gentoo is straight forward:<\/p>\n<pre>\r\nemerge -Dtva media-tv\/plex-media-server\r\n<\/pre>\n<p>The post-installation instructions of the package will tell you:<\/p>\n<pre style=\"font-size:85%\">\r\nPlex Media Server is now installed. Please check the configuration file in \/etc\/plex\/plexmediaserver to verify the default settings.\r\nTo start the Plex Server, run 'rc-config start plex-media-server', you will then be able to access your library at http:\/\/<ip>:32400\/web\/\r\n<\/pre>\n<p>This may be good enough if you&#8217;re just having a home server to watch from the LAN, but if you will be accessing your Plex Media Server from a non-secure network (i.e. over the Internet or via your mobile data provider, etc.), clearly this is not the most secure setup. The instructions tell you to use a plaintext http connection (<code><span style=\"color:red\">http:\/\/<\/span>&lt;ip&gt;:32400\/web\/<\/code>), but with just like any other plaintext connection, your Plex username and password can be sniffed trivially.<\/p>\n<p>To make the connection secure you can obtain and install a free TLS certificate from <a href=\"https:\/\/letsencrypt.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">Let&#8217;s Encrypt<\/a>. If you already know how to obtain and install a Letsencrypt certificate, skip these instructions. On Gentoo you can use the certbot command-line tool, so go ahead and install its package:<\/p>\n<pre>\r\nemerge -Dtva app-crypt\/certbot\r\n<\/pre>\n<p>You may end up with emerge complaining that a series of required dependencies cannot be installed. Make sure you keyword all those packages in <code>\/etc\/portage\/package.keywords<\/code>. For example, may have to append in your <code>package.keywords<\/code>:<\/p>\n<pre>\r\n=app-crypt\/certbot-apache-0.13.0 ~amd64\r\n<\/pre>\n<h3>Obtaining and installing a Let&#8217;s Encrypt certificate for Plex<\/h3>\n<p>Once certbot is installed and provided your server&#8217;s hostname is <code>home-plex.mydomain.com<\/code>, obtain the respective Letsencrypt free certificate:<\/p>\n<pre>\r\ncertbot certonly --standalone --config-dir \/etc\/letsencrypt --preferred-challenges tls-sni-01 -d home-plex.mydomain.com\r\n<\/pre>\n<p>If everything has worked out correctly, your certificate will be installed in <code>\/etc\/letsencrypt\/live\/home-plex.mydomain.com\/<\/code>.<\/p>\n<h3>Converting a Let&#8217;s Encrypt cert for use with Plex Media Server (format PKCS #12)<\/h3>\n<p>Assuming you have OpenSSL already installed (if not <code>emerge -Dtva dev-libs\/openssl<\/code>), you can create a PKCS #12 file containing the Let&#8217;s Encrypt certificate and private key to enable TLS support for home-plex.mydomain.com, using the following script (store in \/etc\/plex\/plex-renew-cert.sh, we&#8217;ll need the script again later):<\/p>\n<pre>\r\n#!\/bin\/bash\r\n#\r\n# store this script in \/etc\/plex\/plex-renew-cert.sh\r\n#\r\n\r\nPLEX_HOSTNAME=<span style=\"color:blue\">home-plex.mydomain.com<\/span>\r\nPLEX_CERT_ENCKEY=<span style=\"color:red\">your-randomly-generated-password<\/span>\r\n\r\npushd \/etc\/plex > \/dev\/null\r\nopenssl pkcs12 -export \\\r\n               -out \/etc\/plex\/${PLEX_HOSTNAME}.pfx \\\r\n               -inkey \/etc\/letsencrypt\/live\/${PLEX_HOSTNAME}\/privkey.pem \\\r\n               -in \/etc\/letsencrypt\/live\/${PLEX_HOSTNAME}\/cert.pem \\\r\n               -certfile \/etc\/letsencrypt\/live\/${PLEX_HOSTNAME}\/chain.pem \\\r\n               -name \"${PLEX_HOSTNAME}\" \\\r\n               -passout pass:${PLEX_CERT_ENCKEY}\r\npopd\r\n\r\n# Set the right ownership and permissions to the generated PKCS #12 container file:\r\nchmod 600 \/etc\/plex\/${PLEX_HOSTNAME}.pfx\r\nchown plex:plex \/etc\/plex\/${PLEX_HOSTNAME}.pfx\r\n\r\n\r\n<\/pre>\n<p>Make sure you replace <span style=\"color:blue\">home-plex.mydomain.com<\/span> with your server&#8217;s hostname and <code><span style=\"color:red\">your-randomly-generated-password<\/span><\/code> with a good password. You can quickly generate one <a href=\"http:\/\/www.sethcardoza.com\/api\/rest\/tools\/random_password_generator\/complexity:alphaNumeric\/length:20\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>, but any will work. <\/p>\n<p>Set good permissions and execute it:<\/p>\n<pre>\r\nchmod 700 \/etc\/plex\/plex-renew-cert.sh\r\n\/etc\/plex\/plex-renew-cert.sh\r\n<\/pre>\n<p>Check the cert container has been generated:<\/p>\n<pre>\r\nls -l \/etc\/plex\/home-plex.mydomain.com.pfx\r\n<\/pre>\n<p>You can even verify the key, using the PLEX_CERT_ENCKEY value when prompted, and if everything is correct you&#8217;ll see something like:<\/p>\n<pre>\r\nopenssl pkcs12 -in \/etc\/plex\/home-plex.mydomain.com.pfx -noout\r\nEnter Import Password:\r\n<span style=\"color:green\">MAC verified OK<\/span>\r\n<\/pre>\n<h3>Using the Letsencrypt PKCS #12 cert with Plex Media Server<\/h3>\n<p>To use the generated certificate in Plex, first start the Plex server (<code>\/etc\/init.d\/plex-media-server start<\/code>) and visit the plaintext web interface <code>http:\/\/home-plex.mydomain.com:32400\/web<\/code>. Login with your Plex.tv account, go to <code>\"Settings > Network\"<\/code>, fill in the following and &#8220;Save Changes&#8221;:<\/p>\n<pre>\r\n        Custom certificate location: \/etc\/plex\/home-plex.mydomain.com.pfx\r\n  Custom certificate encryption key: <span style=\"color:red\">your-randomly-generated-password<\/span>\r\n          Custom certificate domain: home-plex.mydomain.com\r\n<\/pre>\n<div id=\"attachment_1930\" style=\"width: 804px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-1930\" loading=\"lazy\" src=\"\/wp-content\/uploads\/2017\/05\/screenshot.2.png\" alt=\"\" width=\"794\" height=\"325\" class=\"size-full wp-image-1930\" srcset=\"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-content\/uploads\/2017\/05\/screenshot.2.png 794w, https:\/\/www.npcglib.org\/~stathis\/blog\/wp-content\/uploads\/2017\/05\/screenshot.2-300x123.png 300w, https:\/\/www.npcglib.org\/~stathis\/blog\/wp-content\/uploads\/2017\/05\/screenshot.2-768x314.png 768w\" sizes=\"(max-width: 794px) 100vw, 794px\" \/><p id=\"caption-attachment-1930\" class=\"wp-caption-text\">Plex Media Server Letsencrypt Certificate Config<\/p><\/div>\n<p>Restart the Plex Media Server and visit the web interface over encrypted HTTPS now, <code><span style=\"color:green\">https:\/\/<\/span>home-plex.mydomain.com:32400\/web\/<\/code>. You should see in your web browser&#8217;s address bar the green lock indicating a secure connection to the Plex Media Server.<\/p>\n<p>Your done! &#8230;. Well, almost done!<\/p>\n<h3>Renewing the Let&#8217;s Encrypt certificates<\/h3>\n<p>Let&#8217;s Encrypt certificates expire after a few months and the proper way to utilize them with any server\/application is to schedule a frequent renewal check. On top of that, we want to ensure that once our certificate has been renewed, it is also converted to the PKCS #12 container format and the Plex Media Server is restarted to reload the new PKCS #12 certificate.<\/p>\n<p>This is fairly easy, with certbot&#8217;s option <code>--renew-hook<\/code> (check what it does with <code>certbot --help renew<\/code>) and a cronjob like the following:<\/p>\n<pre>\r\n#Mins  Hours  Days   Months  Day of the week\r\n# Attempt a renewal once a day at 5:30am and if successful run --renew-hook command(s)\r\n30 5 * * * certbot certonly --standalone --quiet \\\r\n                                         --config-dir \/etc\/letsencrypt \\\r\n                                         --preferred-challenges tls-sni-01 \\\r\n                                         -d home-plex.mydomain.com \\\r\n                                         --renew-hook \"\/etc\/plex\/plex-renew-cert.sh && \/etc\/init.d\/plex-media-server start\"\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This is a guide useful for anyone using Plex Media Server on Gentoo and seeking to encrypt\/secure their connections with TLS for the Plex Web UI. The instructions can be easily adapted to other distros and should work with minor modifications. I have written these notes using media-tv\/plex-media-server-1.5.5 and app-crypt\/certbot-apache-0.13.0. You&#8217;ll need root in order [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[48,5],"tags":[85,6,84,83,69,82],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v17.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"stathis\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/#website\",\"url\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/\",\"name\":\"sigmoid\",\"description\":\"..oo..oo..oo..oo..oo..oo..\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"\/wp-content\/uploads\/2017\/05\/screenshot.2.png\",\"contentUrl\":\"\/wp-content\/uploads\/2017\/05\/screenshot.2.png\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/#webpage\",\"url\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/\",\"name\":\"Plex Media Server over HTTPS with Letsencrypt Certificates - sigmoid\",\"isPartOf\":{\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/#primaryimage\"},\"datePublished\":\"2017-05-13T16:18:10+00:00\",\"dateModified\":\"2020-11-19T22:49:33+00:00\",\"author\":{\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/#\/schema\/person\/508363c4ebd1fd6066edf00c94e37e41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Plex Media Server over HTTPS with Letsencrypt Certificates\"}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/#\/schema\/person\/508363c4ebd1fd6066edf00c94e37e41\",\"name\":\"stathis\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"http:\/\/2.gravatar.com\/avatar\/214f29f604ec7d8d2f1345c5fa617c09?s=96&d=mm&r=g\",\"contentUrl\":\"http:\/\/2.gravatar.com\/avatar\/214f29f604ec7d8d2f1345c5fa617c09?s=96&d=mm&r=g\",\"caption\":\"stathis\"},\"url\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/author\/stathis\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/","twitter_misc":{"Written by":"stathis","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebSite","@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/#website","url":"https:\/\/www.npcglib.org\/~stathis\/blog\/","name":"sigmoid","description":"..oo..oo..oo..oo..oo..oo..","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.npcglib.org\/~stathis\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"ImageObject","@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/#primaryimage","inLanguage":"en-US","url":"\/wp-content\/uploads\/2017\/05\/screenshot.2.png","contentUrl":"\/wp-content\/uploads\/2017\/05\/screenshot.2.png"},{"@type":"WebPage","@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/#webpage","url":"https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/","name":"Plex Media Server over HTTPS with Letsencrypt Certificates - sigmoid","isPartOf":{"@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/#primaryimage"},"datePublished":"2017-05-13T16:18:10+00:00","dateModified":"2020-11-19T22:49:33+00:00","author":{"@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/#\/schema\/person\/508363c4ebd1fd6066edf00c94e37e41"},"breadcrumb":{"@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/2017\/05\/13\/plex-media-server-over-https-with-letsencrypt-certificates\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.npcglib.org\/~stathis\/blog\/"},{"@type":"ListItem","position":2,"name":"Plex Media Server over HTTPS with Letsencrypt Certificates"}]},{"@type":"Person","@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/#\/schema\/person\/508363c4ebd1fd6066edf00c94e37e41","name":"stathis","image":{"@type":"ImageObject","@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/#personlogo","inLanguage":"en-US","url":"http:\/\/2.gravatar.com\/avatar\/214f29f604ec7d8d2f1345c5fa617c09?s=96&d=mm&r=g","contentUrl":"http:\/\/2.gravatar.com\/avatar\/214f29f604ec7d8d2f1345c5fa617c09?s=96&d=mm&r=g","caption":"stathis"},"url":"https:\/\/www.npcglib.org\/~stathis\/blog\/author\/stathis\/"}]}},"_links":{"self":[{"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/posts\/1922"}],"collection":[{"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/comments?post=1922"}],"version-history":[{"count":31,"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/posts\/1922\/revisions"}],"predecessor-version":[{"id":2017,"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/posts\/1922\/revisions\/2017"}],"wp:attachment":[{"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/media?parent=1922"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/categories?post=1922"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/tags?post=1922"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}