티스토리 뷰

 


A. 개요

duckdns와 letsencrypt로 public 인증서를 만들어 사용할 수 있지만 굳이 대외 서비스를 제공하는 시스템이 아닌, 내부에서만 사용하는 도메인의 경우에는 사설인증서만으로도 충분합니다.
 
root 기관 인증서를 만들고, 해당 인증서로 자체 서명 인증서(사설인증서)를 만드는 방법을 소개합니다.


인증서는 다음과 같은 순서로 생성합니다.

  • root기관 인증서 : key생성(.key) > 요청생성(.req) > 인증서 생성(.csr)
  • 사설인증서 : key생성(.key) > 요청생성(.req) > 인증서 생성(.csr) > 서명된 인증서 발급(.crt)

하나의 root기관 인증서로 여러 개의 사설인증서에 서명을 할 수 있습니다. 
참고로 서명된 인증서를 발급할 때 root기관 인증서에 비밀번호가 있다면 해당 비밀번호가 필요합니다.
 


B. 인증서 만들기

 
인증서를 만들기 위해서는 사용할 도메인이 필요합니다.
도메인은 구매해야 하지만, 테스트를 위해 hosts 파일에 domain을 설정 후 테스트 할 겁니다.
사용할 도메인은 pray.light으로 정하고 인증서를 만들어 보겠습니다.
 
작업할 경로는 /vagrant/certs라는 경로에서 한다고 가정합니다.
 
작업 전에 작업 경로를 만들어 주고 이동하겠습니다.

mkdir -p  /vagrant/certs && cd /vagrant/certs

 


1. root 인증서

 
 

(1) Key 생성

key를 생성할 때 비밀번호를 지정할 수 있습니다.
여기서는 "rootcapw1234"라는 비밀번호를 사용합니다.
이 비밀번호는 다시 확인할 수 없으므로, 꼭 잘 메모해 두시기 바랍니다.
 

openssl genrsa -aes256 -out rootca.key -passout pass:rootcapw1234
chmod 600 rootca.key

 

rootca.key 파일 생성

 

 

(2) CSR(Certificate signing request) 파일 생성

 
아래와 같이 rootca.conf 파일을 만듭니다.
 

cat << EOF > rootca.conf
[ req ]
default_bits            = 2048
default_md              = sha1
default_keyfile         = rootca.key
distinguished_name      = req_distinguished_name
extensions              = v3_ca
req_extensions          = v3_ca
 
[ v3_ca ]
basicConstraints         = critical, CA:TRUE, pathlen:0
subjectKeyIdentifier     = hash
##authorityKeyIdentifier = keyid:always, issuer:always
keyUsage                 = keyCertSign, cRLSign
nsCertType               = sslCA, emailCA, objCA

[req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = KR
countryName_min                 = 2
countryName_max                 = 2

# 회사명 입력
organizationName                = Organization Name (eg, company)
organizationName_default        = W.B.B corp.
 
# 부서 입력
organizationalUnitName          = Organizational Unit Name (eg, section)
organizationalUnitName_default  = DevOps Team.
 
## SSL 서비스할 domain 명 입력
commonName                      = Common Name (eg, your name or your server's hostname)
commonName_default              = W.B.B Certificate Trust Root
commonName_max                  = 64 
EOF

 
rootca의 인증서 서명 요청을 합니다.

openssl req -new -key rootca.key -out rootca.csr -config rootca.conf -passin pass:rootcapw1234

 

rootca의 csr 생성

default 값은 conf 파일에 있는 값으로 출력되니까 그냥 엔터만 눌러도 됩니다.
 

csr 파일 생성 화면

 

 

(3) CRT(Certificate) 파일 생성

rootca 인증서를 생성합니다.
10년(3650일) 짜리 인증서를 만들겠습니다.
기간은 원하시는 대로 설정하시면 됩니다.

openssl x509 -req -days 3650 -extensions v3_ca -set_serial 1 -in rootca.csr -signkey rootca.key -out rootca.crt -extfile rootca.conf -passin pass:rootcapw1234
rootca 의 crt 생성

 

# Check rootca certificate
openssl x509 -text -in rootca.crt

 
 Validity의 Not After 항목은 유효기간입니다. 2034년까지, 10년짜리 인증서가 만들어졌습니다.
이 기간 동안 사설인증서를 이 rootca를 이용해서 서명할 수 있습니다.

rootca 인증서 확인 결과

2. 사설 인증서 생성

 

(1) Key 생성

사설인증서를 만들기 위해서도 같은 방법으로 Key를 만듭니다.
비밀번호는 pass1234로 정하겠습니다.

openssl genrsa -aes256 -out private-cert.key.enc -passout pass:pass1234

 
그런데, 실제로 이 사설인증서를 사용하기 위해서는 비밀번호가 없어야 합니다.
그래서 Key에서 비밀번호를 제거합니다.

openssl rsa -in private-cert.key.enc -out private-cert.key -passin pass:pass1234

 

사설 인증서 key 파일 생성 화면

 

 

 

(2) CSR(Certificate signing request) 파일 생성

 
사설인증서 signing request를 하기 위한 conf 파일을 만듭니다.

cat << EOF > private-cert.conf
[ req ]
default_bits            = 2048
default_md              = sha1
default_keyfile         = rootca.key
distinguished_name      = req_distinguished_name
extensions              = v3_user
## 인증서 요청시에도 extension 이 들어가면 authorityKeyIdentifier 를 찾지 못해 에러가 나므로 막아둔다.
## req_extensions = v3_user

[ v3_user ]
# Extensions to add to a certificate request
basicConstraints       = CA:FALSE
authorityKeyIdentifier = keyid,issuer
subjectKeyIdentifier   = hash
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
## SSL 용 확장키 필드
extendedKeyUsage = serverAuth,clientAuth
subjectAltName         = @alt_names
[ alt_names]
## Subject AltName의 DNSName field에 SSL Host 의 도메인 이름을 적어준다.
## 멀티 도메인일 경우 *.prayoflight.com 처럼 쓸 수 있다.
DNS.1   = prayoflight.com 
DNS.2   = pray.light
DNS.3   = *.pray.light

[req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = KR
countryName_min                 = 2
countryName_max                 = 2

# 회사명 입력
organizationName              = Organization Name (eg, company)
organizationName_default      = pray's tistory.
 
# 부서 입력
organizationalUnitName          = Organizational Unit Name (eg, section)
organizationalUnitName_default  = tistory blog.
 
# SSL 서비스할 domain 명 입력
commonName                      = Common Name (eg, your name or your server's hostname)
commonName_default              = pray.light
commonName_max                  = 64
EOF

 
csr 파일을 만듭니다.

openssl req -new  -key private-cert.key -out private-cert.csr -config private-cert.conf

 

사설 인증서의 CSR 파일 생성 화면

 

 

 

(3) CRT(Certificate) 파일 생성

5년짜리(1825일) 인증서를 만듭니다.
이때 rootca.crt와 rootca의 비밀번호가 필요합니다.

openssl x509 -req -days 1825 -extensions v3_user -in private-cert.csr -CA rootca.crt -CAcreateserial -CAkey  rootca.key -out pray.light.crt  -extfile private-cert.conf -passin pass:rootcapw1234

 
 

사설 인증서 생성(rootca 인증서로 signing)
openssl x509 -text -in pray.light.crt
인증서 생성 결과 확인

5년짜리 인증서가 만들어졌습니다.
발급 기관(Issuer)과  인증서 발급 정보(Subject)가 설정한 정보로 출력되는 것을 확인할 수 있습니다.
 
 


C. Nginx에 설정하고 테스트하기

 
지금까지 생성된 인증서로 test.pray.light라는 주소로 접속 가능한 사이트를 설정해 보겠습니다.


1. 설정

 

(1) Nginx 설치

 
Nginx 가 설치 되어 있지 않다면 아래 명령어로 설치합니다.
 

sudo apt update -y && sudo apt install nginx -y

 
 
Docker 가 설치 되어 있다면  Docker로 설치해도 됩니다.
2024.08.21 - [Infra] - DuckDns + LetsEncrypt로 Nginx HTTPS설정

DuckDns + LetsEncrypt로 Nginx HTTPS설정

프로젝트 초기에는 도메인 및 인증서가 없는 상황이 대부분이다. 하지만 backing system들 중, SSL 인증서가 필요한 환경도 있을 수 있다.(가령 docker registry 등…) 이때, public 도메인과 공인 인증서를

tack0829.tistory.com

 
 
 
 


(2) hosts 파일 설정

hosts에 정보를 등록합니다.
물론 ip는 실제 Nginx 서버의 IP를 넣으셔야 하겠죠?

192.168.0.141 pray.light test.pray.light

 


2. Nginx에 SSL 인증서 복사

 

cd /etc/nginx

 
인증서를 복사해 줍니다.
만든 인증서가 home 경로에 있다고 가정합니다.

sudo mkdir -p ./ssl.d ./ssl

# 기존 파일 삭제
sudo rm -f /etc/nginx/ssl/*

# key 파일과 인증서 복사
sudo cp /vagrant/certs/private-cert.key /etc/nginx/ssl/
sudo cp /vagrant/certs/pray.light.crt /etc/nginx/ssl/

 

nginx 에 적용할 key와 인증서 파일 복사

 
 

ssl option 파일을 만듭니다.

cat << EOF | sudo tee ./ssl.d/ssl.location.opt
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_pass_header Server;
    proxy_set_header X-Scheme \$scheme;
    proxy_set_header Host \$host;
    proxy_set_header X-Real-IP \$remote_addr;
    proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto "https";
EOF

3. Nginx에 SSL 사이트 설정

사이트를 설정해 줍니다.
이때 crt와 key 파일을 경로에 맞게 설정해 줍니다.
주소는 test.pray.light 로 하겠습니다.

cat << EOF | sudo tee ./conf.d/pray.light.conf
server {
    listen 80;
    server_name pray.light *.pray.light;
    return 301 https://\$host\$request_uri;
 }
server {
    listen 443 ssl;
    server_name pray.light test.pray.light;

    ssl_certificate "/etc/nginx/ssl/pray.light.crt";
    ssl_certificate_key "/etc/nginx/ssl/private-cert.key";
    location / {
        include ssl.d/ssl.location.opt;
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
 }
server {
    listen 443 ssl;
    server_name *.pray.light;
    deny all;
 }
EOF

 
nginx 설정을 Test 해 줍니다.

sudo nginx -t
nginx 설정 테스트

 
설정이 이상 없다면 재기동합니다.

sudo nginx -s reload


4. 접속

브라우저로 https://test.pray.light 으로 접속해 봅니다.
 
접속해 보면 주소 옆에 "안전하지 않음"이라는 경고가 뜹니다.
해당 경고를 클릭해서 아래 순서로 들어가 보면 인증서 설정된 게 보입니다.

인증서 정보 여는 방법

 
순서대로 클릭해 보면 아래와 같이 인증서 정보가 팝업으로 출력됩니다.

인증서 정보

 
 
발급자와 발급대상, 유효 기간이 생성한 정보대로 출력되고 있다면 Nginx의 인증서 정보는 이상이 없이 설정되었다고 생각하시면 됩니다.
 
그런데도 저런 경고가 출력되는 건 발급자 정보가 알 수 없는 인증 기관이기 때문입니다.
이제, 로컬 컴퓨터에서 해당 인증기관을 신뢰할 수 있도록 신뢰하는 인증 기관의 인증서로 등록하도록 합니다.
 


5. RootCA 인증서 설치

 
 

(1) Ubuntu에서 확인

아래 명령으로 인증서를 복사합니다.

sudo cp /vagrant/certs/rootca.crt /usr/local/share/ca-certificates/

 
인증서 정보를 갱신합니다.

sudo update-ca-certificates --fresh

 
이제 openssl로 테스트해 봅니다.

openssl s_client -connect test.pray.light:443
openssl 로 ssl 인증서 적용 확인

verify return:1 로 출력 되는지 확인하면 됩니다.
 
이제 curl로 확인해 보면 정상적으로 html 응답이 오면 됩니다.

 

(2) 사용자 컴퓨터가 Windows 인 경우

 
mmc를 실행합니다.

관리콘솔 실행(mmc)

 
 
인증서 스냅인을 추가합니다.

스냅인 추가
인증서 스냅인 추가
컴퓨터 계정
로컬컴퓨터

 
 
이제  rootca인증서를 가져옵니다.

 

신뢰하는 인증기관에 등록할 rootca.crt 파일을 선택 함

 
 

 
정상적으로 가져왔으면 아래와 같이 알림 창이 뜹니다.

 
가져온 인증서를 확인할 수 있습니다.

발급대상으로 등록된 인증서를 확인할 수 있습니다.

 
 


6. Browser에서 최종 설정 확인

 
이제 브라우저를 껐다 켠 이후 다시 접속해 보시면 정상적으로 설정되어 보이는 걸 확인할 수 있습니다.
 

인증서가 정상적으로 설정 된 결과

 
즉, 이 인증서가 적용되기 위해서는 rootca 인증서를 신뢰할 수 있는 루트 인증 기관으로 등록하는 작업을 한번 거쳐야 합니다.