2018年7月22日日曜日

GitLab + GitLab Runner にクライアント認証を導入する

前回 の続き。 クライアント認証できるようにしていく。

環境

PATH_TO_WORKING_DIR も前回と同じ。

クライアント証明書作成

前回準備した openssl 環境でクライアント証明書を作る。

openssl 環境を実行

$WORKING_DIR="PATH_TO_WORKING_DIR"
cd $WORKING_DIR\work
docker-compose.exe run --rm openssl /bin/bash

openssl 環境での作業

CLIENT_COMMON="client.mikoto2000.example.com"
CLIENT_KEY_FILE="/client/${CLIENT_COMMON}.key"
CLIENT_CSR_FILE="/client/${CLIENT_COMMON}.csr"
CLIENT_CRT_FILE="/client/${CLIENT_COMMON}.crt"

CLIENT_COUNTRY="JP"
CLIENT_STATE="Tokyo"
CLIENT_LOCALITY="foo-ku"
CLIENT_ORGANIZATION="bar Inc."
CLIENT_ORGANIZATIONAL_UNIT="baz"
CLIENT_EMAIL="mikoto2000@gmail.com"

# クライアント秘密鍵作成
openssl genrsa -out ${CLIENT_KEY_FILE} 2048

# クライアント証明書要求作成
CLIENT_SUBJECT="/C=${CLIENT_COUNTRY}/ST=${CLIENT_STATE}/L=${CLIENT_LOCALITY}/O=${CLIENT_ORGANIZATION}/OU=${CLIENT_ORGANIZATIONAL_UNIT}/CN=${CLIENT_COMMON}"
openssl req -new -key ${CLIENT_KEY_FILE} -out ${CLIENT_CSR_FILE} -subj "${CLIENT_SUBJECT}"

# クライアント証明書要求確認
openssl req -noout -text -in ${CLIENT_CSR_FILE}

### クライアント証明書作成
cd /client

yes | openssl ca -out ${CLIENT_CRT_FILE} -infiles ${CLIENT_CSR_FILE}

### p12 形式に変換
COMMON="client.mikoto2000.example.com"
CACERT_FILE=/ca/cacert.pem
KEY_FILE=/client/${COMMON}.key
CRT_FILE=/client/${COMMON}.crt
P12_FILE=/client/${COMMON}.p12
openssl pkcs12 -export -out ${P12_FILE} -inkey ${KEY_FILE} -in ${CRT_FILE} -certfile ${CACERT_FILE}

gitlabの設定

設定ファイルの更新

docker-compose.yml を更新する。

version: '3'
services:
    gitlab:
        image: gitlab/gitlab-ce:11.0.1-ce.0
        restart: always
        hostname: gitlab.example.com
        container_name: gitlab.example.com
        volumes:
            - gitlab_etc:/etc/gitlab
            - gitlab_log:/var/log/gitlab
            - gitlab_opt:/var/opt/gitlab
        environment:
            GITLAB_OMNIBUS_CONFIG: |
                external_url 'https://gitlab.example.com/'
                gitlab_rails['gitlab_shell_ssh_port'] = 8022
                nginx['redirect_http_to_https'] = true
                nginx['redirect_http_to_https_port'] = 80
                nginx['ssl_verify_client'] = "on"
                nginx['ssl_client_certificate'] = '/etc/gitlab/trusted-certs/ca.crt'
                nginx['ssl_crl'] = '/etc/gitlab/CA.crl'
        ports:
            - "80:80"
            - "443:443"
            - "8022:22"
        networks:
            gitlab_net:
                ipv4_address: 172.16.238.2
    gitlab-runner:
        image: gitlab/gitlab-runner:v11.0.0
        restart: always
        hostname: gitlab-runner.example.com
        container_name: gitlab-runner.example.com
        volumes:
            - gitlab-runner_config:/etc/gitlab-runner
            - /var/run/docker.sock:/var/run/docker.sock
        depends_on:
            - gitlab
        networks:
            gitlab_net:
                ipv4_address: 172.16.238.3

networks:
    gitlab_net:
        ipam:
            config:
            - subnet: 172.16.238.0/24

volumes:
    gitlab_etc:
        external: true
    gitlab_log:
        external: true
    gitlab_opt:
        external: true
    gitlab-runner_config:
        external: true
  • nginx['ssl_verify_client'] = "on" : クライアント認証を on
  • nginx['ssl_client_certificate'] = '/etc/gitlab/trusted-certs/cacert.pem' : クライアント認証する際に信頼する ca 証明書の場所を指定
  • nginx['ssl_crl'] = '/etc/gitlab/CA.crl' : 失効リストの場所

証明書コピー

GitLab が信頼する CA 証明書を設置する。

適当なコンテナを起動して、コピー。

docker run -it --rm -v "PATH_TO_WORKING_DIR/work/client:/client" -v "gitlab_etc:/gitlab_etc" debian:stretch-slim /bin/bash
cp /client/ca.crt /gitlab_etc/trusted-certs/

gitlab-runner の設定

設定ファイルを変更

gitlab-runner のコンテナ内の /etc/gitlab-runner/config.toml を編集し、 クライアント認証用の設定を行う。

cd $PATH_TO_WORKING_DIR
docker-compose up -d
docker-compose exec gitlab-runner vi /etc/gitlab-runner/config.toml

/etc/gitlab-runner/config.toml を編集し、 tls-cert-file, tls-key-file を追加する。

/etc/gitlab-runner/config.toml

concurrent = 1
check_interval = 0

[[runners]]
  name = "gitlab-runner"
  url = "https://gitlab.example.com/"
  token = "a6219b6094d056e471105e5b026aec"
  executor = "docker"
  environment = ["GODEBUG=netdns=cgo"]
  tls-cert-file = "/etc/gitlab-runner/mycert/client.mikoto2000.example.com.crt"
  tls-key-file = "/etc/gitlab-runner/mycert/client.mikoto2000.example.com.key"
  [runners.docker]
    tls_verify = false
    image = "debian:stretch-slim"
    privileged = false
    disable_cache = false
    volumes = ["/cache"]
    extra_hosts = ["gitlab.example.com:172.16.238.1"]
    shm_size = 0
  [runners.cache]

[[runners]]
  name = "gitlab-runner"
  url = "https://gitlab.example.com/"
  token = "2c55ab3d9289874bfb7e265d37678b"
  executor = "docker"
  environment = ["GODEBUG=netdns=cgo"]
  tls-cert-file = "/etc/gitlab-runner/mycert/client.mikoto2000.example.com.crt"
  tls-key-file = "/etc/gitlab-runner/mycert/client.mikoto2000.example.com.key"
  [runners.docker]
    tls_verify = false
    image = "debian:stretch-slim"
    privileged = false
    disable_cache = false
    volumes = ["/cache"]
    extra_hosts = ["gitlab.example.com:172.16.238.1"]
    shm_size = 0
  [runners.cache]
  • tls-cert-file = "/etc/gitlab-runner/mycert/client.mikoto2000.example.com.crt" : クライアント認証に使うクライアント証明書の配置場所を指定
  • tls-key-file = "/etc/gitlab-runner/mycert/client.mikoto2000.example.com.key" : クライアント認証に使うクライアントの秘密鍵配置場所を指定

証明書・秘密鍵をコンテナにコピー

docker-compose exec gitlab-runner mkdir /etc/gitlab-runner/mycert
docker cp c:/Users/mikoto/project/gitlab-runner5/work/client/client.mikoto2000.example.com.crt 7875f5d4c9e2:/etc/gitlab-runner/mycert/
docker cp c:/Users/mikoto/project/gitlab-runner5/work/client/client.mikoto2000.example.com.key 7875f5d4c9e2:/etc/gitlab-runner/mycert/

動作確認

前回作った job を retry してみる。ok.

参考資料

2018年7月19日木曜日

GitLab + GitLab Runner を HTTPS にする

前回 の続き。 HTTPS 通信できるようにしていく。

環境

証明書の準備

証明書作成環境構築

PowerShell 上での作業

$WORKING_DIR="PATH_TO_WORKING_DIR"
mkdir $WORKING_DIR\work
cd $WORKING_DIR\work

curl https://raw.githubusercontent.com/mikoto2000/docker-images/324bc3d5f81ad602dc9c35280f9cfe6f1dd0484a/openssl/docker-compose.yml -OutFile .\docker-compose.yml

mkdir usr_lib_ssl
curl https://raw.githubusercontent.com/mikoto2000/docker-images/324bc3d5f81ad602dc9c35280f9cfe6f1dd0484a/openssl/usr_lib_ssl/openssl.cnf -OutFile .\usr_lib_ssl\openssl.cnf

curl https://raw.githubusercontent.com/mikoto2000/docker-images/324bc3d5f81ad602dc9c35280f9cfe6f1dd0484a/openssl/usr_lib_ssl/v3_ca.txt -OutFile .\usr_lib_ssl\v3_ca.txt

docker-compose run --rm openssl /bin/bash

CA 構築

openssl コンテナ内での作業

### 各種情報定義
CA_KEY_FILE="/ca/private/cakey.pem"
CA_CSR_FILE="/ca/ca.csr"
CA_CRT_FILE="/ca/cacert.pem"

CA_COUNTRY="JP"
CA_STATE="Tokyo"
CA_LOCALITY="foo-ku"
CA_ORGANIZATION="bar Inc."
CA_ORGANIZATIONAL_UNIT="baz"
CA_COMMON="gitlab.example.com"
CA_EMAIL="mikoto2000@gmail.com"

### CA 初期化開始
cd /ca

# 各種ディレクトリ作成
mkdir cert private crl newcerts
chmod 700 private

# シリアル初期化
echo "01" | tee -a serial

# crlnumber 初期化
echo "01" | tee -a crlnumber

# インデックス初期化
touch index.txt

### CA 鍵と CA 証明書作成開始
# CA 用秘密鍵作成
openssl genrsa -out ${CA_KEY_FILE} 2048

# CA 証明書要求作成
CA_SUBJECT="/C=${CA_COUNTRY}/ST=${CA_STATE}/L=${CA_LOCALITY}/O=${CA_ORGANIZATION}/OU=${CA_ORGANIZATIONAL_UNIT}/CN=${CA_COMMON}"
openssl req -new -key ${CA_KEY_FILE} -out ${CA_CSR_FILE} -subj "${CA_SUBJECT}"

# CA 証明書要求確認
openssl req -noout -text -in $CA_CSR_FILE

# CA 証明書作成
openssl x509 -req -in $CA_CSR_FILE -signkey $CA_KEY_FILE -out $CA_CRT_FILE -extfile /usr/lib/ssl/v3_ca.txt

# 証明書コピー
cp $CA_CRT_FILE /client/ca.crt

サーバー証明書作成

openssl 環境での作業

CLIENT_COMMON="gitlab.example.com"
CLIENT_KEY_FILE="/client/${CLIENT_COMMON}.key"
CLIENT_CSR_FILE="/client/${CLIENT_COMMON}.csr"
CLIENT_CRT_FILE="/client/${CLIENT_COMMON}.crt"

CLIENT_COUNTRY="JP"
CLIENT_STATE="Tokyo"
CLIENT_LOCALITY="foo-ku"
CLIENT_ORGANIZATION="bar Inc."
CLIENT_ORGANIZATIONAL_UNIT="baz"
CLIENT_EMAIL="mikoto2000@gmail.com"

# クライアント秘密鍵作成
openssl genrsa -out ${CLIENT_KEY_FILE} 2048

# クライアント証明書要求作成
CLIENT_SUBJECT="/C=${CLIENT_COUNTRY}/ST=${CLIENT_STATE}/L=${CLIENT_LOCALITY}/O=${CLIENT_ORGANIZATION}/OU=${CLIENT_ORGANIZATIONAL_UNIT}/CN=${CLIENT_COMMON}"
openssl req -new -key ${CLIENT_KEY_FILE} -out ${CLIENT_CSR_FILE} -subj "${CLIENT_SUBJECT}"

# クライアント証明書要求確認
openssl req -noout -text -in ${CLIENT_CSR_FILE}

### クライアント証明書作成
cd /client

yes | openssl ca -out ${CLIENT_CRT_FILE} -infiles ${CLIENT_CSR_FILE}

サーバー設定

docker-compose.yml

version: '3'
services:
    gitlab:
        image: gitlab/gitlab-ce:11.0.1-ce.0
        restart: always
        hostname: gitlab.example.com
        container_name: gitlab.example.com
        volumes:
            - gitlab_etc:/etc/gitlab
            - gitlab_log:/var/log/gitlab
            - gitlab_opt:/var/opt/gitlab
        environment:
            GITLAB_OMNIBUS_CONFIG: |
                external_url 'https://gitlab.example.com/'
                gitlab_rails['gitlab_shell_ssh_port'] = 8022
                nginx['redirect_http_to_https'] = true
                nginx['redirect_http_to_https_port'] = 80
        ports:
            - "80:80"
            - "443:443"
            - "8022:22"
        networks:
            gitlab_net:
                ipv4_address: 172.16.238.2
    gitlab-runner:
        image: gitlab/gitlab-runner:v11.0.0
        restart: always
        hostname: gitlab-runner.example.com
        container_name: gitlab-runner.example.com
        volumes:
            - gitlab-runner_config:/etc/gitlab-runner
            - /var/run/docker.sock:/var/run/docker.sock
        depends_on:
            - gitlab
        networks:
            gitlab_net:
                ipv4_address: 172.16.238.3

networks:
    gitlab_net:
        ipam:
            config:
            - subnet: 172.16.238.0/24

volumes:
    gitlab_etc:
        external: true
    gitlab_log:
        external: true
    gitlab_opt:
        external: true
    gitlab-runner_config:
        external: true
  • external_urlhttps に修正
  • ports443:443 を追加
  • GITLAB_OMNIBUS_CONFIG に下記を追加
    • nginx['redirect_http_to_https'] = true
    • nginx['redirect_http_to_https_port'] = 80

証明書の配置

PowerShell 上での作業

cd $WORKING_DIR
docker run -it --rm -v "$WORKING_DIR\work\client:/client" -v "gitlab-runner_config:/gitlab-runner_config" -v "gitlab_etc:/gitlab_etc" debian:stretch-slim /bin/bash

コンテナ内での作業

# gitlab にコピー
mkdir /gitlab_etc/ssl
chmod 700 /gitlab_etc/ssl
cp /client/gitlab.example.com.key /client/gitlab.example.com.crt /gitlab_etc/ssl

# gitlab-runner にコピー(※ CA の証明書をコピー)
cp /client/ca.crt /gitlab-runner_config/certs/gitlab.example.com.crt

# config.toml 内の `http` を `https` に修正(※ いくつか runner がある場合には、ちゃんとエディタで編集しましょう)
sed -i -e '{s/http:\/\//https:\/\//}' /gitlab-runner_config/config.toml

exit

動作確認

docker-compose up -d

のあと、前回の job を retry して動作確認。 ok.

参考資料

2018年7月16日月曜日

Docker Compose で GitLab + GitLab Runner の環境を整える

前回 の続きから GitLab Runner を追加しようと思ったのだが、 想像以上に苦労してしまったので、もっとミニマムなところから構築していくことにした。

今回は、 Docker Compose で GitLab + GitLab Runner を組み合わせる手順を記録する。

環境

ボリュームリセット

docker container prune
docker volume rm gitlab_etc gitlab_opt gitlab_log gitlab-runner_config
docker volume create gitlab_etc; docker volume create gitlab_log; docker volume create gitlab_opt; docker volume create gitlab-runner_config

gitlab & gitlab-runner の設定

docker-compose.yml の準備

version: '3'
services:
    gitlab:
        image: gitlab/gitlab-ce:11.0.1-ce.0
        restart: always
        hostname: gitlab.example.com
        container_name: gitlab.example.com
        volumes:
            - gitlab_etc:/etc/gitlab
            - gitlab_log:/var/log/gitlab
            - gitlab_opt:/var/opt/gitlab
        environment:
            GITLAB_OMNIBUS_CONFIG: |
                external_url 'http://gitlab.example.com/'
                gitlab_rails['gitlab_shell_ssh_port'] = 8022
        ports:
            - "80:80"
            - "8022:22"
        networks:
            gitlab_net:
                ipv4_address: 172.16.238.2
    gitlab-runner:
        image: gitlab/gitlab-runner:v11.0.0
        restart: always
        hostname: gitlab-runner.example.com
        container_name: gitlab-runner.example.com
        volumes:
            - gitlab-runner_config:/etc/gitlab-runner
            - /var/run/docker.sock:/var/run/docker.sock
        depends_on:
            - gitlab
        networks:
            gitlab_net:
                ipv4_address: 172.16.238.3

networks:
    gitlab_net:
        ipam:
            config:
            - subnet: 172.16.238.0/24

volumes:
    gitlab_etc:
        external: true
    gitlab_log:
        external: true
    gitlab_opt:
        external: true
    gitlab-runner_config:
        external: true

今回は、 172.16.238.0/24 のネットワークに gitlab, gitlab-runner のコンテナをぶら下げる形で docker-compose.yml を作成。

下記設定(+ Runnar への設定)をしないと Failed to connect to gitlab.example.com port 80: Connection refused といわれて CI が成功しない。(参考資料の「ワークアラウンド」参照)

  • この後、 extra_hosts(手動設定) で名前解決の指定をする必要があるため、コンテナ固定 IP の設定を行う
    • services/SERVICE_NAME/networks/NETWORK_NAME/ipv4_address
      • 今回は下記の通り設定した
        • gitlab: 172.16.238.2
        • gitlab-runner: 172.16.238.3
    • networks/NETWORK_NAME/ipam/config
      • 今回は下記の通り設定した
        • subnet: 172.16.238.0/24
  • gitlab-runnergitlab に依存しているのでその設定
    • services/gitlab-runner/depends_on

コンテナ起動

$Env:COMPOSE_CONVERT_WINDOWS_PATHS=1
docker-compose up -d

$Env:COMPOSE_CONVERT_WINDOWS_PATHS=1 をすることで、 /var/run/docker.sock:/var/run/docker.sock が良い感じになる。 環境変数に設定しましょう。

ここまでの動作確認

hosts127.0.0.1 gitlab.example.com を追加してブラウザで gitlab.example.com にアクセスする。

  1. root パスワード設定
  2. 一般ユーザー作成
  3. test プロジェクト作成

ここまでやっておく。

gitlab に gitlab-runner の登録

「ここまでの動作確認」で作成した test プロジェクトから、必要な情報を取得する。

  1. プロジェクト -> Settings -> CI / CD と選択していく
  2. Runners settings に記載されている URLregistration token をメモ

GitLab Runner を起動して登録

「gitlab に gitlab-runner の登録」 の情報をもとに Runner を登録する。

  • GITLAB_HOST_NAME: メモした URL のホスト部分
  • GITLAB_IP: 作った subnet の IP アドレス 1
  • REGISTRATION_TOKEN: メモした registration token
$REGISTRATION_TOKEN="REGISTRATION_TOKEN"
$GITLAB_HOST_NAME="GITLAB_HOST_NAME"
$GITLAB_IP="172.16.238.1"
docker-compose exec gitlab-runner gitlab-runner register `
    --non-interactive `
    --name gitlab-runner `
    --url http://${GITLAB_HOST_NAME}/ `
    --registration-token ${REGISTRATION_TOKEN} `
    --executor docker `
    --env "GODEBUG=netdns=cgo" `
    --docker-image debian:stretch-slim `
    --tag-list test `
    --docker-extra-hosts "${GITLAB_HOST_NAME}:${GITLAB_IP}"
  • --env "GODEBUG=netdns=cgo", --docker-extra-hosts "${GITLAB_HOST_NAME}:${GITLAB_IP}"
    • gitlab-runner の CI 内は、 docker-compose の hotsnamecontainer_name の仕組みの外で名前解決が行われているらしい(参考資料の「ワークアラウンド」参照)ので、これらワークアラウンドの設定を行う

CI 動作確認

リポジトリ初期化

mkdir test
cd test
git init

.gitlab-ci.yml の準備

vim .gitlab-ci.yml

.gitlab-ci.yml

image: debian:stretch-slim

stages:
    - hello

print_hello:
    stage: hello
    tags:
        - test
    script:
        - echo Hello, World!

変更の push

git add .gitlab-ci.yml
git commit -m 'First commit.'
git remote add origin http://gitlab.example.com/mikoto/test.git
git push -u origin master

Runner を登録済みなので、 CI / CD のページに行けばジョブが見えるはず。

  1. プロジェクト -> CI / CD -> Jobs と選択していく
  2. Job 1 の passed ボタンを押下
  3. 下記みたいなログが出力されていれば OK
Running with gitlab-runner 11.0.0 (5396d320)
  on gitlab-runner c22e7436
Using Docker executor with image debian:stretch-slim ...
Pulling docker image debian:stretch-slim ...
Using docker image sha256:3e235dbb0ba6811e57b8d805536b3a9678aa6b11046c7019d93eef4cf4a0f7cc for debian:stretch-slim ...
Running on runner-c22e7436-project-1-concurrent-0 via gitlab-runner.example.com...
Cloning repository...
Cloning into '/builds/mikoto/test'...
Checking out 5c956c15 as master...
Skipping Git submodules setup
$ echo Hello, World!
Hello, World!
Job succeeded

ok, 引き続き HTTPS 化していきたい。

参考資料

更新履歴

日付 更新内容
2018/7/16 新規作成
2019/7/12 GITLAB_IP に何を設定すればよいのかわかりにくかったので、実際使った IP に修正

2018年7月1日日曜日

GitLab の Docker image で HTTPS とクライアント認証の設定をする

この前は、 HTTPS 通信までだったが、 HTTPS + クライアント認証をしたくなったので試す。

環境

イメージ取得

docker pull gitlab/gitlab-ce:11.0.1-ce.0
docker pull mikoto2000/openssl:latest

仕切り直しのためにボリュームを作り直す

docker container prune
docker volume rm gitlab_etc gitlab_opt gitlab_log
docker volume create gitlab_etc; docker volume create gitlab_log; docker volume create gitlab_opt

各種証明書作成

証明書作成用環境準備

作業用ディレクトリを作成し mikoto2000/openssl 環境を整える。

そして

  • CA
  • サーバー証明書
  • クライアント証明書

を作る。

# ディレクトリを作成して移動
mkdir PATH_TO_GITLAB_BASE/work
cd PATH_TO_GITLAB_BASE/work

設定ファイルを持ってくる

# docker-compose.yml
curl https://raw.githubusercontent.com/mikoto2000/docker-images/324bc3d5f81ad602dc9c35280f9cfe6f1dd0484a/openssl/docker-compose.yml -OutFile .\docker-compose.yml

# openssl.cnf
mkdir usr_lib_ssl
curl https://raw.githubusercontent.com/mikoto2000/docker-images/324bc3d5f81ad602dc9c35280f9cfe6f1dd0484a/openssl/usr_lib_ssl/openssl.cnf -OutFile .\usr_lib_ssl\openssl.cnf

# v3_ca.txt
curl https://raw.githubusercontent.com/mikoto2000/docker-images/324bc3d5f81ad602dc9c35280f9cfe6f1dd0484a/openssl/usr_lib_ssl/v3_ca.txt -OutFile .\usr_lib_ssl\v3_ca.txt

移行、「CA」「サーバー」「クライアント」の作業は、この openssl 環境で作業する。

openssl 環境の利用方法

docker-compose run --rm openssl /bin/bash

CA, サーバー, クライアントの分を全部一気に作ってしまう。

CA

CA 初期化

CA の仕事。

cd /ca

# 各種ディレクトリ作成
mkdir cert private crl newcerts
chmod 700 private

# シリアル初期化
echo "01" | tee -a serial

# crlnumber 初期化
echo "01" | tee -a crlnumber

# インデックス初期化
touch index.txt

CA 鍵と CA 証明書作成

CA の仕事。

KEY_FILE="/ca/private/cakey.pem"
CSR_FILE="/ca/ca.csr"

# CA 用秘密鍵作成
openssl genrsa -out ${KEY_FILE} 2048

# CA 証明書要求作成
COUNTRY="JP"
STATE="Tokyo"
LOCALITY="foo-ku"
ORGANIZATION="bar Inc."
ORGANIZATIONAL_UNIT="baz"
COMMON="localhost"
EMAIL="test@example.com"
SUBJECT="/C=${COUNTRY}/ST=${STATE}/L=${LOCALITY}/O=${ORGANIZATION}/OU=${ORGANIZATIONAL_UNIT}/CN=${COMMON}"
openssl req -new -key ${KEY_FILE} -out ${CSR_FILE} -subj "${SUBJECT}"

# CA 証明書要求確認
openssl req -noout -text -in /ca/ca.csr

# CA 証明書作成
openssl x509 -req -in /ca/ca.csr -signkey /ca/private/cakey.pem -out /ca/cacert.pem -extfile /usr/lib/ssl/v3_ca.txt

証明書のコピー

CA 証明書受け渡しのために /client ディレクトリにコピー

cp /ca/cacert.pem /client

サーバー

鍵と証明書要求の作成

サーバーの仕事。

COMMON="localhost"
KEY_FILE="/client/${COMMON}.key"
CSR_FILE="/client/${COMMON}.csr"

# クライアント秘密鍵作成
openssl genrsa -out ${KEY_FILE} 2048

# クライアント証明書要求作成
COUNTRY="JP"
STATE="Tokyo"
LOCALITY="foo-ku"
ORGANIZATION="bar Inc."
ORGANIZATIONAL_UNIT="baz"
EMAIL="test@example.com"
SUBJECT="/C=${COUNTRY}/ST=${STATE}/L=${LOCALITY}/O=${ORGANIZATION}/OU=${ORGANIZATIONAL_UNIT}/CN=${COMMON}"
openssl req -new -key ${KEY_FILE} -out ${CSR_FILE} -subj "${SUBJECT}"

# クライアント証明書要求確認
openssl req -noout -text -in ${CSR_FILE}

証明書作成

CA の仕事。

COMMON="localhost"
CRT_FILE="/client/${COMMON}.crt"
CSR_FILE="/client/${COMMON}.csr"

cd /client

openssl ca -out ${CRT_FILE} -infiles ${CSR_FILE}

クライアント

鍵と証明書要求の作成

クライアントの仕事。

COMMON="client.example.com"
KEY_FILE="/client/${COMMON}.key"
CSR_FILE="/client/${COMMON}.csr"

# クライアント秘密鍵作成
openssl genrsa -out ${KEY_FILE} 2048

# クライアント証明書要求作成
COUNTRY="JP"
STATE="Tokyo"
LOCALITY="foo-ku"
ORGANIZATION="bar Inc."
ORGANIZATIONAL_UNIT="baz"
EMAIL="test@example.com"
SUBJECT="/C=${COUNTRY}/ST=${STATE}/L=${LOCALITY}/O=${ORGANIZATION}/OU=${ORGANIZATIONAL_UNIT}/CN=${COMMON}"
openssl req -new -key ${KEY_FILE} -out ${CSR_FILE} -subj "${SUBJECT}"

# クライアント証明書要求確認
openssl req -noout -text -in ${CSR_FILE}

証明書作成

CA の仕事。

COMMON="client.example.com"
CRT_FILE="/client/${COMMON}.crt"
CSR_FILE="/client/${COMMON}.csr"

cd /client

openssl ca -out ${CRT_FILE} -infiles ${CSR_FILE}

p12 形式に変換

クライアントの仕事。

COMMON="client.example.com"
CACERT_FILE=/ca/cacert.pem
KEY_FILE=/client/${COMMON}.key
CRT_FILE=/client/${COMMON}.crt
P12_FILE=/client/${COMMON}.p12
openssl pkcs12 -export -out ${P12_FILE} -inkey ${KEY_FILE} -in ${CRT_FILE} -certfile ${CACERT_FILE}

GitLab の設定

GitLab のドキュメント Enable 2-way SSL Client Authentication の通りに設定する

docker-compose.yml の作成

cd PATH_TO_GITLAB_BASE
vim docker-compose.yml

docker-compose.yml

version: '3'
services:
    gitlab:
        image: gitlab/gitlab-ce:11.0.1-ce.0
        restart: always
        hostname: 'localhost'
        volumes:
            - gitlab_etc:/etc/gitlab
            - gitlab_log:/var/log/gitlab
            - gitlab_opt:/var/opt/gitlab
        environment:
            GITLAB_OMNIBUS_CONFIG: |
                external_url 'https://localhost:443/'
                nginx['redirect_http_to_https'] = true
                nginx['redirect_http_to_https_port'] = 80
                nginx['ssl_verify_client'] = "on"
                nginx['ssl_client_certificate'] = '/etc/gitlab/trusted-certs/cacert.pem'
                nginx['ssl_crl'] = '/etc/gitlab/CA.crl'
                gitlab_rails['gitlab_shell_ssh_port'] = 8022
        ports:
            - "80:80"
            - "443:443"
            - "8022:22"

volumes:
    gitlab_etc:
        external: true
    gitlab_log:
        external: true
    gitlab_opt:
        external: true

HTTPS の設定にプラスして下記を追加。

  • nginx['ssl_verify_client']: クライアント認証設定("on" or "off")
  • nginx['ssl_client_certificate']: クライアント認証に使う CA 証明書のパス
  • nginx['ssl_crl']: 失効リストのパス

鍵・証明書の配置

GitLab の初回起動に先立って、別コンテナで鍵と証明書を gitlab_etc の所定の位置に格納しておく。

docker run --rm -it -v "PATH_TO_GITLAB_BASE/work/client:/client" -v "gitlab_etc:/etc/gitlab" debian:stretch-slim /bin/bash
mkdir -p /etc/gitlab/trusted-certs
cp /client/CA.crl /etc/gitlab/
cp /client/cacert.pem /etc/gitlab/trusted-certs/
mkdir -p /etc/gitlab/ssl
chmod 700 /etc/gitlab/ssl
cp /client/localhost.crt /client/localhost.key /etc/gitlab/ssl

firefox に証明書を追加

クライアント証明書

  1. メニュー -> オプション -> プライバシーとセキュリティ -> 証明書証明書を表示 ボタンを押下
  2. あなたの証明書インポート ボタンを押下
  3. クライアント証明書(client.example.com.p12) を選択

CA 証明書

  1. メニュー -> オプション -> プライバシーとセキュリティ -> 証明書証明書を表示 ボタンを押下
  2. 認証局証明書インポート ボタンを押下
  3. CA 証明書(cacert.pem) を選択

動作確認

GitLab 起動

docker-compose up -d

ブラウザでアクセス

  1. localhost にアクセス
  2. 個人証明書の要求ダイアログが出てくるので、 firefox に登録した証明書を選択

ok なはず。

参考文献