GitLabでLet's Encryptを使う

# はじめに
オンプレミスなGitサーバーを作るために、GitLabがよく使われます。GitLabへのWebサイトの通信をSSLで保護するために、Let's Encryptの証明書を使用します。
GitLab v10.7からはLet's Encryptとの連携が強化されたようなので、試してみました。


# 設定
https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/ssl.md#lets-encrypt-integration
を参考にして設定をしましょう。

とはいってもとても簡単で、`gitlab.rb` に次の設定を追加するだけです！

```ruby:gitlab.rb
letsencrypt['enable'] = true                      # GitLab 10.5 and 10.6 require this option
external_url "https://gitlab.example.com"	  # Must use https protocol
letsencrypt['contact_emails'] = ['foo@email.com'] # Optional
```

Let's Encryptからのチャレンジに応答するために、次の設定も追加しましょう[^issue]。

[^issue]: https://gitlab.com/gitlab-org/gitlab-ce/issues/43719

```ruby:gitlab.rb
nginx['redirect_http_to_https'] = true
nginx['redirect_http_to_https_port'] = 80
```

`gitlab-ctl reconfigure` すればLet's Encryptの証明書が設定されるはずです :sunglasses: 

# Ansible Roleの使用
GitLabの構築を簡単にするために、できあいのAnsible Roleを使うことができます。
https://github.com/geerlingguy/ansible-role-gitlab

このPlaybookを使う場合、一番簡単な構成は次のようになるかと思います。

```
├── main.yml
├── inventory
│   └── hosts.ini
├── roles
│   ├── geerlingguy.gitlab
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── defaults
│   │   │   └── main.yml
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── meta
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   └── main.yml
│   │   ├── templates
│   │   │   └── gitlab.rb.j2
│   │   ├── tests
│   │   │   ├── README.md
│   │   │   ├── test-version.yml
│   │   │   ├── test.sh
│   │   │   └── test.yml
│   │   └── vars
│   │       ├── Debian.yml
│   │       └── RedHat.yml
├── templates
│   └── mygitlab.rb.j2
└── vars
    └── main.yml
```

一部の設定は適切なvarを宣言すれば書き換えることができます。

```yml:vars/main.yml
gitlab_config_template: mygitlab.rb.j2
gitlab_external_url: https://gitlab.example.com/
# gitlab_create_self_signed_cert: "true"
gitlab_redirect_http_to_https: "true"
gitlab_email_enabled: "true"
gitlab_email_from: "admin@gitlab.example.com"
gitlab_email_display_name: "GitLab Admin"
gitlab_email_reply_to: "admin@gitlab.example.com"
```

Let's Encryptまわりの設定はgitlab.rb.j2を書き換える必要があります。

```diff:templates/mygitlab.rb.j2
# The URL through which GitLab will be accessed.
external_url "{{ gitlab_external_url }}"

# gitlab.yml configuration
gitlab_rails['time_zone'] = "{{ gitlab_time_zone }}"
gitlab_rails['backup_keep_time'] = {{ gitlab_backup_keep_time }}
gitlab_rails['gitlab_email_enabled'] = {{ gitlab_email_enabled }}
{% if gitlab_email_enabled == "true" %}
gitlab_rails['gitlab_email_from'] = "{{ gitlab_email_from }}"
gitlab_rails['gitlab_email_display_name'] = "{{ gitlab_email_display_name }}"
gitlab_rails['gitlab_email_reply_to'] = "{{ gitlab_email_reply_to }}"
{% endif %}

# Default Theme
gitlab_rails['gitlab_default_theme'] = "{{ gitlab_default_theme }}"

# Whether to redirect http to https.
nginx['redirect_http_to_https'] = {{ gitlab_redirect_http_to_https }}
- nginx['ssl_certificate'] = "{{ gitlab_ssl_certificate }}"
+ # nginx['ssl_certificate'] = "{{ gitlab_ssl_certificate }}"
- # nginx['ssl_certificate_key'] = "{{ gitlab_ssl_certificate_key }}"
+ # nginx['ssl_certificate_key'] = "{{ gitlab_ssl_certificate_key }}"

# The directory where Git repositories will be stored.
git_data_dirs({"default" => {"path" => "{{ gitlab_git_data_dir }}"} })

# The directory where Gitlab backups will be stored
gitlab_rails['backup_path'] = "{{ gitlab_backup_path }}"

# These settings are documented in more detail at
# https://gitlab.com/gitlab-org/gitlab-ce/blob/master/config/gitlab.yml.example#L118
gitlab_rails['ldap_enabled'] = {{ gitlab_ldap_enabled }}
gitlab_rails['ldap_host'] = '{{ gitlab_ldap_host }}'
gitlab_rails['ldap_port'] = {{ gitlab_ldap_port }}
gitlab_rails['ldap_uid'] = '{{ gitlab_ldap_uid }}'
gitlab_rails['ldap_method'] = '{{ gitlab_ldap_method}}' # 'ssl' or 'plain'
gitlab_rails['ldap_bind_dn'] = '{{ gitlab_ldap_bind_dn }}'
gitlab_rails['ldap_password'] = '{{ gitlab_ldap_password }}'
gitlab_rails['ldap_allow_username_or_email_login'] = true
gitlab_rails['ldap_base'] = '{{ gitlab_ldap_base }}'

# GitLab Nginx
## See https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/nginx.md
{% if gitlab_nginx_listen_port is defined %}
nginx['listen_port'] = "{{ gitlab_nginx_listen_port }}"
{% endif %}
{% if gitlab_nginx_listen_https is defined %}
nginx['listen_https'] = {{ gitlab_nginx_listen_https }}
{% endif %}

# Use smtp instead of sendmail/postfix
# More details and example configuration at
# https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/smtp.md
gitlab_rails['smtp_enable'] = {{ gitlab_smtp_enable }}
gitlab_rails['smtp_address'] = '{{ gitlab_smtp_address }}'
gitlab_rails['smtp_port'] = {{ gitlab_smtp_port }}
gitlab_rails['smtp_user_name'] = '{{ gitlab_smtp_user_name }}'
gitlab_rails['smtp_password'] = '{{ gitlab_smtp_password }}'
gitlab_rails['smtp_domain'] = '{{ gitlab_smtp_domain }}'
gitlab_rails['smtp_authentication'] = '{{ gitlab_smtp_authentication }}'
gitlab_rails['smtp_enable_starttls_auto'] = {{ gitlab_smtp_enable_starttls_auto }}
gitlab_rails['smtp_tls'] = {{ gitlab_smtp_tls }}
gitlab_rails['smtp_openssl_verify_mode'] = '{{ gitlab_smtp_openssl_verify_mode }}'
gitlab_rails['smtp_ca_path'] = '{{ gitlab_smtp_ca_path }}'
gitlab_rails['smtp_ca_file'] = '{{ gitlab_smtp_ca_file }}'

# 2-way SSL Client Authentication.
{% if gitlab_nginx_ssl_verify_client %}
nginx['ssl_verify_client'] = "{{ gitlab_nginx_ssl_verify_client }}"
{% endif %}
{% if gitlab_nginx_ssl_client_certificate %}
nginx['ssl_client_certificate'] = "{{ gitlab_nginx_ssl_client_certificate }}"
{% endif %}

# To change other settings, see:
# https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md#changing-gitlab-yml-settings

+ letsencrypt['enable'] = true
+ nginx['redirect_http_to_https_port'] = 80
```

Playbookを実行すればGitLabがインストールされ、Let's Encryptの証明書も設定されるはずです！