14. ProxmoxVE 인증서 교체

Proxmox VE 인증서 갱신 방법
Proxmox VE Web UI와 REST API는 HTTPS TCP 8006으로 제공됩니다.
https://<proxmox-node-fqdn-or-ip>:8006
인증서는 browser warning을 없애는 용도만이 아닙니다. Web UI, REST API, Terraform·Ansible·script automation, console access, PBS·internal repository 같은 연계 구간의 신뢰 기반입니다.
인증서가 만료되면 browser, API client, automation tool, security policy에서 오류가 발생할 수 있습니다. 운영 환경에서는 만료일을 monitor하고, 갱신 후 certificate chain·SAN·API access까지 검증해야 합니다.
인증서 방식
Proxmox VE의 pveproxy certificate는 일반적으로 세 방식 중 하나로 운영합니다.
| 방식 | 설명 | 적합한 환경 |
|---|---|---|
| Default Cluster CA | Proxmox가 생성한 cluster CA와 node certificate 사용 | 홈랩, 내부 검증, 기본 구성 |
| External CA | internal PKI 또는 public CA certificate를 수동 적용 | 사내망, 폐쇄망, PKI 운영 환경 |
| ACME | Let’s Encrypt 등 ACME CA certificate 자동 발급·갱신 | public DNS 검증이 가능한 환경 |
Certificate Options
1. Default Cluster CA
└── Proxmox-generated node certificate
2. External CA
└── Internal PKI or Public CA certificate
3. ACME
└── Automated certificate issuance and renewal
기본 Cluster CA는 node certificate 발급과 Proxmox management endpoint 신뢰에 사용됩니다. Corosync cluster communication의 보안 구조는 pveproxy certificate와 별도로 이해해야 합니다.
자동 관리 파일 주의
Proxmox가 자동 생성·관리하는 certificate와 Cluster CA 파일은 직접 수정하거나 교체하지 않습니다.
Do Not Manually Modify
/etc/pve/local/pve-ssl.pem
/etc/pve/local/pve-ssl.key
/etc/pve/pve-root-ca.pem
/etc/pve/priv/pve-root-ca.key
External CA 또는 ACME certificate는 일반적으로 다음 파일을 사용합니다.
/etc/pve/local/pveproxy-ssl.pem
/etc/pve/local/pveproxy-ssl.key
Private Key는 PEM 형식이며 password 없이 저장되어야 합니다.
현재 certificate 정보는 다음 명령으로 확인합니다.
pvenode cert info
인증서 파일의 subject, issuer, expiration, SAN을 직접 확인할 수도 있습니다.
openssl x509 \
-in /etc/pve/local/pveproxy-ssl.pem \
-noout \
-subject \
-issuer \
-dates \
-ext subjectAltName
기본 node certificate를 사용하는 경우에는 pveproxy-ssl.pem 대신 pve-ssl.pem을 확인합니다.
기본 Cluster CA 인증서 갱신
기본 node certificate에 문제가 있거나 갱신이 필요하면 먼저 상태를 확인합니다.
pvenode cert info
현재 node의 기본 certificate를 갱신합니다.
pvenode cert renew
강제 갱신이 필요한 경우에는 아래 명령을 검토합니다.
pvenode cert renew --force
cluster certificate 관련 file과 directory 갱신이 필요한 경우에는 아래 명령을 사용합니다.
pvecm updatecerts
pvecm updatecerts -f는 강제 갱신이 필요한 경우에만 사용합니다. cluster에서는 실행 전 pvecm status, pve-cluster, corosync, /etc/pve 상태를 먼저 확인합니다.
pvecm status
systemctl status pve-cluster
systemctl status corosync
갱신 후 Web UI에 새 certificate가 반영되지 않았거나 pveproxy 상태가 비정상이면 다음을 실행합니다.
systemctl restart pveproxy
systemctl status pveproxy
사설 CA 인증서 갱신
폐쇄망, 사내망, 고객사 PKI 환경에서는 internal CA certificate를 사용할 수 있습니다.
Private PKI
├── Protected Root CA
├── Intermediate CA
├── PVE Node Certificate
├── PBS Certificate
└── Internal Repository Certificate
PVE certificate에는 다음 조건을 확인합니다.
- PEM certificate와 PEM private key
- password 없는 private key
- 접속 FQDN이 포함된 SAN
- 필요한 intermediate certificate를 포함한 full chain
- administrator PC·Bastion·automation server에 Root CA trust 배포
CN = pve-01.example.internal
SAN
├── DNS:pve-01.example.internal
├── DNS:pve-admin.example.internal
└── IP:10.10.10.11
운영은 IP보다 FQDN 접속을 우선 권장합니다. IP로 접속해야 한다면 IP address도 SAN에 포함해야 합니다.
서버 certificate와 intermediate CA certificate를 연결해 full chain을 만듭니다.
cat node-certificate.pem intermediate-ca.pem \
> pveproxy-ssl.pem
Root CA는 일반적으로 server full chain에 넣지 않고 client·server trust store에 배포합니다.
certificate와 key를 적용합니다.
pvenode cert set \
/root/certs/pveproxy-ssl.pem \
/root/certs/pveproxy-ssl.key
적용 후 certificate와 private key가 같은 pair인지 확인합니다.
openssl x509 \
-in /root/certs/pveproxy-ssl.pem \
-pubkey \
-noout \
| openssl sha256
openssl pkey \
-in /root/certs/pveproxy-ssl.key \
-pubout \
| openssl sha256
두 SHA256 value가 같아야 합니다.
pvenode cert set 후 새 certificate가 반영되지 않았다면 pveproxy 상태를 확인하고 필요 시 재시작합니다.
systemctl restart pveproxy
systemctl status pveproxy
CSR·private key 작업 directory에 남은 key copy도 민감정보입니다. 불필요한 복사본은 승인된 절차에 따라 보관 또는 폐기하고, root만 읽을 수 있도록 관리합니다.
chmod 600 /root/certs/pveproxy-ssl.key
chown root:root /root/certs/pveproxy-ssl.key
ACME와 Let’s Encrypt
ACME는 certificate issuance와 renewal을 자동화하는 protocol입니다. Proxmox VE는 Let’s Encrypt 같은 ACME CA를 Web UI와 API에서 통합 지원합니다.
| Challenge | 동작 | 적합한 환경 |
|---|---|---|
| HTTP-01 | external CA가 TCP 80의 challenge file 확인 | public inbound HTTP가 가능한 환경 |
| DNS-01 | public DNS TXT record로 domain ownership 확인 | inbound access 없이 public DNS를 관리할 수 있는 환경 |
| TLS-ALPN-01 | TLS handshake 기반 검증 | client·proxy·network support를 별도 검토할 환경 |
DNS-01은 public inbound access 없이 사용할 수 있고 wildcard certificate 발급도 가능합니다. 단, public CA가 public authoritative DNS의 TXT record를 확인할 수 있어야 합니다. 완전히 internal-only domain에는 public ACME CA 대신 internal CA를 사용합니다.
ACME account는 Web UI의 Datacenter → ACME에서 등록하거나 pvenode CLI를 사용할 수 있습니다.
pvenode acme cert order
pvenode acme cert renew --force
운영 ACME 설정 전에는 Let’s Encrypt Staging으로 challenge flow를 검증합니다. Staging certificate는 browser가 신뢰하지 않지만 rate limit 없이 발급 과정을 검증하는 데 유용합니다.
ACME certificate가 정상 설정되면 Proxmox의 pve-daily-update.service는 certificate가 이미 만료됐거나 30일 이내 만료 예정일 때 renewal을 시도합니다. 자동 갱신과 별도로 expiry monitoring을 유지해야 합니다.
갱신 후 검증
certificate 갱신 후에는 Web UI만 확인하지 말고 SAN, chain, TLS validation, API automation을 검증합니다.
# local certificate 확인
pvenode cert info
openssl x509 \
-in /etc/pve/local/pveproxy-ssl.pem \
-noout \
-subject \
-issuer \
-dates \
-ext subjectAltName
remote endpoint에서 확인합니다.
echo | openssl s_client \
-connect pve-01.example.internal:8006 \
-servername pve-01.example.internal \
-showcerts
internal CA file로 명시적으로 검증할 수도 있습니다.
echo | openssl s_client \
-connect pve-01.example.internal:8006 \
-servername pve-01.example.internal \
-CAfile /root/certs/internal-root-ca.pem
API endpoint도 certificate validation을 유지한 상태에서 확인합니다.
curl --fail --silent --show-error \
[https://pve-01.example.internal:8006/api2/json/version](https://pve-01.example.internal:8006/api2/json/version)
curl -k는 certificate validation을 우회하므로 최종 검증에 사용하지 않습니다.
다음도 함께 확인합니다.
systemctl status pveproxy
journalctl -u pveproxy -n 200 --no-pager
ss -lntp | grep 8006
만료일 모니터링
certificate는 만료 전에 경고를 받아야 합니다.
openssl x509 \
-in /etc/pve/local/pveproxy-ssl.pem \
-noout \
-checkend $((30 * 24 * 60 * 60))
기본 node certificate는 아래 파일로 확인합니다.
openssl x509 \
-in /etc/pve/local/pve-ssl.pem \
-noout \
-checkend $((30 * 24 * 60 * 60))
권장 알림 기준은 다음과 같습니다.
| 만료까지 남은 기간 | 권장 조치 |
|---|---|
| 60일 | 갱신 계획과 담당자 확인 |
| 30일 | 새 certificate 발급·ACME renewal 상태 점검 |
| 14일 | test 적용과 API·automation 검증 완료 |
| 7일 | 운영 적용과 node별 검증 완료 |
| 3일 이하 | 긴급 변경 절차 검토 |
| 만료 | 즉시 갱신·TLS·API·service 상태 확인 |
cluster environment에서는 모든 node의 TCP 8006 certificate를 확인합니다.
for node in pve-01 pve-02 pve-03; do
echo "===== ${node} ====="
echo | openssl s_client \
-connect "${node}.example.internal:8006" \
-servername "${node}.example.internal" \
2>/dev/null \
| openssl x509 -noout -subject -issuer -dates
done
트러블슈팅
Web UI certificate warning이 발생하면 아래를 확인합니다.
- 접속 FQDN이 certificate SAN에 포함되는가
- certificate가 만료되지 않았는가
- intermediate chain이 full chain에 포함됐는가
- administrator PC와 Bastion이 Root CA를 신뢰하는가
pveproxy가 새 certificate를 로드했는가- DNS가 의도한 node IP를 반환하는가
- Load Balancer·Reverse Proxy가 다른 certificate를 제공하는가
pveproxy가 certificate 적용 후 시작하지 않으면 다음을 확인합니다.
systemctl status pveproxy
journalctl -u pveproxy -n 200 --no-pager
대표 원인은 certificate-key mismatch, encrypted private key, PEM format error, missing intermediate CA, 잘못된 node 적용, /etc/pve·pve-cluster 문제, disk full입니다.
핵심 정리
- Proxmox VE Web UI와 REST API는 HTTPS TCP 8006에서 제공됩니다.
- Proxmox는 기본 Cluster CA, external CA, ACME certificate 방식을 제공합니다.
- 자동 관리되는
pve-ssl.*와 Cluster CA file은 직접 수정하거나 교체하지 않습니다. - external·ACME certificate는
pveproxy-ssl.pem과 password 없는pveproxy-ssl.key를 사용합니다. - 기본 certificate 갱신은
pvenode cert renew, cluster certificate file 갱신은pvecm updatecerts를 사용합니다. - internal CA certificate에는 FQDN SAN, full chain, password 없는 key, trust store distribution이 필요합니다.
- ACME는 public DNS·domain validation이 가능한 환경에 적합하며, 완전 폐쇄망은 internal CA가 일반적으로 적합합니다.
- 갱신 후에는 certificate subject·issuer·expiry·SAN·chain, pveproxy, Web UI, API, Terraform·Ansible·PBS 연결을 함께 검증합니다.
- certificate expiry는 최소 30일 전부터 monitor하고, cluster는 node별로 관리합니다.
참고 자료
- Proxmox VE Certificate Management
- Proxmox VE pvenode Manual
- Proxmox VE pvecm Manual
- Let’s Encrypt Challenge Types