For years the answer to “can I get a free, trusted SSL certificate for a bare IP address?” was no. That changed in January 2026, when Let’s Encrypt made IP address certificates generally available, for both IPv4 and IPv6. This guide covers that option, when a domain is still the better choice, and the fallbacks for internal services.
Your Options at a Glance
| Situation | Best option |
|---|---|
| Public website or API people will remember | A domain name with a normal Let’s Encrypt certificate |
| A service reached only by IP — an API endpoint, a panel, a VPN portal | A Let’s Encrypt IP address certificate |
| Testing, or traffic between your own servers | Self-signed certificate or a private CA |
Option 1 — A Let’s Encrypt Certificate for Your IP
Let’s Encrypt now issues certificates whose subject is an IP address. Three things are different from a domain certificate:
- They are short-lived: valid for 160 hours, just over six days, so renewal must be fully automatic.
- They use the
shortlivedprofile, which you have to request explicitly. - Validation is HTTP-01 or TLS-ALPN-01 only — Let’s Encrypt must reach the IP itself on port 80 or 443. DNS validation cannot prove control of an address.
The IP must be yours alone and stay yours. Every VPS For Life plan includes a dedicated IPv4 address, which is exactly what this needs; a shared or NAT address will not work.
Step 1 — Install a Current Certbot
IP address support arrived in Certbot 5.3, and webroot support for IP addresses in 5.4. Distribution packages are often older, so install Certbot from the snap or with pip, and check the version:
certbot --version
Step 2 — Serve a Webroot on Port 80
With Nginx, a minimal server block for the IP:
server {
listen 80;
server_name 203.0.113.10;
location /.well-known/acme-challenge/ { root /var/www/acme; }
}
sudo mkdir -p /var/www/acme
sudo nginx -t && sudo systemctl reload nginx
Make sure port 80 is open in the firewall.
Step 3 — Request the Certificate
Test against the staging server first, then drop --staging:
sudo certbot certonly --staging \
--preferred-profile shortlived \
--webroot --webroot-path /var/www/acme \
--ip-address 203.0.113.10
The files are written to /etc/letsencrypt/live/203.0.113.10/.
Step 4 — Use It, and Reload on Renewal
At the time of writing, Certbot obtains IP certificates but its Nginx and Apache installers do not configure them, so point your web server at the files yourself:
server {
listen 443 ssl;
server_name 203.0.113.10;
ssl_certificate /etc/letsencrypt/live/203.0.113.10/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/203.0.113.10/privkey.pem;
}
Because the certificate lasts about six days, the web server must reload after every renewal. Add a deploy hook:
sudo certbot reconfigure --cert-name 203.0.113.10 --deploy-hook "systemctl reload nginx"
sudo certbot renew --dry-run
Certbot’s timer runs twice a day and renews well before expiry. Check it is active with systemctl list-timers | grep certbot (or snap.certbot).
Option 2 — Use a Domain Name
For anything public, a domain is still better: people can remember it, you can move the service to a new server without new certificates for clients, and certificates last 90 days rather than six. Point an A record at your VPS — see How to Point a Domain to Your VPS — and Certbot’s Nginx or Apache plugin does the rest. A subdomain from a dynamic DNS provider works the same way if you do not want to buy a domain.
Option 3 — Self-Signed Certificate
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout selfsigned.key -out selfsigned.crt \
-subj "/CN=203.0.113.10" -addext "subjectAltName=IP:203.0.113.10"
Traffic is encrypted, but browsers warn every visitor because no trusted authority issued it. Fine for testing and for connections between systems you control, where you can pin or trust the certificate on the client. Not for anything public.
Option 4 — A Private Certificate Authority
If many of your own servers talk to each other, a private CA (for example with step-ca) issues certificates for internal addresses and you install its root certificate on your clients once. More setup, no browser warnings inside your own environment.
Common Problems
“Invalid identifier” or a profile error — Certbot is too old, or --preferred-profile shortlived is missing. IP certificates are only issued on that profile.
Challenge fails with a connection error — port 80 is closed in the firewall, or another service answers on it. Test from outside with curl http://203.0.113.10/.well-known/acme-challenge/test.
The site shows an expired certificate after a week — the certificate renewed but the web server was never reloaded. Add the deploy hook from Step 4.
It works on IPv4 but not IPv6 — request the IPv6 address separately with another --ip-address, and make sure your server and firewall answer on it.
FAQ
Is an IP certificate as secure as a domain certificate?
The encryption is the same. The difference is what it identifies, and that it must renew far more often.
Will this work on any VPS?
Only where the public IP is yours and reaches your server directly, as with a dedicated IPv4 address.
Continue Reading
- How to Install Let’s Encrypt SSL with Certbot (Nginx & Apache)
- Common SSL Certificate Errors and How to Fix Them
- How to Build and Secure a REST API on a VPS
- IPv6 VPS
Browse more articles in SSL/TLS & Certificates.