概要
docker の token 認証を使った場合にどのようなリクエストが docker registry 側から飛んでくるのかを確認したくてダミーの認証サーバを作成して確認してみました
環境
- macOS 11.2.3
- docker 20.10.5
- Ruby 3.0.0
自己署名した SSL 証明書の作成
openssl req -x509 -nodes -new -sha256 -days 1024 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=US/CN=Registry Auth CA"
openssl x509 -outform pem -in RootCA.pem -out RootCA.crt
サーバ SSL 証明書でなければいけません
認証サーバから送られてきたトークン情報を証明書を使って復号化してチェックするためです
今回は registry から送信される情報を確認するだけなので認証サーバで正常なトークンの生成などは行いません
ちなみに証明書が SSL 用でなかったり正常に作成されていないと registry 起動時に 「token auth requires at least one token signing root certificate
」というエラーが表示されます
docker registry 用の設定ファイル作成
auth.token の設定を行います
先程作成した RootCA.crt
を使うように設定します
version: 0.1
log:
fields:
service: registry
storage:
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
delete:
enabled: true
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
auth:
token:
realm: http://host.docker.internal:4567/jwt/auth
service: container_registry
issuer: gitlab-issuer
rootcertbundle: /home/RootCA.crt
realm はダミー認証サーバのエンドポイントを指定します
今回は mac 上で動作させるのと Sinatra を予定しているので上記のエンドポイントを指定します
docker registry 起動
作成した設定ファイルと証明書をマウントするように起動します
docker run -d -p 5000:5000 -v $(pwd)/config.yml:/etc/docker/registry/config.yml -v $(pwd)/RootCA.crt:/home/RootCA.crt registry:2
リクエストを確認するためのダミー認証サーバの作成
先程説明したように Sinatra で作成します
設定ファイルに記載したとおり /jwt/auth
で受けるようにします
vim app.rb
require 'sinatra'
require "sinatra/json"
get '/jwt/auth' do
logger.info params
logger.info request.env.select {|k,v| k.start_with? "HTTP_" }
'auth error'
end
今回はレスポンスを適当に返しているので認証は必ずエラーになります
これでどんなリクエストが registry の token 認証時に送信されているのかが確認できます
動作確認
bundle exec ruby app.rb -o 0.0.0.0
docker login localhost:5000
これでログインしてみると以下のようなログが表示されると思います
I, [2021-04-01T10:22:30.046322 #51291] INFO -- : {"account"=>"root", "client_id"=>"docker", "offline_token"=>"true", "service"=>"container_registry"}
I, [2021-04-01T10:22:30.046940 #51291] INFO -- : {"HTTP_VERSION"=>"HTTP/1.1", "HTTP_ACCEPT_ENCODING"=>"gzip", "HTTP_AUTHORIZATION"=>"Basic cm9vdDph", "HTTP_CONNECTION"=>"close", "HTTP_HOST"=>"host.docker.internal:4567", "HTTP_USER_AGENT"=>"docker/20.10.5 go/go1.13.15 git-commit/363e9a8 kernel/4.19.121-linuxkit os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.5 \\(darwin\\))"}
127.0.0.1 - - [01/Apr/2021:10:22:30 +0900] "GET /jwt/auth?account=root&client_id=docker&offline_token=true&service=container_registry HTTP/1.1" 200 10 0.0096
認証サーバ側では account や HTTP_AUTHORIZATION
の情報を使ってデータベースなどと照合してログイン情報が合っているのかを確認する感じになります
あとは scope などの認可判定なども実装する必要があります
最後に
docker registry の token 時にどのようなリクエストが来るのかをダミーの認証サーバを構築して確認してみました
実際はこれらのリクエスト情報を元に実際に認証するような仕組みを開発する必要があります
自前で作るのが面倒な場合は docker_auth という簡単に構築できる認証サーバもあるのでこれを使ってもよいと思います
0 件のコメント:
コメントを投稿