This guide is the operational runbook for deploying the lab in AWS and capturing the required evidence.
- Apache domain: ec2-54-82-9-48.compute-1.amazonaws.com
- Spring domain: ec2-34-233-121-121.compute-1.amazonaws.com
- Frontend origin: https://ec2-54-82-9-48.compute-1.amazonaws.com
- API origin: https://ec2-34-233-121-121.compute-1.amazonaws.com
- Apache domain: apache-ander.duckdns.org
- Spring domain: spring-ander.duckdns.org
- Frontend origin: https://apache-ander.duckdns.org
- API origin: https://spring-ander.duckdns.org
Parameter rule:
- For
<FRONTEND_DOMAIN>and<API_DOMAIN>, pass only the hostname (nohttp://orhttps://). - For
<FRONTEND_ORIGIN>and<API_ORIGIN>, pass a full URL origin (the scripts normalize to HTTPS automatically).
Important:
- Let's Encrypt will not issue certificates for AWS EC2 public hostnames like
*.compute-1.amazonaws.com(forbidden by CA policy). - You must use domains you control and map them to your EC2 public IPs.
- Recommended naming for frontend: frontend.yourdomain.com -> Apache EC2 public IP
- Recommended naming for API: api.yourdomain.com -> Spring EC2 public IP
- Two EC2 instances (Amazon Linux 2023):
- Apache server (frontend)
- Spring server (API)
- Two DNS records:
- frontend.yourdomain.com -> Apache public IP
- api.yourdomain.com -> Spring public IP
- Security groups:
- Apache SG: 22 (admin IP), 80, 443
- Spring SG: 22 (admin IP), 443, optional 80 for certbot standalone
- SSH key pair with access to both instances.
ssh -i your-key.pem ec2-user@<APACHE_IP>
git clone https://github.com/AnderssonProgramming/secure-application-design.git
cd secure-application-design
chmod +x scripts/setup-apache.sh
./scripts/setup-apache.sh frontend.yourdomain.com https://api.yourdomain.comExact command for your current domain:
./scripts/setup-apache.sh ec2-54-82-9-48.compute-1.amazonaws.com https://ec2-34-233-121-121.compute-1.amazonaws.comExact command for DuckDNS:
./scripts/setup-apache.sh apache-ander.duckdns.org https://spring-ander.duckdns.orgValidation:
curl -I https://frontend.yourdomain.com
sudo systemctl status httpdssh -i your-key.pem ec2-user@<SPRING_IP>
git clone https://github.com/AnderssonProgramming/secure-application-design.git
cd secure-application-design
chmod +x scripts/setup-spring.sh
./scripts/setup-spring.sh api.yourdomain.com https://frontend.yourdomain.com YOUR_KEYSTORE_PASSWORDExact command for your current domain:
./scripts/setup-spring.sh ec2-34-233-121-121.compute-1.amazonaws.com https://ec2-54-82-9-48.compute-1.amazonaws.com YOUR_KEYSTORE_PASSWORDExact command for DuckDNS:
./scripts/setup-spring.sh spring-ander.duckdns.org https://apache-ander.duckdns.org YOUR_KEYSTORE_PASSWORDValidation:
curl -I https://api.yourdomain.com/api/public/health
sudo systemctl status secure-apichmod +x scripts/renew-certs.sh
./scripts/renew-certs.sh api.yourdomain.com YOUR_KEYSTORE_PASSWORD /home/ec2-user/keystore.p12
sudo certbot renew --dry-runExact renewal command for your current domain:
./scripts/renew-certs.sh ec2-34-233-121-121.compute-1.amazonaws.com YOUR_KEYSTORE_PASSWORD /home/ec2-user/keystore.p12Exact renewal command for DuckDNS:
./scripts/renew-certs.sh spring-ander.duckdns.org YOUR_KEYSTORE_PASSWORD /home/ec2-user/keystore.p12- Open https://apache-ander.duckdns.org.
- Register a user.
- Login with the same user.
- Call /api/secure/me from the UI.
- Confirm unauthorized behavior without token.
- EC2 instances list
- Security groups
- DNS records
- Apache service running
- Frontend HTTPS in browser
- Spring service running
- API health endpoint HTTPS
- Certbot output on Apache
- Certbot output on Spring
- PKCS12 conversion step
- Login success
- Login failure
- BCrypt hash stored in DB
- Protected endpoint
- Test suite passing
If the browser shows ERR_CONNECTION_REFUSED for https://spring-ander.duckdns.org/api/..., run this checklist on the Spring server:
sudo systemctl status secure-api --no-pager
sudo journalctl -u secure-api -n 120 --no-pager
sudo ss -tulpen | grep ':443'
curl -vk https://localhost/api/public/healthThen verify network and DNS from your local machine:
nslookup spring-ander.duckdns.org
curl -vk https://spring-ander.duckdns.org/api/public/healthMost common causes:
secure-apiis down due to Java runtime startup issues from file capabilities on the Java binary. Current script uses systemd capability settings instead.- Spring Security Group does not allow inbound
443/tcp. - DuckDNS A record points to a different IP than the Spring instance.
- Service was created before fix; rerun setup script once to regenerate the systemd unit.