前書き

GoCDは、テストおよびリリースプロセスを自動化するために設計された強力な継続的統合および配信プラットフォームです。 ビルドの比較、複雑なワークフローの視覚化、ビルドバージョンの追跡の自動化など、多くの高度な機能を備えたGoCDは、十分にテストされたソフトウェアを実稼働環境に提供するのに役立つ柔軟なツールです。

前回の記事では、https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-gocd-on-ubuntu-16-04 [GoCDサーバーをインストールし、エージェントをセットアップし、および構成された認証]。 このガイドでは、信頼できるLet’s Encrypt SSL証明書を使用するようにGoCDを設定し、ウェブインターフェースにアクセスする際のブラウザーの警告を防ぎます。 2つの異なる構成の手順を説明します。

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

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

前提条件

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

  • サーバーホストとしてDigitalOceanを使用している場合、ブロックストレージボリュームをアーティファクトストレージの場所として使用できます。 このガイドに従って、https://www.digitalocean.com/community/tutorials/how-to-use-block-storage-on-digitalocean [DigitalOceanブロックストレージボリュームをプロビジョニング、フォーマット、およびマウントする方法]を学習してください。

  • DigitalOceanを使用していない場合は、このガイドに従ってhttps://www.digitalocean.com/community/tutorials/how-to-partition-and-format-storage-devices-in-linux [パーティション分割、フォーマット、汎用ホストにデバイスをマウントします]。

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

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

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

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

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

追加要件

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

上記のガイドを完了しても、GoCDは `+ https://:8154 +`にアクセスして自己署名証明書を使用してアクセスでき、ポートを削除するとLet’s Encrypt証明書を使用してデフォルトのNginxページが表示されます。仕様。

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

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

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

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

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

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

/ etc / nginx / sites-available / default

server {
   . . .

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

/ etc / nginx / sites-available / default

. . .

server
   . . .

   location / {
       try_files $uri $uri/ =404;


   }

   . . .

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

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

sudo nginx -t

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

sudo systemctl restart nginx

GoCD Web UIは、 `+ https:// +`プロトコルを使用して通常のドメイン名からアクセスできるようになります。

調整が必要な最後の項目は、GoCDのWeb UI内のサイトURL設定です。

新しいアドレスを使用するためのGoCDサイトURLの更新

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

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

https://

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

image:https://assets.digitalocean.com/articles/gocd_ssl_1604/config_server_link.png [GoCD構成サーバーリンク]

  • Server Management セクションで、 Site URL *を変更して、末尾から `+:8154 +`ポート指定を削除します。 以前にドメイン名の代わりにIPアドレスを使用していた場合、ドメイン名も使用するようにURLを変更します。

image:https://assets.digitalocean.com/articles/gocd_ssl_1604/site_url_setting.png [GoCDサイトURL設定]

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

オプション2:Let’s Encrypt Certificatesを使用するためのGoCDのネイティブSSLの構成

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

追加要件

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

上記のガイドを完了しても、GoCDは、 `+ https://:8154 `にアクセスして自己署名証明書を使用してアクセスでき、Let’s Encryptが提供する証明書ファイルは ` / etc / letsencrypt内で利用可能になります。 / live / + `ディレクトリ。

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

GoCDはhttps://www.digitalocean.com/community/tutorials/java-keytool-essentials-working-with-java-keystores[Javaキーストア]を使用してSSL証明書を処理します。 残念ながら、これはLet’s Encryptで使用されるものとは異なる形式です。 Let’s Encrypt証明書をGoCDで使用するには、非常に具体的な手順を使用して証明書を変換する必要があります。

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

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=""
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’s Encrypt証明書ディレクトリに展開される変数を設定します。 + mktemp +`コマンドで一時的な作業ディレクトリを作成し、その値を別の変数に割り当てます。 GoCDにはすべてのJavaキーストアパスワードが必要が `+ serverKeystorepa55w0rd +である、その値を保持する別の変数を設定します。

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

その後、実際の変換を行う関数を作成します。 最初の関数は、秘密キーと完全チェーン証明書を作業ディレクトリにコピーすることにより、ワークスペースをセットアップします。 `+ convert_to_pkcs12 `関数は ` openssl +`を使用して、キーツールが使用するhttps://en.wikipedia.org/wiki/PKCS_12[PKCS 12ファイル]の組み合わせで完全チェーン証明書ファイルと秘密鍵ファイルを結合します。 このプロセスにはエクスポートパスワードが必要なので、GoCDパスワード変数を使用します。

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

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

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

初期変換の実行

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

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

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

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

sudo /usr/local/bin/convert_certs_for_gocd.sh

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

sudo watch netstat -plnt

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

OutputEvery 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 :::                 :::*                    LISTEN      8942/java
tcp6       0      0 :::                 :::*                    LISTEN      8942/java

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

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

https://:8154

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

image:https://assets.digitalocean.com/articles/gocd_ssl_1604/ssl_cert_not_trusted_icon.png [Chrome SSL cert not trusted icon]

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

image:https://assets.digitalocean.com/articles/gocd_install_1604/browser_ssl_warning.png [ブラウザーSSL警告]

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

image:https://assets.digitalocean.com/articles/gocd_ssl_1604/ssl_cert_trusted_icon.png [Chrome SSL cert trusted icon]

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

自動更新フックのセットアップ

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

次を入力して、 `+ / etc / letsencrypt / renewal +`ディレクトリ内のドメインの更新設定ファイルを開きます。

sudo nano /etc/letsencrypt/renewal/.conf

内部で、ファイルの `+ [renewalparams] `セクションで、スクリプトの場所に ` renew_hook +`を設定する行を追加します。

/etc/letsencrypt/renewal/example.com.conf

. . .
[renewalparams]
. . .
renew_hook = /usr/local/bin/convert_certs_for_gocd.sh

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

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

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

sudo certbot renew --dry-run
OutputSaving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/.conf
-------------------------------------------------------------------------------
Cert not due for renewal, but simulating renewal for dry run
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for
Waiting for verification...
Cleaning up challenges


-------------------------------------------------------------------------------
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live//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//fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)

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

結論

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