Capstone: Secure, Monitor, and Back Up
July 16, 2026 ยท View on GitHub
The public HTTP site works. This stage turns it into an operable HTTPS service.
Step 1: Issue a Certificate
Before issuance, confirm:
dig A example.dpdns.org
dig AAAA example.dpdns.org
dig A www.example.dpdns.org
curl -I http://example.dpdns.org
Use a maintained ACME client supported by the server environment. Request names only after both reach the intended server.
Do not copy private keys into notes or screenshots.
Step 2: Verify HTTPS Directly
curl -I https://example.dpdns.org
curl -I https://www.example.dpdns.org
Inspect the certificate:
openssl s_client -connect example.dpdns.org:443 -servername example.dpdns.org </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates -ext subjectAltName
Expected:
- Current validity dates
- Root and
wwwin the subject alternative names - A chain trusted by the intended clients
Step 3: Configure Canonical Redirects
Choose the root domain as canonical for this project.
HTTP redirect:
server {
listen 80;
listen [::]:80;
server_name example.dpdns.org www.example.dpdns.org;
return 308 https://example.dpdns.org$request_uri;
}
Add an HTTPS redirect virtual host for www using the certificate configuration produced by the reviewed ACME workflow, then serve the content from the root hostname.
Validate and reload:
sudo nginx -t
sudo systemctl reload nginx
Step 4: Verify the Redirect Path
curl -IL http://www.example.dpdns.org/about.html
The response should reach the canonical HTTPS URL without loops or unnecessary chains.
Step 5: Test Certificate Renewal
Run the documented dry-run or test-renewal command for the installed ACME client. Verify the scheduled timer or task and review its latest status.
Create an independent expiration alert. The same client that fails renewal should not be the only system expected to report the failure.
Step 6: Apply Server Baseline
- Confirm only required public ports are open.
- Confirm website files are not broadly writable.
- Confirm Nginx and the operating system are updated.
- Confirm SSH recovery access before tightening authentication.
- Confirm logs rotate.
- Confirm time synchronization.
- Remove default pages and unused services.
Re-run:
sudo ss -lntup
sudo nginx -t
Step 7: Create a Website Backup
sudo tar -C /var/www -czf /tmp/example-site-backup.tar.gz example.dpdns.org
tar -tzf /tmp/example-site-backup.tar.gz | sed -n '1,80p'
Copy the verified archive to a protected system separate from the server. Back up the Nginx site configuration and the source repository as separate recovery inputs.
Step 8: Restore in Isolation
On a safe test system or isolated directory:
mkdir restore-test
tar -xzf example-site-backup.tar.gz -C restore-test
find restore-test -maxdepth 3 -type f -print
Serve the restored files on 127.0.0.1 and verify Home, About, and CSS. Record the restore duration.
Step 9: Create Monitors
At minimum:
- Domain expiration reminder
- Canonical HTTPS status and content check
- TLS expiration check
- Backup job result
- Server disk-space alert
- Unexpected nameserver or address change check
Every alert needs an owner and a first-response instruction.
Step 10: Run a Failure Drill
Temporarily use a safe test environment to simulate one failure, such as a missing static file or stopped local test server. Confirm that:
- Monitoring detects it.
- The operator follows the runbook.
- Recovery restores the expected page.
- The incident is recorded.
Do not intentionally break public DNS or production certificates for a learning drill.
Continue to Final Acceptance and Handover.