序章

GoCD は、テストとリリースのプロセスを自動化するように設計された強力な継続的インテグレーションおよびデリバリープラットフォームです。 GoCDは、ビルドの比較、複雑なワークフローの視覚化、ビルドバージョンの追跡の自動化などの多くの高度な機能を備えており、チームが十分にテストされたソフトウェアを本番環境に提供するのに役立つ柔軟なツールです。

前回の記事では、 GoCDサーバーをインストールし、エージェントをセットアップし、認証を構成しました。 このガイドでは、信頼できるLet’s Encrypt SSL証明書を使用して、Webインターフェイスにアクセスする際のブラウザーの警告を防ぐようにGoCDを構成します。 2つの異なる可能な構成の手順を提供します。

最初の方法では、接続をGoCDのHTTPエンドポイントに転送するリバースプロキシとしてNginxWebサーバーをインストールします。 この選択により、よりシームレスなLet’s Encryptエクスペリエンスが提供され、ほとんどの人にとっておそらく最良のオプションになります。

ここで説明する2番目の方法では、Let’s Encryptから証明書を取得してから、GoCDのHTTPSエンドポイントで使用される証明書を切り替えます。 これにより、別のWebサーバーが不要になり、リソースが節約される可能性がありますが、GoCDは、Let’sEncryptが提供する証明書形式と直接互換性のないJavaキーストアSSL証明書リポジトリを使用します。 更新が発生するたびに、証明書を期待される形式に自動的に変換するスクリプトを作成する必要があります。 このオプションは、サーバーのリソースが最小限で、利用可能なすべてのものをGoCD自体に割り当てたい場合に最適です。

前提条件

Ubuntu 16.04でGoCDサーバーをまだ構成していない場合は、このガイドを開始する前に構成する必要があります。 ベースサーバーには、少なくとも2GのRAMと2つのCPUコアが必要です。 GoCDには、アーティファクトの保存に使用する専用のパーティションまたはディスクも必要です。 次の2つのガイドのいずれかを使用して、この追加スペースを構成する方法を学ぶことができます。

  • サーバーホストとしてDigitalOceanを使用している場合は、アーティファクトの保存場所としてブロックストレージボリュームを使用できます。 このガイドに従って、 DigitalOceanブロックストレージボリュームをプロビジョニング、フォーマット、およびマウントする方法を学習してください。
  • DigitalOceanを使用していない場合は、このガイドに従って、汎用ホストでデバイスをパーティション分割、フォーマット、およびマウントする方法を学習してください。

サーバーのセットアップ後、次のガイドを使用して、初期構成を実行し、GoCDをインストールできます。

Let’s EncryptからSSL証明書を取得するには、サーバーにドメイン名が必要です。

さらなる要件は、追求したい方法によって異なり、適切なセクションで説明されます。 続行する準備ができたら、使用する方法を選択し、関連する手順に従います。

オプション1:GoCDのリバースプロキシとしてNginxを構成する

NginxをGoCDのSSL終端リバースプロキシとして設定する場合は、このセクションに従ってください。 この構成では、Let’sEncrypt証明書を使用してHTTPSトラフィックを処理するようにNginxが構成されます。 クライアント接続を復号化し、通常のHTTPを使用してトラフィックをGoCDのWebインターフェイスに転送します。 これには、Nginxフロントエンドに追加のオーバーヘッドが必要ですが、より簡単なアプローチです。

追加要件

NginxをGoCDのリバースプロキシとして使用する場合は、最初にNginxとLet’s Encryptクライアントをインストールしてから、ドメインの証明書をリクエストする必要があります。 これらのチュートリアルは、証明書を取得してWebサーバーを構成するために必要な手順を提供します。

上記のガイドを完了した後も、次の方法で自己署名証明書を使用してGoCDにアクセスできるはずです。 https://your_domain:8154 ポート指定を削除すると、Let’sEncrypt証明書を使用してデフォルトのNginxページが表示されます。

これで、クライアント接続がLet’s Encrypt証明書で暗号化されるように、GoCDバックエンドにリクエストをプロキシするようにNginxを構成できます。

GoCDのHTTPWebインターフェイスにプロキシするためのNginxの構成

Let’s EncryptからSSL証明書をダウンロードし、デフォルトのSSLポートでリクエストを処理するときに証明書を使用するようにNginxを構成しました。 次のステップは、ポート8153で利用可能なGoCDの通常のHTTPWebインターフェイスにこれらのリクエストをプロキシするようにNginxを構成することです。

開始するには、Let’sEncrypt証明書を使用するように構成されているデフォルトのNginxサーバーブロックファイルを開きます。

  1. sudo nano /etc/nginx/sites-available/default

ファイルの上部、外部 server ブロックして、新しいものを開きます upsteam セクション。 このブロックを呼びます gocd 後で簡単に認識できるようにします。 内部で、NginxがGoCDのHTTPインターフェースに接続するために使用できるアドレスを指定します。 この場合、これはローカルループバックデバイスを使用するため、完全なアドレスは次のようになります。 127.0.0.1:8153:

/ etc / nginx / sites-available / default
upstream gocd {
    server 127.0.0.1:8153;
}

server {
    . . .

次に、 server ブロック、見つけます location / ブロック。 内部で、コメントアウトします try_files プロキシ構成を指定できるようにするためのディレクティブ。 の代わりに try_files 行、プロキシパスをに追加します gocd を使用して定義したアップストリーム http:// プロトコル。 を含める proxy_params ロケーションブロックに必要な他のプロキシ設定を設定するファイル:

/ etc / nginx / sites-available / default
. . .

server
    . . .

    location / {
        #try_files $uri $uri/ =404;
        proxy_pass http://gocd;
        include proxy_params;
    }
    
    . . .

終了したら、ファイルを保存して閉じます。

コマンドラインに戻ったら、次のように入力して、構文エラーがないかNginx構成を確認します。

  1. sudo nginx -t

エラーが見つからない場合は、次のように入力してNginxサービスを再起動します。

  1. sudo systemctl restart nginx

これで、GoCD Web UIに、通常のドメイン名からアクセスできるようになります。 https:// プロトコル。

注: Nginxを介してポート80と443でリクエストをプロキシしていますが、ファイアウォールで8154HTTPSポートを開いたままにする必要があります。 サーバーがクライアントのSSL証明書を直接検証できるように、GoCDエージェントはGoCDサーバーに直接(プロキシなしで)接続できる必要があります。 ポート8154を開いたままにしておくと、外部エージェントがサーバーに正しく接続できるようになりますが、ブラウザを介した通常のWebリクエストはプロキシを経由できます。

調整する必要がある最後の項目は、GoCDのWebUI内のサイトURL設定です。

新しいアドレスを使用するようにGoCDサイトのURLを更新する

Nginxを再起動した後の残りのタスクは、GoCDが適切なリンクを構築するために内部で使用するサイトURL設定を変更することだけです。

WebブラウザでGoCDサーバードメインにアクセスし、必要に応じてログインします。

https://example.com

次に、上部のメニューバーで ADMIN をクリックし、ドロップダウンメニューからサーバー構成を選択します。

サーバー管理セクションで、サイトURLを変更して :8154 最後からポート指定。 以前にドメイン名の代わりにIPアドレスを使用していた場合は、ドメイン名も使用するようにURLを変更します。

ページの一番下までスクロールし、 SAVE をクリックして、変更をすぐに実装します。 これで、Nginxを介してドメインのすべてのリクエストをGoCDWebUIにプロキシするようにサイトが設定されました。

オプション2:Let’sEncrypt証明書を使用するようにGoCDのネイティブSSLを構成する

Let’s Encrypt証明書を使用するようにGoCD独自のWebサーバーを構成する場合は、このセクションに従ってください。 この構成では、GoCDサーバーですでに使用されている自己署名証明書を、Let’sEncryptによって提供される信頼できる証明書に置き換えます。 ただし、これを行うには、証明書ファイルを新しい形式に変換し、Javaキーストアファイルにインポートする必要があります。 証明書ファイルが更新されるたびにプロセスを繰り返すことができるように、スクリプトを作成します。

追加要件

GoCD自体からすべてのSSL操作を処理する場合は、Webサーバーの構成手順なしでLet’sEncryptから証明書をダウンロードする必要があります。 このガイドに従って適切なクライアントをダウンロードし、ドメインの証明書を取得してください。

上記のガイドを完了した後も、次の方法で自己署名証明書を使用してGoCDにアクセスできるはずです。 https://your_domain:8154 Let’s Encryptが提供する証明書ファイルは、 /etc/letsencrypt/live/your_domain ディレクトリ。

証明書変換スクリプトの作成

GoCDは、Javaキーストアを使用してSSL証明書を処理します。 残念ながら、これはLet’sEncryptで使用されている形式とは異なります。 Let’s Encrypt証明書をGoCDで使用するには、非常に特殊な手順を使用して証明書を変換する必要があります。

手順が複雑で、更新するたびに証明書を変換する必要があるため、手順を自動化するスクリプトを作成します。 の中に /usr/local/bin ディレクトリ、作成して、というスクリプトを開きます convert_certs_for_gocd.sh テキストエディタで:

  1. sudo nano /usr/local/bin/convert_certs_for_gocd.sh

中に、次のスクリプトを貼り付けます。 更新する必要がある唯一の設定は、 base_domain 変数。 これをGoCDサーバーのドメイン名に設定します(これは、内のディレクトリの値と一致する必要があります /etc/letsencrypt/live/):

/usr/local/bin/convert_certs_for_gocd.sh
#!/bin/bash

base_domain="example.com"
le_directory="/etc/letsencrypt/live/${base_domain}"
working_dir="$(mktemp -d)"
gocd_pass="serverKeystorepa55w0rd"


clean_up () {
    rm -rf "${working_dir}"
}

# Use this to echo to standard error
error () {
    printf "%s: %s\n" "$(basename "${BASH_SOURCE}")" "${1}" >&2
    clean_up
    exit 1
}

trap 'error "An unexpected error occurred."' ERR

copy_cert_files () {
    cp "${le_directory}/fullchain.pem" "${working_dir}"
    cp "${le_directory}/privkey.pem" "${working_dir}"
}

convert_to_pkcs12 () {
    openssl_pkcs12_args=(
        "pkcs12"
        "-inkey" "${working_dir}/privkey.pem"
        "-in" "${working_dir}/fullchain.pem"
        "-export"
        "-out" "${working_dir}/${base_domain}.crt.pkcs12"
        "-passout" "pass:${gocd_pass}"
    )
    openssl "${openssl_pkcs12_args[@]}"
}

import_to_keytool () {
    keytool_args=(
        "-importkeystore"
        "-srckeystore" "${working_dir}/${base_domain}.crt.pkcs12"
        "-srcstoretype" "PKCS12"
        "-srcstorepass" "${gocd_pass}"
        "-destkeystore" "${working_dir}/keystore"
        "-srcalias" "1"
        "-destalias" "cruise"
        "-deststorepass" "${gocd_pass}"
        "-destkeypass" "${gocd_pass}"
    )
    keytool "${keytool_args[@]}"
}

install_new_keystore () {
    cp /etc/go/keystore /etc/go/keystore.bak
    mv "${working_dir}/keystore" "/etc/go/keystore"
    chown go:go /etc/go/keystore
    systemctl restart go-server
}

if (( EUID != 0 )); then
    error "This script requires root privileges"
fi

copy_cert_files && convert_to_pkcs12 && import_to_keytool && install_new_keystore && clean_up

このスクリプトが何をしているのかを正確に調べてみましょう。

最初に、スクリプトを操作しやすくするためにいくつかの変数を設定しました。 変換する証明書のドメイン名と、Let’sEncrypt証明書ディレクトリに展開する変数を設定します。 で一時的な作業ディレクトリを作成します mktemp コマンドを実行し、値を別の変数に割り当てます。 GoCDでは、すべてのJavaキーストアパスワードserverKeystorepa55w0rd、その値を保持するために別の変数を設定します。

次に、呼び出されたときに一時ディレクトリを削除する関数を定義します。 スクリプトの最後でこれを使用して、自分自身の後で、また予期しないエラーが発生したときにクリーンアップします。 この2番目の可能性を実現するために、エラーメッセージを表示し、終了する前にクリーンアップする別の関数を作成します。 を使用します trap エラーが発生するたびにこの関数を自動的に呼び出すコマンド。

その後、実際の変換を行う関数を作成します。 最初の関数は、秘密鍵とフルチェーン証明書を作業ディレクトリにコピーすることによってワークスペースを設定します。 The convert_to_pkcs12 関数は使用します openssl keytoolが使用するPKCS12ファイルを組み合わせたフルチェーン証明書ファイルと秘密鍵ファイルを結合します。 このプロセスにはエクスポートパスワードが必要なため、GoCDパスワード変数を使用します。

次の関数は、新しいPKCS12ファイルをJavaキーストアファイルにインポートします。 ファイルをインポートし、エクスポートパスワードを提供します。 次に、キーストアファイルのさまざまなパスワードに同じパスワードを指定します。 最後に、最後の関数は新しい関数をコピーします keystore ファイルに /etc/go ディレクトリ(古いものをバックアップした後 keystore)、ファイルの所有権を調整し、GoCDサーバーを再起動します。

スクリプトの最後に、有効なユーザーIDが「root」と同じ権限を持つ「0」であるかどうかを確認することにより、スクリプトが適切な権限で呼び出されていることを確認します。 次に、適切な順序で関数を呼び出して、証明書を正しく変換し、新しいものをインストールします keystore ファイル。

終了したら、ファイルを保存して閉じて続行します。

初期変換の実行

変換スクリプトができたので、それを使用して最初の証明書変換を実行する必要があります。

まず、スクリプトを実行可能としてマークして、インタープリターを呼び出さずに直接実行できるようにします。

  1. sudo chmod +x /usr/local/bin/convert_certs_for_gocd.sh

次に、でスクリプトを呼び出します sudo 初期変換を実行するには、生成されたをインストールします keystore ファイルを作成し、GoCDプロセスを再起動します

  1. sudo /usr/local/bin/convert_certs_for_gocd.sh

GoCDサーバーを再起動する必要があるため、プロセスに時間がかかる場合があります。 スクリプトが完了した後、サーバーが接続をリッスンする準備ができるまで、さらに1、2秒かかる場合があります。 次のように入力すると、アプリケーションで現在使用されているポートを確認できます。

  1. sudo watch netstat -plnt

このビューには、アプリケーションが現在リッスンしているTCPポートが2秒のリフレッシュレートで表示されます。 GoCDがポート8153および8154のリッスンを開始すると、画面は次のようになります。

Output
Every 2.0s: netstat -plnt Thu Jul 27 20:16:20 2017 Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1736/sshd tcp6 0 0 :::22 :::* LISTEN 1736/sshd tcp6 0 0 :::8153 :::* LISTEN 8942/java tcp6 0 0 :::8154 :::* LISTEN 8942/java

ポート8153と8154が表示されたら、CTRL-Cを押して表示を終了します。

アプリケーションが接続のリッスンを開始したら、HTTPSを使用してポート8154のGoCDドメインにアクセスし、Webインターフェイスを確認します。

https://example.com:8154

以前は、このページにアクセスしたときに、アドレスバーのアイコンは、証明書が信頼できないことを示していました(ブラウザの視覚的なインジケータが異なる場合があることに注意してください)。

初めてアクセスしたときは、ブラウザの警告画面をクリックする必要がありました。

自己署名証明書をLet’sEncryptが提供する信頼できる証明書に置き換えたので、ブラウザーは証明書が信頼できることを示し、ユーザーはサイトにアクセスするためにブラウザーの警告をバイパスする必要がありません。 現在のタブ、ウィンドウ、またはセッションを閉じるまで、以前の証明書がブラウザによってキャッシュされる可能性があることに注意してください。

これは、GoCDが変換したLet’sEncrypt証明書を使用できたことを意味します。

自動更新フックの設定

スクリプトが証明書アセットを正しく変換したことを確認したので、次のことを確認できます。 certbot 証明書が更新されるたびにスクリプトを呼び出します。

内のドメインの更新構成ファイルを開きます /etc/letsencrypt/renewal 次のように入力してディレクトリを作成します。

  1. sudo nano /etc/letsencrypt/renewal/example.com.conf

中、中 [renewalparams] ファイルのセクションに、行設定を追加します renew_hook スクリプトの場所へ:

/etc/letsencrypt/renewal/example.com.conf
. . .
[renewalparams]
. . .
renew_hook = /usr/local/bin/convert_certs_for_gocd.sh

The certbot ソフトウェアは cron 証明書を1日2回更新する必要があるかどうかを確認するジョブ。 証明書が更新された後、によって指定されたスクリプト renew_hook 実行されます。 このようにして、GoCDがLet’sEncryptから取得した最新の有効な証明書を常に使用していることを確認できます。

終了したら、ファイルを保存して閉じます。

更新手順をドライランすることで、ファイルに構文エラーが発生していないことをテストできます。 これでは証明書変換スクリプトは実行されませんが、スキップされたという通知が出力されることに注意してください。

  1. sudo certbot renew --dry-run
Output
Saving debug log to /var/log/letsencrypt/letsencrypt.log ------------------------------------------------------------------------------- Processing /etc/letsencrypt/renewal/example.com.conf ------------------------------------------------------------------------------- Cert not due for renewal, but simulating renewal for dry run Renewing an existing certificate Performing the following challenges: http-01 challenge for example.com Waiting for verification... Cleaning up challenges Dry run: skipping renewal hook command: /usr/local/bin/convert_certs_for_gocd.sh ------------------------------------------------------------------------------- new certificate deployed without reload, fullchain is /etc/letsencrypt/live/example.com/fullchain.pem ------------------------------------------------------------------------------- ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates below have not been saved.) Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/example.com/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.)

上記の出力は、行った変更が証明書の更新を妨げなかったことを確認します。 この出力は、更新フックが正しいスクリプトの場所を指していることも示しています。

結論

このガイドでは、Let’sEncryptの信頼できるSSL証明書を使用してGoCDインストールを保護する2つの異なる方法について説明しました。 最初の方法では、Nginxを使用して証明書を設定してから、トラフィックをGoCDのWebインターフェイスにプロキシします。 2番目のオプションは、Let’sEncrypt証明書ファイルをPKCS12形式に変換し、GoCDでネイティブに使用できるようにJavaキーストアファイルにインポートしました。 どちらのオプションも、信頼できる証明書を使用してGoCDのWebインターフェイスを保護しますが、さまざまな戦略と独自のトレードオフを使用してこれを実現します。 あなたに適したアプローチは、チームの要件と目標に大きく依存します。