::: IT인터넷 :::

자체 서명 인증서 만들기

곰탱이푸우 2022. 2. 28. 08:20
Docker로 테스트하거나 실서비스 운영을 하다보면 HTTPS 접근 방법에 대한 고민을 하게 된다.

 

HTTPS를 사용하려면 공인 인증서 또는 사설 인증서를 적용해야 한다.
 
공인 인증서를 사용하는 방법은 크게 두 가지이다.
 
하나는 공인 인증기관을 통해 발급한 인증서를 적용하는 것이고, 다른 하나는 무료 공인 인증서인 Let's Encrypt를 사용하는 것이다.
 
공인 인증 기관에서 발급 받는 인증서는 가장 교과서적인 방법이지만 비싸서 개인이 운영하기에는 부담이 된다.
물론 회사에서 운영하는 서비스는 회사 비용을 사용해서 공인 인증서를 발급 받는 것을 권장한다.
 
개인의 경우 무료로 제공하는 공인 인증서인 Let's Enrypt를 사용하는 방법이 있다.
90일 마다 갱신해야 하므로 번거롭다는 단점이 존재하며, 구글링하면 자동 갱신하는 방법이 많이 있으니 참고하면 도움이 된다.
 
시놀로지 NAS에서 Let's Encrypt 인증서 발급 받는 방법은 아래 포스팅을 참고한다.
일반 서버 환경에서 Let's Encyrpt 인증서를 발급 받는 방법은 아래 포스팅 참고한다. 정리가 아주 잘 되어 있다.
Docker로 특정 시스템을 테스트를 하거나 내부에서만 사용할 목적으로 운영하는 경우, 자체 서명한 사설 인증서 적용하는 방법도 있다.
사설 인증서이기 때문에 브라우저에서 경고 메시지가 출력되지만, 개발과 테스트 목적인 경우는 큰 문제가 되지 않는다.
 
공인 인증서를 적용하는 것은 외부와 통신이 필요하거나 공식으로 서비스를 오픈할 때 고민하면 된다.
 
순서는 다음과 같다.
  1. 루트 인증서의 키(KEY) 생성
  2. 루트 인증서의 인증 서명 요청 (CSR) 생성
  3. 루트 인증서의 인증서 (CRT) 생성
  4. 사설 인증서의 키(KEY) 생성
  5. 사설 인증서의 인증 서명 요청 (CSR) 생성
  6. 사설 인증서의 인증서 (CRT) 생성
  7. 사설 인증서의 JKS (Java Keystroke) 생성 (Optional)
 
 

openssl 설치

일반적으로 Ubuntu 20.04 환경에서는 설치되어 있어 새로 설치할 필요는 없다.
 
아래 명령으로 설치 여부와 버전을 확인한다.
$ openssl version

OpenSSL 1.1.1f  31 Mar 2020
 
현재 시스템에는 2020년 3월 1일에 배포 된 1.1.1f 버전이 설치되어 있다.
 
해당 정보가 확인되지 않으면 아래 명령어로 설치를 진행한다.
$ sudo apt update
$ sudo apt install openssl
 

루트 인증서 (CA)

먼저 인증서 파일들을 저장하기 위한 폴더를 만들고 해당 폴더로 이동한다.
$ mkdir ~/certs
$ cd ~/certs
 
앞으로 모든 작업은 ~/certs 폴더에서 진행한다.
 
인증서를 생성할때 비밀번호 (key pass phrase)를 입력해야 한다.
경우에 따라 인증서를 사용하는 설정 파일에 비밀번호를 입력해야 하므로 공개해도 되는 문자열로 입력한다.
여기서는 testcerts를 사용한다.
 
 

루트 인증서 키 만들기

루트 인증서를 생성하는데 사용할 키 (key)를 생성한다.
 
다음과 같이 실행한다.
# root ca 키생성
$ openssl genrsa -aes256 -out rootca.key 2048

 

RSA 2048로 키를 생성하고 aes256 암호화 기법으로 암호화 하여 rootca.key 파일로 저장
2048은 RSA 키 생성 길이를 의미하며 1024, 4096도 된다. 키 값의 길이가 길 수록 보안성이 우수하다.
 

루트 인증서 CSR(인증 서명 요청) 만들기

csr 타입의 루트 인증서 서명 요청 파일을 만든다.
앞서 생성한 루트 인증서 키 파일을 사용한다.
 
# root ca 요청서 만들기
$ openssl req -new -key rootca.key -out rootca.csr

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:KR
State or Province Name (full name) []:GG  # 경기도
Locality Name (eg, city) [Default City]:SN  # 성남시
Organization Name (eg, company) [Default Company Ltd]:test  # 조직/회사명 입력
Organizational Unit Name (eg, section) []:unit  # 부서명 입력
Common Name (eg, your name or your server's hostname) []:test  # 서버 이름 입력
Email Address []:test@test.com    # 이메일 주소
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: testcerts  # 공개되도 상관 없는 암호 입력 
  An optional company name []:    # 비워놓고 엔터 (다른 이름 부여 가능)
 

루트 인증서 (CRT) 만들기

앞서 생성한 루트 인증서의 Key (키)파일과 CSR (인증 서명 요청) 파일을 사용하여 루트 인증서를 생성한다.
$ openssl x509 -req -days 3650 -set_serial 1 -in rootca.csr -signkey rootca.key -out rootca.crt

Signature ok
subject=C = KR, ST = GG, L = SN, O = test, OU = unit, CN = test, emailAddress = test@test.com
Getting Private key
 
암호를 요구하는 경우 CSR 파일을 생성할 때 입력한 암호를 입력한다.
-days 3650 옵션을 부여했으므로 유효 기간은 10년이다.

 

 

사설 인증서

이제 웹 서버에서 사용할 사설 인증서를 생성한다.
 

사설 인증서 키 만들기

사설 인증서를 생성하는데 사용할 키 (key)를 생성한다. 루트 인증서 키 생성과 동일하다.
 
다음과 같이 실행한다.
# 사설 인증서 키생성
$ openssl genrsa -aes256 -out 서버IP.key 2048
 
RSA 2048로 키를 생성하고 aes256 암호화 기법으로 암호화 하여 파일로 저장
2048은 RSA 키 생성 길이를 의미하며 1024, 4096도 된다. 키 값의 길이가 길 수록 보안성이 우수하다.
 
아래 명령을 사용하여 키 암호를 제거한다.
# 키 암호 제거
$ openssl rsa -in 서버IP.key -out 서버IP.np.key
 

사설 인증서 CSR(인증 서명 요청) 만들기

csr 타입의 루트 인증서 서명 요청 파일을 만든다.
앞서 생성한 사설 인증서 키 파일을 사용한다.
 
루트 인증서 서명 요청 파일과 동일한 화면이 출력되는데 동일하게 입력한다.
# 요청서 만들기
$ openssl req -new -key 서버IP.np.key -out 서버IP.csr

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:KR
State or Province Name (full name) []:GG  # 경기도 
Locality Name (eg, city) [Default City]:SN  # 성남시 
Organization Name (eg, company) [Default Company Ltd]:test  # 조직/회사명 입력 
Organizational Unit Name (eg, section) []:unit  # 부서명 입력 
Common Name (eg, your name or your server's hostname) []:test  # 서버 이름 입력 
Email Address []:test@test.com    # 이메일 주소 
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: testcerts  # 공개되도 상관 없는 암호 입력   
  An optional company name []:    # 비워놓고 엔터 (다른 이름 부여 가능)
 
 

사설 인증서 (CRT) 만들기

앞서 생성한 사설 인증서의 Key (키)파일과 CSR (인증 서명 요청) 파일, 그리고 루트 인증서의 CRT 파일을 사용하여 사설 인증서를 생성한다.
# 인증서 만들기
$ openssl x509 -req -days 3650 -extensions v3_user -in 서버IP.csr -CA rootca.crt \
    -CAcreateserial -CAkey rootca.key -out 서버IP.crt
 
암호를 요구하는 경우 CSR 파일을 생성할 때 입력한 암호를 입력한다.
-days 3650 옵션을 부여했으므로 유효 기간은 10년이다.

 

생성 된 인증서 정보 확인은 다음 명령을 사용한다.
# 확인
$ openssl x509 -text -in 서버IP.crt
 

Java Key Stroke File 생성

Jenkins와 Nexus 같은 일부 Java 기반 시스템의 경우 JKS (Java Keystroke) 포맷을 사용하므로 변경해야 한다.
 

PEM 파일로 변경

생성한 사설 인증서의 CRT 파일을 PEM 파일로 변경한다.
## crt를 pem으로 변경
openssl x509 -in 서버IP.crt -out 서버IP.pem -outform PEM
 

PFX 파일 생성

생성 된 PEM 파일을 사용하여 PFX 파일을 생성한다.
## pfx 파일 생성
# 아래 명령 실행 후 password를 입력해야 하는데, 이후 jetty 설정 파일에 평문으로 기입하는데 사용한다.
# 서버에 접속 가능한 다른 사용자가 보아도 되는 password를 입력한다.
$ openssl pkcs12 -export -name 서버IP -in 서버IP.pem -inkey 서버IP.key -out 서버IP.pfx

# password 입력
 

JKS 파일 생성

생성 된 pfx 파일을 사용하여 jks 파일을 생성한다.
## jks 파일 생성
$ keytool -importkeystore -srckeystore 서버IP.pfx -srcstoretype pkcs12 \
    -destkeystore 서버IP.jks -deststoretype jks
# password 입력
## keystore.jks 파일 생성
$ cp 서버IP.jks keystore.jks
 
 

인증서 사용

이제 생성 된 인증서를 사용하여 각 서비스의 HTTPS 설정 적용에 사용하면 된다.
사설 인증서의 CRT 파일과 Key 파일을 주로 사용하며, 경우에 따라 JKS 파일을 사용하기도 한다.
 
각 서비스의 인증서 사용 방법에 맞춰 사용하면 된다.
이 부분은 적용하고자 하는 서비스의 기술 문서를 참고한다.
 
최초 접속시 브라우저에서 빨간 화면을 출력하는 것은 사라진다.
그러나 사설 인증서이므로 브라우저의 주소창에 아래와 같이 빨간 경고 표시로 안전하지 않음으로 표시 된다.
 
내부에서만 운영하거나 테스트 목적인 경우 이 정도만 적용해도 충분히 활용 가능하다.