{"id":5543,"date":"2026-01-17T11:10:49","date_gmt":"2026-01-17T16:10:49","guid":{"rendered":"https:\/\/underhost.com\/blog\/?p=5543"},"modified":"2026-01-17T11:10:49","modified_gmt":"2026-01-17T16:10:49","slug":"ssl-for-public-ips-guide-to-lets-encrypt-without-a-domain","status":"publish","type":"post","link":"https:\/\/underhost.com\/blog\/ssl-for-public-ips-guide-to-lets-encrypt-without-a-domain\/","title":{"rendered":"SSL for Public IPs: Guide to Let&#8217;s Encrypt Without a Domain"},"content":{"rendered":"<p><!-- Hero Section --><\/p>\n<div class=\"hero-section\" style=\"margin-bottom: 40px; text-align: center; padding: 20px 0;\">\n<h1 style=\"color: #2a5d84; font-size: 2.5em; margin-bottom: 10px;\">SSL for Public IPs: The Complete 2026 Guide<\/h1>\n<h2 style=\"color: #2a5d84; font-size: 2.2em; margin-bottom: 10px;\">How to Get Let&#8217;s Encrypt Certificates Without a Domain Name<\/h1>\n<p style=\"font-size: 1.2em; color: #555;\">Unlock secure, HTTPS-encrypted connections for your API gateways, staging servers, and internal tools using only a public IP address and SSH access.<\/p>\n<\/div>\n<div class=\"excerpt\" style=\"border-left: 3px solid #2b6cce; padding-left: 15px; font-style: italic;\"><strong>For DevOps engineers and system administrators, the ability to secure a service at the IP level is a game-changer.<\/strong> Forget the complexities of DNS for internal projects. This definitive guide walks you through installing, configuring, and automating Let&#8217;s Encrypt IP-based SSL certificates on any Linux server with a public IP.<\/div>\n<hr \/>\n<div class=\"post-content\">\n<h2><i class=\"fas fa-server\" style=\"color: #ff6b00;\"><\/i> Why IP-Based SSL is a DevOps Essential<\/h2>\n<p>The need for encrypted traffic isn&#8217;t limited to public-facing websites with pretty domain names. Modern infrastructure relies heavily on secure, machine-to-machine communication where a domain name is an unnecessary abstraction. Think about:<\/p>\n<ul>\n<li><strong>API Gateway Security:<\/strong> Securing backend APIs accessed directly by IP during development or within a private network segment.<\/li>\n<li><strong>Staging &#038; Testing Environments:<\/strong> Configuring HTTPS for pre-production servers before DNS records are pointed to them.<\/li>\n<li><strong>IoT &#038; Embedded Systems:<\/strong> Devices or appliances that have a public IP but no associated domain name require encryption for management interfaces.<\/li>\n<li><strong>Ephemeral Infrastructure:<\/strong> Containers or temporary cloud instances spun up for a specific task that need immediate, trusted SSL.<\/li>\n<\/ul>\n<p>Historically, securing an IP required expensive, manually-issued certificates. The introduction of Let&#8217;s Encrypt&#8217;s IP certificate capability changed everything, but with a crucial caveat: <strong>6-day validity periods.<\/strong> This isn&#8217;t a limitation\u2014it&#8217;s a design feature for automation-first security, perfectly aligning with Infrastructure-as-Code (IaC) principles.<\/p>\n<blockquote style=\"background: #f8fafc; border-left: 4px solid #2a5d84; padding: 15px; margin: 20px 0;\">\n<h3 style=\"margin-top: 0; color: #2a5d84;\">The UnderHost Infrastructure Advantage<\/h3>\n<p>When you run this setup on an <a href=\"https:\/\/underhost.com\/cloud-vps.php\" style=\"color: #2a5d84; font-weight: bold;\">UnderHost Cloud VPS<\/a> or <a href=\"https:\/\/underhost.com\/dedicated-servers-offshore.php\" style=\"color: #2a5d84; font-weight: bold;\">Dedicated Server<\/a>, you&#8217;re building on a foundation of 10Gbps connectivity, enterprise-grade DDoS protection, and 99.9% uptime. Our global network ensures the HTTP-01 validation challenge\u2014essential for IP certificates\u2014is fast and reliable, removing a common point of failure.<\/p>\n<\/blockquote>\n<h2><i class=\"fas fa-clipboard-check\" style=\"color: #2b6cce;\"><\/i> The Non-Negotiable Prerequisites<\/h2>\n<p>Success with IP-based SSL hinges on meeting specific server and network conditions. Let&#8217;s validate your environment.<\/p>\n<div style=\"background: #f0f8ff; padding: 20px; border-radius: 8px; margin: 20px 0; border: 1px solid #cfe2ff;\">\n<h3 style=\"color: #2a5d84; margin-top: 0;\"><i class=\"fas fa-list-check\"><\/i> Mandatory Checklist<\/h3>\n<ul>\n<li><strong>&#x2705; Public, Routable IP:<\/strong> The IP must be publicly accessible on the internet. <strong>NAT, private IPs (like 10.x.x.x, 192.168.x.x), or cloud provider internal IPs will not work.<\/strong> Verify with:<br \/>\n<code style=\"background: #e9ecef; padding: 5px 10px; border-radius: 4px; display: inline-block; margin-top: 5px;\">curl -4 ifconfig.me<\/code><\/li>\n<li><strong>&#x2705; Open Ports 80 &#038; 443:<\/strong> Let&#8217;s Encrypt must validate your control over the IP via HTTP on port 80. Ensure your firewall (e.g., <code>ufw<\/code>, <code>firewalld<\/code>, <code>iptables<\/code>) allows inbound connections on these ports.<\/li>\n<li><strong>&#x2705; No Proxy\/CDN in Front:<\/strong> The validation request must hit your server directly. If you use Cloudflare (in proxy mode) or another CDN that terminates SSL before your IP, it will block validation.<\/li>\n<li><strong>&#x2705; Root or Sudo SSH Access:<\/strong> You need elevated privileges to install packages, stop\/start the web server, and modify its configuration.<\/li>\n<li><strong>&#x2705; Compatible OS:<\/strong> Ubuntu 20.04+, Debian 11+, AlmaLinux 8+, Rocky Linux 8+.<\/li>\n<\/ul>\n<\/div>\n<h2><i class=\"fas fa-terminal\" style=\"color: #9c27b0;\"><\/i> Step-by-Step: Installation &#038; Configuration via SSH<\/h2>\n<p>This is a hands-on walkthrough. Connect to your server via SSH and follow each step.<\/p>\n<h3>Step 1: Install Certbot<\/h3>\n<p>The tool of choice is Certbot, the official Let&#8217;s Encrypt client.<\/p>\n<p><strong>For Ubuntu\/Debian:<\/strong><\/p>\n<pre style=\"background: #2d3748; color: #e2e8f0; padding: 15px; border-radius: 5px; overflow: auto;\">\r\n<code>sudo apt update && sudo apt install -y certbot<\/code><\/pre>\n<p><strong>For AlmaLinux\/Rocky:<\/strong><\/p>\n<pre style=\"background: #2d3748; color: #e2e8f0; padding: 15px; border-radius: 5px; overflow: auto;\">\r\n<code>sudo dnf install -y epel-release\r\nsudo dnf install -y certbot<\/code><\/pre>\n<h3>Step 2: Temporarily Free Port 80<\/h3>\n<p>Certbot&#8217;s &#8220;standalone&#8221; mode for IP validation needs to bind to port 80. You must stop your web server for a few seconds.<\/p>\n<pre style=\"background: #2d3748; color: #e2e8f0; padding: 15px; border-radius: 5px; overflow: auto;\">\r\n<code># For Nginx:\r\nsudo systemctl stop nginx\r\n\r\n# For Apache:\r\nsudo systemctl stop apache2   # or httpd on some systems<\/code><\/pre>\n<h3>Step 3: Request the Certificate<\/h3>\n<p>Replace <code>YOUR_PUBLIC_IP<\/code> with your actual IP address. For an IPv6 address, use it directly without brackets in this command.<\/p>\n<pre style=\"background: #2d3748; color: #e2e8f0; padding: 15px; border-radius: 5px; overflow: auto;\">\r\n<code>sudo certbot certonly --standalone \\\r\n  --preferred-challenges http \\\r\n  --agree-tos \\\r\n  --register-unsafely-without-email \\\r\n  -d YOUR_PUBLIC_IP<\/code><\/pre>\n<p>If successful, you&#8217;ll see a confirmation with the certificate paths. They will be in <code>\/etc\/letsencrypt\/live\/YOUR_PUBLIC_IP\/<\/code>.<\/p>\n<h3>Step 4: Configure Your Web Server<\/h3>\n<p>Now, point your web server to the new certificate files. <strong>Restart your web server first:<\/strong> <code>sudo systemctl start nginx<\/code> (or <code>apache2<\/code>).<\/p>\n<p><strong>Nginx Configuration Snippet:<\/strong> Add this to your server block (e.g., in <code>\/etc\/nginx\/sites-available\/default<\/code> or a new file in <code>\/etc\/nginx\/conf.d\/<\/code>).<\/p>\n<pre style=\"background: #2d3748; color: #e2e8f0; padding: 15px; border-radius: 5px; overflow: auto;\">\r\n<code>server {\r\n    listen 443 ssl;\r\n    server_name YOUR_PUBLIC_IP; # Use your actual IP\r\n\r\n    ssl_certificate \/etc\/letsencrypt\/live\/YOUR_PUBLIC_IP\/fullchain.pem;\r\n    ssl_certificate_key \/etc\/letsencrypt\/live\/YOUR_PUBLIC_IP\/privkey.pem;\r\n\r\n    # ... your root, index, and other directives ...\r\n}<\/code><\/pre>\n<p><strong>Apache Configuration Snippet:<\/strong> Ensure the SSL module is enabled (<code>sudo a2enmod ssl<\/code>), then configure a virtual host.<\/p>\n<pre style=\"background: #2d3748; color: #e2e8f0; padding: 15px; border-radius: 5px; overflow: auto;\">\r\n<code>&lt;VirtualHost *:443&gt;\r\n    ServerName YOUR_PUBLIC_IP\r\n    SSLEngine on\r\n    SSLCertificateFile \/etc\/letsencrypt\/live\/YOUR_PUBLIC_IP\/fullchain.pem\r\n    SSLCertificateKeyFile \/etc\/letsencrypt\/live\/YOUR_PUBLIC_IP\/privkey.pem\r\n    # ... your DocumentRoot and other directives ...\r\n&lt;\/VirtualHost&gt;<\/code><\/pre>\n<p>After editing, test your config (<code>sudo nginx -t<\/code> or <code>sudo apachectl configtest<\/code>) and reload (<code>sudo systemctl reload nginx<\/code> or <code>apache2<\/code>).<\/p>\n<h3>Step 5: Test the SSL Connection<\/h3>\n<pre style=\"background: #2d3748; color: #e2e8f0; padding: 15px; border-radius: 5px; overflow: auto;\">\r\n<code>curl -vI https:\/\/YOUR_PUBLIC_IP<\/code><\/pre>\n<p>You should see the SSL handshake succeed. You can also visit <code>https:\/\/YOUR_PUBLIC_IP<\/code> in a browser (you&#8217;ll likely get a privacy warning because the IP is not a domain, but you can view the certificate details).<\/p>\n<h2><i class=\"fas fa-robot\" style=\"color: #4caf50;\"><\/i> The Critical Step: Automating Renewal (6-Day Certs)<\/h2>\n<p>This is not optional. Let&#8217;s Encrypt IP certificates expire in <strong>6 days<\/strong>. Manual renewal is unsustainable. The solution is a cron job that renews daily.<\/p>\n<p>First, create a renewal script that safely stops the web server, runs the renewal, and starts it again. The <code>certbot renew<\/code> command only renews certificates that are near expiry.<\/p>\n<pre style=\"background: #2d3748; color: #e2e8f0; padding: 15px; border-radius: 5px; overflow: auto;\">\r\n<code>sudo nano \/usr\/local\/bin\/le-ip-renew.sh<\/code><\/pre>\n<p>Paste the following script:<\/p>\n<pre style=\"background: #2d3748; color: #e2e8f0; padding: 15px; border-radius: 5px; overflow: auto;\">\r\n<code>#!\/bin\/bash\r\n# Stop web server\r\nsystemctl stop nginx 2>\/dev\/null || systemctl stop apache2 2>\/dev\/null || systemctl stop httpd 2>\/dev\/null\r\n\r\n# Renew certificates if they are due\r\ncertbot renew --quiet --non-interactive --post-hook \"systemctl start nginx 2>\/dev\/null || systemctl start apache2 2>\/dev\/null || systemctl start httpd 2>\/dev\/null\"\r\n\r\n# Start web server (post-hook handles this, but this is a safety net)\r\nsystemctl start nginx 2>\/dev\/null || systemctl start apache2 2>\/dev\/null || systemctl start httpd 2>\/dev\/null<\/code><\/pre>\n<p>Make it executable and add a daily cron job:<\/p>\n<pre style=\"background: #2d3748; color: #e2e8f0; padding: 15px; border-radius: 5px; overflow: auto;\">\r\n<code>sudo chmod +x \/usr\/local\/bin\/le-ip-renew.sh\r\nsudo crontab -e<\/code><\/pre>\n<p>Add this line to run the script daily at 3 AM (choose a low-traffic time):<\/p>\n<pre style=\"background: #2d3748; color: #e2e8f0; padding: 15px; border-radius: 5px; overflow: auto;\">\r\n<code>0 3 * * * \/usr\/local\/bin\/le-ip-renew.sh > \/dev\/null 2>&1<\/code><\/pre>\n<h2><i class=\"fas fa-headset\" style=\"color: #ff9800;\"><\/i> When To Let UnderHost Handle It<\/h2>\n<p>This guide empowers you to manage SSL for IPs yourself. However, if your time is better spent on core development, or you need this scaled across multiple servers, our <strong><a href=\"https:\/\/customerpanel.ca\/client\/store\/server-management\">UnderManagement<\/a><\/strong> service is the answer.<\/p>\n<div style=\"display: flex; flex-wrap: wrap; gap: 20px; justify-content: center; margin: 30px 0;\">\n<div style=\"flex: 1; min-width: 250px; background: #f8fafc; padding: 25px; border-radius: 8px; border-top: 3px solid #d82c20; box-shadow: 0 3px 10px rgba(0,0,0,0.05);\">\n<h3 style=\"color: #2a5d84; font-size: 1.2em; margin-top: 0; text-align: center;\">For the Hands-On DevOps<\/h3>\n<ul style=\"text-align: left; padding-left: 20px;\">\n<li>Follow the guide above.<\/li>\n<li>Leverage our <a href=\"https:\/\/underhost.com\/cloud-vps.php\">high-performance VPS<\/a> as your foundation.<\/li>\n<li>Use <a href=\"https:\/\/customerpanel.ca\/client\">@CustomerPanel<\/a> for any network or hardware queries.<\/li>\n<\/ul>\n<\/div>\n<div style=\"flex: 1; min-width: 250px; background: #f8fafc; padding: 25px; border-radius: 8px; border-top: 3px solid #2a5d84; box-shadow: 0 3px 10px rgba(0,0,0,0.05);\">\n<h3 style=\"color: #2a5d84; font-size: 1.2em; margin-top: 0; text-align: center;\">For Teams Focused on Scale<\/h3>\n<ul style=\"text-align: left; padding-left: 20px;\">\n<li>Offload SSL management entirely to our experts.<\/li>\n<li>Get 24\/7 monitoring, backup, and security hardening.<\/li>\n<li>Ideal for <a href=\"https:\/\/underhost.com\/dedicated-servers-offshore.php\">dedicated server<\/a> deployments.<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<p><!-- CTA Section --><\/p>\n<div class=\"pricing-cta\" style=\"background: linear-gradient(135deg, #2a5d84 0%, #1e3c72 100%); color: white; padding: 30px; border-radius: 10px; text-align: center; margin: 40px 0;\">\n<h2 style=\"margin-top: 0; font-size: 1.8em;\">Build on a Secure, High-Performance Foundation<\/h2>\n<p style=\"font-size: 1.2em; margin-bottom: 20px;\">Whether you DIY or opt for full management, start with infrastructure you can trust.<\/p>\n<p><a style=\"background: #d82c20; color: white; padding: 12px 30px; border-radius: 5px; text-decoration: none; font-weight: bold; display: inline-block; font-size: 1.1em; margin: 10px;\" href=\"https:\/\/underhost.com\/cloud-vps.php\">Deploy a Cloud VPS<\/a><br \/>\n<a style=\"background: transparent; color: white; padding: 12px 30px; border-radius: 5px; text-decoration: none; font-weight: bold; display: inline-block; font-size: 1.1em; margin: 10px; border: 2px solid white;\" href=\"https:\/\/customerpanel.ca\/client\/store\/server-management\">Explore Managed Services<\/a>\n<\/div>\n<p><!-- FAQ --><\/p>\n<div class=\"faq-section\" style=\"margin-bottom: 30px;\">\n<h2 style=\"color: #2a5d84; font-size: 1.8em; border-bottom: 2px solid #f0f0f0; padding-bottom: 10px;\">SSL for IPs: Frequently Asked Questions<\/h2>\n<div style=\"margin-top: 20px;\">\n<h3 style=\"color: #d82c20;\">Q: Can I get a wildcard certificate for an IP range?<\/h3>\n<p>No. Let&#8217;s Encrypt does not issue wildcard certificates for IP addresses. You must validate and obtain a certificate for each individual public IP address.<\/p>\n<\/div>\n<div style=\"margin-top: 20px;\">\n<h3 style=\"color: #d82c20;\">Q: Why does my browser still show a &#8220;Not Secure&#8221; warning?<\/h3>\n<p>This is normal for IP-based certificates. The warning is related to <strong>domain name validation<\/strong>, not the encryption itself. The padlock in the URL bar and the SSL\/TLS connection are fully encrypted. Browsers expect a domain name, not an IP, in the certificate&#8217;s Subject Alternative Name (SAN) field. Advanced users and API clients will trust the connection.<\/p>\n<\/div>\n<div style=\"margin-top: 20px;\">\n<h3 style=\"color: #d82c20;\">Q: What if I&#8217;m behind a restrictive firewall that blocks port 80?<\/h3>\n<p>You cannot use the HTTP-01 challenge method required for IP certificates. Your only alternative is to use a traditional domain-based certificate (even if it points to an IP) and validate it via the DNS-01 challenge, which doesn&#8217;t require an open port 80.<\/p>\n<\/div>\n<div style=\"margin-top: 20px;\">\n<h3 style=\"color: #d82c20;\">Q: Does this work on UnderHost&#8217;s Offshore Servers?<\/h3>\n<p>Absolutely. The process is identical whether your <a href=\"https:\/\/underhost.com\/dedicated-servers-offshore.php\" style=\"color: #2a5d84;\">offshore dedicated server<\/a> is in the Caribbean, Hong Kong, or our Bulletproof Datacenter. Our network is configured to allow the necessary validation traffic.<\/p>\n<\/div>\n<div style=\"margin-top: 20px;\">\n<h3 style=\"color: #d82c20;\">Q: I hit an error during validation. What should I check?<\/h3>\n<p>First, triple-check the prerequisites: public IP, open port 80, no CDN. Then, look at the specific Certbot error. Common issues include another process (like a forgotten <code>certbot<\/code> instance) already using port 80, or a firewall rule on your server or at the datacenter level. Our support team via <a href=\"https:\/\/customerpanel.ca\/client\" style=\"color: #2a5d84;\">@CustomerPanel<\/a> can assist with network-level diagnostics.<\/p>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>For DevOps engineers and system administrators, the ability to secure a service at the IP level is a game-changer. Forget DNS complexities for internal projects. This definitive guide walks you through installing, configuring, and automating Let&#8217;s Encrypt IP-based SSL certificates on any Linux server with a public IP.<\/p>\n","protected":false},"author":1,"featured_media":5436,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16,1,11,24,29,20,80],"tags":[],"class_list":["post-5543","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-articles","category-news","category-how-to","category-install","category-ip","category-ssh","category-ssl"],"_links":{"self":[{"href":"https:\/\/underhost.com\/blog\/wp-json\/wp\/v2\/posts\/5543","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/underhost.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/underhost.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/underhost.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/underhost.com\/blog\/wp-json\/wp\/v2\/comments?post=5543"}],"version-history":[{"count":2,"href":"https:\/\/underhost.com\/blog\/wp-json\/wp\/v2\/posts\/5543\/revisions"}],"predecessor-version":[{"id":5546,"href":"https:\/\/underhost.com\/blog\/wp-json\/wp\/v2\/posts\/5543\/revisions\/5546"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/underhost.com\/blog\/wp-json\/wp\/v2\/media\/5436"}],"wp:attachment":[{"href":"https:\/\/underhost.com\/blog\/wp-json\/wp\/v2\/media?parent=5543"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/underhost.com\/blog\/wp-json\/wp\/v2\/categories?post=5543"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/underhost.com\/blog\/wp-json\/wp\/v2\/tags?post=5543"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}