JenkinsサーバのSSL対応とBasic認証

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

渡辺です。前回のエントリーでJenkinsによるCIサーバをEC2上に構築しました。ユーザ認証も行い、最低限のセキュリティは適用しましたが、業務で運用するはもう少し設定が必要です。今回は、HTTPSによる暗号化と、Basic認証の設定を行います。Basic認証を設定する事で、GitHub,Stash,Bitbucketなどのリポジトリサービスからセキュアなビルドフックを設定できるようになります。

Jenkins.graffle

設定の流れは次の通りです。

  1. Nginxをインストールする
  2. NginxにSSLを設定する
  3. NginxにJenkinsへプロキシ設定する
  4. NginxにBasic認証を設定する

Jenkinsサーバの設定

JenkinsサーバのSSL対応とBasic認証の設定を行います。

Nginxをインストールする

Amazon LinuxはCentOSベースなのでyumコマンドでサクっとインストールします。

$ sudo yum -y install nginx

NginxにSSLを設定する

はじめにSSLを設定しましょう。今回はSSLで暗号化したいだけなのでオレオレ証明書で済まします。/etc/nginx/sslの元にサーバー鍵とCSR(Certificate signing request:証明書署名要求)を配置しましょう。

$ sudo mkdir /etc/nginx/ssl
$ cd /etc/nginx/ssl/

はじめにサーバ鍵を作成します。

$ sudo openssl genrsa -des3 -out server.key 1024

続けて、CSRを作成します。組織名などは適当に入力してください。

$ sudo openssl req -new -key server.key -out server.csr

今回は暗号化だけが目的ですし、パスフレーズの入力を省略させます。

$ sudo cp server.key server.key.org
$ sudo openssl rsa -in server.key.org -out server.key

仕上げとして自己署名します。

$ sudo openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

最後に、/etc/nginx/conf.d/virtual.confを開き、SSLの設定を追加します。

server {
    listen       443;
#    server_name  XXX;

    ssl on;
    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
}

ここまで設定したならば、Nginxを起動してSSLでトップページが表示されるか確認しておきましょう。なお、EC2のコンソールからセキュリティグループの設定で、443ポートを開放するのを忘れないでください

$ sudo /etc/init.d/nginx start

NginxにJenkinsへプロキシ設定する

続けて8080ポートで動作しているJenkinsへのプロキシ設定を行います。/etc/nginx/conf.d/virtual.confを開き、locationセクションを追加してください。

server {
    listen       443;
#    server_name  XXX;

    ssl on;
    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
    location / {
        proxy_pass http://localhost:8080;
    }
}

再起動します。

$ sudo /etc/init.d/nginx restart

ブラウザをリロードして、Jenkinsの画面が表示できることを確認します。

NginxにBasic認証を設定する

最後にBasic認証を設定します。はじめにパスワードファイルを作成するためにhtpasswdをインストールします。httpd-toolsに含まれているのでyumでインストールしましょう。

$ sudo yum -y install httpd-tools

パスワードファイルを作成します。

$ sudo htpasswd -c /etc/nginx/.htpasswd jenkinsuser

最後に/etc/nginx/conf.d/virtual.confを開き、locationセクションにBasic認証の設定を追加します。

server {
    listen       443;
#    server_name  XXX;

    ssl on;
    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
    location / {
        auth_basic "jenkins server";
        auth_basic_user_file /etc/nginx/.htpasswd;
        proxy_pass http://localhost:8080;
        proxy_set_header Authorization "";
    }
}

最後の行にある「proxy_set_header」を忘れないようにします。この記述を忘れるとAuthorizationヘッダがJenkins本体まで通知されてしまい、NginxのBasic認証は通るがJenkinsが401を返すという理不尽な状況に嵌まります。

再起動後、ブラウザをリロードして、Basic認証が求められることを確認します。

$ sudo /etc/init.d/nginx restart

サービスフック

各種リポジトリサービスにpushされた時にJenkinsのビルドをフックする設定です。ここではメジャーなリポジトリサービス3種類を紹介していますが、次のようにすべて同じURL形式でBasic認証を行うことができます。

https://jenkinsuser:PASSWORD@JENKINS_SERVER/job/JOB_NAME/build

GitHub

JenkinsフックではBasic認証が利用できないようなので、WebHook URLsを利用します。

Stash

StashではHTTP GET Post-Receive Hook for Stashフックをインストールして利用します。

Bitbucket

BitbucketではPOST hookを利用します。