Mr. I forgot to open port 443, one shall not forget to open port 443.
@Novasty you know how cockpit auto updates the system. Is there a way to alias it to do so for tumbleweed
sudo zypper up doesn’t update the system when in tumbleweed. Sudo zypper dup does
Mr. I forgot to add a semi-colon for the nth time.
fuck off I havent had my coffee with bourbon creme yet… LMAO
god dammit. I hate those bugs. I get them in C too… ill forget it and be like why is this fucking crashing you stupid piece of $hit… oh… im the stupid piece of $hit
Alright all. I got my SSL down packed. A little mood music:
@SgtAwesomesauce @Novasty paying it forward. Most of the process wasnt bad. There are like two dirty tricks in here. Also a more “optimal” nginix configuration for proxying/load balancing (takes higher connection load and takes more advantage of gzip. I mean whats extra CPU cycles when you can burn up a pi and chuck another in right )
Okay guys assuming your nginx sites-available and enabled (or srv/www site) are done correctly we have a little nginx configuration to do in order to maximize our security with SSL (This will break anything that doesnt support TLSv1.2 and above)
So I grabbed my cert with certbot manually because I am going to be making a fullchain RSA4096 key as the main pem that will be renewed (mostly to retain a fallback if I find my migration to Elliptic Curves breaks stuff). So I went ahead and did the process for that kind of key first.
Certbot Command: (replace your email in)
During the run make sure you copy your acme settings to your DDNS provider!!!
sudo certbot certonly --agree-tos --email <email> --manual --preferred-challenges=dns -d *.utangard.net --server https://acme-v02.api.letsencrypt.org/directory --rsa-key-size 4096
This generated the following in the URL’s live directory
[email protected]:/etc/letsencrypt/live# cd utangard.net/
[email protected]:/etc/letsencrypt/live/utangard.net# ls
cert.pem chain.pem fullchain.pem privkey.pem README
So now I have all the keys I need for falling back to an RSA4096 key exchange cert. Cool.
Now we can move onto creating the ECC Key (which we will use certbot to renew manually ) Lets create that key
Explanation of why to use SECP384R1 (dont use Koblitz or SECP521R1) SOURCE: STACK EXCH
The main culprit is NSA Suite B – or, rather, people who read that document as something that it is not. NSA Suite B says that NSA uses curves P-256 and P-384. Some people have chosen to interpret that as “don’t use any other curve”. P-521 (aka “secp521r1”) is not one of these curves, hence its removal.
There is nothing wrong with P-521, except that it is, in practice, useless. Arguably, P-384 is also useless, because the more efficient P-256 curve already provides security that cannot be broken through accumulation of computing power (see this answer for a discussion on that subject). Yet people and even NSA uses P-384, which goes a long way to show that the choice of what elliptic curve to use in a given cryptographic protocol is not fully a matter of pure rational logic and security assessment. People who are in the position to decide whether a given curve is acceptable or not will make choices based on their perception of how their choices will be perceived by other people who themselves are not necessarily the most logical of thinkers (or not at least perceived to be such).
[email protected]:/etc/letsencrypt/live/utangard.net# openssl ecparam -genkey -name secp384r1 -out ecprivkey.pem
That will generate the key upon which you can verify its proper generation by
[email protected]:/etc/letsencrypt/live/utangard.net# openssl ec -in ecprivkey.pem -noout -text
Output should look like
Obviously Im not just going to hand the key over
Now while remaining in the live directory that letsencrypt uses to keep your keys create the file openssl.conf. We will override settings we wish to override and nothing more
[ req ]
prompt = no
encrypt_key = no
default_md = sha512
distinguished_name = dname
req_extensions = reqext
[ dname ]
CN = utangard.net
emailAddress = <your email>
[ reqext ]
subjectAltName = DNS:utangard.net, DNS:*.utangard.net
Theres no reason why we shouldnt use SHA-512 https://crypto.stackexchange.com/questions/26336/sha512-faster-than-sha256
Optionally you can use what hash you wish as long as its secure.
Now execute:
openssl req -new -config openssl.conf -key ecprivkey.pem -out eccsr.pem
This creates a csr for our elliptic curve. I distinguished this with an ec at the beginning of the name. The certificate signing request is what we will forward to letsencrypt to sign our cert with.
Just for piece of mind one can verify:
Now the magic happens. Let us take advantage of certbot to attach a certificate to utangard (or your URL) via DNS so that we may renew both when we manually run certbot every three months (it can be automated but I have calendar reminders and manual allows me finer control). The command changes slightly as we need to specify the certificate signing request since we generated our own cert for let’s encrypt to sign. (see end of the line)
During the run make sure you copy your acme settings to your DDNS provider!!!
sudo certbot certonly --manual --preferred-challenges=dns -d *.utangard.net --server https://acme-v02.api.letsencrypt.org/directory --csr eccsr.pem
Eh Voila
[email protected]:/etc/letsencrypt/live/utangard.net# ls -a
. .. 0000_cert.pem 0000_chain.pem 0001_chain.pem cert.pem chain.pem eccsr.pem ecprivkey.pem fullchain.pem openssl.conf privkey.pem README
assuming all goes as planned. 0000_cert.pem is your EC cert 000x_chain.pem are your EC Chains. 0001_chain.pem is your EC chain. There is a 0000 fallback RSA2048 chain that is only selected if TLS1.2 finds a client that cannot do EC. Done. If you would like verification
openssl x509 -in 0001_chain.pem -noout -text
Now that we have completed this we need to generate a Diffie-Hellman parameter (I like having my own).
Source for what it does: https://security.stackexchange.com/questions/94390/whats-the-purpose-of-dh-parameters
Dont go to my insane level 4096 is fine. I was doing 16384 for kicks and testing. That said do not go below 2048. It is said in the next decade 2048 may not be safe. Because I created different lengths I specified different names. 4096 took my system 11 minutes. 16384 took all night (LMFAO)
Run this command inside the live directory. (I am in root terminal so you will need to sudo)
(Generator irrelevant)
openssl dhparam -5 -out dhparams4096.pem 4096
Optional crazy maxsize DH-Param lol:
openssl dhparam -5 -out dhparams16384.pem 16384
Now we can configure NGINX to handle all the extra security and harden the reverse proxy front end with Strict Hyper Transport Security (prevent downgrade attacks) etc.
My configuration is as follows (this is for reference as I describe my security settings):
[email protected]:/etc/nginx# cat nginx.conf
## Main Block
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
## Events Block
events {
# High Throughput Settings
worker_connections 65535;
multi_accept on;
use epoll;
}
## HTTP Block
http {
# Override Buffer Limitations
client_body_buffer_size 10K;
client_header_buffer_size 1k;
client_max_body_size 8m;
large_client_header_buffers 2 1k;
# Send the client a "request timed out" if the body is not loaded by this time. Default 60.
client_body_timeout 32;
client_header_timeout 32;
# Every 60 seconds server broadcasts Sync packets, so 90 is a conservative upper bound.
keepalive_timeout 90; # reminder: default 65
send_timeout 120; # reminder: default 60
# Allow the server to close the connection after a client stops responding.
# Reason: Frees up socket-associated memory.
reset_timedout_connection on;
# Open file descriptors. Caches information about open FDs, freqently accessed files.
open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# Setting the certs, keys and diffie-hellman parameters
ssl_certificate /etc/letsencrypt/live/utangard.net/0001_chain.pem;
ssl_certificate_key /etc/letsencrypt/live/utangard.net/ecprivkey.pem;
ssl_dhparam /etc/letsencrypt/live/utangard.net/dhparam.pem;
# Specify Protocols
ssl_protocols TLSv1.2 TLSv1.3;
# Specify Ciphers
ssl_ciphers !AES128:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
# Mandate Server ciphers
ssl_prefer_server_ciphers on;
# Other Settings
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Specify Safe Elliptic Curves
ssl_ecdh_curve secp521r1:secp384r1;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/utangard.net/0001_chain.pem;
# Strict Transport Security
#add_header Content-Security-Policy "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'none'";
add_header X-Content-Type-Options "nosniff";
add_header X-Frame-Options "sameorigin";
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# Additional Settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Logging Settings
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Take advantage of G-Zip everywhere possible
gzip on;
gzip_disable "MSIE [1-6]\.";
# Only allow proxy request with these headers to be gzipped.
gzip_proxied expired no-cache no-store private auth;
# Default is 6 (1<n<9), but 2 -- even 1 -- is enough. The higher it is, the more CPU cycles will be wasted.
# Let's waste alot
gzip_comp_level 9;
gzip_min_length 500; # Reminder: Default 20
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# Virtual Host Configs
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
# Server Upgrade Block
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Upstream Websocket for Cockpit
upstream websocket {
server (INTERNAL SENSITIVE NOT SHOWN);
}
}
[email protected]:/etc/nginx#
If you want to take full advantage of your EC curve you must point NGINX to use it. Thus
ssl_certificate /etc/letsencrypt/live/utangard.net/0001_chain.pem;
ssl_certificate_key /etc/letsencrypt/live/utangard.net/ecprivkey.pem;
ssl_dhparam /etc/letsencrypt/live/utangard.net/dhparam.pem;
The certificate will be your 0001_chain.pem or whatever had your SECP384R1 curve
The key must be ecprivkey.pem or whatever you named your private key. If not you absolutely will get a cipher mismatch!
Specify your dhparam following. In my case I am using the 16384 for kicks. I have renamed it as my main. I also renamed the 4096 to dhparam-fallback.pem. I like testing boundaries. Get used to it
The next thing I proceeded to do is disable all but the strongest security settings. I am going to split this up a bit. Most blocks are self explanatory. Let us specify we dont want old protocols (this will break old devices|You have been warned)
Specify TLS1.2+
# Specify Protocols
ssl_protocols TLSv1.2 TLSv1.3;
Now we need to specify our ciphers in this order !whatWeDontWant:Most Preferred:Least Preferred
# Specify Ciphers
ssl_ciphers !AES128:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
Setting the server to mandate server ciphers will allow the server to control security
# Mandate Server ciphers
ssl_prefer_server_ciphers on;
Default session timeouts are what I left them at
# Other Settings
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
I specified the only two curves I want the EC cert to use. 521r1 or 384r1. You can optionally allow smaller primes if you should so feel like it however I am going for the A+!
# Specify Safe Elliptic Curves
ssl_ecdh_curve secp521r1:secp384r1;
In order to achieve the A+ we must have the ability to OCSP staple so we can phone home and my certificates can be verified
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/utangard.net/0001_chain.pem;
In order to further achieve the A+ we must enable HSTS or HTTPS Strict Transport Security. This will prevent any data from being sent over HTTPS and prevent downgrade attacks. The age can be set as long as you want. The longer the better. This prevents the downgrade from happening in that amount of seconds. I prefer preloading to be on and to include all subdomains. If you are using a reverse proxy leave the top line commented out unless you want SEVERE BREAKAGE (ask me how I know )
# Strict Transport Security
#add_header Content-Security-Policy "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'none'";
add_header X-Content-Type-Options "nosniff";
add_header X-Frame-Options "sameorigin";
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
The dirty ssl configuration trick to disable TLSv1.3 128 ciphers (cant do from nginx)
Alright guys I hate weak ciphers and I want that A+ Qualsys end result. TLS1.3 is screwing me over what do? LOL well let us have openSSL slap NGINX around a bit.
At the bottom of /usr/lib/ssl/openssl.cnf (raspbian AARCH64)
We will add two line items CipherSuites and Options
[default_conf]
ssl_conf = ssl_sect
[ssl_sect]
system_default = system_default_sect
[system_default_sect]
MinProtocol = TLSv1.2
CipherString = [email protected]=2
Ciphersuites = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
Options = ServerPreference,PrioritizeChaCha
[email protected]:/etc/nginx#
Specifying the same ciphers we wanted from NGINX for all protocols above TLS1.2. I also prioritized CHACHA20-POLY1305. CHACHA is really cool. Its the principle cipher suite behind wireguard and its a lot more efficient than high SHA AES 256 GCM. Its a very promising cipher suite
Great pages on it. Highly recommend the read:
Alright now all we need to do is sudo systemctl restart nginx.service
If it goes without errors you did it right
DONT FORGET SEMICOLONS
Results: (they are very good)
yes I know the IP’s can easily be found. Truth be told I just rather you dont blurt them out
My configuration: (see additional details for why EC’s are simply better)
https://www.ssllabs.com/ssltest/analyze.html?d=utangard.net
ADDITIONAL COOL DETAILS
Since this is the same between IPv6 and 4 I will just post 6
Certificate Information:
Why EC’s are better. (Smaller keys better encryption)
Handshake Simulations: (Shows what breaks and what doesnt)
Compare against the forum: (@wendell if you do take issue with this academic endeavor of testing the forum on the site let me know I will absolutely remove it)
https://www.ssllabs.com/ssltest/analyze.html?d=forum.level1techs.com
Compare against the big GOOG:
https://www.ssllabs.com/ssltest/analyze.html?d=google.com
B isnt bad but it happens because these pages must retain as much backwards compatibility as possible. I do not need to be hindered by such things so my situation is different!
Anyways was a fun learning process. (@Novasty thanks for the help. Hope this paid it back the GPLv2 way. BTW I altered the NGINX config to make some optimizations )
All of this work preps me for the final step. A large ZFS Raid-Zed2 Pool and a Nextcloud+JellyFin going up soon ™!
Asking for a friend: Does anybody know if the cloudflared DDOS protection is worth it on a home deal?
Just because I enjoy trolling the fuck out of you and I know you have this weird OCD about it.
EDIT: I turned off OCSP Must Staple because it broke things for me.
It broke my cockpit page I’m not doing it again
You had your certs reissued for EC huh?
All I know is I finally got an A+ lol
only because I found out the CA has EC roots.
Lame sauce. I think I have to wait on that for letsencrypt. I wanted to move over to all EC. (More efficient keys)
On another end to make you pull your hair out.
You can change the ecdh curve to be higher than what is shown by default.
REALLY EASILY, I’m never going to tell you though, just so you can agonize on how easy it is.
I know. Did you see mine? Its the same lol
You just have to specify what safe curves you want to use right?
Or did you dirty slap nginx around? I’m guessing it’s SSL because that’s how we got TLS1.3 doing what we would like it to do
I ahh see it, you’re mega post was too long, I probably scrolled past it while reading.
God why does this thread have a solution button I keep accidently pressing it.
Yeah it was long. I wanted to cover what I did in one post.
Its in the additional information section.
I see you too are a man of elliptic curves culture
That A+ was difficult ish to figure out. I kept getting stuck on A like wtf
@Novasty you know what’s strange?
Last night we were talking about letsencrypt not doing CSR by themselves at SHA256 but you could self create higher. I did at 512 and the sign still ended up at 256 lol.
512 is more efficient on modern CPUs. I know we were both shocked
Weird that it lost my 512
Let’s Encypt is big gay. It wont do what I asked, I may purchase a cert.
You use namecheap right? Might as well stop being poor. Was a cool learning process lol!
To be fair beggers cant be choosers.
Im not buying one. Thats expensive for what I am using it for. Ill wait for letsencrypt to stop being gay