2023年5月6日土曜日

OSSのコンテナレジストリ「Harbor」を自己署名証明書でHTTPS通信させる

以前、OSSのコンテナレジストリ「Harbor」を構築する手順を記載した。

上記手順では、手順簡略化のためにHarborとDocker間をHTTPにて通信するよう構成したが、本来HarborもDockerもHTTPSによるSSL通信を前提としている。

そこで今回は、Harborに自己署名証明書を登録し、HarborとDocker間をHTTPSにて通信できるよう構成してみた。

環境

Harbor自体はDockerコンテナとして動作する。Harbor及びDockerが動作するOSとしてはAlmaLinuxを使用した。

  • OS : AlmaLinux release 8.6
  • Docker : 23.0.5
  • Docker Compose : v2.17.3
  • Harbor : v2.8.0

Harborをインストールするサーバのホスト名とIPアドレスは以下となり、DNSで名前解決できる状態としてある。

  • ホスト名 : t1050harb
  • IPアドレス : 192.168.11.50

自己署名証明書作成

自己署名証明書のSSLサーバ証明書の作成手順は、以下記事を参照すること。

本記事では、手順の概要のみ記載する。

1. 秘密鍵の作成

秘密鍵を作成するディレクトリは任意の場所で問題ないが、不特定多数が見れないディレクトリが望ましい。

今回は/etc/pki/tls/misc/に作成することとする。秘密鍵はopensslコマンドを使って以下の通り作成する。

# cd /etc/pki/tls/misc/
# openssl genrsa 2048 > server.key

2. CSRを作成

作成した秘密鍵からCSRを作成する。

# openssl req -new -key server.key > server.csr

オレオレ認証局として構築済みのサーバに、先ほど作成したserver.csrをコピーし、/etc/pki/tls/misc/newreq.pemというファイル名で配置する。

3. SAN情報を作成

近年のサーバ証明書は、Common Nameに記載された情報ではなく、SAN(Subject Alternative Name; サブジェクト代替名)と呼ばれる情報に記載されたFQDNやIPアドレスの情報と、接続先のURLが一致することを確認する。

今回は、SANの情報として、Harborのホスト名、FQDN、IPアドレスを登録するようにした。

# cd /etc/pki/tls/misc/
# cat << EOF > san.txt
subjectAltName = DNS:t1050harb, DNS:t1050harb..example.com, IP:192.168.11.50
EOF

4. オレオレ認証局にて署名

CSRへの署名はCAスクリプトを用いて実施する。Red Hat 8以降のopensslにはCAスクリプトが含まれていないため、以前のバージョンのRPMなどから入手すること。

# ./CA -sign

作成された証明書はnewcert.pemという名前で保存されるので、ファイル名を変えておこう。

# ls -l newcert.pem
-rw-r--r-- 1 root root 4199  4月 29 13:08 newcert.pem
cp newcert.pem server_t1050harb.crt

5. 秘密鍵とサーバ証明書を配置

作成した秘密鍵とサーバ証明書は、それぞれ以下ディレクトリに配置する。

証明書 ファイル名 ディレクトリ
サーバ証明書 server_t1050harb.crt /etc/pki/tls/certs/
秘密鍵 server_t1050harb.key /etc/pki/tls/private/

Harborインストール

Harborのインストール手順も大きくは以前の記事の手順と変わらない。

インストール時に使用する設定ファイルであるharbor.ymlのみ差異があるため、その個所を抜粋して記載する。

1. harbor.ymlの修正

HTTPSで通信させる場合は、harbor.ymlの修正箇所は以下3か所のみとなる。

  • hostname
  • certificate
  • private_key

harbor.yml

# Configuration file of Harbor

# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: t1050harb.example.com ←★ホスト名を設定する。DNSなどで名前解決できる場合はFQDN設定が望ましい

# http related config
http:
  # port for http, default is 80. If https enabled, this port will redirect to https port
  port: 80

# https related config
https:
  # https port for harbor, default is 443
  port: 443
  # The path of cert and key files for nginx
  certificate: /etc/pki/tls/certs/server_t1050harb.crt ←★サーバ証明書のパスを指定
  private_key: /etc/pki/tls/private/server_t1050harb.key ←★秘密鍵のパスを指定

~(以下略)~

4. ログイン確認

harbor.yml修正後インストールを行い、HarborのGUIに以下デフォルトユーザー・パスワードでアクセスしてみよう。

  • ユーザー名 : admin
  • パスワード : Harbor12345

ブラウザで証明書情報を確認すると、作成した自己署名証明書でHTTPS通信されていることが確認できる。オレオレ認証局のCA証明書を「信頼されたルート証明機関」の証明書として登録しておけば、ブラウザの証明書エラーも表示されることなくアクセスできる。

DockerからHarborへ接続

次にDockerからHTTPSで接続するための設定を行う。結論から言うと、単純に何もしないと以下の通りdocker loginした際にx509: certificate signed by unknown authorityのエラーで失敗する。

# docker login 192.168.11.50
Username: admin
Password:
Error response from daemon: Get "https://192.168.11.50/v2/": x509: certificate signed by unknown authority

1. オレオレ人書局のCA証明書を「信頼されたルート証明機関」の証明書として配置

エラーを解消するために、オレオレ人書局のCA証明書を信頼される証明書として配置する。Dockerの場合はOSの証明書設定とは別に、以下ルールに沿った配置が必要となる。

  • ディレクトリは/etc/docker/certs.d/[FQDN or IPアドレス]で作成する
  • CA証明書のファイルはca.crtというファイル名にする

今回は、DockerからIPアドレスで接続するため、192.168.11.50でフォルダを作成し、CA証明書を配置する。

# mkdir -p /etc/docker/certs.d/192.168.11.50
# cp /tmp/ca.crt /etc/docker/certs.d/192.168.11.50/ca.crt

2. Dcokerから接続確認

Doockerからの接続確認は、docker loginコマンドで行う。ユーザ名・パスワードは、HarborのGUIログイン時に使用するものと同じとなる。

  • ユーザー名 : admin
  • パスワード : Harbor12345

以下のようにLogin Succeededと表示されれば成功となる。

# docker login 192.168.11.50
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

もし、以下のようにService Unavailableのエラーが表示される場合は、何らかの理由でコンテナレジストリへの接続に失敗している。

# docker login 192.168.11.50
Username: admin
Password:
Error response from daemon: Get "https://192.168.11.50/v2/": Get "https://t1050harb..example.com/service/token?account=admin&client_id=docker&offline_token=true&service=harbor-registry": Service Unavailable

Service Unavailableのエラーの場合は、そもそも接続に失敗している可能性がある。DNSの名前解決(DNSを使えない場合はhostsにレコードを登録する)や、プロキシ除外設定(IPアドレスだけでなくFQDNも除外する)などの設定に問題がないか確認してみよう。

最後に、docker logoutを実行し、認証情報の削除を行う。

# docker logout 192.168.11.50
Removing login credentials for 192.168.11.50

以上で、Harborに自己署名証明書を登録し、HarborとDocker間をHTTPSにて通信できるよう構成する手順は完了となる。

0 件のコメント:

コメントを投稿

人気の投稿