리눅스/이모저모

[OpenSSL] 사설인증서 만들기

싱숭생숭늉 2025. 12. 23. 15:32

집중

사설 인증서(Private CA)란? 왜 쓰나?

사설 인증서는 “공인 인증기관(예: Let’s Encrypt, DigiCert)”이 아니라 내가 직접 만든 CA(인증기관) 가 서명해 발급한 인증서다.

왜 쓰는가?

  • 폐쇄망/내부망(인터넷 차단)에서 HTTPS를 써야 할 때
  • 개발/스테이징에서 도메인 기반 TLS 테스트가 필요할 때
  • 사내 서비스 간 통신(mTLS 포함)을 내부 신뢰 체계로 통제하고 싶을 때
  • Kubernetes Ingress, 내부 API Gateway, 사내 Git/Nexus/Harbor 등에 TLS 적용하려고

단점(중요)

  • 브라우저/OS는 내 CA를 모르기 때문에 처음엔 “주의 요함/비공개 연결 아님” 이 뜬다.
  • 해결은 간단: 내 PC/서버의 신뢰 저장소에 Root CA 인증서(ca.crt)를 등록하면 된다. > 요건 인증서 생성하고 다시 설명!!

Root CA → Server Cert

내가 만드는 파일들의 관계는 아래처럼 생각해 보자

  • ca.key : Root CA의 개인키로 절대 유출 금지!!
  • ca.crt : Root CA 인증서 배포 후 "신뢰"로 등록 하기 위함
  • server.key : 서버 개인키로 서버에서만 사용
  • server.csr : 서버가 “이 도메인으로 인증서 발급해줘” 라고 CA에 요청하는 서류
  • server.crt : CA가 서명해 발급한 서버 인증서

Ubuntu 24.04에서 사설 인증서 만들기

해당 인증서는 “SAN(Subject Alternative Name)” 포함 기준으로 작성했습니다.

폴더를 하나 생성 후 작업하는 것을 추천합니다!

mkdir /etc/ssl
cd /etc/ssl

1) SAN 파일 생성

vi san.conf
[ req ]
# openssl req 명령이 사용할 기본 설정 섹션
default_bits		= 2048
# CSR 생성 시 기본 키 길이(여기서는 서버 키 규격과 맞춤)
prompt			= no
# 실행할 때 질문(국가/조직 등) 묻지 말고 파일 내용대로 자동 진행
default_md		= sha256
# SHA-256 해시를 기본으로 사용(현 표준)
distinguished_name	= dn
# Subject 정보가 들어있는 섹션 이름
req_extensions		= v3_req
# CSR에 확장(extensions) 정보를 넣을 섹션 지정

[ dn ] 
CN			= *.test.io
# Subject의 CN. 참고용으로 둔다 (중요한 건 SAN)

[ v3_req ] 
subjectAltName		= @alt_names
# SAN을 alt_names에 정의된 DNS 목록으로 넣는다

[ alt_names ] 
DNS.1			= *.test.io
# nginx.test.io, api.test.io 같은 1단계 서브도메인 커버
DNS.2			= test.io
# 루트 도메인은 와일드카드로 커버가 안 되므로 따로 넣음
# **와일드카드는 a.test.io는 커버하지만, test.io 자체는 커버하지 못한다.**
# **그래서 루트 도메인은 꼭 별도 DNS 항목으로 넣어주자!!**

 

2) Root CA 개인키 생성

 
openssl genrsa -out ca.key 4096
  • CA 키는 서명 권한이 있는 핵심 키다.
  • 보안상 4096 키 길이를 많이 쓴다.
  • 서버 키보다 CA 키를 더 강하게 잡는 게 일반적이다.

3) Root CA 인증서(Self-signed) 생성

openssl req -x509 -new -nodes -key ca.key -days 3650 -out ca.crt -subj "/CN=TEST Root CA"

 

  • req : 인증서 요청/생성 관련 명령
  • -x509 : CSR이 아니라 바로 X.509 인증서(자체서명 Root CA) 생성
  • -new : 새로 생성
  • -nodes : 개인키 암호(passphrase) 없이 저장 > test로 만드는 거니깐 일단 암호 없이 생성
    • 자동화/운영 편의성은 좋지만, 파일 유출 시 치명적
    • 그래서 ca.key는 접근 통제/오프라인 보관이 핵심
  • -key ca.key : CA 인증서 생성에 사용할 개인키 (위에 생성한 ca.key를 사용하겠다!)
  • -days 3650 : 유효기간(10년 예시) > 1년 단위 or 3년 단위가 적정하다고 생각하는데 여긴 test로 만드는 거니깐!
  • -out ca.crt : 결과 인증서 파일
  • -subj "/CN=TEST Root CA" : 대화형 입력 대신 Subject를 한 줄로 지정

** CA 인증서는 "서버용" 이 아니라 "발급자" 라서 san.cnf 파일은 여기서 사용하지 않는다!! **

4) 서버 개인키 생성

openssl genrsa -out server.key 2048

 

  • 서버 키는 TLS 핸드셰이크에 직접 쓰이고, 
    대부분 환경에서 RSA 2048이 여전히 호환성과 속도 측면에서 무난하게 사용가능 하다.

5) 서버 CSR 생성 (san.conf 포함)

openssl req -new -key server.key -out server.csr -config san.conf
  • 여기서 중요!!
  • san.conf가 제대로 적용되지 않으면 “CN만 있는 인증서”가 발급되어 브라우저에서 계속 경고가 뜬다.

6) CSR 내용 확인

openssl req -in server.csr -noout -text
  • 정상적으로 san.conf가 적용되었다면, Subject Alternative Name 섹션에
  • Subject Alternative Name 섹션에 아래 DNS 가 들어있어야한다!!!
    • DNS:*.test.io
    • DNS:test.io

7) CA로 서버 인증서 서명(발급)

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650 -sha256 -extfile san.conf -extensions v3_req
 
 
  • x509 : X.509 인증서 관련 명령
  • -req : 입력이 CSR임을 의미
  • -in server.csr : CSR 입력
  • -CA ca.crt : 서명자(발급자) 인증서
  • -CAkey ca.key : 서명자 개인키(진짜 서명 권한)
  • -CAcreateserial : 일련번호(serial) 파일 자동 생성(ca.srl)
  • -out server.crt : 결과 서버 인증서
  • -days 3650 : 유효기간(10년 예시) > 1년 단위 or 3년 단위가 적정하다고 생각하는데 여긴 test로 만드는 거니깐!
  • -sha256 : 서명 해시 알고리즘
  • -extfile san.conf -extensions v3_req : SAN 확장 정보를 인증서에 반영

8) 서버 인증서 확인

openssl x509 -in server.crt -noout -text
  • 여기서도 중요!!
  • Subject Alternative Name에 DNS 목록이 찍히는지 확인

 

이상으로, 사설 인증서 만드는 것 확인했다!! 이제 이걸 사용해서 서버에도 적용하고 내PC에도 적용하면 들어갈때 잠금모양으로 들어갈 수 있다!

내 PC에 적용하는 방법은 다음 기회에... 뭐 사실 ca.crt 클릭해서 인증서 등록하면 되는데...

 

일단 끝!!!

참고 사이트
https://docs.redhat.com/ko/documentation/red_hat_enterprise_linux/8/html/securing_networks/creating-a-private-ca-using-openssl_creating-and-managing-tls-keys-and-certificates

 

2.2. OpenSSL을 사용하여 개인 CA 생성 | 네트워크 보안 | Red Hat Enterprise Linux | 8 | Red Hat Documentation

보다 포괄적 수용을 위한 오픈 소스 용어 교체 Red Hat은 코드, 문서, 웹 속성에서 문제가 있는 언어를 교체하기 위해 최선을 다하고 있습니다. 자세한 내용은 다음을 참조하세요.Red Hat 블로그.

docs.redhat.com