Creating SSL Certificates
These tutorials briefly cover creating a new SSL certificates for your panel and/or wings.
- Certbot
- Apache w/CloudFlare API
- Caddy w/CloudFlare API
This way is the most recommended and should work in 98% of setups.
To begin, we will install certbot, a simple script that automatically renews our certificates and allows much easier creation of them. The command below is for Ubuntu distributions, but you can always check Certbot's official site for installation instructions. We have also included a command below to install certbot's Nginx/Apache plugin so you won't have to stop your webserver.
- NGINX
- Apache
- Caddy / Other
sudo apt install -y python3-certbot-nginx
sudo apt install -y python3-certbot-apache
sudo apt install -y certbot
Creating a Certificate
After installing certbot, we need to generate a certificate. There are a couple of ways to do that, but the easiest is to use the web server-specific certbot plugin you just installed.
For Wings-only machines that don't need a web server, use the standalone or DNS method of the certbot as you don't need a web server for it.
Then, in the command below, you should replace example.com
with the domain you would like to generate a certificate
for. When you have multiple domains you would like certificates for, simply add more -d anotherdomain.com
flags to the
command. You can also look into generating a wildcard certificate but that is not covered in this tutorial.
When you are using certbot's Nginx/Apache plugin, you won't need to restart your webserver to have the certificate applied assuming that you've already configured the webservers to use SSL as instructed in the web server configuration step.
HTTP challenge
HTTP challenge requires you to expose port 80 for the challenge verification.
- NGINX
- Apache
- Standalone
certbot certonly --nginx -d example.com
certbot certonly --apache -d example.com
certbot certonly --standalone -d example.com
DNS challenge
DNS challenge requires you to create a new TXT DNS record to verify domain ownership, instead of having to expose port 80. The instructions are displayed when you run the certbot command below.
certbot -d example.com --manual --preferred-challenges dns certonly
Auto Renewal
You'll also probably want to configure the automatic renewal of certificates to prevent unexpected certificate expirations.
You can open crontab with sudo crontab -e
and add the line from below to the bottom of it for attempting renewal every day at 23 (11 PM).
Deploy hook would restart the Nginx service to apply a new certificate when it's renewed successfully. Change nginx
in the restart command to suit your own needs, such as to apache
or wings
.
For advanced users, we suggest installing and using acme.sh which provides more options, and is much more powerful than certbot.
0 23 * * * certbot renew --quiet --deploy-hook "systemctl restart nginx"
Troubleshooting
If you get an Insecure Connection
or SSL/TLS related error when trying to access your panel or wings, the certificate has likely expired.
This can be easily fixed by renewing the SSL certificate, although using the command certbot renew
might not do the job if port 80 is in use, as it'll return errors like: Error: Attempting to renew cert (domain) from /etc/letsencrypt/renew/domain.conf produced an unexpected error
.
This will happen especially if you're running Nginx instead of Apache. The solution for this is to use Nginx or Apache plugins with --nginx
and --apache
. Alternatively, you can stop Nginx, then renew the certificate, finally restart Nginx. Replace nginx
with your own web server or with wings
should you be renewing the certificate for Wings.
Stop Nginx:
systemctl stop nginx
Renew the certificate:
certbot renew
Once the process has completed, you can restart Nginx:
systemctl start nginx
You may also need to restart Wings as not every service is able to automatically apply an updated certificate:
systemctl restart wings
This is for advanced users, whose server systems do not have access to port 80. The command below is for Ubuntu distributions and CloudFlare API (you may google for other APIs for other DNS providers), but you can always check acme.sh's official site for installation instructions.
Make sure you read both instructions, as some people may have moved to CloudFlare's new authorization system (Modern), but other's have not (Legacy).
curl https://get.acme.sh | sh
- Legacy
- Modern
Obtaining CloudFlare API Key (Legacy)
After installing acme.sh, we need to fetch a CloudFlare API key.
On Cloudfare's website, select your domain, then on the right side, copy your "Zone ID" and "Account ID".
Click on "Get your API token", click on "Create Token" > select the template "Edit zone DNS" > select the scope of "Zone Resources"
Click on "Continue to summary", copy your token.
Creating a Certificate
Since the configuration file is based on Certbot, we need to create the folder manually.
sudo mkdir -p /etc/letsencrypt/live/example.com
After installing acme.sh and obtaining CloudFlare API key, we need to then generate a certificate. First input the CloudFlare API credentials.
export CF_Token="Your_CloudFlare_API_Key"
export CF_Account_ID="Your_CloudFlare_Account_ID"
export CF_Zone_ID="Your_CloudFlare_Zone_ID"
Obtaining CloudFlare API Key (Modern)
After installing acme.sh, we need to fetch a CloudFlare API key.
- Cloudfare's website, click on your profile on the top right.
- Go to "My Profile" --> "API Tokens".
- Click "Create Token" and use the "Edit zone DNS" template.
- Then once on the next page, goto "Zone Resources" and "Include" - "Specific Zone" - (Select the domain you want to use).
- Continue to the summery.
- Confirm you'd like to create the token.
Creating a Certificate
Since the configuration file is based on Certbot, we need to create the folder manually.
sudo mkdir -p /etc/letsencrypt/live/example.com
After installing acme.sh and obtaining CloudFlare API key, we need to then generate a certificate. First input the CloudFlare API credentials.
export CF_Key="Your_CloudFlare_API_Key"
export CF_Email="Your_CloudFlare_Email"
This is for advanced users, who are running Cloudflare in proxy mode or do not have access to port 80
.
Installing Caddy with Cloudflare DNS plugin
Caddy does not come by default with Cloudflare DNS plugin, you need to install it yourself.
There are two main methods:
- Using
xcaddy
- CLI tool to build your own Caddy build - Downloading prebuilt binary from Caddy's download page.
- Using Ansible to download and install Caddy with plugins. See caddy-ansible
Build Caddy using xcaddy
on your server
Please refer to Caddy docs on building Caddy.
Obtaining CloudFlare API Token
After installing acme.sh, we need to fetch a CloudFlare API key. Please make sure that a DNS record (A or CNAME record) is pointing to your target node, and set the cloud to grey (bypassing CloudFlare proxy). Then go to My Profile > API keys and on Global API Key subtab, click on "view", enter your CloudFlare password, and copy the API key to clipboard.
After install Caddy with Cloudflare DNS plugin, we need to fetch a Cloudflare API token. Please make sure that a DNS record (A or CNAME record) is pointing at your target node. Then go to My Profile > API Tokens and on API Tokens click "Create Token". Create API Token > API token templates, at the end of line with "Edit zone DNS", click "Use template". Under Zone Resources, select your DNS zone for which you wish to create the API token, click "Continue to summary". Review the API token summary and click "Create Token". Finally copy the API token to clipboard.
Reconfiguring Caddy to use Cloudflare DNS for obtaining certificates
Create an environment variable file (like .env
), keep in mind that this file contains secrets and should not be accessed by public.
We recommend that you create the secret file in the following location: /etc/caddy/.secrets.env
.
CLOUDFLARE_API_TOKEN=<cloudflare api token>
For security reasons, we recommend setting permissions to 0600
(only owner can read or write to the file).
# Set ownership of the `.secrets.env` file to `caddy` system user
chown caddy:caddy /etc/caddy/.secrets.env
# Set read-write permissions only to owner - the `caddy` system user
chmod 0600 /etc/caddy/.secrets.env
Modify the systemd unit file, to load environment variables from file (add --envfile /etc/caddy/.secrets.env
flag to ExecStart
), the default systemd unit file location is /etc/systemd/system/caddy.service
:
[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target
[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --envfile /etc/caddy/.secrets.env --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
You can add a tls
block to your Caddyfile
, under the <domain>
block of your panel configuration, the Caddy config file location is /etc/caddy/Caddyfile
:
<domain> {
# ...s
tls {
dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}
}