I strongly recommend everyone to use Let’s Encrypt to generate certificates but I understand that not all of you have your own domain. And Self-Signed certificate is better then nothing. If you do have your own domain, read my guide how to generate a wildcard certificate with Let’s Encrypt.
But in this guide I’ll go trough how to generate a self-signed certificate for Lighttpd, NGINX and Apache2.
Introduction
Validated on
This how-to have been tested and known to work, but not limited to the following versions
- Ubuntu 24.04
- Ubuntu 22.04
Prerequisite
- Sudo or root access to your Ubuntu Server
- SSH access to your Ubuntu Server
- SSH software
- macOS, you can use Terminal
- Linux, you can use Terminal
- Windows, I do recommend you to use PuTTY
Good to know
- During this guide you need to replace some of the text with your unique name etc.
- Nano commands
- To save a file after you have made changes press CTRL+X and then Y
- Go to the end of the file press CTRL+W and then CTRL+V
Recommendation
- If you haven’t secured SSH on your Ubuntu Server I do recommend you to read my guide about it
Generate Certificate
We need to create a folder where we can save our certificate
sudo mkdir /etc/nginx/ssl
sudo mkdir /etc/apache2/ssl
sudo mkdir /etc/lighttpd/ssl
Time to create our certificate, you can change the name of certificate if you like just change selfsigned.key/.crt or selfsigned.pem to whatever you like. This certificate is valid for 365 days, you can increase or decrease that by changing the value 365
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/selfsigned.key -out /etc/nginx/ssl/selfsigned.crt
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/selfsigned.key -out /etc/apache2/ssl/selfsigned.crt
sudo openssl req -new -x509 -keyout /etc/lighttpd/ssl/selfsigned.pem -out /etc/lighttpd/ssl/selfsigned.pem -days 365 -nodes
When you have executed the command above you need to answer a series of questions, make sure to answer them.
Now we need to generate a strong Diffie-Hellman group, this can take some time to finish
sudo curl https://ssl-config.mozilla.org/ffdhe2048.txt > /etc/nginx/ssl/dhparam.pem
sudo curl https://ssl-config.mozilla.org/ffdhe2048.txt > /etc/apache2/ssl/dhparam.pem
sudo curl https://ssl-config.mozilla.org/ffdhe2048.txt > /etc/lighttpd/ssl/dhparam.pem
Create Snippet (optional)
(I’ll later add how to do this with Lighttpd)
Our life’s will get much easier when we are going to create server blocks in NGINX and APACHE2 if we create snippets for SSL. So, let’s do that
First, we need to create a snippet where we can add the location of our SSL certificates
sudo nano /etc/nginx/snippets/ssl-cert.conf
sudo mkdir /etc/apache2/snippets sudo nano /etc/apache2/snippets/ssl-cert.conf
Add the following to the file
ssl_certificate /etc/nginx/ssl/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/privkey.pem; ssl_dhparam /etc/nginx/ssl/dhparam.pem;
SSLCertificateFile /etc/apache2/ssl/fullchain.pem SSLCertificateKeyFile /etc/apache2/ssl/privkey.key SSLOpenSSLConfCmd DHParameters /etc/apache2/ssl/dhparam.pem
Now we are going to create a snippet with SSL parameters
sudo nano /etc/nginx/snippets/ssl-param.conf
sudo nano /etc/apache2/snippets/ssl-param.conf
Add the following to the file
ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; ssl_session_timeout 1440m; ssl_stapling on; ssl_stapling_verify on; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; 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"; add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload"; add_header X-XSS-Protection "1; mode=block"; add_header Referrer-Policy "strict-origin-when-cross-origin"; add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options nosniff always;
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite 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 SSLHonorCipherOrder off SSLSessionTickets off SSLUseStapling On SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
Conclusion
Now we have generated our own self-signed certificate, it’s better then nothing but as I stated before it’s easy to generate a wildcard certificate with Let’s Encrypt and I have made a guide for it.