1. 개요
Docker REST API는 기본적으로 ID와 Password를 통한 인증을 제공하지 않기때문에 외부프로그램등의 인증관리 기능을 사용하거나 방화벽을 이용하여 접근가능한 IP나 네트워크 대역을 제한하고 사용해야 안전하며 SSL/TLS 인증서를 적용하여 인증서를 소유하지 아니한 비인가IP에서 접근하는것을 차단하고 가급적 외부에 REST API Port(Default 2375)는 Open을 지양한다.
2. Docker Daemon SSL인증서 생성 및 적용방법
1) 운영중인 Docker Daemon에 SSL 인증서 적용여부 확인
ps -ef | grep dockerd |
2) CA와 public key 생성(국가나 도시의 경우 공백으로 두어도 상관없다)
openssl genrsa -aes256 -out ca-key.pem 4096 openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem |
3) 서버키 생성
openssl genrsa -out server-key.pem 4096 |
4) 인증요청서 생성($HOST 부분은 사용중인 IP나 도메인을 입력한다)
– 만약 Can’t load /root/.rnd into RNG 와 같은 에러가 발생하면 무시해도 된다.
openssl req -subj “/CN=$HOST” -sha256 -new -key server-key.pem -out server.csr |
5) extfile 생성($HOST 부분은 사용중인 IP나 도메인을 입력한다)
echo subjectAltName = IP:$HOST,IP:127.0.0.1 > extfile.cnf |
6) 서버측 인증서 생성
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf |
7) 클라이언트 측 파일 생성
openssl genrsa -out key.pem 4096 openssl req -subj ‘/CN=client’ -new -key key.pem -out client.csr echo extendedKeyUsage = clientAuth > extfile.cnf |
8) 클라이언트측 인증서 생성
openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf |
9) 인증요청서 삭제 및 권한설정
rm -v client.csr server.csr chmod -v 0400 ca-key.pem key.pem server-key.pem chmod -v 0444 ca.pem server-cert.pem cert.pem |
10) Docker 데몬실행
dockerd –debug –tls=true –tlsverify –tlscacert=ca.pem –tlscert=server-cert.pem –tls key=server-key.pem -H=0.0.0.0:2376 |
3. SSL 인증서 사용방법(Client)
– 생성된 인증서 파일을 클라이언트로 복사하여 임의의 경로에 붙여넣고 해당 인증서를 사용하여 Docker 명령어를 실행해야 한다. Client에서 필요한 인증서는 ca.pem , cert.pem , key.pem이다(2번 인증서 생성방법으로 생성 시)
ex) docker –tlsverify –tlscacert=ca.pem –tlscert=cert.pem –tlskey=key.pem -H=192.168.56.127:2376 ps -a
4. Docker 클라이언트 실행화면
Docker Daemon Client | SSL 인증서 미적용(TCP 2375) | SSL 인증서 적용(TCP 2376) |
Client 인증서 없음 | 접속가능(취약) | 인증서를 찾을 수 없음 에러 발생4-1,2 |
Client 인증서 있음 | – | SSL 접속가능4-3 |
1) 클라이언트 인증서가 없는경우(Linux)
→ 클라이언트 인증서 경로를 지정해줘야하나 해당 경로에 인증서가 없으므로 인증서를 찾을 수 없다는 에러 발생
→ 인증서를 지정하지 않을경우 HTTP 요청으로 인식하기때문에 경고 발생
2) 클라이언트 인증서가 없는경우(Windows)
→ 윈도우의 경우에도 브라우저 인증서에서 제공하지 않는 인증서이므로 에러 발생
3-3) Client(인증서 있음) -> Daemon:2376(SSL 적용) 접속시
→ 정상접근
3-4) Client -> Docker Daemon:2376(SSL 적용) Non SSL 요청시
→ 서버에 SSL이 적용되어있으나 Non-SSL 요청으로 인해 서버측에서 경고를 Response하고 있다.
4) Docker Auth Plugin 적용방법
4-1) 모든 요청을 허용할 빈정책 정의
mkdir -p /etc/docker/policies cat >/etc/docker/policies/authz.rego <<EOF package docker.authz allow = true EOF |
4-2) opa-docker-authz 플러그인 설치
docker plugin install openpolicyagent/opa-docker-authz-v2:0.4 opa-args=”-policy-file /opa/policies/authz.rego” ============================== SSL 적용시 ================================ docker –tlsverify –tlscacert=ca.pem –tlscert=cert.pem –tlskey=key.pem -H=$HOST:2375 plugin install openpolicyagent/opa-docker-authz-v2:0.4 opa-args=”-policy-file /opa/policies/authz.rego” |
4-3) Docker 데몬 구성파일 생성
cat > /etc/docker/daemon.json <<EOF { “authorization-plugins”: [“openpolicyagent/opa-docker-authz-v2:0.4”] } EOF |
4-4) Docker 구성파일 reload
kill -HUP $(pidof dockerd) |
4-5) 모든 요청을 거부하도록 정책수정
cat > /etc/docker/policies/authz.rego <<EOF package docker.authz allow = false EOF |
4-6) docker-authz 플러그인 동작테스트(All Deny)
– Client -> Non-SSL Docker Daemon 요청시
→ request rejected by administrative policy 메시지 발생
추가적인 사용자별 접근제어 등은 아래사이트를 참고
상세설명 : https://www.openpolicyagent.org/docs/v0.11.0/docker-authorization/
좋은정보 감사합니다.