Docker와 인증서 (2/2)

squareBird·2022년 4월 5일
0

Docker

목록 보기
3/3
post-thumbnail

Docker의 인증서

앞의 글에서 설명드렸던 것 처럼 인증서가 신뢰할 수 있다는 것을 증명하기 위해서는 인증서 체인을 통해 해당 인증서Root 인증서를 찾을 수 있어야 합니다.

그렇다면 Docker에 올라갈 컨테이너들이 인증서를 사용하기 위해서는 어떻게 해야할까요?
Docker가 설치된 서버의 어딘가에 해당 서버의 인증서Root CA의 인증서가 존재해야 합니다.


CA 인증서와 Server 인증서의 구분

먼저 DockerCA 인증서Server 인증서를 어떻게 구분할까요?
Docker는 확장자를 통해 인증서를 구분합니다.

/etc/docker/certs.d/{server 정보}/ 디렉토리에 위치하는 파일의 확장자가
crt일 경우 CA 인증서로 인식하고, cert일 경우 서버의 인증서로 인식합니다.


인증서 생성 실습

그렇다면 실제로 인증서를 생성하는 실습을 진행해 보겠습니다.

실습의 절차는 다음과 같습니다.

  1. AWS EC2를 이용해 VM 생성
  2. 해당 서버를 Root CA로 만들기 위해 Root 인증서 생성
  3. 웹 서비스가 사용할 SSL 인증서를 생성
  4. 해당 인증서Root 인증서를 통해 서명

1. 서버 생성

먼저 실습을 진행하기 위해 EC2를 생성하겠습니다.
AWS EC2를 생성하고, 공인 IP를 부여해 SSH를 통해 접속하겠습니다.

Server Name : Docker
Public IP : 13.125.70.250
OS : Ubuntu 20.04

2. Root 인증서 생성

먼저 Docker를 설치하겠습니다.

# Docker 설치
$ apt-get update
$ apt-get install docker.io
$ systemctl start docker

다음으로 Root 인증서를 생성하겠습니다.

# 1. 인증서 보관 폴더 생성
$ mkdir ~/certs
$ cd ~/certs

# 2. Root CA 비밀키 생성
$ openssl genrsa -out ca.key 4096

# 3. Root CA의 비밀키를 이용해 비밀키와 쌍을 이루는 공개키 생성
$ openssl req -x509 -new -nodes -sha512 -days 365 \
-key ca.key \ 
-out ca.crt

# 4. 인증기관 정보 입력
Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:Korea
Locality Name (eg, city) []:Seoul
Organization Name (eg, company) [Internet Widgits Pty Ltd]:SquareBird
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:fails9503@gmail.com

# 5. 생성된 인증서 확인
$ ll
total 16
drwxr-xr-x 2 root   root   4096 Apr  5 02:06 ./
drwxr-xr-x 5 ubuntu ubuntu 4096 Apr  5 02:06 ../
-rw-r--r-- 1 root   root   2029 Apr  5 02:05 ca.crt # Root CA의 공개키
-rw------- 1 root   root   3243 Apr  5 02:05 ca.key # Root CA의 개인키

3. 서버 인증서 생성

다음은 서버 인증서를 생성하겠습니다.

# 1. Server의 비밀키 생성
$ openssl genrsa -out server.key 4096

# 2. Server의 CSR 파일 생성
$ openssl req -sha512 -new \
-key server.key \
-out server.csr

# 3. 서버 정보 입력
Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:Korea
Locality Name (eg, city) []:Suwon
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Velog
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:

# 4. 인증서 확인
$ ll
total 24
drwxr-xr-x 2 root   root   4096 Apr  5 02:11 ./
drwxr-xr-x 5 ubuntu ubuntu 4096 Apr  5 02:06 ../
-rw-r--r-- 1 root   root   2029 Apr  5 02:05 ca.crt # Root CA의 공개키
-rw------- 1 root   root   3243 Apr  5 02:05 ca.key # Root CA의 개인키
-rw-r--r-- 1 root   root   1639 Apr  5 02:11 server.csr # Server의 공개키
-rw------- 1 root   root   3243 Apr  5 02:10 server.key # Server의 개인키

4. Root CA를 통해 Server 인증서 생성

# 1. 접속할 서버 정보 정의
#    사설 IP, Local(127.0.0.1), 공인IP 정보 입력
$ cat > v3ext.cnf <<-EOF
subjectAltName = IP:10.0.1.89,IP:127.0.0.1,IP:13.125.70.250
EOF

# 2. CA를 통한 인증작업 수행
$ openssl x509 -req -sha512 -days 365 \
-extfile v3ext.cnf \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in server.csr \
-out server.crt

# 3. 서명 완료 확인
Signature ok
subject=C = KR, ST = Korea, L = Suwon, O = Velog
Getting CA Private Key

# 4. Docker가 서버 인증서로 인식하도록 하기 위해 crt파일 cert로 변환
$ openssl x509 -inform PEM -in server.crt -out server.cert

위의 2번 작업을 보면 extfile을 통해 서버의 정보를 전달합니다.
그리고 server.csrCA의 키를 통해 서명을 완료하여 server.crt 파일을 만들어냅니다.

그리고 맨 위에 설명했던 것 처럼 Dockercrt 파일CA 인증서로, cert 파일은 서버 인증서로 인식하므로 서버 인증서로 인식하도록 하기 위해 해당 server.crt 파일을 cert로 변환해줍니다.

5. Docker에 인증서 등록

# 인증서 등록
$ sudo mkdir -p /etc/docker/certs.d/13.125.70.250
$ cp server.cert /etc/docker/certs.d/13.125.70.250/
$ cp server.key /etc/docker/certs.d/13.125.70.250/
$ cp ca.crt /etc/docker/certs.d/13.125.70.250/

# Docker 재시작
$ systemctl restart docker

6. 테스트

# 1. Docker Nginx 컨테이너 실행
$ docker run -d -p 80:80 -p 443:443 --name certificate-test nginx

# 2. 컨테이너 확인
$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS        PORTS                                                                      NAMES
15f2dd00252d   nginx     "/docker-entrypoint.…"   2 seconds ago   Up 1 second   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp   certificate-test
profile
DevOps...

0개의 댓글