Installing Certbot on Amazon Linux 2023 via EPEL or pip
You’re right - Amazon Linux 2023 doesn’t include snapd in its repositories. Let’s use the native approach with certbot
directly from the EPEL repository or Python pip. Here’s the corrected method for AL2023:
Step 1: Install Certbot (Corrected for AL2023)
Option A: Using Python pip (Recommended for AL2023)
# Install Python and pip if not already installed
sudo dnf install -y python3 python3-pip
# Install certbot and nginx plugin
sudo python3 -m pip install --upgrade pip
sudo python3 -m pip install certbot certbot-nginx
# Create symlink for system-wide access
sudo ln -sf /usr/local/bin/certbot /usr/bin/certbot
Option B: Using EPEL Repository
# Install EPEL repository for AL2023
sudo dnf install -y epel-release
# Update repository cache
sudo dnf update -y
# Try to install certbot
sudo dnf install -y certbot python3-certbot-nginx
If EPEL doesn’t work, use Option A with pip.
Step 2: Verify Installation
# Check certbot version
certbot --version
# Check Nginx is running
sudo systemctl status nginx
Step 3: Configure Nginx for HTTP-01 Challenge (Zero Downtime)
Create the ACME challenge configuration:
# Create directory structure
sudo mkdir -p /var/www/letsencrypt
sudo mkdir -p /etc/nginx/snippets
# Create Let's Encrypt snippet
sudo tee /etc/nginx/snippets/letsencrypt.conf > /dev/null <<'EOF'
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /var/www/letsencrypt;
try_files $uri =404;
}
EOF
# Set proper permissions
sudo chown -R nginx:nginx /var/www/letsencrypt
Add to your Nginx configuration:
# Edit your domain config (adjust path as needed)
sudo nano /etc/nginx/conf.d/default.conf
# OR if using sites-available:
# sudo nano /etc/nginx/sites-available/default
Include the snippet in your server block:
server {
listen 80;
server_name your-domain.com www.your-domain.com;
# Include Let's Encrypt location
include /etc/nginx/snippets/letsencrypt.conf;
# Your existing configuration
location / {
root /usr/share/nginx/html;
index index.html;
}
}
Test and reload:
sudo nginx -t
sudo systemctl reload nginx
Step 4: Obtain Certificate with Webroot Method
# Get certificate using webroot (replace domain and email)
sudo certbot certonly \
--webroot \
-w /var/www/letsencrypt \
--email your-email@example.com \
--agree-tos \
--no-eff-email \
--deploy-hook "systemctl reload nginx" \
-d your-domain.com \
-d www.your-domain.com
Step 5: Configure SSL in Nginx
Create SSL parameters file:
sudo tee /etc/nginx/snippets/ssl-params.conf > /dev/null <<'EOF'
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=63072000" always;
EOF
Update your site configuration:
sudo tee /etc/nginx/conf.d/your-domain.conf > /dev/null <<'EOF'
# Redirect HTTP to HTTPS
server {
listen 80;
server_name your-domain.com www.your-domain.com;
include /etc/nginx/snippets/letsencrypt.conf;
location / {
return 301 https://$server_name$request_uri;
}
}
# HTTPS Configuration
server {
listen 443 ssl http2;
server_name your-domain.com www.your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
include /etc/nginx/snippets/ssl-params.conf;
include /etc/nginx/snippets/letsencrypt.conf;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
EOF
Remember to adjust the domain name, then test and reload:
sudo nginx -t
sudo systemctl reload nginx
Step 6: Set Up Automatic Renewal
Using Crontab (Most Compatible)
# Add renewal cron job
sudo crontab -e
Add this line:
0 3 * * * /usr/bin/certbot renew --quiet --deploy-hook "systemctl reload nginx"
Or Using Systemd Timer
Create a systemd service:
sudo tee /etc/systemd/system/certbot-renew.service > /dev/null <<'EOF'
[Unit]
Description=Certbot Renewal
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --deploy-hook "systemctl reload nginx"
EOF
sudo tee /etc/systemd/system/certbot-renew.timer > /dev/null <<'EOF'
[Unit]
Description=Run certbot twice daily
[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=43200
Persistent=true
[Install]
WantedBy=timers.target
EOF
# Enable and start the timer
sudo systemctl daemon-reload
sudo systemctl enable certbot-renew.timer
sudo systemctl start certbot-renew.timer
# Check timer status
sudo systemctl status certbot-renew.timer
Step 7: Test Everything
# Test renewal process
sudo certbot renew --dry-run
# Check certificate
echo | openssl s_client -servername your-domain.com -connect your-domain.com:443 2>/dev/null | openssl x509 -noout -dates
# Verify HTTPS
curl -I https://your-domain.com
Alternative: Using Certbot Nginx Plugin (Simpler but Less Control)
If you want a simpler approach with the nginx plugin:
# Run certbot with nginx plugin (automatically configures Nginx)
sudo certbot --nginx \
--email your-email@example.com \
--agree-tos \
--no-eff-email \
-d your-domain.com \
-d www.your-domain.com
This method automatically: - Obtains the certificate - Configures Nginx SSL - Sets up redirects - Handles renewals
But gives you less control over the specific configuration.
The manual webroot method I detailed above gives you complete control and ensures zero downtime during renewals.