FugokuFugoku Docs
Mask

Domains & SSL

Point custom domains to Fugoku and configure TLS with Let's Encrypt or your own certificate

Domains & SSL

Fugoku does not sell domain names — use any external registrar (Namecheap, Cloudflare Registrar, Google Domains, Porkbun, etc.) and point DNS records to Fugoku. Once your domain resolves to a Fugoku IP, you can terminate TLS at a load balancer or directly on an instance with certbot and Let's Encrypt.

Overview

StepWhatWho
1. Register domainBuy from any registrarYou
2. Point DNSA/AAAA record → Fugoku Elastic IPYou (at registrar)
3. Get TLS certificateFree via Let's Encrypt, or bring your ownFugoku LB / your instance
4. Terminate TLSAt the load balancer or on the instanceYou

Free TLS option: Let's Encrypt issues 90-day certificates automatically via certbot. With the --renew hook, renewal is fully automated.


Step 1: Register Your Domain

Pick any registrar. Common options:

RegistrarNotes
Cloudflare RegistrarAt-cost pricing, integrates with Cloudflare DNS
PorkbunFree WHOIS privacy, low cost
NamecheapWide TLD selection
Google DomainsSimple UI, Google Workspace integration
HoverClean interface, no upsells
GandiEthical registrar

Buy your domain and note where its DNS is hosted (often the registrar, but you can move DNS to Cloudflare, Route 2, or any authoritative DNS provider).


Step 2: Reserve a Fugoku IP

Reserve a static public IP to point your domain at. Fugoku Elastic IPs are BGP-anycast with DDoS protection and survive instance recreation.

# Reserve an IPv4
fugoku eips reserve --region ashburn-1 --ipv4
# Output: Reserved 203.0.113.50

# Or IPv6 /64 block
fugoku eips reserve --region ashburn-1 --ipv6

Tip: Use an Elastic IP rather than a server's ephemeral public IP — if the instance restarts or is replaced, the Elastic IP persists and you don't need to update DNS.


Step 3: Point DNS to Your Fugoku IP

In your registrar or DNS provider, create an A record (IPv4) or AAAA record (IPv6):

TypeHostValueTTL
A@203.0.113.50300
Awww203.0.113.50300
Aapi203.0.113.50300

For apex domains (example.com), some providers require an ALIAS/ANAME or CNAME flattening record (Cloudflare supports this; Route 2 supports ALIAS).

Verify Propagation

dig +short a.example.com
# 203.0.113.50

dig +short www.example.com
# 203.0.113.50

# Check from multiple DNS resolvers
dig @1.1.1.1 a.example.com
dig @8.8.8.8 a.example.com

DNS propagation can take up to 48 hours (most often minutes) — TTL controls how long resolvers cache the previous answer.


Step 4: Get a TLS Certificate

You have three options:

OptionCostAuto-RenewalBest For
Let's Encrypt (certbot)FreeYes (cron/systemd timer)Most web apps
Bring your own certVariesManualWildcard, EV, internal CA
Self-signedFreeManualDev/staging only

Option A: Let's Encrypt with certbot

Let's Encrypt issues free, automated, 90-day certificates. certbot handles request, validation, and renewal.

Install certbot

# Ubuntu / Debian
sudo apt update
sudo apt install -y certbot

# Rocky / AlmaLinux / RHEL
sudo dnf install -y epel-release
sudo dnf install -y certbot

Option 1: Standalone (no web server running)

sudo certbot certonly --standalone \
  -d example.com \
  -d www.example.com \
  -d api.example.com \
  --non-interactive --agree-tos \
  --email admin@example.com

Certificates land in /etc/letsencrypt/live/example.com/:

  • fullchain.pem — server + intermediate certs
  • privkey.pem — private key
  • chain.pem — intermediate certs only

Option 2: Webroot (server already running)

# Nginx example — make /.well-known/acme-challenge reachable
sudo certbot certonly --webroot -w /var/www/html \
  -d example.com -d www.example.com \
  --non-interactive --agree-tos \
  --email admin@example.com

Option 3: DNS-01 challenge (for wildcard certs)

Wildcard certs (*.example.com) require DNS-01 validation. Most DNS providers have a certbot plugin:

# Install plugin for your DNS provider
sudo apt install -y python3-certbot-dns-cloudflare

# Configure API credentials
sudo tee /etc/letsencrypt/cloudflare.ini > /dev/null <<EOF
dns_cloudflare_api_token = <your-cloudflare-api-token>
EOF
sudo chmod 600 /etc/letsencrypt/cloudflare.ini

# Issue wildcard cert
sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d example.com \
  -d "*.example.com" \
  --non-interactive --agree-tos \
  --email admin@example.com

Tip: The Cloudflare API token can be scoped to a single zone with Zone:DNS:Edit permission. Store the token in a secrets manager, not in plaintext on the server.

Verify Auto-Renewal

# Dry-run renewal
sudo certbot renew --dry-run

# The certbot package installs a systemd timer or cron that renews twice daily
systemctl list-timers | grep certbot
# Or
ls /etc/cron.d/certbot

Option B: Bring Your Own Certificate

If you have a cert from DigiCert, Sectigo, GlobalSign, or your internal CA, upload it to the load balancer via the console:

  1. Navigate to Load Balancers → select your LB → Certificates
  2. Click Upload Certificate
  3. Paste the full certificate chain (including intermediates) and private key
  4. Go to Listeners and create an HTTPS listener on port 443, selecting your uploaded certificate

See Load Balancers → SSL Termination for details.


Step 5: Terminate TLS

Best for most web deployments. Centralizes cert management and offloads TLS.

If using Let's Encrypt (free): See Step 6 below for certbot instructions, then upload the resulting certificate via the console's Certificates tab.

If using your own certificate: Upload via the console as described in Option B above.

Backends can now speak plain HTTP to the LB on the private network — TLS work happens once at the edge.

Option B: On the Instance (Direct)

For single-instance deployments, when you don't want a load balancer, or when you need mutual TLS / end-to-end encryption.

Nginx + certbot

# Install nginx and certbot
sudo apt install -y nginx certbot python3-certbot-nginx

# Obtain cert and configure automatically
sudo certbot --nginx -d example.com -d www.example.com \
  --non-interactive --agree-tos \
  --email admin@example.com

# Test renewal
sudo certbot renew --dry-run

certbot --nginx automatically edits /etc/nginx/sites-available/default to:

  • Listen on 80 and 443
  • Redirect HTTP → HTTPS
  • Set the cert paths
  • Add HSTS / OCSP stapling defaults

Verify the config:

sudo nginx -t
sudo systemctl reload nginx

# Test
curl -I https://example.com
# HTTP/2 200

Auto-reload after renewal

Certbot renews by default, but your web server needs to reload to pick up the new cert. The Nginx plugin handles this. For other servers, add a deploy hook:

# /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
#!/bin/bash
systemctl reload nginx

# Make executable
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

Option C: Passthrough / Mutual TLS

Use a Layer 4 TCP load balancer configured in the console with TLS passthrough, and terminate on the instance. End-to-end encryption, ideal for compliance.

See Load Balancers → SSL Termination → Passthrough.


certbot on Ubuntu — Full Walkthrough

This is the canonical setup for a single Ubuntu instance running Nginx with auto-renewing TLS.

1. Provision and configure

# Create the instance (from your laptop)
fugoku create instance \
  --name web-1 \
  --plan vm-standard \
  --image ubuntu-24.04 \
  --region ashburn-1 \
  --ssh-key laptop

# Reserve and assign Elastic IP
fugoku eips reserve --region ashburn-1 --ipv4
fugoku eips assign 203.0.113.50 --instance web-1

# Point DNS A record at 203.0.113.50

2. SSH in and install

ssh ubuntu@203.0.113.50

sudo apt update && sudo apt upgrade -y
sudo apt install -y nginx certbot python3-certbot-nginx

3. Open firewall for HTTP/HTTPS

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

4. Place your site

sudo tee /etc/nginx/sites-available/example.com <<'EOF'
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}
EOF

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

5. Issue the cert

sudo certbot --nginx -d example.com -d www.example.com \
  --non-interactive --agree-tos \
  --email admin@example.com

6. Verify

curl -I https://example.com
# HTTP/2 200
# strict-transport-security: max-age=31536000

7. Confirm auto-renewal

sudo certbot renew --dry-run
systemctl status certbot.timer

Multiple Domains & Wildcards

Multiple distinct domains

sudo certbot --nginx \
  -d example.com -d www.example.com \
  -d api.example.com -d staging.example.com \
  --non-interactive --agree-tos \
  --email admin@example.com

Wildcard (DNS-01 only)

sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d example.com -d "*.example.com" \
  --non-interactive --agree-tos \
  --email admin@example.com

Wildcards cover one level deep only — *.example.com matches api.example.com but not api.staging.example.com. For deeper subdomains, issue additional wildcards (*.staging.example.com).


HSTS, OCSP Stapling, Modern TLS

Nginx hardening example

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header X-Content-Type-Options nosniff always;
    add_header X-Frame-Options DENY always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    root /var/www/example.com;
    index index.html;
}

Test your TLS grade:


cert-manager for Kubernetes

For Kubernetes workloads, use cert-manager to automate Let's Encrypt issuance via Ingress or Gateway resources.

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.0/cert-manager.yaml

# ClusterIssuer for Let's Encrypt
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@example.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: nginx
EOF

Annotate an Ingress to auto-issue:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - example.com
    secretName: example-tls
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80

Troubleshooting

IssueResolution
DNS not resolvingCheck dig +short example.com, wait for TTL, verify record at registrar
certbot challenge fails (HTTP-01)Port 80 must be reachable from the internet — check fugoku firewalls and ufw
certbot challenge fails (DNS-01)Verify API token has DNS edit scope for the zone
"Connection refused" on 443Web server not running, firewall blocking 443, or certbot didn't reload
Cert renewed but server still serves old certWeb server needs reload — add a --deploy-hook for certbot
Mixed content warningsYour site loads HTTPS but references HTTP resources — update all <img>, <script>, <link> URLs
HSTS not applyingBrowsers cache HSTS — clear site data or use Strict-Transport-Security: max-age=0 to reset
certbot rate limitLet's Encrypt allows 50 certs per domain per week — re-use existing certs across renewals
OCSP stapling failsServer can't reach OCSP responder — check egress, ensure ssl_stapling_verify on works

Best Practices

  1. Terminate TLS at the load balancer — centralize certs, offload CPU, easier rotation
  2. Use Let's Encrypt with auto-renewal — free, automated, 90-day rotation
  3. Pin to TLS 1.2+ — disable TLS 1.0/1.1 (deprecated and insecure)
  4. Enable HSTS with preload — for high-traffic production domains, submit to the HSTS preload list
  5. OCSP stapling — improves TLS handshake latency and privacy
  6. Use DNS-01 for wildcard certs — wildcard certs only available via DNS-01
  7. Don't commit private keys — store in /etc/letsencrypt/ (mode 600) or a secrets manager
  8. Rotate at 30 days, not 90 — for high-value domains, shorten the rotation window
  9. Test certificate renewal — certbot renew --dry-run quarterly
  10. Monitor expiration — alert when certs are under 14 days from expiry

Getting Help


Next Steps:

On this page