SSL Config: Difference between revisions

From Sea of Fate
Jump to navigationJump to search
Created page with "==Intoduction== ==The Process == There will be two setups for SSL/TLS one for the seaoffate.local and one for seaoffate.net. ===Local DNS Names SSL Setup=== We will do the SSL/TLS for the .local access first mainly because because it is better to see it working on a local level and if we did the global first there is a good chance we would never get a around to doing the local, in which case some of the access will be completely without any cert. It is part of the lea..."
 
No edit summary
Line 1: Line 1:
==Intoduction==
==Intoduction==


==The Process ==
There will be two setups for SSL/TLS one for the seaoffate.local and one for seaoffate.net.  
There will be two setups for SSL/TLS one for the seaoffate.local and one for seaoffate.net.


===Local DNS Names SSL Setup===
===Local DNS Names SSL Setup===

Revision as of 01:53, 15 March 2025

Intoduction

There will be two setups for SSL/TLS one for the seaoffate.local and one for seaoffate.net.

Local DNS Names SSL Setup

We will do the SSL/TLS for the .local access first mainly because because it is better to see it working on a local level and if we did the global first there is a good chance we would never get a around to doing the local, in which case some of the access will be completely without any cert. It is part of the learning curve to generate SSL certificates. While it would be fairly easier to do a self cert for the local access it is better to experience the whole process from start to finish to get a complete understanding of how it is done and the failures that inevitably appear.

The Process Flow

The process flow is to get the Certificates generated on the webserver host, get it signed by the Certificate Authority then apply it to the webserver, once that is done the SSL config needs to be applied to the host, after that it we would make a config to the reverse proxy. The reverse proxy will have it's own certificate to use for all of the hosts that it is forwarding to and once the cert is applied it will not need to have it applied again, we would just refer to it in the individual SSL config.

Generating SSL Certificates

The first thing to do is to generate a private key, this is done on the webserver with the command

sudo openssl genrsa -out /etc/ssl/private/strawberry.seaoffate.local.key 2048

The out directive will specify where the private key will stored, in this case the default location is used. The .key does need to be stored privately as it is the key that will be used to encrypt or decrypt the internet traffic and is the core item in the security of the Internet. Once the private key has been generated access should be restricted to the root user only so we need to do the chmod/chown commanda s follows

sudo chmod 600 /etc/ssl/private/strawberry.seaoffate.local.key
sudo chown root:root /etc/ssl/private/strawberry.seaoffate.local.key

Now that we have the private key we can look at getting the public certificate. To get the certificate with any sort of trust it has to be signed by a Certificate Authority. We have a personal CA available on Alpine, it will only be trusted by us and not the rest of the world as it is a personal CA. To have a cert signed we must generate a Certificate Signing Request and present it to the CA the command to generate a CSR is

sudo openssl req -new -key /etc/ssl/private/strawberry.seaoffate.local.key -out /etc/ssl/certs/strawberry.seaoffate.local.csr

As this script executes it will ask a numer of questions.

  • Country Name (2 letter code) [AU]:GB
  • State or Province Name (full name) [Some-State]:Hampshire
  • Locality Name (eg, city) []:Basingstoke
  • Organization Name (eg, company) [Internet Widgits Pty Ltd]:Sea of Fate
  • Organizational Unit Name (eg, section) []: (Your department or unit, if applicable, or leave blank)
  • Common Name (e.g. server FQDN or YOUR name) []: strawberry.seaoffate.local (This is crucial, it must match the hostname)
  • Email Address []:[email protected]
  • A challenge password []: (Leave blank, or add a password, but it is not needed for webserver certificates)
  • An optional company name []: (Leave blank, or add an optional company name)

Note that the Common Name is critical The other fields are not so important but should be accurate (don't lie someone may read them), the fields could be left blank (except common name). the challenge password is rarely used for webserver certs and can be left blank.

Note that the command uses the private key that we just generated. The CSR is added to the certs directory it is not secret but it should not be modified so it still need to be stored in a form that has at least 744 on it. As this is a signing request we have to get is to the signing software, the CA, in a secure manner. generally SCP is the best option to transfer a file securely as it uses the same connection as SSH. An example is

scp /etc/ssl/certs/strawberry.seaoffate.local.csr user@alpine:~/easy-rsa/easyrsa3/pki/reqs/

If this doesn't work with the user that is available try copying to /tmp

scp /etc/ssl/certs/strawberry.seaoffate.local.csr user@alpine:/tmp

When the file is copied to Apline we must login to the Alpine host to do the signing. I the CSR file could not be added directly to the reqs directory it should be copied there now.

cp /tmp/strawberry.seaoffate.local.csr ~/easy-rsa/easyrsa3/pki/reqs

Unfortunately, easyrsa need to see CSRs with the extension of .req but the openssl generates them as .csr the solution is to mv the .csr to .req

mv ~/easy-rsa/easyrsa3/pki/reqs/strawberry.seaoffate.local.csr ~/easy-rsa/easyrsa3/pki/reqs/strawberry.seaoffate.local.req

Assuming that the CSR is in the /reqs directory and it has the correct extension we can proceed with the signing. We should be in the ~/easy-rsa/easyrsa3/ directory to run the script

./easyrsa sign-req server strawberry.seaoffate.local

the script will ask to confirm the details that would have been submitted when creating the signing request on the web host and the first answer has to be "yes" or it will not continue. The next question is to supply the passphrase for the script to have access to the CA.key, if it can't be given the request fails. Once the CSR/REQ has been signed the certificate will be created and stored in the issued directory and is ready to be returned to the webserver again using SCP. We could copy the .CRT directly to the /ect/ssl/certs dir on the web host but since we are using Ubuntu we can't because the permissions fail. We should create a dir off of the user's home dir and call it signed we can then SCP

SCP ~/easy-rsa/easyrsa3/pki/issued/strawberry.seaoffate.local.crt [email protected]:~/signed

When that is done swap back to the web host (strawberry) and mv the signed cert to the correct directory

sudo mv signed/strawberry.seaoffate.local.crt /etc/ssl/certs/

We should set the permissions on the cert to be read only and owned by root

sudo chmod 644 /etc/ssl/certs/strawberry.seaoffate.local.crt
sudo chown root:root /etc/ssl/certs/strawberry.seaoffate.local.crt

As a final job we can verify that the cert and key match each other

sudo openssl x509 -noout -modulus -in /etc/ssl/certs/strawberry.seaoffate.local.crt | sudo openssl sha256
sudo openssl rsa -noout -modulus -in /etc/ssl/private/strawberry.seaoffate.local.key | sudo openssl sha256

check to make sure that the two hashes are identical, if they are not SSL will not work on the website.

Create Apache SSL Configuration

Now that we have a signed certificate we can proceed to configure Apache to listen & serve SSL/TLS request on port 443. As we have used Strawberry as the example for the cert generation we will continue to use the same host for the configs. First we should cd to the site-available so that the config file we create matches the existing and we get the correct docroot. We should create a config file,

sudo nano /etc/apache2/sites-available/strawberry.seaoffate.local-ssl.conf

and enter the following

<VirtualHost *:443>
   ServerName strawberry.seaoffate.local
   DocumentRoot /var/www/strawberry/public_html
   SSLEngine on
   SSLCertificateFile /etc/ssl/certs/strawberry.seaoffate.local.crt
   SSLCertificateKeyFile /etc/ssl/private/strawberry.seaoffate.local.key
   <Directory /var/www/strawberry/public_html/>
       AllowOverride All
       Require all granted
   </Directory>
   # Security Headers (Recommended)
   Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
   Header always set X-Frame-Options "SAMEORIGIN"
   Header always set X-Content-Type-Options "nosniff"
   Header always set Referrer-Policy "strict-origin-when-cross-origin"
   # SSL Protocol and Cipher Configuration (Recommended)
   SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
   SSLCipherSuite HIGH:!aNULL:!MD5
   ErrorLog ${APACHE_LOG_DIR}/error.log
   CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

Save and exit. To enable the SSL site and enable the SSL modules.

 sudo a2ensite strawberry.seaoffate.local-ssl.conf
sudo a2enmod ssl
sudo a2enmod headers

To restart Apache & check for errors

sudo systemctl restart apache2
sudo systemctl status apache2

To test with curl

curl -v https://strawberry.seaoffate.local

We should also look in a browser to be sure that the config works.

Raisin Nginx Reverse Proxy Configuration

Once we have tested the webserver SSL config we should do the same for Raisin, the Reverse Proxy, First of all ssh to raisin and cd to /etc/nginx/sites-available to check what the format is for the existing configs. Create anew config for strawberry

sudo nano strawberry.seaoffate.local.ssl.conf

fill in the following configuration

server {
   listen 443 ssl;
   server_name strawberry.seaoffate.local;
   ssl_certificate /etc/nginx/ssl/raisin.crt; # Path to your SSL certificate on raisin
   ssl_certificate_key /etc/nginx/ssl/raisin.key; # Path to your SSL key on raisin
   ssl_protocols TLSv1.2 TLSv1.3;
   ssl_ciphers 'HIGH:!aNULL:!MD5'; # !aNULL: This excludes ciphers that use anonymous Diffie-Hellman key exchange !MD5' excludes weak md5 hash 
   location / {
       proxy_pass https://*.*.*.23; # IP of strawberry
       proxy_set_header Host $host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-Proto $scheme;
       proxy_ssl_verify off; # only needed if strawberry has a self signed cert.
   }
}

Save and exit. If this is the first SSL website to be proxy, we will need to create the SSL directory for the certs.

sudo mkdir -p /etc/nginx/ssl

If keys and certs have not been created follow the instructions above. Assuming SSL dir creation is done we should make the site enabled

sudo ln -s /etc/nginx/sites-available/strawberry.seaoffate.local /etc/nginx/sites-enabled/

We can test the config with

sudo nginx -t

If all is well Restart Nginx to apply the changes

sudo systemctl restart nginx
sudo systemctl status nginx

We can run a test with curl

curl -v https://strawberry.seaoffate.local

We should also open a browser to see if it can open the website

https://strawberry.seaoffate.local