Created
January 7, 2026 19:01
-
-
Save jajansen/3369e447b30345f459d98af690be113e to your computer and use it in GitHub Desktop.
Proper certificates for for GLKVM Comet (Pro) using Certbot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Automated certbot setup script for KVMD (PiKVM) with Cloudflare DNS | |
| # Usage: ./setup-certbot-glkvm.sh <domain> <cloudflare-api-token> | |
| set -e # Exit on any error | |
| # Validate arguments | |
| if [ "$#" -ne 2 ]; then | |
| echo "Usage: $0 <domain> <cloudflare-api-token>" | |
| echo "Example: $0 glkvm.example.com YOUR_CLOUDFLARE_API_TOKEN" | |
| exit 1 | |
| fi | |
| DOMAIN="$1" | |
| CF_TOKEN="$2" | |
| VENV_PATH="/opt/certbot" | |
| CF_CREDS_FILE="${HOME}/cf-credentials.txt" | |
| echo "=== Certbot Setup for KVMD ===" | |
| echo "Domain: ${DOMAIN}" | |
| echo "Virtual Environment: ${VENV_PATH}" | |
| # Create Python virtual environment for certbot isolation | |
| echo "Step 1: Creating Python virtual environment..." | |
| python3 -m venv "${VENV_PATH}" | |
| # Upgrade pip to latest version in virtual environment | |
| echo "Step 2: Upgrading pip..." | |
| "${VENV_PATH}/bin/pip" install --upgrade pip | |
| # Install certbot and nginx plugin into virtual environment | |
| echo "Step 3: Installing certbot and certbot-nginx..." | |
| "${VENV_PATH}/bin/pip" install certbot certbot-nginx | |
| # Install Cloudflare DNS plugin for DNS-01 challenge | |
| echo "Step 4: Installing certbot-dns-cloudflare plugin..." | |
| "${VENV_PATH}/bin/pip" install certbot-dns-cloudflare | |
| # Create symlink to make certbot available system-wide | |
| echo "Step 5: Creating certbot symlink..." | |
| if [ ! -L /usr/bin/certbot ]; then | |
| ln -s "${VENV_PATH}/bin/certbot" /usr/bin/certbot | |
| fi | |
| # Create Cloudflare credentials file with API token | |
| echo "Step 6: Creating Cloudflare credentials file..." | |
| cat > "${CF_CREDS_FILE}" <<EOF | |
| # Cloudflare API token used by Certbot | |
| dns_cloudflare_api_token = ${CF_TOKEN} | |
| EOF | |
| # Set restrictive permissions on credentials file (read-only for owner) | |
| echo "Step 7: Setting secure permissions on credentials file..." | |
| chmod 400 "${CF_CREDS_FILE}" | |
| # Request certificate using Cloudflare DNS-01 challenge | |
| echo "Step 8: Requesting certificate from Let's Encrypt..." | |
| certbot certonly \ | |
| --non-interactive \ | |
| --agree-tos \ | |
| --email "" \ | |
| --dns-cloudflare \ | |
| --dns-cloudflare-credentials "${CF_CREDS_FILE}" \ | |
| -d "${DOMAIN}" | |
| # Backup existing KVMD nginx SSL configuration | |
| echo "Step 9: Backing up existing nginx SSL configuration..." | |
| if [ -f /etc/kvmd/nginx/ssl.conf ]; then | |
| cp /etc/kvmd/nginx/ssl.conf /etc/kvmd/nginx/ssl.conf.backup | |
| fi | |
| # Update KVMD nginx SSL configuration to use Let's Encrypt certificates | |
| echo "Step 10: Updating nginx SSL configuration..." | |
| cat > /etc/kvmd/nginx/ssl.conf <<EOF | |
| ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1; | |
| ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; | |
| #ssl_certificate /etc/kvmd/user/ssl/server.crt; | |
| #ssl_certificate_key /etc/kvmd/user/ssl/server.key; | |
| ssl_certificate /etc/letsencrypt/live/${DOMAIN}/fullchain.pem; | |
| ssl_certificate_key /etc/letsencrypt/live/${DOMAIN}/privkey.pem; | |
| add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; | |
| EOF | |
| # Restart KVMD nginx service to apply new SSL certificates | |
| echo "Step 11: Restarting kvmd-nginx service..." | |
| /etc/init.d/S99kvmd-nginx restart | |
| # Set up automatic certificate renewal via crontab with random sleep delay | |
| echo "Step 12: Setting up automatic certificate renewal..." | |
| SLEEPTIME=$(awk 'BEGIN{srand(); print int(rand()*(3600+1))}') | |
| CRON_ENTRY="0 0,12 * * * root sleep $SLEEPTIME && certbot renew -q --dns-cloudflare --dns-cloudflare-credentials ${CF_CREDS_FILE} --post-hook '/etc/init.d/S99kvmd-nginx restart'" | |
| # Check if crontab entry already exists to avoid duplicates | |
| if ! grep -q "certbot renew" /etc/crontab 2>/dev/null; then | |
| echo "${CRON_ENTRY}" >> /etc/crontab | |
| echo "Added certbot renewal to crontab (runs at midnight and noon with ${SLEEPTIME}s random delay)" | |
| else | |
| echo "Certbot renewal already exists in crontab, skipping..." | |
| fi | |
| echo "" | |
| echo "=== Setup Complete ===" | |
| echo "Certificate location: /etc/letsencrypt/live/${DOMAIN}/" | |
| echo "Certificate expires: $(date -d "+90 days" +%Y-%m-%d)" | |
| echo "Credentials file: ${CF_CREDS_FILE}" | |
| echo "" | |
| echo "Next steps:" | |
| echo "1. Test HTTPS access: https://${DOMAIN}" | |
| echo "2. Verify automatic renewal: certbot renew --dry-run" | |
| echo "3. Check crontab entry: cat /etc/crontab | grep certbot" | |
| echo "" | |
| echo "To run this script over SSH without uploading:" | |
| echo " ssh root@glkvm.local 'bash -s' < setup-certbot-glkvm.sh glkvm.example.com YOUR_CLOUDFLARE_API_TOKEN" |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A remote way to update glkvm
ssh root@glkvm.local 'bash -s' < setup-certbot-glkvm.sh glkvm.example.com YOUR_CLOUDFLARE_API_TOKEN