A bash script to automatically configure SSL certificates for Proxmox VE and Proxmox Backup Server using Proxmox's built-in ACME functionality with Cloudflare DNS-01 challenge.
This script automates the process of:
- Connecting to Proxmox API (local or remote)
- Registering ACME account with Let's Encrypt
- Configuring Cloudflare DNS challenge plugin
- Ordering SSL certificates via Proxmox's built-in ACME
- Verifying certificate installation and functionality
- Local access: Must be run as root directly on the Proxmox host (uses
pveshfor authentication) - Remote access: Requires a Proxmox API token (
-k) and API URL (-a) - Internet Connectivity: Required for Let's Encrypt certificate requests
- Tools:
curlandjqmust be installed.pveshis required for local access (included with Proxmox).
- Proxmox VE or Proxmox Backup Server must be installed and running
- Domain must point to the server's IP address
- Proxmox must be accessible via the domain name
- Proxmox API must be accessible (local or remote)
- Cloudflare account with the domain
- API token with the following permissions:
Zone:Read- to read zone informationDNS:Edit- to create/delete DNS records for DNS-01 challenge
-
Download the script to your Proxmox server:
wget https://raw.githubusercontent.com/matthew-on-git/proxmox-ssl-setup/refs/heads/master/setup-proxmox-ssl.sh chmod +x setup-proxmox-ssl.sh
-
Create Cloudflare API Token:
- Log into Cloudflare dashboard
- Go to "My Profile" → "API Tokens"
- Click "Create Token"
- Use "Custom token" template
- Set permissions:
Zone:Read,DNS:Edit - Select your domain zone
- Create and copy the token
sudo ./setup-proxmox-ssl.sh -d <domain> -e <email> -t <cf_token> -p <proxmox_type>| Argument | Short | Description | Example |
|---|---|---|---|
--domain |
-d |
Proxmox domain name | proxmox.example.com |
--email |
-e |
Email for Let's Encrypt registration | admin@example.com |
--cf-token |
-t |
Cloudflare API token | your_api_token_here |
--proxmox-type |
-p |
Proxmox installation type | ve or pbs |
| Argument | Short | Description | Example |
|---|---|---|---|
--api-url |
-a |
Proxmox API URL | https://proxmox.example.com:8006 |
--api-token |
-k |
Proxmox API token | user@pam!tokenid=secret |
For Proxmox VE installation (local):
sudo ./setup-proxmox-ssl.sh \
-d proxmox.example.com \
-e admin@example.com \
-t your_cloudflare_api_token \
-p veFor Proxmox VE installation (remote):
./setup-proxmox-ssl.sh \
-d proxmox.example.com \
-e admin@example.com \
-t your_cloudflare_api_token \
-p ve \
-a https://proxmox.example.com:8006 \
-k user@pam!tokenid=secretFor Proxmox Backup Server installation (remote):
./setup-proxmox-ssl.sh \
-d pbs.example.com \
-e admin@example.com \
-t your_cloudflare_api_token \
-p pbs \
-a https://pbs.example.com:8007 \
-k user@pam!tokenid=secretShow help:
./setup-proxmox-ssl.sh --help- Verifies API access (root for local or API token for remote)
- Checks required tools (curl, jq)
- Tests Proxmox API connectivity
- Displays Proxmox version
- Registers ACME account with Let's Encrypt
- Uses Proxmox's built-in ACME client
- Handles existing account scenarios gracefully
- Configures Cloudflare DNS challenge plugin
- Stores Cloudflare API token securely in Proxmox
- Uses Proxmox's native plugin system
- Orders SSL certificate via Proxmox API
- Uses DNS-01 challenge with Cloudflare
- Leverages Proxmox's built-in certificate management
- Checks certificate status via API
- Verifies HTTPS connectivity
- Displays certificate information
- Confirms successful installation
- Proxmox handles certificate renewal automatically
- No external scripts or cron jobs needed
- Built-in ACME client manages renewal process
The script configures Proxmox's built-in ACME functionality:
- ACME account registration with Let's Encrypt
- Cloudflare DNS challenge plugin configuration
- Certificate ordering and management via Proxmox API
- Certificates are managed by Proxmox's native ACME client
- No manual file copying or permission setting required
- Automatic renewal handled by Proxmox
When running locally, the script uses pvesh which maps to these same API paths. When running remotely, curl is used with the full URL.
| Endpoint | Method | Purpose |
|---|---|---|
/version |
GET | Check Proxmox connectivity |
/cluster/acme/account |
POST | Register ACME account |
/cluster/acme/plugins |
POST | Configure challenge plugin |
/nodes/{node}/config |
PUT | Configure ACME domain on node |
/nodes/{node}/certificates/acme/certificate |
POST | Order certificate |
/nodes/{node}/certificates/info |
GET | Check certificate status |
- Proxmox VE: Uses port 8006 (HTTPS)
- Proxmox Backup Server: Uses port 8007 (HTTPS)
1. API Connection Issues
# Check local Proxmox connectivity (run as root on the Proxmox host)
pvesh get /version --output-format json
# For remote access, verify API token
curl -k -H "Authorization: PVEAPIToken=user@pam!tokenid=secret" \
https://proxmox:8006/api2/json/version2. Cloudflare API Token Issues
- Verify token has correct permissions (Zone:Read, DNS:Edit)
- Check token is not expired
- Ensure domain is managed by Cloudflare
3. ACME Account Registration Issues
- Check if account already exists
- Verify email address is valid
- Ensure Let's Encrypt API is accessible
4. Certificate Ordering Issues
- Verify domain points to server IP
- Check DNS propagation
- Ensure Cloudflare plugin is configured correctly
# Local (run as root on Proxmox host)
pvesh get /nodes/proxmox/certificates/info --output-format json
# Remote (via API token)
curl -k -H "Authorization: PVEAPIToken=user@pam!tokenid=secret" \
https://proxmox:8006/api2/json/nodes/proxmox/certificates/info
# Via Proxmox GUI
# Datacenter → ACME → Accounts
# System → Certificates# Local: configure ACME domain and order certificate
pvesh set /nodes/proxmox/config \
--acmedomain0 "domain=proxmox.example.com,plugin=cloudflare" \
--acme "account=letsencrypt"
pvesh create /nodes/proxmox/certificates/acme/certificate --force 1
# Remote: same steps via curl with API token
curl -k -X PUT https://proxmox:8006/api2/json/nodes/proxmox/config \
-H "Authorization: PVEAPIToken=user@pam!tokenid=secret" \
-d "acmedomain0=domain=proxmox.example.com,plugin=cloudflare" \
-d "acme=account=letsencrypt"
curl -k -X POST https://proxmox:8006/api2/json/nodes/proxmox/certificates/acme/certificate \
-H "Authorization: PVEAPIToken=user@pam!tokenid=secret" \
-d "force=1"# For Proxmox VE
journalctl -u pveproxy
journalctl -u pvedaemon
# For Proxmox Backup Server
journalctl -u proxmox-backup-proxy# For Proxmox VE
systemctl status pveproxy pvedaemon
# For Proxmox Backup Server
systemctl status proxmox-backup-proxy- Cloudflare credentials are stored securely in Proxmox's configuration
- API tokens are handled securely and not stored in files
- Certificates are automatically renewed by Proxmox's built-in ACME client
- No external scripts or cron jobs required
- All operations use Proxmox's native security model
This script leverages Proxmox's built-in ACME functionality:
- Native Integration: Uses Proxmox's built-in certificate management
- Simplified Management: Certificates managed through Proxmox GUI
- Automatic Renewal: No external scripts or cron jobs needed
- Remote Support: Can manage certificates on remote Proxmox instances
- Better Error Handling: Uses Proxmox's native error reporting
- No External Dependencies: No need for certbot or additional packages
For issues and questions:
- Check the troubleshooting section above
- Review Proxmox and Let's Encrypt documentation
- Check script logs for error messages
- Verify all prerequisites are met
This script is part of the proxmox-ssl-setup project. See the main project LICENSE file for details.