인증서로 레포지토리 클라이언트 검증하기
인증서로 레포지토리 클라이언트 검증하기
이전에 Docker를 HTTPS로 실행하기에서 Docker가 기본적으로 네트워크에 연결되지 않은 Unix 소켓으로 실행되고, Docker 클라이언트와 데몬이 HTTPS로 안전하게 통신하려면 TLS를 활성화해야 한다는 것을 배웠어요. TLS는 레지스트리 엔드포인트의 신뢰성을 보장하고 레지스트리와 주고받는 트래픽을 암호화해 주죠. 이번 글에서는 Docker 레지스트리 서버와 그 클라이언트인 Docker 데몬 사이의 트래픽을 인증서 기반 클라이언트-서버 인증으로 암호화하고 제대로 인증하는 방법을 보여드릴게요. 레지스트리용 CA 루트 인증서를 설치하는 방법과 검증을 위한 클라이언트 TLS 인증서를 설정하는 방법도 함께 알아볼게요.
출처: 공식문서
설정 이해하기
사용자 정의 인증서는 데몬의 인증서 루트 디렉터리 아래에 레지스트리 호스트 이름과 같은 이름의 디렉터리를 만들어서 구성해요. 예를 들어 localhost처럼요. 이 디렉터리에 있는 모든 *.crt 파일은 CA 루트로 추가돼요.
인증서 루트가 어디에 있는지는 플랫폼에 따라 달라져요.
- 네이티브 Linux 엔진:
/etc/docker/certs.d/ - Rootless Linux:
$XDG_CONFIG_HOME/docker/certs.d(기본값은~/.config/docker/certs.d)이고,/etc/docker/certs.d가 아니에요. - 네이티브 Windows 엔진(Windows 컨테이너):
%PROGRAMDATA%\docker\certs.d(보통C:\ProgramData\docker\certs.d). 레지스트리 주소에 포트가 포함되어 있으면 Windows 파일 이름에는:를 쓸 수 없으므로 디렉터리 이름에서 콜론을 빼야 해요. 예를 들어registry.example.com:5000은registry.example.com5000이 돼요. - Linux 컨테이너를 사용하는 Docker Desktop: 호스트의
~/.docker/certs.d에 클라이언트 인증서를 넣어요. Docker Desktop이 VM으로 복사하니까 VM 안에서 직접/etc/docker/certs.d를 구성하지 마세요. 신뢰할 수 있는 CA는 호스트 인증서 저장소(Windows에서는 Windows 인증서 저장소)에서 가져올 수도 있어요.
참고: Linux에서는 모든 루트 인증 기관이 시스템 기본값(호스트의 루트 CA 세트 포함)과 병합돼요. Windows Server에서 Docker를 실행하거나 Windows 컨테이너용 Docker Desktop for Windows를 사용하는 경우, 사용자 정의 루트 인증서가 구성되어 있지 않을 때만 시스템 기본 인증서가 사용돼요.
하나 이상의 <filename>.key/cert 쌍이 있으면 Docker는 원하는 레포지토리에 접근하는 데 사용자 정의 인증서가 필요하다고 인식해요.
참고: 인증서가 여러 개 있으면 알파벳 순서로 하나씩 시도해요. 4xx 또는 5xx 수준의 인증 오류가 발생하면 Docker는 다음 인증서로 계속 시도해요.
다음은 사용자 정의 인증서를 사용하는 구성 예시예요.
/etc/docker/certs.d/ <-- Certificate directory
└── localhost:5000 <-- Hostname:port
├── client.cert <-- Client certificate
├── client.key <-- Client key
└── ca.crt <-- Root CA that signed
the registry certificate, in PEM
앞의 예시는 운영 체제에 따라 다르고 설명을 위한 것일 뿐이에요. OS에서 제공하는 번들 인증서 체인을 만들려면 운영 체제 문서를 참조해야 해요.
클라이언트 인증서 만들기
OpenSSL의 genrsa와 req 명령을 사용해서 먼저 RSA 키를 생성하고, 그 키로 인증서를 만들어요.
$ openssl genrsa -out client.key 4096
$ openssl req -new -x509 -text -key client.key -out client.cert
참고: 이 TLS 명령은 Linux에서만 제대로 동작하는 인증서 세트를 생성해요. macOS의 OpenSSL 버전은 Docker가 요구하는 인증서 유형과 호환되지 않아요.
문제 해결 팁
Docker 데몬은 .crt 파일을 CA 인증서로, .cert 파일을 클라이언트 인증서로 해석해요. CA 인증서에 실수로 .crt 대신 .cert 확장자를 사용하면 Docker 데몬이 다음 오류 메시지를 기록해요.
Missing key KEY_NAME for client certificate CERT_NAME. CA certificates should use the extension .crt.
포트 번호 없이 Docker 레지스트리에 접근한다면 디렉터리 이름에 포트를 추가하지 마세요. 다음은 기본 포트 443을 사용하고 docker login my-https.registry.example.com으로 접근하는 레지스트리의 구성 예시예요.
/etc/docker/certs.d/
└── my-https.registry.example.com <-- Hostname without port
├── client.cert
├── client.key
└── ca.crt