OCI WAF SSL 인증서 자동 갱신 아키텍처 다이어그램

OCI WAF(Web Application Firewall)를 사용하면 DDoS 방어와 HTTP→HTTPS 리다이렉트를 자동으로 얻을 수 있습니다. 하지만 SSL 인증서 갱신이라는 함정이 숨어 있습니다.

서버의 certbot은 Let's Encrypt 인증서를 자동 갱신하지만, WAF에 업로드된 인증서는 별도로 갱신해야 합니다. 이를 잊으면 어느 날 갑자기 사이트가 접속 불가 상태가 됩니다.

이 글에서는 실제 운영 환경에서 겪은 WAF 인증서 만료 위기를 해결하고, certbot deploy hookOCI CLI로 완전 자동화하는 과정을 공유합니다.

문제: 이중 인증서 구조

[사용자 브라우저] │ ▼ [OCI WAF] ←── WAF SSL 인증서 (수동 업로드) │ ▼ [Apache 서버] ←── 서버 SSL 인증서 (certbot 자동갱신)

certbot이 서버 인증서를 갱신해도, WAF 인증서는 그대로입니다. 두 인증서의 만료일이 다르기 때문에 서버 인증서가 유효해도 WAF 인증서가 만료되면 사이트 접속이 불가합니다.

⚠️ 실전 상황: 서버 certbot 인증서는 5월 21일까지 유효한데, WAF 인증서는 2일 후(3월 22일) 만료 예정이었습니다. deploy hook도 없고 OCI CLI도 없는 상태에서 발견.

진단: 현재 상태 파악

서버 인증서 확인

sudo certbot certificates
# Expiry Date: 2026-05-21 (VALID: 62 days) ← 정상

sudo ls -la /etc/letsencrypt/renewal-hooks/deploy/
# 비어있음 ← 자동화 없음

oci --version 2>/dev/null || echo "OCI CLI 미설치"
# OCI CLI 미설치 ← API 호출 불가

WAF 인증서 확인

OCI 콘솔 → WAF Policies → 정책 선택 → SettingsGeneral settings에서 SSL certificate expiration date 확인.

긴급 처치: 수동 인증서 갱신

1
서버 인증서 파일 추출
sudo cp /etc/letsencrypt/live/도메인/fullchain.pem /home/opc/
sudo cp /etc/letsencrypt/live/도메인/privkey.pem /home/opc/
sudo chown opc:opc /home/opc/*.pem
2
로컬 PC로 다운로드
scp opc@서버IP:~/fullchain.pem ./
scp opc@서버IP:~/privkey.pem ./
3
OCI 콘솔에서 업로드

WAF Policy → Settings → Edit → Upload or paste certificate and private key → Files 선택 → fullchain.pem + privkey.pem 업로드 → Save changes

Self signed certificate체크하지 않음 — Let's Encrypt는 공인 CA입니다.

영구 해결: OCI CLI + certbot deploy hook

OCI CLI 설치

# Oracle Linux 8
sudo yum install -y python36-oci-cli
oci --version

OCI CLI 설정

기존 설정이 있을 수 있으니 먼저 확인:

cat ~/.oci/config 2>/dev/null

설정이 없거나 인증 실패하면 oci setup config를 실행합니다. 필요한 값:

항목확인 위치
User OCIDOCI 콘솔 → 우측 상단 사람 아이콘 → My profile → OCID Copy
Tenancy OCIDOCI 콘솔 → 사람 아이콘 → Tenancy → OCID Copy
Region콘솔 우측 상단 (예: ap-chuncheon-1)

설정 완료 후 생성된 공개키를 OCI에 등록:

cat ~/.oci/oci_api_key_public.pem
# 출력 내용 복사 → My profile → API keys → Add API key → Paste
💡 API 키 제한: OCI는 사용자당 API 키 3개까지 허용합니다. 이미 3개면 미사용 키를 삭제 후 추가하세요. OCI에서 어떤 키가 사용 중인지 직접 알 수 있는 기능은 없으며, Audit 로그에서 fingerprint로 간접 확인 가능합니다.

deploy hook 스크립트

sudo tee /etc/letsencrypt/renewal-hooks/deploy/upload-to-waf.sh << 'SCRIPT'
#!/bin/bash
LOG="/var/log/waf-cert-upload.log"
OCI="/usr/bin/oci --config-file /home/opc/.oci/config"
WAF_ID="<WAF_POLICY_OCID>"

echo "$(date) ==============================" >> "$LOG"
echo "$RENEWED_DOMAINS" | grep -q "도메인" || { echo "$(date) 스킵" >> "$LOG"; exit 0; }

CERT_PATH="$RENEWED_LINEAGE/fullchain.pem"
KEY_PATH="$RENEWED_LINEAGE/privkey.pem"
COMPARTMENT_ID=$(${OCI} waas waas-policy get \
    --waas-policy-id ${WAF_ID} \
    --query 'data."compartment-id"' --raw-output)

# 1. 인증서 리소스 생성
CERT_RESULT=$(${OCI} waas certificate create \
    --compartment-id "$COMPARTMENT_ID" \
    --certificate-data "$(cat ${CERT_PATH})" \
    --private-key-data "$(cat ${KEY_PATH})" \
    --display-name "auto-$(date +%Y%m%d%H%M%S)")

CERT_OCID=$(echo "$CERT_RESULT" | \
    python3 -c "import sys,json; print(json.load(sys.stdin)['data']['id'])")

# 2. WAF 정책에 연결
${OCI} waas waas-policy update \
    --waas-policy-id "$WAF_ID" \
    --policy-config "{\"certificateId\":\"${CERT_OCID}\",\"isSniEnabled\":true,\"isHttpsEnabled\":true,\"isHttpsForced\":true,\"tlsProtocols\":[\"TLS_V1_2\",\"TLS_V1_3\"]}" \
    --force >> "$LOG" 2>&1

echo "$(date) 완료: $CERT_OCID" >> "$LOG"
SCRIPT

sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/upload-to-waf.sh

트러블슈팅 포인트

증상원인해결
certificateData is not validfile:// 형식 전달$(cat 파일)로 변경
No such option: --configWAAS API 파라미터명 상이--policy-config 사용
업데이트 후 변경 안 됨비동기 처리 (최대 15분)oci waas work-request get으로 확인
✅ 결과: certbot이 인증서를 갱신할 때마다 deploy hook이 자동 실행 → OCI WAF 인증서 교체. 더 이상 수동 개입 불필요.
위로 스크롤