1. 흐름 이해
1. CA 개인키 생성
2. CA 인증서 생성
3. 서버 개인키 생성
4. 서버 CSR 생성
5. CA가 CSR을 서명해서 서버 인증서 발급
6. 서버 인증서 + CA 인증서를 묶어 fullchain 생성
7. nginx/apache 등에 적용
8. 클라이언트에 ca.crt를 신뢰 저장소로 배포
2. 사설 CA 만들기
2-1. CA 개인키 생성
ca.key는 인증기관의 비밀키
openssl genrsa -out ca.key 4096
2-2. CA 인증서 생성
자기 자신의 인증서를 생성
openssl req -x509 -new -key ca.key -sha256 -days 3650 -out ca.crt
Country Name (2 letter code) [XX]: KR
State or Province Name (full name) []: Seoul
Locality Name (eg, city) []: Seoul
Organization Name (eg, company) []: MyCompany
Organizational Unit Name (eg, section) []: Infra
Common Name (e.g. server FQDN or YOUR name) []: My Private Root CA
Email Address []:
- -x509 : CSR이 아니라 인증서를 만들겠다는 의미
- car.crt는 CA 자신의 인증서 (즉, "나는 이런 이름의 인증기관이다")
3. 사설 인증서 만들기
3-1. 서버 개인키 생성
서버가 TLS 통신에 사용할 개인키
※ 실제 CA에도 보내지 않으며, CA에서도 요구하지 않음
openssl genrsa -out server.key 2048
3-2. 서버 CSR 만들기
방법 A. 인터랙티브 방식
CN을 입력할 수는 있지만, SAN을 넣기 불편함
openssl req -new -key server.key -out server.csr
방법 B. config 파일을 이용한 방식
실무에서는 보통 config 파일 방식을 많이 사용
# server-cert.cnf
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = req_distinguished_name
req_extensions = req_ext
[ req_distinguished_name ]
C = KR
ST = Seoul
L = Seoul
O = MyCompany
OU = Infra
CN = ahndrenaline.io
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = ahndrenaline.io
DNS.2 = www.ahndrenaline.io
DNS.3 = api.ahndrenaline.io
openssl req -new -key server.key -out server.csr -config server-cert.cnf
- CN : 대표 도메인
- SAN : 실제 접속 가능한 도메인 목록
- 해당 인증서 하나로 보호할 수 있는 추가적인 도메인들의 리스트
- 요즘 브라우저 / 클라이언트는 SAN을 기준으로 이름을 검증함
3-3. CA가 서버 CSR 서명해서 서버 인증서 발급
이제 CA가 server.csr을 보고 server.crt를 만든다.
여기서도 SAN 정보가 인증서에 제대로 들어가야 하므로, 서명 시 확장 설정을 명시해주는게 좋다.
# server-ext.cnf
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = ahndrenaline.io
DNS.2 = www.ahndrenaline.io
DNS.3 = api.ahndrenaline.io
openssl x509 -req \
-in server.csr \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-out server.crt \
-days 365 \
-sha256 \
-extfile server-ext.cnf
결과
- server.crt : CA가 server.csr을 보고 서명해서 만들어준 결과물 (즉, 서버 인증서)
- ca.srl : CA가 인증서를 발급할 때 쓰는 시리얼 번호 기록 파일 시리얼 번호 관리 파일
각 옵션 의미
- -req : 입력이 CSR이라는 뜻
- -in server.csr : 서버의 요청서
- -CA ca.crt : 서명에 사용할 CA 인증서
- -CAkey ca.key : 서명에 사용할 CA 개인키
- -CAcreateserial : 시리얼 파일 생성
- -out server.crt : 최종 발급될 서버 인증서
- -extfile server-ext.cnf : SAN, 용도 등의 확장 정보 반영
4. fullchain.pem 만들기
이제 서버 인증서와 상위 CA 인증서를 하나로 묶는다.
중요! 반드시 아래 순서여야 함
순서가 뒤집히면 일부 클라이언트에서 체인 검증이 꼬일 수 있음
1. 서버 인증서
2. 상위 CA 인증서
server.crt
ca.crt
4-1. 인증서 하나로 묶기
cat server.crt ca.crt > fullchain.pem
5. 클라이언트가 신뢰하도록 ca.crt 배포
사설 CA는 공인 루트 저장소에 없기 때문에 브라우저 / OS는 기본적으로 이 CA를 신뢰하지 않는다.
따라서 ca.crt를 클라이언트의 신뢰 저장소에 넣어야 한다.
5-1. 운영체제 별 인증서 설치
Windows
1. ca.crt 실행
2. 인증서 설치
3. "로컬 컴퓨터"
4. "신뢰할 수 있는 루트 인증 기관" 저장소에 추가
Rocky / RHEL / CentOS / Fedora 계열
sudo cp ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust
Debian / Ubuntu 계열
sudo cp ca.crt /usr/local/share/ca-certificates/my-private-ca.crt
sudo update-ca-certificates
macOS
1. Keychain Access 열기
2. System 키체인에 ca.crt 추가
3. Trust를 Always Trust로 설정
6. 검증 (내용 보기)
1. 서버 인증서 내용 보기
openssl x509 -in server.crt -text -noout
2. CSR 내용 보기
openssl req -in server.csr -text -noout
3. CA 인증서 내용 보기
openssl x509 -in ca.crt -text -noout
4. 체인 검증
openssl verify -CAfile ca.crt server.crt