Generate Self-Signed certificate

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.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.