GuidesGuide

SSL Certificate for an IP Address with Let's Encrypt (Free, 2026)

For years, opening a control panel, an admin interface or an internal service at https://203.0.113.10 meant the browser's "Not secure" warning, because no free authority issued certificates for IP addresses. Since January 2026 Let's Encrypt issues free certificates for IPv4 and IPv6 addresses too: they are valid for about 6 days (160 hours), must be requested with the shortlived profile and are validated with an HTTP request on port 80 or TLS on port 443. Here's how to get one on Ubuntu, how to renew it without thinking about it, and what to watch out for.

How it differs from a regular certificate

Certificate for a domain Certificate for an IP
Lifetime 90 days (classic profile) 160 hours, about 6 days
ACME profile default shortlived, required
Validation HTTP, TLS or DNS HTTP (port 80) or TLS-ALPN (port 443); no DNS, an IP has no zone
Renewal about every 60 days every 2-3 days

The short lifetime is the thing to understand: an IP certificate without automatic renewal stops working in less than a week. It's not something to do by hand.

When you need it

  • the panel of a freshly created server, before it has a domain name;
  • phpMyAdmin, webmail or other interfaces on ports other than 443, opened by IP;
  • internal services or APIs called by address;
  • appliances and servers without DNS, as long as they are reachable from the Internet on port 80 or 443.

If the server is behind NAT with private addresses only (192.168.x.x, 10.x.x.x), Let's Encrypt can't reach it: you need the public address and port forwarding.

With certbot

IP address support arrived in certbot 5.4. The Ubuntu 24.04 package is older, so install the official snap:

sudo apt remove certbot
sudo snap install --classic certbot
sudo ln -sf /snap/bin/certbot /usr/bin/certbot
certbot --version

Then request the certificate. With a web server already on port 80, use webroot:

sudo certbot certonly --webroot -w /var/www/html \
  --preferred-profile shortlived \
  --ip-address 203.0.113.10 \
  --deploy-hook "systemctl reload nginx"

If nothing runs on port 80, --standalone instead of --webroot -w … briefly starts its own server. The nginx and apache plugins don't handle IP addresses yet: configure the certificate in the web server by hand, from the files in /etc/letsencrypt/live/203.0.113.10/:

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;
    # ...
}

Certbot's timer renews certificates by itself as they get close to expiry; the --deploy-hook reloads nginx after every renewal. Check with sudo certbot renew --dry-run.

With acme.sh

acme.sh supported IPs and profiles before certbot:

acme.sh --issue --server letsencrypt \
  --cert-profile shortlived --days 3 \
  -d 203.0.113.10 \
  --webroot /var/www/html

--days 3 tells acme.sh to renew after 3 days, halfway through the certificate's life, leaving room to retry if a renewal fails.

The traps

  • Port 80 closed: many cloud providers have a network firewall on top of the server's own. If port 80 doesn't reach the server, HTTP validation fails; TLS-ALPN on 443 is the alternative, but 443 must be free or handled by the ACME client.
  • Unreachable IPv6: if you request a certificate for IPv4 and IPv6 together and IPv6 doesn't answer, the whole request fails. Request it only for the addresses that really answer.
  • Renewal breaking silently: with a 6-day lifetime, a broken renewal becomes an unreachable site within days. Keep an eye on expiry, as explained in SSL certificates and backups that fail silently.
  • Let's Encrypt rate limits: many failed attempts in a short time lead to a temporary block. After an error, wait and fix it before retrying.

How Koapanel does it

Since version 0.30 Koapanel asks Let's Encrypt for the certificate of the server's IP address by itself, already during installation:

  • panel, phpMyAdmin and webmail open by IP without "Not secure";
  • renewal is automatic halfway through the certificate's life (about 3 days), or sooner if Let's Encrypt asks, with a different offset for each server;
  • validation uses port 80 or, if it's closed, 443; IPv6 is included only if it answers;
  • under Server › Security the "Panel certificate" box shows the type, expiry, last and next renewal, errors and a Renew now button; if the server is behind NAT it says so;
  • if issuance fails, the self-signed certificate stays, so the panel is always reachable;
  • alternatively you can give the panel a name of yours, like panel.mydomain.com, with a regular 90-day certificate, and send visitors of the IP to that name.

All the details are in the manual, section Panel certificate.

FAQ

Is the IP certificate really free?

Yes, like every Let's Encrypt certificate.

Can I get a 90-day certificate for an IP?

Not from Let's Encrypt: for IP addresses it issues only the shortlived profile, about 6 days.

Do I need a domain?

No, the IP address just has to be public and reachable on port 80 or 443.

Does it work for private addresses?

No. Let's Encrypt must reach the address from the Internet; internal networks need your own certificate authority.

Try Koapanel

Look around the public demo or install it on a fresh Ubuntu 24.04, free for up to 3 sites:

curl -fsSL https://get.koapanel.app | sudo bash

Try Koapanel on your server

One command on Ubuntu 24.04, free up to 3 sites. Are you a provider or an agency? Let's talk wholesale pricing and migrations.

More guides