Encryption
SSL/TLS
Free Certificates
Let's Encrypt is a non-profit certificate authority run by Internet Security Research Group that provides X.509 certificates for Transport Layer Security encryption at no charge. The certificate is valid for 90 days, during which renewal can take place at any time. This uses the Automated Certificate Management Environment (ACME) protocol. ACME Clients:
These days I prefer to let pfSense manage the certificate creation and renewal and use a post-renewal script to push the certificate(s) to the machines that need them.
3rd Party Testing
- SSL Labs SSL Tester
- SSL Labs SSL Tester (Development version)
- DNS CAA Record Generator
- Security Certificate Revocation Awareness Test
- How To Use OpenSSL s_client To Check and Verify SSL/TLS Of HTTPS Webserver
Local Testing
Here's a basic example of how to show the certificate details of an SSL-backed service:
openssl s_client -showcerts -servername example.jeremybryansmith.com -connect example.jeremybryansmith.com:443 </dev/null
And here is an example of the output:
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1 verify return:1 depth=1 C = US, O = Let's Encrypt, CN = R3 verify return:1 depth=0 CN = example.jeremybryansmith.com verify return:1 CONNECTED(00000003) --- Certificate chain DONE 0 s:CN = example.jeremybryansmith.com i:C = US, O = Let's Encrypt, CN = R3 -----BEGIN CERTIFICATE----- MIIGDDCCBPSgAwIBAgISBCenL3NNOHTistAB77mKXCMjMA0GCSqGSIb3DQEBCwUA MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD ... output shortened for brevity R9SUnmSJ8hlfgxxuUIm+cjl7SEovzX/aYUz8yifX2Hm8EcowjrRKRHo6C2AGq6Tt ZH9XDzqzpO90nBoAHo+t0QjGDQLRKnd0OXya0buK/BKIwHyh0/XuOesMu7T2FGlo OB+zRM/YT2fI/5w4TWmV3w== -----END CERTIFICATE----- 1 s:C = US, O = Let's Encrypt, CN = R3 i:C = US, O = Internet Security Research Group, CN = ISRG Root X1 -----BEGIN CERTIFICATE----- MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh ... output shortened for brevity MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX nLRbwHOoq7hHwg== -----END CERTIFICATE----- 2 s:C = US, O = Internet Security Research Group, CN = ISRG Root X1 i:O = Digital Signature Trust Co., CN = DST Root CA X3 -----BEGIN CERTIFICATE----- MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/ MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT ... output shortened for brevity he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5 -----END CERTIFICATE----- --- Server certificate subject=CN = example.jeremybryansmith.com issuer=C = US, O = Let's Encrypt, CN = R3 --- No client certificate CA names sent Peer signing digest: SHA256 Peer signature type: RSA-PSS Server Temp Key: X25519, 253 bits --- SSL handshake has read 5064 bytes and written 394 bytes Verification: OK --- New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384 Server public key is 4096 bit Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated Early data was not sent Verify return code: 0 (ok) ---
You can get full certificate information like so:
openssl s_client -servername example.jeremybryansmith.com -connect example.jeremybryansmith.com:443 </dev/null | openssl x509 -text
And an example of the output would be:
Certificate:
Data: Version: 3 (0x2) Serial Number: 04:27:a7:2f:73:4d:38:74:e2:b2:d0:01:ef:b9:8a:5c:23:23 Signature Algorithm: sha256WithRSAEncryption Issuer: C = US, O = Let's Encrypt, CN = R3 Validity Not Before: Nov 20 07:16:47 2023 GMT Not After : Feb 18 07:16:46 2024 GMT Subject: CN = example.jeremybryansmith.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (4096 bit) Modulus: 00:aa:ef:32:b2:de:68:dc:56:a9:4d:be:d3:c7:4b: ... output shortened for brevity 6e:87:ad Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Key Usage: critical Digital Signature, Key Encipherment X509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client Authentication X509v3 Basic Constraints: critical CA:FALSE X509v3 Subject Key Identifier: 35:84:FC:D7:72:C0:EB:2E:29:9C:95:85:F3:66:F2:24:78:E6:9F:D5 X509v3 Authority Key Identifier: keyid:14:2E:B3:17:B7:58:56:CB:AE:50:09:40:E6:1F:AF:9D:8B:14:C2:C6 Authority Information Access: OCSP - URI:http://r3.o.lencr.org CA Issuers - URI:http://r3.i.lencr.org/ X509v3 Subject Alternative Name: DNS:example.jeremybryansmith.com X509v3 Certificate Policies: Policy: 2.23.140.1.2.1 CT Precertificate SCTs: Signed Certificate Timestamp: Version : v1 (0x0) Log ID : 3B:53:77:75:3E:2D:B9:80:4E:8B:30:5B:06:FE:40:3B: 67:D8:4F:C3:F4:C7:BD:00:0D:2D:72:6F:E1:FA:D4:17 Timestamp : Nov 20 08:16:47.879 2023 GMT Extensions: none Signature : ecdsa-with-SHA256 30:44:02:20:26:F9:DC:CC:08:08:87:41:A3:B0:19:3E: 34:43:A8:D7:62:70:73:81:E1:22:66:90:D0:3F:45:9D: D0:6E:01:56:02:20:20:3A:79:3E:8A:DA:30:00:09:F9: BA:7C:84:41:B6:A6:26:1A:1A:6D:89:0F:AE:42:D0:C2: 2F:02:89:AA:1B:7D Signed Certificate Timestamp: Version : v1 (0x0) Log ID : EE:CD:D0:64:D5:DB:1A:CE:C5:5C:B7:9D:B4:CD:13:A2: 32:87:46:7C:BC:EC:DE:C3:51:48:59:46:71:1F:B5:9B Timestamp : Nov 20 08:16:47.923 2023 GMT Extensions: none Signature : ecdsa-with-SHA256 30:46:02:21:00:E2:27:68:62:CA:46:BF:02:4D:96:16: 0A:84:CA:A6:06:01:99:A3:00:7E:8D:8A:62:FB:A4:90: 12:77:7C:33:52:02:21:00:89:EB:6B:75:D8:8B:A5:A3: 35:52:50:A7:06:DE:C8:33:EF:C3:A4:FF:57:35:5D:D0: 3F:F4:2E:24:4B:45:D4:7A TLS Feature: status_request Signature Algorithm: sha256WithRSAEncryption 21:1a:80:e0:70:8d:da:3a:28:15:50:7e:4c:d1:7d:3c:3b:7e: ... output shortened for brevity 4d:69:95:df -----BEGIN CERTIFICATE----- MIIGDDCCBPSgAwIBAgISBCenL3NNOHTistAB77mKXCMjMA0GCSqGSIb3DQEBCwUA MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD ... output shortened for brevity ZH9XDzqzpO90nBoAHo+t0QjGDQLRKnd0OXya0buK/BKIwHyh0/XuOesMu7T2FGlo OB+zRM/YT2fI/5w4TWmV3w== -----END CERTIFICATE-----
Server Name Indication (SNI)
SNI allows you to determine where to route traffic based on host name
Allows you to use a single TCP port to provide access to multiple services, depending on the hostname the client is trying to connect to. In addition, each service can have its own unique SSL certificate. This is the most useful way to avoid requirement of a dedicated IP address for each DNS name on a web server.
Test with:
Working example:
root@jeremybryansmith:~# echo "" | openssl s_client -servername opencontrolcenter.com -connect opencontrolcenter.com:443 | grep 'CN =' depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 verify error:num=20:unable to get local issuer certificate 0 s:CN = opencontrolcenter.com i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 i:O = Digital Signature Trust Co., CN = DST Root CA X3 subject=CN = opencontrolcenter.com issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
Non-working example:
root@jeremybryansmith:~# echo "" | openssl s_client -servername gitlab.jeremybryansmith.com -connect gitlab.jeremybryansmith.com:443 2>/dev/null | grep 'CN =' 0 s:CN = apttechnologysystems.com i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 i:O = Digital Signature Trust Co., CN = DST Root CA X3 subject=CN = apttechnologysystems.com issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
Key Management
SSH Key Management
Key Creation
As of March 2020, the most secure key type is ed25519.
FYI: ed25519 keys are always 256-bit.
USER="jeremy" DOMAIN="jbsnet.xyz" KEY_TYPE="ed25519" KEY_FILENAME="${USER}+${KEY_TYPE}@${DOMAIN}" KEY_COMMENT="$KEY_FILENAME" ssh-keygen -t "${KEY_TYPE}" -C "${KEY_COMMENT}" -f "${KEY_FILENAME}"
Which results in the following files being created:
jeremy+ed25519@jbsnet.xyz jeremy+ed25519@jbsnet.xyz.pub
Older clients may not support ed25519, but fuck them. Get with the program, guys.
Key File Password Change
ssh-keygen -p -f existing_key_filename
Secure Configuration
Using crypto is only the first step. You need to ensure that the tools you use are locked down to enforce only the protocols that are not known to be weak.
SSH
Server Config
Ciphers
As of 2015-12-04, the best Ciphers setting in /etc/ssh/sshd_config is:
Ciphers aes192-ctr,aes256-ctr,arcfour256,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,arcfour
MACs
As of 2015-12-04, the best MACs setting in /etc/ssh/sshd_config is:
- Disable anything using MD5
- Disable anything using less than 128 bits
- Disable anything not using -etm mode
Use the following config file:
MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-64-etm@openssh.com,umac-128-etm@openssh.com
Alternatively, in newer versions of OpenSSH, you can now disable specific algorithms like so:
# Disable known weak key exchange algorithms KexAlgorithms -diffie-hellman-group1-sha1 # Disable known weak HMAC algorithms MACs -hmac-sha1,hmac-sha1-etm@openssh.com
SSL/TLS Key Management
Key Creation
If you need a SSL/TLS cert that is signed by a root authority for public use in a web browser or other SSL/TLS client, use Let’s Encrypt to get free SSL certificates.
Let’s Encrypt is a new Certificate Authority: It’s free, automated, and open. In Public Beta 2015-12-03.
Adding Password
If for some crazy reason you end up with a key file that is not password protected ( OpenVPN client export feature of pfSense -- I'm looking at you! ), it's best to assume that key has been compromised and revoke it.
If you are certain that you want to keep that key ( e.g. it has only been written to volatile memory and can be securely erased ), you can add a password to it like so:
Assuming your key file is key.private.clear.pem and you will be creating a new key file key.private.passworded.pem:
openssl rsa -aes256 -in key.private.clear.pem -out key.private.passworded.pem
The above command will interactively prompt you for the new key file password. I suggest you use a good random password generated from something like:
apg -m 48 -x 48 -a 1 -n 1
You can then shred the old cleartext key file ( this is only secure on a very limited types of filesystems like tmpfs ):
shred -u key.private.clear.pem
You should still make sure you keep your key file permissions minimal:
chmod 600 key.private.passworded.pem
Converting
Before you can convert anything, you'll need to know what the various formats are.
- pem
- der
- text
From pem to text
openssl x509 -in your-cert.pem -noout -text
From pem to der
openssl x509 -outform der -in your-cert.pem -out your-cert.crt
Secure SSL/TLS Ciphers
Unless you want to support obsolete, weak, vulnerable encryption, you'll want to limit your encryption settings to the most recent versions. These days, that is TLS 1.3.
See https://www.owasp.org/index.php/TLS_Cipher_String_Cheat_Sheet
Stunnel
Stunnel is an open-source multi-platform application used to provide a universal TLS/SSL tunneling service. Stunnel can be used to provide secure encrypted connections for clients or servers that do not speak TLS or SSL natively.
Stunnel is a handy utility that allows you to add SSL/TLS support to any TCP application that otherwise does not support it. It basically wraps whatever TCP protocol with SSL/TLS. This is great for adding security to services that do not support SSL/TLS or only support obsolete versions. This is especially useful on old hardware whose firmware is no longer updated. Here are a few example configurations:
[ Old router that only supports HTTP ]<---HTTP--->[ stunnel ]<----HTTPS---->[ Your web browser ]
[ Old router that only supports HTTPS with SSL 1.0 ]<---HTTPS w/SSL 1.0--->[ stunnel ]< ----HTTPS w/TLS 1.3---- >[ Your web browser ]
[ TCP HTTP/WHATEVER server with TLS ]<----TLS wrapped HTTP/WHATEVER---->[ stunnel ]<---HTTP/WHATEVER--->[ HTTP/WHATEVER client that does not support TLS ]
It's normal use is on the server side, but can also be used on the client side to strip SSL and provide access to whatever TCP protocol for clients that do not support SSL/TLS. As of 2018-07-02, using TLS 1.3 with stunnel, this is the most secure configuration (TLS 1.2 and 1.3 only): Need to test this:
sslVersion TLSv1.3
Old:
verify = 2 sslVersion = all options = NO_SSLv3 options = NO_TLSv1 options = NO_TLSv1.1 options = NO_TLSv1.2 options = CIPHER_SERVER_PREFERENCE options = DONT_INSERT_EMPTY_FRAGMENTS ciphers = TLS13-AES-256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384
HAProxy
HAProxy is free, open source software that provides a high availability load balancer and proxy server for TCP and HTTP-based applications that spreads requests across multiple servers. It is written in C and has a reputation for being fast and efficient. Mostly known/used as reverse-proxy and/or load-balancer, HAProxy makes stunnel obsolete.
See:
I use HAProxy to implement SNI so that I can have a single listening service on port 443 that redirects to the appropriate service depending on what DNS name is used.
For example:
[ web browser accessing www.domain.com:443 ]----->(port 443)[ ]------>[ Nginx on port 6080 ] [ web browser accessing xyz.domain.com:443 ]----->(port 443)[ ]------>[ apache on port 7080 ] [ email client accessing imap.domain.com:993 ]----->(port 993)[ HAProxy TLS ]------>[ sendmail on port 143 ] [ telnet client accessing telnet.domain.com:3021 ]----->(port 3021)[ ]------>[ telnet on port 21 ] [ NNTP client accessing nntps.domain.com:563 ]----->(port 563)[ ]------>[ Leafnode on port 119 ] [ XMPP client accessing xmpp.domain.com:5223 ]----->(port 5222)[ ]------>[ Leafnode on port 5222 ]
As of 2020-04-08, using TLS 1.3 with HAProxy, this is the most secure configuration (TLS 1.3 only):
ssl-default-bind-ciphers TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:TLS13-CHACHA20-POLY1305-SHA256:EECDH+AESGCM:EECDH+CHACHA20 ssl-default-bind-options force-tlsv13
Apache HTTP Web Server
he Apache HTTP Server, colloquially called Apache, is a free and open-source cross-platform web server software, released under the terms of Apache License 2.0. Apache is developed and maintained by an open community of developers under the auspices of the Apache Software Foundation.
As of 2020-04-08, using TLS 1.3 with apache, this is the most secure configuration (TLS 1.3 only).
See:
- https://httpd.apache.org/docs/2.4/ssl/ssl_howto.html
- https://httpd.apache.org/docs/2.4/ssl/ssl_faq.html
SSLEngine On SSLHonorCipherOrder On SSLProtocol -ALL +TLSv1.3 SSLCipherSuite TLSv1.3 TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256 SSLOpenSSLConfCmd Curves X25519:secp521r1:secp384r1:prime256v1 # Enable Strict Transport Security (HSTS) Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains;" # Enable OCSP Stapling (See https://cwiki.apache.org/confluence/display/HTTPD/OCSPStapling) SSLUseStapling on SSLStaplingCache shmcb:logs/ssl_stapling(32768)
SNI
https://cwiki.apache.org/confluence/display/HTTPD/NameBasedSSLVHostsWithSNI
Nginx
Nginx is a web server which can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache. The software was created by Igor Sysoev and first publicly released in 2004. A company of the same name was founded in 2011 to provide support and Nginx plus paid software. >br>
As of 2020-04-08, using TLS 1.3 with Nginx, this is the most secure configuration (TLS 1.3 only):
ssl_protocols TLSv1.3; ... ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256'
libsodium
libsodium is an open-source, high-speed software library for network communication, encryption, decryption, signatures, etc