MastaG 4 Posted July 29, 2024 Posted July 29, 2024 (edited) I'm running the official Emby docker beta image version 4.9.0.28. I have issued a ZeroSSL certificate with 2048bit RSA key. This should provide better compatibility compared to Elliptic Curve (ECC) keys. However when I enforce secure connections, Android /w GoogleTV and certain Android TV television sets refuse to connect. Other Emby clients, such as LG WebOS and the Android client on my Samsung Galaxy phone work fine though. I've created my PFX certificate with OpenSSL: $ openssl pkcs12 -export -inkey "${HOME}/.acme.sh/mycert/mycert.key" -in "${HOME}/.acme.sh/mycert/fullchain.cer" -out "/docker/emby_data/cert.pfx" -password pass:mypassword Here's the testssl report: $ testssl https://xx:8920 ########################################################### testssl 3.2rc3 from https://testssl.sh/dev/ This program is free software. Distribution and modification under GPLv2 permitted. USAGE w/o ANY WARRANTY. USE IT AT YOUR OWN RISK! Please file bugs @ https://testssl.sh/bugs/ ########################################################### Using "OpenSSL 3.2.1 30 Jan 2024 (Library: OpenSSL 3.2.1 30 Jan 2024)" [~94 ciphers] on razerblade15:/usr/bin/openssl (built: "Feb 9 00:00:00 2024", platform: "linux-x86_64") Start 2024-07-29 11:34:26 -->> yy:8920 (xx) <<-- rDNS (yy): zz Service detected: HTTP Testing protocols via sockets except NPN+ALPN SSLv2 not offered (OK) SSLv3 not offered (OK) TLS 1 not offered TLS 1.1 not offered TLS 1.2 offered (OK) TLS 1.3 offered (OK): final NPN/SPDY not offered ALPN/HTTP2 h2, http/1.1 (offered) Testing cipher categories NULL ciphers (no encryption) not offered (OK) Anonymous NULL Ciphers (no authentication) not offered (OK) Export ciphers (w/o ADH+NULL) not offered (OK) LOW: 64 Bit + DES, RC[2,4], MD5 (w/o export) not offered (OK) Triple DES Ciphers / IDEA not offered Obsoleted CBC ciphers (AES, ARIA etc.) offered Strong encryption (AEAD ciphers) with no FS not offered Forward Secrecy strong encryption (AEAD ciphers) offered (OK) Testing server's cipher preferences Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits Cipher Suite Name (IANA/RFC) ----------------------------------------------------------------------------------------------------------------------------- SSLv2 - SSLv3 - TLSv1 - TLSv1.1 - TLSv1.2 (server order) xc030 ECDHE-RSA-AES256-GCM-SHA384 ECDH 253 AESGCM 256 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 xc02f ECDHE-RSA-AES128-GCM-SHA256 ECDH 253 AESGCM 128 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 xc028 ECDHE-RSA-AES256-SHA384 ECDH 253 AES 256 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 xc027 ECDHE-RSA-AES128-SHA256 ECDH 253 AES 128 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 TLSv1.3 (server order) x1302 TLS_AES_256_GCM_SHA384 ECDH 253 AESGCM 256 TLS_AES_256_GCM_SHA384 x1303 TLS_CHACHA20_POLY1305_SHA256 ECDH 253 ChaCha20 256 TLS_CHACHA20_POLY1305_SHA256 x1301 TLS_AES_128_GCM_SHA256 ECDH 253 AESGCM 128 TLS_AES_128_GCM_SHA256 Has server cipher order? yes (OK) -- TLS 1.3 and below Testing robust forward secrecy (FS) -- omitting Null Authentication/Encryption, 3DES, RC4 FS is offered (OK) TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-SHA384 TLS_AES_128_GCM_SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 Elliptic curves offered: prime256v1 secp384r1 secp521r1 X25519 X448 Finite field group: ffdhe2048 ffdhe3072 ffdhe4096 ffdhe6144 ffdhe8192 TLS 1.2 sig_algs offered: RSA-PSS-RSAE+SHA256 RSA-PSS-RSAE+SHA384 RSA-PSS-RSAE+SHA512 RSA+SHA256 RSA+SHA384 RSA+SHA512 RSA+SHA224 TLS 1.3 sig_algs offered: RSA-PSS-RSAE+SHA256 RSA-PSS-RSAE+SHA384 RSA-PSS-RSAE+SHA512 Testing server defaults (Server Hello) TLS extensions (standard) "renegotiation info/#65281" "EC point formats/#11" "session ticket/#35" "status request/#5" "supported versions/#43" "key share/#51" "max fragment length/#1" "application layer protocol negotiation/#16" "encrypt-then-mac/#22" "extended master secret/#23" Session Ticket RFC 5077 hint 7200 seconds, session tickets keys seems to be rotated < daily SSL Session ID support yes Session Resumption Tickets: yes, ID: yes TLS clock skew Random values, no fingerprinting possible Certificate Compression none Client Authentication none Signature Algorithm SHA384 with RSA Server key size RSA 2048 bits (exponent is 65537) Server key usage Digital Signature, Key Encipherment Server extended key usage TLS Web Server Authentication, TLS Web Client Authentication Serial B58642E12F232AB5FF4984A58F4746EF (OK: length 16) Fingerprints SHA1 021D163300156605D0673C8CC258D4034B17F91D SHA256 B74D0EB06A2D25CE22EF53F5D2E4CCA1B3EE0460D77D36F3A10C3C2B946C039D Common Name (CN) xx subjectAltName (SAN) xx Trust (hostname) Ok via SAN and CN (same w/o SNI) Chain of trust Ok EV cert (experimental) no Certificate Validity (UTC) 78 >= 60 days (2024-07-17 00:00 --> 2024-10-15 23:59) ETS/"eTLS", visibility info not present Certificate Revocation List -- OCSP URI http://zerossl.ocsp.sectigo.com OCSP stapling offered, not revoked OCSP must staple extension -- DNS CAA RR (experimental) available - please check for match with "Issuer" below: issue=sectigo.com Certificate Transparency yes (certificate extension) Certificates provided 2 Issuer ZeroSSL RSA Domain Secure Site CA (ZeroSSL from AT) Intermediate cert validity #1: ok > 40 days (2030-01-29 23:59). ZeroSSL RSA Domain Secure Site CA <-- USERTrust RSA Certification Authority Intermediate Bad OCSP (exp.) Ok Testing HTTP header response @ "/" HTTP Status Code 302 Found, redirecting to "web/index.html" HTTP clock skew -1 sec from localtime Strict Transport Security not offered Public Key Pinning -- Server banner (no "Server" line in header, interesting!) Application banner -- Cookie(s) (none issued at "/") -- maybe better try target URL of 30x Security headers -- Reverse Proxy banner -- Testing vulnerabilities Heartbleed (CVE-2014-0160) not vulnerable (OK), no heartbeat extension CCS (CVE-2014-0224) not vulnerable (OK) Ticketbleed (CVE-2016-9244), experiment. not vulnerable (OK) ROBOT Server does not support any cipher suites that use RSA key transport Secure Renegotiation (RFC 5746) supported (OK) Secure Client-Initiated Renegotiation not vulnerable (OK) CRIME, TLS (CVE-2012-4929) not vulnerable (OK) BREACH (CVE-2013-3587) no gzip/deflate/compress/br HTTP compression (OK) - only supplied "/" tested POODLE, SSL (CVE-2014-3566) not vulnerable (OK), no SSLv3 support TLS_FALLBACK_SCSV (RFC 7507) No fallback possible (OK), no protocol below TLS 1.2 offered SWEET32 (CVE-2016-2183, CVE-2016-6329) not vulnerable (OK) FREAK (CVE-2015-0204) not vulnerable (OK) DROWN (CVE-2016-0800, CVE-2016-0703) not vulnerable on this host and port (OK) make sure you don't use this certificate elsewhere with SSLv2 enabled services, see https://search.censys.io/search?resource=hosts&virtual_hosts=INCLUDE&q=B74D0EB06A2D25CE22EF53F5D2E4CCA1B3EE0460D77D36F3A10C3C2B946C039D LOGJAM (CVE-2015-4000), experimental not vulnerable (OK): no DH EXPORT ciphers, no DH key detected with <= TLS 1.2 BEAST (CVE-2011-3389) not vulnerable (OK), no SSL3 or TLS1 LUCKY13 (CVE-2013-0169), experimental potentially VULNERABLE, uses cipher block chaining (CBC) ciphers with TLS. Check patches Winshock (CVE-2014-6321), experimental not vulnerable (OK) RC4 (CVE-2013-2566, CVE-2015-2808) no RC4 ciphers detected (OK) Running client simulations (HTTP) via sockets Browser Protocol Cipher Suite Name (OpenSSL) Forward Secrecy ------------------------------------------------------------------------------------------------ Android 6.0 TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 256 bit ECDH (P-256) Android 7.0 (native) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256 bit ECDH (P-256) Android 8.1 (native) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 253 bit ECDH (X25519) Android 9.0 (native) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) Android 10.0 (native) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) Android 11 (native) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) Android 12 (native) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) Chrome 79 (Win 10) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) Chrome 101 (Win 10) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) Firefox 66 (Win 8.1/10) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) Firefox 100 (Win 10) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) IE 6 XP No connection IE 8 Win 7 No connection IE 8 XP No connection IE 11 Win 7 TLSv1.2 ECDHE-RSA-AES256-SHA384 256 bit ECDH (P-256) IE 11 Win 8.1 TLSv1.2 ECDHE-RSA-AES256-SHA384 256 bit ECDH (P-256) IE 11 Win Phone 8.1 TLSv1.2 ECDHE-RSA-AES128-SHA256 256 bit ECDH (P-256) IE 11 Win 10 TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256 bit ECDH (P-256) Edge 15 Win 10 TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 253 bit ECDH (X25519) Edge 101 Win 10 21H2 TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) Safari 12.1 (iOS 12.2) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) Safari 13.0 (macOS 10.14.6) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) Safari 15.4 (macOS 12.3.1) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) Java 7u25 No connection Java 8u161 TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256 bit ECDH (P-256) Java 11.0.2 (OpenJDK) TLSv1.3 TLS_AES_256_GCM_SHA384 256 bit ECDH (P-256) Java 17.0.3 (OpenJDK) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) go 1.17.8 TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) LibreSSL 2.8.3 (Apple) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 253 bit ECDH (X25519) OpenSSL 1.0.2e TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256 bit ECDH (P-256) OpenSSL 1.1.0l (Debian) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 253 bit ECDH (X25519) OpenSSL 1.1.1d (Debian) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) OpenSSL 3.0.3 (git) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) Apple Mail (16.0) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256 bit ECDH (P-256) Thunderbird (91.9) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519) Rating (experimental) Rating specs (not complete) SSL Labs's 'SSL Server Rating Guide' (version 2009q from 2020-01-30) Specification documentation https://github.com/ssllabs/research/wiki/SSL-Server-Rating-Guide Protocol Support (weighted) 100 (30) Key Exchange (weighted) 90 (27) Cipher Strength (weighted) 90 (36) Final Score 93 Overall Grade A Grade cap reasons Grade capped to A. HSTS is not offered Done 2024-07-29 11:35:16 [ 52s] -->> yy:8920 (xx) <<-- And the output of openssl s_client: $ openssl s_client -connect xx:8920 Connecting to yy CONNECTED(00000003) depth=2 C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority verify return:1 depth=1 C=AT, O=ZeroSSL, CN=ZeroSSL RSA Domain Secure Site CA verify return:1 depth=0 CN=xx verify return:1 --- Certificate chain 0 s:CN=xx i:C=AT, O=ZeroSSL, CN=ZeroSSL RSA Domain Secure Site CA a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA384 v:NotBefore: Jul 17 00:00:00 2024 GMT; NotAfter: Oct 15 23:59:59 2024 GMT 1 s:C=AT, O=ZeroSSL, CN=ZeroSSL RSA Domain Secure Site CA i:C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA384 v:NotBefore: Jan 30 00:00:00 2020 GMT; NotAfter: Jan 29 23:59:59 2030 GMT --- Server certificate .. As you can see, it offers the complete chain. I've also tested every web-browser and they all work fine. Except for Android/Google TV. Any ideas? Edited July 29, 2024 by MastaG
Lessaj 467 Posted July 29, 2024 Posted July 29, 2024 (edited) They may not trust the ZeroSSL RSA Domain Secure Site CA or the root USERTrust RSA Certification Authority. You could try to add the CA manually, if there's an option to install a CA from storage, and see if that resolves it, otherwise switch to the ZeroSSL ECC Domain Secure Site CA/USERTrust ECC Certification Authority issued certificates. EDIT: Your chain is missing the root certificate, that could also be what's missing. There should be your cert at 0, intermediate at 1, and root at 2. Edited July 29, 2024 by Lessaj 1
Q-Droid 989 Posted July 29, 2024 Posted July 29, 2024 7 hours ago, MastaG said: I've also tested every web-browser and they all work fine. Except for Android/Google TV. Any ideas? Are you trying to force TLS on LAN? How are you trying to force it?
MastaG 4 Posted July 29, 2024 Author Posted July 29, 2024 (edited) @Q-Droid I'm using the generated PFX certificate in Emby server and there is an option you can set to enforce TLS encryption and not allow unencrypted clients. See my attached picture. I'm not connecting from LAN, only over WAN. Now this seems to be a bug in Emby Server where it doesn't seem to serve out the complete chain. If I use the exact same PFX file in Plex Media Server, I do get the full chain like @Lessajwas mentioning. Plex Media Server: $ openssl s_client -connect XX:32400 Connecting to XX CONNECTED(00000003) depth=2 C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority verify return:1 depth=1 C=AT, O=ZeroSSL, CN=ZeroSSL RSA Domain Secure Site CA verify return:1 depth=0 CN=XX verify return:1 --- Certificate chain 0 s:CN=XX i:C=AT, O=ZeroSSL, CN=ZeroSSL RSA Domain Secure Site CA a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA384 v:NotBefore: Jul 29 00:00:00 2024 GMT; NotAfter: Oct 27 23:59:59 2024 GMT 1 s:C=AT, O=ZeroSSL, CN=ZeroSSL RSA Domain Secure Site CA i:C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA384 v:NotBefore: Jan 30 00:00:00 2020 GMT; NotAfter: Jan 29 23:59:59 2030 GMT 2 s:C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority i:C=GB, ST=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=AAA Certificate Services a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA384 v:NotBefore: Mar 12 00:00:00 2019 GMT; NotAfter: Dec 31 23:59:59 2028 GMT --- Emby: $ openssl s_client -connect XX:8920 Connecting to XX CONNECTED(00000003) depth=2 C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority verify return:1 depth=1 C=AT, O=ZeroSSL, CN=ZeroSSL RSA Domain Secure Site CA verify return:1 depth=0 CN=XX verify return:1 --- Certificate chain 0 s:CN=XX i:C=AT, O=ZeroSSL, CN=ZeroSSL RSA Domain Secure Site CA a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA384 v:NotBefore: Jul 29 00:00:00 2024 GMT; NotAfter: Oct 27 23:59:59 2024 GMT 1 s:C=AT, O=ZeroSSL, CN=ZeroSSL RSA Domain Secure Site CA i:C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA384 v:NotBefore: Jan 30 00:00:00 2020 GMT; NotAfter: Jan 29 23:59:59 2030 GMT --- The ZeroSSL acme.sh client has an option to generate the PFX file with the --to-pkcs12 --password XXX options. And the same thing happens when using the PFX generated by the acme.sh client. Only Plex seems to serve the full chain. So this is definitely a bug in Emby's http server. Edited July 29, 2024 by MastaG
Q-Droid 989 Posted July 29, 2024 Posted July 29, 2024 WAN only then, good. It doesn't have to present the full chain during the handshake and many web servers and proxies don't. The CA root is expected to be in the client trust store and the client uses that to validate the chain as long as intermediate certs aren't missing. Even so it doesn't hurt anything to include the root. Do the same devices and same certs work with plex but not Emby?
MastaG 4 Posted July 29, 2024 Author Posted July 29, 2024 1 minute ago, Q-Droid said: WAN only then, good. It doesn't have to present the full chain during the handshake and many web servers and proxies don't. The CA root is expected to be in the client trust store and the client uses that to validate the chain as long as intermediate certs aren't missing. Even so it doesn't hurt anything to include the root. Do the same devices and same certs work with plex but not Emby? Yes, using Plex on the same Android TV works. And my Plex server is also configured to only allow secure (TLS) connections. So unless the Plex Android TV client ships its own SSL/TLS client and ca-bundle this must be a issue in the Emby Android TV client. Also I can't imagine the TV vendor not shipping the ZeroSSL CA. Its firmware is from a couple of months ago and on many forums they recommend the use of ZeroSSL' RSA CA due to its CA being issued way before LetsEncrypt. For the record, I've also tried it with a new ZeroSSL ECC cert (ec-256) which uses a different chain and I'm getting the same results. It works on the Plex client but not on Emby (Same Android TV device). Tomorrow I'll bind Emby to localhost and try with Nginx as proxy/ssl-offloader instead. Will post back the results. 1
Q-Droid 989 Posted July 30, 2024 Posted July 30, 2024 Does your pfx file really have the full chain in it? How many certs are in "${HOME}/.acme.sh/mycert/fullchain.cer"? I'm asking out of curiosity more than anything. The LE certbot creates a fullchain file with only the server and intermediate certs. The root is nowhere in issuing or renewals and I think the ACME standard does not include the trust anchor (root) in the download/deployment. So I'm wondering if PLEX is adding the root on its own. In reality I don't think this is why your clients are failing to connect because nobody should trust the root cert presented in a TLS handshake. It has to be in the client's keystore and used for the chain validation.
MastaG 4 Posted July 30, 2024 Author Posted July 30, 2024 (edited) 40 minutes ago, Q-Droid said: Does your pfx file really have the full chain in it? How many certs are in "${HOME}/.acme.sh/mycert/fullchain.cer"? I'm asking out of curiosity more than anything. The LE certbot creates a fullchain file with only the server and intermediate certs. The root is nowhere in issuing or renewals and I think the ACME standard does not include the trust anchor (root) in the download/deployment. So I'm wondering if PLEX is adding the root on its own. In reality I don't think this is why your clients are failing to connect because nobody should trust the root cert presented in a TLS handshake. It has to be in the client's keystore and used for the chain validation. Yes, both the fullchain.cer and PFX contain all 3 certificates. Here you can see the output of all certs when I list them from the PFX which is used by Emby. mastag@fedora:~/ssd/container_data/emby_data$ openssl pkcs12 -nokeys -info -in cert.pfx Enter Import Password: MAC: sha256, Iteration 2048 MAC length: 32, salt length: 8 PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256 Certificate bag Bag Attributes localKeyID: 38 F4 69 A0 5D 7D 41 81 77 A5 6B 50 25 2F A3 93 73 99 19 3D subject=CN=XX issuer=C=AT, O=ZeroSSL, CN=ZeroSSL RSA Domain Secure Site CA -----BEGIN CERTIFICATE----- XX -----END CERTIFICATE----- Certificate bag Bag Attributes: <No Attributes> subject=C=AT, O=ZeroSSL, CN=ZeroSSL RSA Domain Secure Site CA issuer=C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority -----BEGIN CERTIFICATE----- XX -----END CERTIFICATE----- Certificate bag Bag Attributes: <No Attributes> subject=C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority issuer=C=GB, ST=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=AAA Certificate Services -----BEGIN CERTIFICATE----- XX -----END CERTIFICATE----- PKCS7 Data Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256 Like I said before, when using the same PFX certificate with Plex Media Server, it will serve the complete chain. Also the Plex client does work on the same Android TV (with force tls enabled in the server). It's only Emby's http server which does not. Edited July 30, 2024 by MastaG
Q-Droid 989 Posted July 30, 2024 Posted July 30, 2024 I just remembered something - Emby (via .Net) keeps a cert store and it has caused problems in the past. I wouldn't call it a cache though it seems to behave like one. I have no idea how it works or why it stores certs. Check under your /config/.dotnet/corefx/cryptography/x509stores/ca to see if there are any files. If there are any stop Emby, delete the files and start it.
MastaG 4 Posted July 31, 2024 Author Posted July 31, 2024 16 hours ago, Q-Droid said: I just remembered something - Emby (via .Net) keeps a cert store and it has caused problems in the past. I wouldn't call it a cache though it seems to behave like one. I have no idea how it works or why it stores certs. Check under your /config/.dotnet/corefx/cryptography/x509stores/ca to see if there are any files. If there are any stop Emby, delete the files and start it. Thank you for the suggestion, but the /config directory inside the docker container doesn't have any of these directories. I just need to find the time to setup nginx as proxy forwarder / ssl offloader. I'll make sure to use the exact same fullchain.cer. Then I'll post back my findings. 1
MastaG 4 Posted August 3, 2024 Author Posted August 3, 2024 So I found the time to setup NGINX for proxy forwarding and ENFORCING TLS by always redirecting. map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 8096; # Force TLS if ($scheme = "http") { return 301 https://$host:8920$request_uri; } listen 8920 ssl http2; # listen [::]:443 ssl http2; server_name xx; access_log /var/log/nginx/emby.access.log; error_log /var/log/nginx/emby.error.log; # Use Mozilla's guidelines for SSL/TLS settings # https://mozilla.github.io/server-side-tls/ssl-config-generator/ # NOTE: some settings below might be redundant ssl_certificate /etc/nginx/acme_cert/fullchain.cer; ssl_certificate_key /etc/nginx/acme_cert/xx.key; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; # intermediate configuration. tweak to your needs. ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305; ssl_prefer_server_ciphers on; ssl_dhparam /etc/pki/tls/certs/dhparam.pem; # Add headers to serve security related headers # Before enabling Strict-Transport-Security headers please read into this # topic first. add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always; # # WARNING: Only add the preload option once you read about # the consequences in https://hstspreload.org/. This option # will add the domain to a hardcoded list that is shipped # in all major browsers and getting removed from this list # could take several months. location / { proxy_pass http://127.0.0.1:8097$request_uri; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Forwarded-Scheme $scheme; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Accept-Encoding ""; proxy_set_header Host $host; client_body_buffer_size 512k; proxy_read_timeout 86400s; client_max_body_size 0; proxy_connect_timeout 86400s; proxy_send_timeout 86400s; # Websocket proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } } I've changed the Emby server to listen on port 8097 and I'm using the exact same fullchain.cer and key. And guess what? It works like a charm on all platforms, including Android (TV). This means that Emby's builtin http server is DEFINITELY bugged. It broke somewhere not long ago, but I don't feel like trying out every previous release to figure out which one broke it. So to sum things up: - The fullchain.cer generated by ZeroSSL acme.sh client contains all 3 certificates (full chain). - I've created a PFX using the official acme client: $ ./acme.sh --home /home/mastag/.acme.sh --domain xx --to-pkcs12 --password 'yy' But also manually: $ openssl pkcs12 -export -inkey "${HOME}/.acme.sh/mycert/mycert.key" -in "${HOME}/.acme.sh/mycert/fullchain.cer" -out "/docker/emby_data/cert.pfx" -password pass:mypassword In BOTH cases, I can verify that the generated PFX contains all 3 certifcates (full chain) using: openssl pkcs12 -nokeys -info -in cert.pfx - When I configure Plex Media Server to use the PFX and enforce TLS, it will work on all platforms. OpenSSL's s_client will show that Plex Media Server is serving out the full chain, all 3 certificates. - When I configure Emby Media Server to use the PFX and enforce TLS, it will not work on Android devices. My Android smartphone will prompt me to trust/accept the ZeroSSL certificate when I open the Emby application. Also OpenSSL's s_client will only show 2 out of the 3 certificates as shown in earlier examples. - When I use NGINX as proxy forwarder/ssl offloader as shown in the configuration above, it will work on all platforms, including Android TV/Google TV. In this case OpenSSL's s_client will show the full chain, all 3 certificates which is served by NGINX. This means that Emby's builtin http server is definitely messed up. People shouldn't be setting up their own proxy forwarders. I hope this bug will be fixed asap.
Q-Droid 989 Posted August 3, 2024 Posted August 3, 2024 Bug or not you're better off with a proper LB proxy or web server as reverse proxy. You'll have better control over your security, they have a much larger user base, vulnerabilities are discovered sooner and get fixed much faster. Nginx or any of the other big ones is the way to go. Now that you have it working you might as well keep it. 2
Q-Droid 989 Posted August 3, 2024 Posted August 3, 2024 On 7/30/2024 at 8:16 AM, MastaG said: subject=C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority issuer=C=GB, ST=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=AAA Certificate Services Have you tried Plex and nginx using the self-signed USERTRUST root certificate in your keystore (pfx) instead of the one that is cross-signed by Comodo? I'm curious if your problematic devices would still work without the much older Comodo root in the chain.
Q-Droid 989 Posted August 4, 2024 Posted August 4, 2024 (edited) @Luke, this thread reveals something @MastaG mentioned earlier and I have been able to verify. Whether it's a bug or by design the Emby server appears to be truncating the certificate chain presented during the TLS handshake. Technically a TLS termination point (web, proxy, app, etc.) doesn't need to include a Root CA certificate with the chain. And by choice most don't because it's the client that verifies the certs and validates the chain using its own trust store (CA bundle). But this is at the discretion of the admin who configures the server and leaves the Root CA out of the cert list. The servers will normally present what you give them. Emby on the other hand is cutting off the first CA and not presenting the rest even when they're in the keystore. I don't know if it's statically fixed at depth=1 or if it stops at the first CA (x509 Basic Constraints CA:TRUE). I suspect the OP's problem is some devices don't have the USERTRUST (Sectigo) root in their store but this root also has a cross-signed version which if presented during handshake the client could use either of the Comodo or Microsoft (until 2025) root CAs which have cross-signed them. But Emby is not offering the cross-signed roots when present in the keystore, their depth would be 2 and 3 if allowed. Edited August 4, 2024 by Q-Droid
Luke 42077 Posted August 5, 2024 Posted August 5, 2024 11 hours ago, Q-Droid said: @Luke, this thread reveals something @MastaG mentioned earlier and I have been able to verify. Whether it's a bug or by design the Emby server appears to be truncating the certificate chain presented during the TLS handshake. Technically a TLS termination point (web, proxy, app, etc.) doesn't need to include a Root CA certificate with the chain. And by choice most don't because it's the client that verifies the certs and validates the chain using its own trust store (CA bundle). But this is at the discretion of the admin who configures the server and leaves the Root CA out of the cert list. The servers will normally present what you give them. Emby on the other hand is cutting off the first CA and not presenting the rest even when they're in the keystore. I don't know if it's statically fixed at depth=1 or if it stops at the first CA (x509 Basic Constraints CA:TRUE). I suspect the OP's problem is some devices don't have the USERTRUST (Sectigo) root in their store but this root also has a cross-signed version which if presented during handshake the client could use either of the Comodo or Microsoft (until 2025) root CAs which have cross-signed them. But Emby is not offering the cross-signed roots when present in the keystore, their depth would be 2 and 3 if allowed. Hi, if that's true then that's happening internally within the dotnet runtime. I know I've seen issues in their github repo related to this sort of thing in the past. We'll have to see if there's a way we can configure it preserve the whole chain.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now