This blog post is run-book how to deploy NGINX web server with Automatic TLS certificate issuance and renewal leveraging Let’s Encrypt DNS Challenge via Active24 DNS provider.
This article describes how to deploy NGINX on FreeBSD with both HTTP and HTTPS support, where the TLS certificate is automatically issued and renewed using Let’s Encrypt, acme.sh, and the Active24 DNS API.
The solution uses the DNS-01 challenge, so the web server does not need to expose port 80 for certificate validation. This is useful for internal services, servers behind NAT, wildcard certificates, or environments where HTTP validation is not suitable.
Target Architecture
Internet
|
v
NGINX on FreeBSD
|
+-- HTTP on TCP/80
|
+-- HTTPS on TCP/443
|
v
TLS certificate
|
v
acme.sh renewal
|
v
Active24 DNS API
|
v
DNS-01 challenge
Prerequisites
You need the following:
- FreeBSD server
- Domain hosted in Active24 DNS
- Active24 API Key
- Active24 API Secret
- Root access to the FreeBSD server
- Internet access from the server
In this example I will use:
example.cz
Replace it with your real domain.
Install Required Packages
pkg update
pkg install -y nginx acme.sh
Enable NGINX:
sysrc nginx_enable="YES"
Enable cron, because acme.sh uses cron for automatic renewal:
sysrc cron_enable="YES"
service cron start
Verify cron:
service cron status
Create Web Root Directory
mkdir -p /usr/local/www/blog.uw.cz
Create a simple test page:
cat > /usr/local/www/blog.uw.cz/index.html <<EOF
<html>
<body>
<h1>NGINX on FreeBSD</h1>
</body>
</html>
EOF
Set ownership:
chown -R www:www /usr/local/www/example.czInstall Active24 hook
mkdir -p /root/.acme.sh/dnsapi
fetch -o /root/.acme.sh/dnsapi/dns_active24.sh \
https://raw.githubusercontent.com/acmesh-official/acme.sh/master/dnsapi/dns_active24.sh
chmod 600 /root/.acme.sh/dnsapi/dns_active24.sh
Configure Active24 API Credentials
To make Active24 API Credentials persistent for the root user, add them to:
/root/.profile
For example:
vi /root/.profile
Add:
export Active24_ApiKey="YOUR_API_KEY"
export Active24_ApiSecret="YOUR_API_SECRET"
Load the profile:
. /root/.profileIssue TLS Certificate Using Active24 DNS Challenge
Register account:
acme.sh \
--register-account \
-m david.pasek@gmail.com
Request a certificate using the Active24 DNS hook:
acme.sh \--issue \--dns dns_active24 \-d blog.uw.czThis command requests a certificate for a single service (blog.uw.cz).
The wildcard certificate for *.uw.cz is useful for services such as:
www.uw.cz
admin.uw.cz
grafana.uw.cz
cloud.uw.cz
... but not as secure as a single service.
During validation, acme.sh creates a temporary TXT record:
_acme-challenge.example.cz
The record is created through the Active24 API. After successful validation, Let’s Encrypt issues the certificate.
Install Certificate for NGINX
Create a directory for NGINX certificates:
mkdir -p /usr/local/etc/nginx/certs/blog.uw.cz
Install the certificate:
acme.sh \
--install-cert \
-d blog.uw.cz \
--key-file /usr/local/etc/nginx/certs/blog.uw.cz/key.pem \
--fullchain-file /usr/local/etc/nginx/certs/blog.uw.cz/fullchain.pem \
--reloadcmd "service nginx reload"
The important part is:
--reloadcmd "service nginx reload"
This means that after every successful certificate renewal, NGINX is reloaded automatically.
Configure NGINX
Edit the NGINX configuration file:
vi /usr/local/etc/nginx/nginx.conf
Example configuration:
worker_processes auto;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
server {
listen 80;
server_name blog.uw.cz;
root /usr/local/www/blog.uw.cz;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
server {
listen 443 ssl http2;
server_name blog.uw.cz;
ssl_certificate /usr/local/etc/nginx/certs/blog.uw.cz/fullchain.pem;
ssl_certificate_key /usr/local/etc/nginx/certs/blog.uw.cz/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
root /usr/local/www/blog.uw.cz;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
}
Validate the configuration:
nginx -t
Start NGINX:
service nginx start
Verify HTTP and HTTPS
Check that NGINX is listening on ports 80 and 443:
sockstat -4 -l | grep nginx
Test HTTPS certificate:
openssl x509 \
-in /usr/local/etc/nginx/certs/example.cz/fullchain.pem \
-noout \
-dates
You should see something like:
notBefore=...
notAfter=...
Open the site in a browser:
https://blog.uw.cz
Automatic Certificate Renewal
acme.sh usually installs a cron job automatically. Verify it:
crontab -l
You should see something similar to:
15 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
This job runs daily, but certificates are renewed only when they are close to expiration.
If cron job is not there, just add it ...
crontab -e
15 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/nullList managed certificates:
acme.sh --list
Test Renewal Manually
You can force a renewal test:
acme.sh \
--renew \
-d blog.uw.cz \
--ecc \
--force
Expected flow:
Renew certificate
Install renewed certificate
Reload NGINXConclusion
This setup provides a clean FreeBSD-based web service with NGINX, HTTP, HTTPS, automatic TLS certificate issuance, and automatic renewal using the Active24 DNS API.
The main advantage of the DNS-01 challenge is that certificate validation does not depend on public HTTP access. This makes the solution suitable for internal services, wildcard certificates, servers behind NAT, and enterprise-style deployments.
No comments:
Post a Comment