Let’s Encrypt Certificate Authority (CA) provides free TLS/SSL certificates to enable encrypted HTTPS on web servers. This guide walks you through obtaining a free SSL certificate and configuring it for a Jenkins installation behind an NGINX reverse proxy on Ubuntu.
Table of Contents
- Prerequisites
- Installing Let’s Encrypt Client
- Installing NGINX
- Domain Validation Setup
- Creating Certification Configuration
- Requesting the Certificate
- Configuring Jenkins with Reverse Proxy
- Auto-Renewal Configuration
Prerequisites
Before you begin, ensure you have the following:
- A server running Ubuntu 16.04 (or later) with root access.
- A Fully Qualified Domain Name (FQDN) pointing to your server’s IP address (e.g.,
jenkins.your-domain.com). - Port 80 and 443 open on your firewall.
Installing Let’s Encrypt Client
First, we need to clone the Let’s Encrypt client (Certbot) from GitHub. Ensure git is installed:
sudo apt-get update && sudo apt-get install git -y
Now, clone the repository to the /opt directory:
sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
Installing NGINX
We will use NGINX as a reverse proxy. This allows NGINX to handle the SSL termination and forward traffic to Jenkins running on its default port (8080).
sudo apt-get install nginx -y
Domain Validation Setup
Let’s Encrypt needs to validate that you own the domain. We will use the Webroot plugin, which requires placing a temporary file in a specific directory on your server.
Edit the default NGINX configuration: sudo vim /etc/nginx/sites-available/default
Add the following location block to handle the ACME challenge. Replace jenkins.your-domain.com with your actual domain:
server {
listen 80;
server_name jenkins.your-domain.com;
location '/.well-known/acme-challenge' {
default_type "text/plain";
root /var/www/letsencrypt;
allow all;
}
}Verify and reload NGINX: sudo nginx -t && sudo nginx -s reload
Creating Certification Configuration
Instead of passing many arguments to the command line, we’ll create a configuration file. Create a directory for configs if it doesn’t exist: sudo mkdir -p /etc/letsencrypt/configs
Create the config file /etc/letsencrypt/configs/your-domain.conf. Update the domains and email fields:
# Generate certificates for the specified domains.
domains = your-fully-qualified-domain
# Use a strong 4096-bit RSA key
rsa-key-size = 4096
# Email for renewal reminders
email = [email protected]
# Use the webroot authenticator.
authenticator = webroot
# Path served by NGINX for validation
webroot-path = /var/www/letsencrypt/Requesting the Certificate
Run the Let’s Encrypt client to generate your certificates:
cd /opt/letsencrypt sudo ./letsencrypt-auto --config /etc/letsencrypt/configs/your-domain.conf certonly
Upon success, your certificates will be stored in /etc/letsencrypt/live/your-domain/.
Configuring Jenkins with Reverse Proxy
1. Install Jenkins (Optional)
If you haven’t installed Jenkins yet:
wget -q -O - https://jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update && sudo apt-get install jenkins -y
2. Update NGINX Config
Now, configure NGINX to redirect all traffic to HTTPS and proxy it to Jenkins. Update /etc/nginx/sites-available/default:
upstream jenkins {
server 127.0.0.1:8080 fail_timeout=0;
}
server {
listen 80;
server_name jenkins.your-domain.com;
# Redirect all HTTP traffic to HTTPS
location / {
return 301 https://$host$request_uri;
}
location '/.well-known/acme-challenge' {
default_type "text/plain";
root /var/www/letsencrypt;
allow all;
}
}
server {
listen 443 ssl;
server_name jenkins.your-domain.com;
ssl_certificate /etc/letsencrypt/live/jenkins.your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/jenkins.your-domain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384';
location / {
proxy_set_header Host $host:$server_port;
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_redirect http:// https://;
proxy_pass http://jenkins;
}
}Test and restart NGINX: sudo nginx -t && sudo systemctl restart nginx
Auto-Renewal Configuration
Let’s Encrypt certificates expire every 90 days. We can automate renewal with a simple cron job.
Create /etc/cron.monthly/renew-ssl.sh and make it executable: sudo chmod +x /etc/cron.monthly/renew-ssl.sh
#!/bin/bash
cd /opt/letsencrypt/
./letsencrypt-auto --config /etc/letsencrypt/configs/your-domain.conf certonly
if [ $? -eq 0 ]
then
systemctl reload nginx
else
echo "SSL Renewal failed!" | mail -s "Alert: Jenkins SSL Renewal" [email protected]
fiCongratulations! Your Jenkins instance is now secured with a free, auto-renewing SSL certificate.