Kahibaro
Discord Login Register

5.1.4 SSL/HTTPS

Why SSL and HTTPS Matter on Linux Web Servers

In web server administration, SSL and HTTPS turn plain HTTP traffic into encrypted, authenticated, and integrity protected communication. On Linux servers you will routinely terminate HTTPS either directly in Apache or Nginx or at a reverse proxy in front of your application stack. This chapter focuses on the practical aspects that are specific to SSL and HTTPS on Linux web servers, including certificates, key management, protocol and cipher choices, and typical configuration patterns.

Core Concepts: SSL, TLS, HTTPS

SSL is the older protocol that originally secured HTTP. Modern deployments use TLS, currently versions 1.2 and 1.3, but the term “SSL” is still widely used in file paths and commands. HTTPS simply means HTTP transported over TLS, usually on port 443, with the TLS handshake happening before any HTTP data is sent.

The security properties of HTTPS depend entirely on correct key and certificate management, sane protocol and cipher choices, and correct server configuration. A misconfigured HTTPS site can be worse than HTTP, for example if it presents the wrong certificate, leaks private keys, or allows obsolete protocols that attackers can break.

Always terminate HTTPS with:

  1. Valid certificates that match the hostname.
  2. Private keys stored securely and with restrictive permissions.
  3. Modern TLS versions only, and disallow obsolete SSLv2, SSLv3, TLS 1.0, and TLS 1.1.

Certificates and Keys on Linux

On Linux, SSL certificates and keys are just files. Understanding where they live and how they are structured is essential for secure and maintainable web server setups.

Certificate and key file formats

Most web servers on Linux use PEM format, which is a Base64 encoded ASCII representation wrapped in header lines. A typical private key looks like:

-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----

and a certificate looks like:

-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

A complete certificate chain file may contain multiple BEGIN CERTIFICATE blocks concatenated together. The first is usually the server certificate, followed by intermediate CA certificates.

You may also encounter PKCS#12 (.p12 or .pfx) bundles, especially when importing or exporting from other systems. Use openssl pkcs12 to convert those into PEM files that Apache or Nginx can read.

Certificate types and trust

On a Linux server, the most common certificate types are:

Self signed certificates, which you generate locally. These do not chain to any trusted public CA, so browsers will show warnings unless you deploy your own trust anchor.

Public CA signed certificates, issued by a public certificate authority such as Let’s Encrypt, GlobalSign, or DigiCert. Browsers already trust these CAs through their root trust stores.

Wildcard certificates, which secure *.example.com. These allow you to cover multiple subdomains with one certificate, but they need careful private key protection because compromise affects all covered subdomains.

SAN (Subject Alternative Name) certificates, which secure multiple specific hostnames in a single certificate, for example www.example.com and api.example.com.

The browser validates that the hostname requested by the client is present in the certificate’s SAN extension. As an administrator, you must ensure that the Common Name and SANs include exactly the hostnames you serve.

Key storage and filesystem permissions

On Linux servers, you typically store private keys in directories only readable by the web server user and root. A common convention is:

Apache: /etc/ssl/private or /etc/apache2/ssl

Nginx: /etc/ssl/private or /etc/nginx/ssl

Certificates themselves can be more widely readable because they are public information, for example in /etc/ssl/certs.

Use restrictive permissions on private keys. A typical pattern is:

chown root:root /etc/ssl/private/example.com.key
chmod 600 /etc/ssl/private/example.com.key

Avoid world readable or group readable private keys. Any user who can read the key can impersonate your site.

Certificate Management with OpenSSL

On Linux, openssl is the standard tool for low level certificate and key management. While high level tools like certbot automate most tasks, you still need openssl for many administrative operations.

Generating a private key and CSR

To obtain a CA signed certificate, you normally generate a private key and a Certificate Signing Request (CSR) locally, then send the CSR to the CA.

A common pattern for a 2048 bit RSA key and CSR is:

openssl genrsa -out example.com.key 2048
openssl req -new -key example.com.key -out example.com.csr \
  -subj "/C=US/ST=State/L=City/O=Example Corp/CN=www.example.com"

Alternatively, you can omit -subj and allow openssl to ask you for values interactively.

The CSR includes your public key and identity information. The private key stays on the server and is never sent to the CA. Store the CSR until the certificate is issued, or regenerate it if needed.

Inspecting certificates and keys

To view certificate details, use:

openssl x509 -in example.com.crt -text -noout

This shows the subject, issuer, validity period, SAN list, and supported key usage flags.

To check a private key:

openssl rsa -in example.com.key -check

To verify that a certificate matches a private key, compare their modulus:

openssl rsa -in example.com.key -noout -modulus | openssl md5
openssl x509 -in example.com.crt -noout -modulus | openssl md5

If the hashes are identical, the key and certificate belong together.

Let’s Encrypt and Automated Certificates

Let’s Encrypt and the ACME protocol brought free and automated TLS certificates to Linux servers. In practice, you use a client such as certbot, acme.sh, or a distribution specific ACME client to handle the entire lifecycle: issuance, renewal, and deployment.

ACME challenges

For HTTP based validation, the CA asks you to prove control of a domain by placing a specific token at a URL under http://example.com/.well-known/acme-challenge/. Your ACME client and web server must cooperate so that this path is reachable from the Internet.

DNS based validation requires placing a TXT record under _acme-challenge.example.com. This works well for wildcard certificates, but requires DNS automation if you want full hands off renewal.

On Linux, these clients usually integrate with systemd timers or cron jobs and reload the web server automatically on renewal.

Certbot usage patterns

A common certbot pattern for Apache is:

certbot --apache -d example.com -d www.example.com

Certbot edits Apache virtual host configurations to add HTTPS support and sets up automatic renewal.

For Nginx, you can use:

certbot --nginx -d example.com -d www.example.com

If you prefer manual integration, you can use certbot in --webroot mode, specifying a directory that your web server serves for ACME challenges. Certbot will place challenge files there without changing your main server configuration.

Certbot also sets up a systemd timer called certbot.timer or a cron job, depending on your distribution. You must ensure that these automated tasks run and that the web server reloads or restarts when certificates change.

Enabling HTTPS in Apache

Apache handles HTTPS through the mod_ssl module. On many distributions, this module is available but not enabled by default. You need to enable it and create HTTPS virtual hosts.

Basic SSL virtual host structure

A typical Linux Apache HTTPS virtual host looks like:

<VirtualHost *:443>
    ServerName www.example.com
    ServerAlias example.com
    DocumentRoot /var/www/example.com
    SSLEngine on
    SSLCertificateFile      /etc/ssl/certs/example.com.crt
    SSLCertificateKeyFile   /etc/ssl/private/example.com.key
    SSLCertificateChainFile /etc/ssl/certs/example.com-chain.crt
    # Additional directives, logging, etc.
</VirtualHost>

On Debian and Ubuntu, you enable SSL and the site with:

a2enmod ssl
a2ensite default-ssl
systemctl reload apache2

On Red Hat based systems, you typically edit /etc/httpd/conf.d/ssl.conf or add similar content in your own vhost file under /etc/httpd/conf.d/, then restart or reload httpd.

TLS protocols and ciphers in Apache

Apache provides SSLProtocol and SSLCipherSuite directives, along with modern preset profiles. A simple robust configuration for a modern server is:

SSLProtocol             all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite          HIGH:!aNULL:!MD5
SSLHonorCipherOrder     on

Many distributions also ship with SSLOpenSSLConfCmd directives to tune TLS 1.3 ciphers. Consult current hardening guides such as Mozilla’s SSL Configuration Generator to choose a suitable profile for your environment.

You should also enable OCSP stapling if supported, by using SSLUseStapling on and related directives, to improve revocation checking performance.

HTTP to HTTPS redirection in Apache

To enforce HTTPS, create or modify an HTTP virtual host on port 80 that only redirects to HTTPS. An example is:

<VirtualHost *:80>
    ServerName www.example.com
    Redirect permanent / https://www.example.com/
</VirtualHost>

This centralizes encryption requirements and makes sure all visitors are upgraded to encrypted connections.

Enabling HTTPS in Nginx

Nginx is widely used as an HTTPS terminator because of its simple and performant TLS handling. On Linux, you typically manage Nginx configuration under /etc/nginx/nginx.conf and /etc/nginx/sites-available or /etc/nginx/conf.d, depending on distribution conventions.

Basic SSL server block

A typical Nginx HTTPS server block is:

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    ssl_certificate     /etc/ssl/certs/example.com-fullchain.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;
    root /var/www/example.com;
    index index.html;
    # Additional location blocks, proxying, etc.
}

The ssl_certificate directive often points to a file that already contains the full chain including server and intermediate certificates. Many ACME clients such as certbot create such fullchain.pem files directly.

HTTP/2 can be enabled with http2 on the listen directive, which is standard for modern browsers.

TLS protocols and ciphers in Nginx

To restrict protocols and choose ciphers in Nginx, use ssl_protocols and ssl_ciphers. A conservative modern profile is:

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'HIGH:!aNULL:!MD5';
ssl_prefer_server_ciphers on;

TLS 1.3 ciphers are not set through ssl_ciphers in older Nginx with certain OpenSSL versions, but modern stacks usually handle both with a single directive. Check your specific combination and documentation.

Nginx also supports session tickets and session caches, which you can tune with ssl_session_cache and ssl_session_timeout. On busy Linux servers, this can significantly reduce CPU usage by reusing TLS sessions.

HTTP to HTTPS redirection in Nginx

To force HTTPS, create an HTTP server block that simply redirects:

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

This preserves the path and query string while upgrading the scheme to HTTPS.

Mixed Content, HSTS, and Browser Behavior

Once you enable HTTPS, your pages must load all subresources such as images, scripts, and stylesheets over HTTPS as well. If some are loaded over HTTP, modern browsers will report mixed content and may block those resources.

On Linux web servers, this usually means updating application configuration, absolute URLs, and reverse proxy rules so that everything behind the HTTPS endpoint speaks HTTPS, or at least travels through a trusted internal network behind the TLS terminator.

HTTP Strict Transport Security (HSTS) instructs browsers to always use HTTPS for a site once they have seen the header. You set it in Apache or Nginx as an HTTP response header. In Nginx, for example:

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

HSTS prevents downgrade attacks but makes rollbacks harder. Misconfiguring HSTS for domains where you cannot always serve HTTPS can lock users out, so introduce it carefully and test on smaller scopes first.

TLS Offloading and Reverse Proxies

On Linux, it is common to terminate HTTPS at a reverse proxy like Nginx or HAProxy and forward plain HTTP to backend application servers. This separates TLS concerns from the application and allows a single front end to manage certificates for many internal services.

A typical Nginx HTTPS reverse proxy server block is:

server {
    listen 443 ssl http2;
    server_name app.example.com;
    ssl_certificate     /etc/ssl/certs/app.example.com-fullchain.crt;
    ssl_certificate_key /etc/ssl/private/app.example.com.key;
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }
}

The X-Forwarded-Proto header informs the backend that the original connection from the client was HTTPS. Applications can then generate correct absolute URLs and make security decisions based on this information.

From the Linux administrator’s perspective, you must secure the network between the TLS terminator and backend servers, enforce firewall rules, and treat internal HTTP as trusted only within that boundary.

Protocol Versions and Deprecation

TLS protocol versions evolve over time. On Linux, you control which versions are acceptable through web server configuration as shown earlier. Old protocols are weak and should not be allowed, even if some legacy clients require them.

The typical policy on an Internet facing Linux web server is:

Allow TLS 1.2 and TLS 1.3.

Deny SSLv2, SSLv3, TLS 1.0, and TLS 1.1.

Within your organization, you may temporarily allow an older protocol on an internal server while you upgrade legacy clients, but you should treat this as a short term exception and isolate it with network policies.

Never enable SSLv2 or SSLv3 on public facing Linux web servers. These protocols are fundamentally broken and expose users to active attacks.

You can verify supported protocols using tools like openssl s_client or external scanners such as SSL Labs, which connect to your Linux server and report the current TLS configuration.

Testing and Troubleshooting HTTPS on Linux

When deploying or modifying HTTPS on a Linux server, you should systematically test the configuration before exposing it to users.

Using openssl s_client

You can use openssl s_client to test handshakes and inspect certificates:

openssl s_client -connect example.com:443 -servername example.com

This shows the full certificate chain, selected ciphers, and protocol version. You can force a specific protocol or cipher to see if the server supports it, for example:

openssl s_client -connect example.com:443 -tls1_2

If -tls1_2 fails, then TLS 1.2 is disabled or misconfigured. Use similar options for other versions as needed.

Looking at logs on Linux

Both Apache and Nginx log SSL related errors in their main error logs. On many Linux systems, these live in:

Apache: /var/log/apache2/error.log or /var/log/httpd/error_log

Nginx: /var/log/nginx/error.log

Certificate mismatch errors, missing key files, wrong permissions on private keys, or syntax errors in SSL directives will be reported there. When changing SSL configuration, follow the normal Linux practice of running a configuration test first, for example:

Apache on Debian based: apache2ctl configtest

Apache on Red Hat based: httpd -t

Nginx: nginx -t

This prevents reloading a broken configuration.

System trust stores and client tools

On Linux, the system’s CA trust store resides under /etc/ssl/certs or a similar path, depending on the distribution. Command line tools such as curl, wget, and git rely on this store to verify server certificates.

If you deploy an internal CA, you must import its root certificate into the system trust store on Linux clients for trust to work without warnings. Each distribution has its own update mechanism, for example update-ca-certificates on Debian and Ubuntu, or update-ca-trust on Red Hat based systems.

Summary

Running HTTPS on Linux web servers involves careful management of keys and certificates, strict protocol and cipher configuration, and consistent integration with Apache or Nginx. Automation through ACME clients like certbot removes much of the manual renewal burden, but you remain responsible for secure file permissions, correct virtual host configuration, and disciplined use of modern TLS versions. By thoroughly testing with tools such as openssl s_client and monitoring web server logs, you ensure that your Linux based web infrastructure delivers secure and reliable HTTPS service.

Views: 67

Comments

Please login to add a comment.

Don't have an account? Register now!