Installing Certbot on Amazon Linux 2023 via EPEL or pip

From Qiki
Jump to navigation Jump to search

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.