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
| Step | What | Who |
|---|---|---|
| 1. Register domain | Buy from any registrar | You |
| 2. Point DNS | A/AAAA record → Fugoku Elastic IP | You (at registrar) |
| 3. Get TLS certificate | Free via Let's Encrypt, or bring your own | Fugoku LB / your instance |
| 4. Terminate TLS | At the load balancer or on the instance | You |
Free TLS option: Let's Encrypt issues 90-day certificates automatically via
certbot. With the--renewhook, renewal is fully automated.
Step 1: Register Your Domain
Pick any registrar. Common options:
| Registrar | Notes |
|---|---|
| Cloudflare Registrar | At-cost pricing, integrates with Cloudflare DNS |
| Porkbun | Free WHOIS privacy, low cost |
| Namecheap | Wide TLD selection |
| Google Domains | Simple UI, Google Workspace integration |
| Hover | Clean interface, no upsells |
| Gandi | Ethical 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 --ipv6Tip: 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):
| Type | Host | Value | TTL |
|---|---|---|---|
A | @ | 203.0.113.50 | 300 |
A | www | 203.0.113.50 | 300 |
A | api | 203.0.113.50 | 300 |
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.comDNS 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:
| Option | Cost | Auto-Renewal | Best For |
|---|---|---|---|
| Let's Encrypt (certbot) | Free | Yes (cron/systemd timer) | Most web apps |
| Bring your own cert | Varies | Manual | Wildcard, EV, internal CA |
| Self-signed | Free | Manual | Dev/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 certbotOption 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.comCertificates land in /etc/letsencrypt/live/example.com/:
fullchain.pem— server + intermediate certsprivkey.pem— private keychain.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.comOption 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.comTip: The Cloudflare API token can be scoped to a single zone with
Zone:DNS:Editpermission. 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/certbotOption 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:
- Navigate to Load Balancers → select your LB → Certificates
- Click Upload Certificate
- Paste the full certificate chain (including intermediates) and private key
- 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
Option A: At the Load Balancer (Recommended)
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-runcertbot --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 200Auto-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.shOption 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.502. 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-nginx3. Open firewall for HTTP/HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable4. 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 nginx5. Issue the cert
sudo certbot --nginx -d example.com -d www.example.com \
--non-interactive --agree-tos \
--email admin@example.com6. Verify
curl -I https://example.com
# HTTP/2 200
# strict-transport-security: max-age=315360007. Confirm auto-renewal
sudo certbot renew --dry-run
systemctl status certbot.timerMultiple 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.comWildcard (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.comWildcards 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:
- SSL Labs — comprehensive TLS audit
- Hardenize — security headers, cert, and DNS check
- Mozilla SSL Configuration Generator — modern config templates
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
EOFAnnotate 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: 80Troubleshooting
| Issue | Resolution |
|---|---|
| DNS not resolving | Check 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 443 | Web server not running, firewall blocking 443, or certbot didn't reload |
| Cert renewed but server still serves old cert | Web server needs reload — add a --deploy-hook for certbot |
| Mixed content warnings | Your site loads HTTPS but references HTTP resources — update all <img>, <script>, <link> URLs |
| HSTS not applying | Browsers cache HSTS — clear site data or use Strict-Transport-Security: max-age=0 to reset |
| certbot rate limit | Let's Encrypt allows 50 certs per domain per week — re-use existing certs across renewals |
| OCSP stapling fails | Server can't reach OCSP responder — check egress, ensure ssl_stapling_verify on works |
Best Practices
- Terminate TLS at the load balancer — centralize certs, offload CPU, easier rotation
- Use Let's Encrypt with auto-renewal — free, automated, 90-day rotation
- Pin to TLS 1.2+ — disable TLS 1.0/1.1 (deprecated and insecure)
- Enable HSTS with
preload— for high-traffic production domains, submit to the HSTS preload list - OCSP stapling — improves TLS handshake latency and privacy
- Use DNS-01 for wildcard certs — wildcard certs only available via DNS-01
- Don't commit private keys — store in
/etc/letsencrypt/(mode 600) or a secrets manager - Rotate at 30 days, not 90 — for high-value domains, shorten the rotation window
- Test certificate renewal —
certbot renew --dry-runquarterly - Monitor expiration — alert when certs are under 14 days from expiry
Getting Help
- Let's Encrypt docs: letsencrypt.org/docs
- certbot docs: certbot.eff.org
- Support: support@fugoku.com
- DNS / Networking: network@fugoku.com
Next Steps: