# Redmine #547 - 외부 VM HTTPS 운영 런북 ## 운영 구조 - 공개 endpoint: `https://kb.cloud-handson.com` - 공개 배포 VM: `opc@161.33.6.45` - Nginx: VM의 80/443에서 TLS termination, HTTP redirect, HSTS - Spring Boot: `127.0.0.1:8080`에서만 수신 - 외부 애플리케이션 포트 직접 접근: OCI NSG와 VM firewalld 모두 deny - 인증서: Let’s Encrypt / Certbot Nginx plugin FQDN의 A 레코드는 VM public IP `161.33.6.45`를 가리켜야 한다. 현재 운영 경로는 Nginx가 `127.0.0.1:8080`의 `vpd-backoffice.service`로 프록시하는 구조다. `hermes` 또는 `8082` 응답만 보고 운영 반영 완료로 판단하지 않는다. ## 최초 준비 아래 작업은 시스템 패키지와 방화벽을 바꾸므로 개별 승인을 받은 뒤 수행한다. 1. 소유 FQDN의 A 레코드를 VM public IP로 설정하거나 고정 public IPv4 사용을 확정한다. 2. OCI NSG와 VM firewalld에서 80/443 ingress를 허용한다. 3. 기존 8082 ingress를 OCI NSG와 firewalld에서 제거한다. 4. Oracle Linux/RHEL 계열 VM에 Nginx와 Certbot Nginx plugin을 설치한다. 5. `vpd-backoffice.service`는 `127.0.0.1:8080`에만 바인딩한다. ## 적용 먼저 로컬 검증과 앱 배포를 수행한다. ```bash mvn test ``` 운영 배포는 `161.33.6.45` 대상에 수행한다. SSH alias를 쓴다면 해당 alias가 반드시 `opc@161.33.6.45`를 가리키는지 먼저 확인한다. ```bash ssh <운영-alias> 'hostname; hostname -I; systemctl status vpd-backoffice --no-pager' ``` 배포 후에는 systemd 서비스를 재시작하고 공개 URL로 확인한다. ```bash ssh <운영-alias> 'sudo systemctl restart vpd-backoffice' curl -k -sS https://kb.cloud-handson.com/login ``` ## 반복 검증 설정을 바꾸지 않고 외부 검증만 다시 수행할 수 있다. 검증 항목: - HTTP `/login`이 동일 host의 HTTPS로 전환됨 - HTTPS 인증서가 공개 신뢰됨 - HSTS 1년 - `JSESSIONID`의 Secure/HttpOnly/SameSite=Lax - 외부 애플리케이션 포트 직접 연결 실패 - `https://kb.cloud-handson.com/login`의 HTML이 현재 배포된 jar의 로그인 화면과 일치 ## 인증서 갱신과 모니터링 Certbot timer가 Let’s Encrypt 인증서를 갱신한다. Nginx 설정과 인증서 갱신 상태를 함께 확인한다. ```bash ssh <운영-alias> 'systemctl is-active nginx && systemctl is-enabled nginx' ssh <운영-alias> 'systemctl is-active certbot-renew.timer && systemctl is-enabled certbot-renew.timer' ssh <운영-alias> 'sudo nginx -t' ssh <운영-alias> 'sudo journalctl -u nginx --since "24 hours ago" --no-pager' ``` ACME 오류, 인증서 만료 경고, 반복 reload 실패를 알림 대상으로 삼는다. ## 장애와 롤백 1. 앱이 살아 있는지 VM 내부에서 확인한다. ```bash ssh <운영-alias> 'curl -sS -H "X-Forwarded-Proto: https" -H "X-Forwarded-Host: kb.cloud-handson.com" -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/login' ``` 2. Nginx 로그와 설정을 확인한다. 3. 설정 변경 직후 장애라면 가장 최근 Nginx 설정 backup을 복원한다. 4. 앱 jar 롤백이 필요하면 직전 승인된 artifact를 배포하고 앱과 Nginx를 모두 재검증한다. 장애 우회를 위해 애플리케이션 포트를 직접 공개하지 않는다. 서비스 중단이나 방화벽/NSG 롤백은 개별 승인을 받는다.