docker 는 API 를 이용하여 외부에서 접속 할 수 있는 기능이 있다.
하지만 그냥 API를 이용하기에는 보안 위험성이 너무 크기 때문에 SSL 인증서를 적용하여 이용 하는 방법을 알아보도록 하자.
이글은 아래 사이트를 참고하여 작성 되었다.
https://docs.docker.com/engine/security/https/
docker 서버에 접속하여 docker 명령으로 tls 인증을 통한 옵션을 한번 살펴보도록 하자
root@docker-02:~# docker Usage: docker [OPTIONS] COMMAND A self-sufficient runtime for containers Options: --config string Location of client config files (default "/root/snap/docker/384/.docker") -D, --debug Enable debug mode -H, --host list Daemon socket(s) to connect to -l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info") --tls Use TLS; implied by --tlsverify --tlscacert string Trust certs signed only by this CA (default "/root/snap/docker/384/.docker/ca.pem") --tlscert string Path to TLS certificate file (default "/root/snap/docker/384/.docker/cert.pem") --tlskey string Path to TLS key file (default "/root/snap/docker/384/.docker/key.pem") --tlsverify Use TLS and verify the remote -v, --version Print version information and quit
위 예제처럼 tls 의 관련 옵션이 존재 하며 기본 경로는 /root/snap/docker/384/.docker 로 되어 있는것을 확인 할 수 있다.(필자는 snap 으로 docker 를 설치하여 위처럼 경로가 설정 됨)
먼저 기본 경로인 /root/snap/docker/384/.docker 로 이동 하자
> cd /root/snap/docker/384/.docker
OpenSSL을 사용하여 CA, 서버 및 클라이언트 키 만들기
CA 개인 키와 공개 키를 생성 해보자
> openssl genrsa -aes256 -out ca-key.pem 4096 > openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
Common Name 항목에 서버 호스트명을 정확하게 입력하도록 주의하자.
root@docker-02:~/snap/docker/384/.docker# openssl genrsa -aes256 -out ca-key.pem 4096 Generating RSA private key, 4096 bit long modulus …………………………………………………….++ ……………………………………………++ e is 65537 (0x010001) Enter pass phrase for ca-key.pem: Verifying - Enter pass phrase for ca-key.pem: root@docker-02:~/snap/docker/384/.docker# openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem Enter pass phrase for ca-key.pem: 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) [AU]:KR State or Province Name (full name) [Some-State]: Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:docker-02 Email Address []:
$HOST 항목에는 호스트 서버의 도메인이나 ip를 입력한다
>openssl genrsa -out server-key.pem 4096
>openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr
root@docker-02:~/snap/docker/384/.docker# openssl genrsa -out server-key.pem 4096 Generating RSA private key, 4096 bit long modulus ……………………………………………………………………………………………………………….++ ………………………..++ e is 65537 (0x010001) root@docker-02:~/snap/docker/384/.docker# openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr
tls 연결은 DNS 와 ip 주소를 통해 이루어 진다. ip와 DNS를 모두 추가하려면 아래와 같이 입력 한다.
> echo subjectAltName = DNS:$HOST,IP:10.10.10.20,IP:127.0.0.1 >> extfile.cnf
이제 서명된 인증서를 생성 해보자. CN에 DNS 명도 정확한지 확인하자
$ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out server-cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=your.host.com
Getting CA Private Key Enter pass phrase for ca-key.pem:
이제부터는 tls 통신을 위한 클라이언트 측 인증서 파일을 만들어 보도록 하자
> openssl genrsa -out key.pem 4096
> openssl req -subj '/CN=client' -new -key key.pem -out client.csr
> echo extendedKeyUsage = clientAuth > extfile-client.cnf
이제 서명된 인증서를 생성해 보자
> openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile-client.cnf
불필요한 인증서 서명 요청파일을 삭제 하자
> rm -v client.csr server.csr extfile.cnf extfile-client.cnf
실수로 인한 인증서 파일 손상을 막기 위해 권한을 변경 하자
>chmod -v 0400 ca-key.pem key.pem server-key.pem
>chmod -v 0444 ca.pem server-cert.pem cert.pem
이제 인증서 생성작업은 모두 완료 되었다. Docker 서비스를 중지하고 아래 명령으로 실행 해 보자
> service docker stop > docker daemon --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem -H=0.0.0.0:2376
필자는 ubuntu 18 버전에 snap 으로 설치해서 조금 다르게 입력해야 동작 한다.
> snap stop docker > /usr/bin/snap run docker.dockerd --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock
이제 인증서를 클라이언트 서버에 복사 후 아래와 같이 tls 인증을 통한 curl 테스트를 해볼 수 있다.
curl https://$HOST:2376/images/json \
--cert ~/.docker/cert.pem \
--key ~/.docker/key.pem \ --cacert ~/.docker/ca.pem