能書き
私的サーバー構築日誌:仕切り直しからの自宅サーバー構築の続きです。
とても気になっているGitLabとMattermostです。以前一度インストールしたその後に、当時使っていたサーバーマシンが壊れてしまうという悲劇に見舞われて、そのままになってしまっていました。新しいサーバーでも、ようやくここまで追い付きました。
そのGitLabとMattermostのサーバーですが。私の環境では(そして大多数の方々の環境でも)GitLabとMattermostで1つのグローバルIPアドレスを共有する事になります。その他のサービスでも同じIPアドレスを共有せざるを得ない事も多いでしょう。しかしGitLabサーバーをリバースプロキシの後ろに立てると問題が発生しがちのようで、その解説や解決の記事が巷に氾濫しているようです。
今回の記事はその試行錯誤の結果になります。まずはGitLabが立ち上がったので、その手順についてまとめました。
※2023.12.28.追記
Mattermostは諦めました。
リバースプロキシの存在下でGitLabと連携させるのが難しい上、MattermostはWebSocketを使用しているのでリバースプロキシでその点も考慮する必要があります。
心が折れました…
※2024.05.06.追記
Mattermostをリバースプロキシの下で動かす方法を模索しました。
目標
- GitLabサーバーを立てます。
- Let's Encrypt の証明書を取得してhttpsアクセスできるようにします。
- LDAPと連携して、LDAP登録したユーザーでログインできるようにします。
- リバースプロキシを立てます。
参考文献
公式ドキュメントです。
前回私が立てた際の記録記事です。今回はリバースプロキシを立てる都合で、結構な差異があります。
GitLabそのものではなく、その周辺の設定について、現在の私の環境です。
- 私的サーバー構築日誌:LAN内DNSサーバー Unbound - Qiita … 私のサーバーのDNS設定です。
- 私的サーバー構築日誌:LDAPサーバー OpenLDAP over TLS とログ確認 … 私の環境のLDAPサーバーです。
- ユーザー登録 - 私的サーバー構築日誌:LDAPサーバー OpenLDAP・ユーザー登録 - qiita … 私のLDAPサーバーに登録したユーザーです。
- 私的サーバー構築日誌:nginx on docker でリバースプロキシ - Qiita … リバースプロキシの基本的な手順です。
- 私的サーバー構築日誌:nginx on docker のリバースプロキシ環境で Let's Encrypt - Qiita … リバースプロキシ環境で Let's Encrypt する手順です。
その他、参考にさせていただいた各種の設定情報など。
- Nginxのserver_nameって複数設定できるの?【Apachのエイリアスみたいなものです】 - ハピ部
- Nginx で 80 と 443 ポートアクセスを両方とも受け付けて共存させる設定
-
gitlabをリバースプロキシ下で運用する場合のURL問題の解決 - Qiita … リバースプロキシでの
proxy_set_header
設定を参考にしました。 - GitLabをReverse Proxy越しに利用する設定を確認したら迷走する事案が発生 - 今日もまた踏みました
余談。10080番ポートを使ってはいけないらしい。
概要
今回はGitLabだけ立てました。
※2023.12.28.追記
Mattermostは諦めました。それを考慮して、文章を少し修正します。
- LXDコンテナにGitLab-EE(omnibus版)をインストール
- リバースプロキシを立てて、1つのIPアドレスをGitLabとその他のサービスで共有できるように設定 … この点が前回と異なります
- Let's Encrypt でgitlabの証明書を取得(mattermostの証明書は次回) … この点も前回と異なります
- LDAPサーバーと連携
DockerコンテナでGitLabサーバーを立てる方法もありますが、細かい設定で不自由したりするようですので、やはりLXDコンテナにomnibus版をインストールする事にしました。
そしてインストールするのはCEではなくEEにします。ライセンスを購入しなければEEはCEと同等との記述があったからです。
DNS
まず最初にDNSを設定します。外からアクセス可能にする関係で、お金を出して買った独自ドメインを使用して下さい。ここでは仮にexample.com
にしておきますが、このまま設定しないで下さい。
MY_DOMAIN=example.com
GITLAB_DOMAIN=gitlab.$MY_DOMAIN
そして外部のDNSにこれを設定し、家庭内ルーターのポートフォワードなども設定しておきます。この辺りの手順はそれぞれ異なりますので、各々のマニュアルなどを参照して下さい。
そして家庭内DNSです。Unboundで上記のドメインを設定します。
サーバーの家庭内でのIPアドレスは、私の環境では下記の通りです。
HOST_IPADDR=172.16.1.2
CNAMEの設定は面倒なようなので、Aレコードを設定します。
cd /etc/unbound/unbound.conf.d/
cat <<___ | sudo tee -a machines.list >/dev/null
local-data: "$GITLAB_DOMAIN. 3600000 IN A $HOST_IPADDR"
___
設定したら文法チェックして、Unboundに読み込みます。
unbound-checkconf
sudo systemctl restart unbound
そしてSubversion登録。
sudo svn st /etc
sudo svn st /etc | grep "^?" | cut -b9- | sudo xargs -I{} find {} -type f -or -type d -or -type l | sudo xargs -t svn add
sudo svn ci /etc -m"DNS setting for GitLab"
GitLab
LXDポートフォワードの設定
LXDコンテナに関する設定です。各々の値は他で未使用な事を確認して下さい。
CONTAINER_NAME=gitlab1
CONTAINER_IPADDR=192.168.0.202
CONTAINER_PORT_HTTP=20080
lxc network forward port add lxdbr0 $HOST_IPADDR tcp $CONTAINER_PORT_HTTP $CONTAINER_IPADDR 80
LXDコンテナ作成
LXDコンテナを作成します。
lxc init images:ubuntu/jammy/cloud $CONTAINER_NAME --device eth0,ipv4.address=$CONTAINER_IPADDR
基本的な初期設定です。インストールするパッケージについては公式を参照。
lxc config set $CONTAINER_NAME cloud-init.user-data="$(cat <<___
#cloud-config
timezone: Asia/Tokyo
locale: ja_JP.utf8
package_update: true
package_upgrade: true
packages:
- curl
- openssh-server
- ca-certificates
- tzdata
- perl
___
)"
コンテナ開始。そして開始完了まで待ちましょう。
lxc start $CONTAINER_NAME
lxc exec $CONTAINER_NAME -- cloud-init status --wait
GitLabインストール
いよいよGitLabです。
gitlab-eeのインストール時に環境変数EXTERNAL_URL
を参照します。これはインストール完了時のURLを表します。上述の環境変数GITLAB_DOMAIN
を設定しておけば、コンテナ内でそれを参照する手順にしています。
なお、EXTERNAL_URLをhttpsにすると Let's Encrypt から自動的に証明書を取り寄せてしまうとの事。後でリバースプロキシを立てて、そこで証明書を取得するので、ここではhttpにしておきます。
なお、このインストールまで一気にcloud-initで操作しない理由は、このインストールには時間が掛かるからです。そして時々失敗するようです。そのため別操作としました。
これらインストール操作については公式を参照して下さい。
lxc exec $CONTAINER_NAME --env EXTERNAL_URL="http://$GITLAB_DOMAIN" bash
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | bash
apt install gitlab-ee
インストールに成功したら、コンテナを抜けてホストに戻りましょう。
exit
ひとまずここまででGitLabのログイン画面は表示できる筈です。ブラウザで確認してみましょう。ホストマシンでcurl
コマンドでも良いです。なおcurl
コマンドはWindowsにも存在するようです。
curl
コマンドは-i
オプションを付けるとレスポンスヘッダも出力してくれます。リダイレクトの様子を見るにはその方が良いかも知れません。
curl -i http://$HOST_IPADDR:$CONTAINER_PORT_HTTP/
リバースプロキシ
Dockerコンテナ
Dockerコンテナでリバースプロキシを立てて、Let's Encrypt 証明書発行を仕込みます。
cd
mkdir docker-proxy
cd docker-proxy
mkdir -p config/nginx
mkdir -p data/nginx
mkdir -p html/ssl-proof
mkdir letsencrypt
cat <<___ >docker-compose.yml
version: "3.9"
services:
proxy:
build: .
container_name: proxy
restart: unless-stopped
ports:
- 80:80
- 443:443
volumes:
- ./config/nginx:/etc/nginx/conf.d
- ./data/nginx:/var/log/nginx
- ./html:/usr/share/nginx/html
- ./letsencrypt:/etc/letsencrypt
logging:
driver: json-file
options:
max-size: 10m
max-file: '3'
___
cat <<___ >Dockerfile
FROM nginx:latest
RUN apt update \
&& apt install -y certbot \
&& apt -y clean
___
cat <<___ >config/nginx/default.conf
server {
listen 80 default_server;
server_name _;
server_tokens off;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
___
cat <<___ >config/nginx/gitlab.conf
server {
listen 80;
server_name $GITLAB_DOMAIN;
server_tokens off;
location ^~ /.well-known/acme-challenge/ {
root /usr/share/nginx/html/ssl-proof;
}
location / {
proxy_pass http://$HOST_IPADDR:$CONTAINER_PORT_HTTP;
}
}
___
プロキシを起動。
docker compose up -d
この段階でブラウザからhttp://gitlab.example.com/
を表示できます。リダイレクトされて、サインイン画面が表示されます。
curl
コマンドを使う場合は下記。
curl -i http://$GITLAB_DOMAIN/
Let's Encrypt 証明書を取得
Let's Encrypt で証明書を取得して設定します。
docker compose exec proxy certbot certonly --register-unsafely-without-email --agree-tos --webroot -w /usr/share/nginx/html/ssl-proof -d $GITLAB_DOMAIN
cat <<___ >config/nginx/gitlab.conf
server {
listen 80;
server_name $GITLAB_DOMAIN;
server_tokens off;
location ^~ /.well-known/acme-challenge/ {
root /usr/share/nginx/html/ssl-proof;
}
location / {
return 301 https://$GITLAB_DOMAIN;
}
}
server {
listen 443 ssl;
server_name $GITLAB_DOMAIN;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/$GITLAB_DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$GITLAB_DOMAIN/privkey.pem;
location / {
proxy_set_header Host \$http_host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_pass http://$HOST_IPADDR:$CONTAINER_PORT_HTTP;
}
}
___
docker compose exec proxy nginx -s reload
external_urlを設定
URLhttps://gitlab.example.com/
をGitLabに認識させます。
cd /tmp
mkdir gitlab_url
cd gitlab_url
設定ファイルgitlab.rb
の修正にはpatch
を利用しますが、エディタで手作業しても良いです。修正内容は見ればわかるかと。
cat <<___ >gitlab_url.patch
32c32
< external_url 'http://$GITLAB_DOMAIN'
---
> external_url 'https://$GITLAB_DOMAIN'
1661c1661
< # nginx['listen_port'] = nil
---
> nginx['listen_port'] = 80
1665c1665
< # nginx['listen_https'] = nil
---
> nginx['listen_https'] = false
___
lxc file pull $CONTAINER_NAME/etc/gitlab/gitlab.rb .
patch gitlab.rb <gitlab_url.patch
lxc file push gitlab.rb $CONTAINER_NAME/etc/gitlab/
設定を反映させる為のオマジナイです。
lxc exec $CONTAINER_NAME gitlab-ctl reconfigure
https://gitlab.example.com/
を表示できます。
curl -i https://$GITLAB_DOMAIN/
確認できたら後始末。
cd ..
rm -r gitlab_url
Let's Encrypt 証明書を維持
証明書を維持する為の設定です。
cd
cd docker-proxy
cat <<___ >certbot-renew.sh
#!/bin/bash
cd
cd docker-proxy
/usr/bin/date -Iseconds
/usr/bin/docker compose exec proxy certbot renew
/usr/bin/docker compose exec proxy nginx -s reload
echo "====="
___
chmod +x certbot-renew.sh
sudo ln -s $PWD/certbot-renew.sh /usr/local/bin/certbot-renew.sh
sudo mkdir /var/log/letsencrypt
sudo chown $USER /var/log/letsencrypt
cat <<___ | sudo tee /etc/logrotate.d/certbot-renew >/dev/null
/var/log/letsencrypt/certbot-renew.log {
missingok
rotate 3
compress
monthly
minsize 1M
}
___
cat <<___ | sudo tee /etc/cron.d/certbot-renew >/dev/null
0 3 1,15 * * $USER /usr/local/bin/certbot-renew.sh >>/var/log/letsencrypt/certbot-renew.log 2>&1
___
GitLab設定
メールとLDAP連携を一気に設定しようとしたのですが、修正量が多くなりますので分けます。
メール
設定
公式ドキュメントはこちら。基本的には前回の私の設定を踏襲します。
我が家の設定だと下記のような感じです。
SMTP_SERVER=primary.home
SMTP_PORT=25
SMTP_DOMAIN=$MY_DOMAIN
GITLAB_EMAIL=gitlab@$SMTP_DOMAIN
GITLAB_REPLY=noreply@$SMTP_DOMAIN
cd /tmp
mkdir gitlab_smtp
cd gitlab_smtp
cat >gitlab_smtp.patch <<___
85,87c85,87
< # gitlab_rails['smtp_enable'] = true
< # gitlab_rails['smtp_address'] = "smtp.server"
< # gitlab_rails['smtp_port'] = 465
---
> gitlab_rails['smtp_enable'] = true
> gitlab_rails['smtp_address'] = "$SMTP_SERVER"
> gitlab_rails['smtp_port'] = $SMTP_PORT
90c90
< # gitlab_rails['smtp_domain'] = "example.com"
---
> gitlab_rails['smtp_domain'] = "$SMTP_SERVER"
93c93
< # gitlab_rails['smtp_tls'] = false
---
> gitlab_rails['smtp_tls'] = false
98c98
< # gitlab_rails['smtp_openssl_verify_mode'] = 'none'
---
> gitlab_rails['smtp_openssl_verify_mode'] = 'none'
105c105
< # gitlab_rails['gitlab_email_enabled'] = true
---
> gitlab_rails['gitlab_email_enabled'] = true
109,112c109,112
< # gitlab_rails['gitlab_email_from'] = 'example@example.com'
< # gitlab_rails['gitlab_email_display_name'] = 'Example'
< # gitlab_rails['gitlab_email_reply_to'] = 'noreply@example.com'
< # gitlab_rails['gitlab_email_subject_suffix'] = ''
---
> gitlab_rails['gitlab_email_from'] = '$GITLAB_EMAIL'
> gitlab_rails['gitlab_email_display_name'] = 'GitLab'
> gitlab_rails['gitlab_email_reply_to'] = '$GITLAB_REPLY'
> gitlab_rails['gitlab_email_subject_suffix'] = '[GitLab] '
___
lxc file pull $CONTAINER_NAME/etc/gitlab/gitlab.rb .
patch gitlab.rb <gitlab_smtp.patch
lxc file push gitlab.rb $CONTAINER_NAME/etc/gitlab/
設定を反映させる為のオマジナイ。
lxc exec $CONTAINER_NAME gitlab-ctl reconfigure
確認できてないけど後始末。
cd ..
rm -r gitlab_smtp
ブラウザで確認と設定
ここまで来たら、ブラウザでアクセスして、rootサインインからユーザー作成してメールが飛ぶ事を確認します。
まずはrootの初期パスワードを確認。
lxc file pull $CONTAINER_NAME/etc/gitlab/initial_root_password -
ブラウザでhttps://gitlab.example.com/
にアクセスするとログイン画面が表示されます。
Username or primary email 欄はroot
、パスワード欄には確認した初期パスワードを入力し、サインインします。
なにはともあれまずは日本語化です。
サイドバーの右上のアバターをクリックし、ドロップダウンメニューからPreferencesを選択します。
Preferences画面の下の方にLocalizationがあり、その中にLanguage欄があります。そのドロップダウンリストから Japanese - 日本語 を選択し、Save changes ボタンをクリックします。
そうしたら一度サインアウトします。
サインイン画面で、root
の初期パスワードを使用して再度サインインします。
画面が日本語になりました。
そして、画面上部にドキドキする警告文が表示されています。ここは勧めに従って、サインアップ制限しましょう。
まずは無効化ボタンをクリックします。すると管理者エリア>一般の、ユーザーが新しいアカウントを作成する方法の設定が表示されます。
ここで、私は下記のように設定しました。
- 「サインアップは有効です」 →チェックを外す
- 「新しいサインアップには管理者の承認が必要」 →チェックする
- 「メールの確認設定」 →ハード
設定できたら、少し下の方にある 変更を保存 ボタンをクリックします。
次に、root
ユーザーのパスワードを変更しましょう。アバターをクリックし、ドロップダウンメニューから設定を選択します。
サイドバー>ユーザー設定>パスワードを選択。
現在のパスワードと新しいパスワードを入れて、パスワードを保存ボタンをクリックして下さい。
するとサインイン画面に遷移し、また、パスワード変更の通知メールも届きますので確認します。以前設定したPostfixにより、taro
ユーザーに転送された筈です。
サインイン画面で新しいパスワードにてサインインしましょう。
そうしたら、root
のユーザー設定を一通り確認し、必要に応じて変更します。メールアドレスなどもあるので御注意ください。
root
の設定が一通り終わったら、ユーザー作成の際にメールが飛ぶ事も確認しましょう。
画面左上のタヌキロゴをクリックすると、GitLabへようこそ画面が表示されます。この一番下にある GitLabを調整する をクリックします。
管理者エリア>ユーザー
ユーザー画面が表示されるので、画面右上の 新しいユーザー ボタンをクリック。
新しいユーザー画面になります。必要事項を入力してユーザーの作成ボタンをクリックします。
すると新しく作成したユーザーの画面が表示され、同時に入力したメールアドレスへメールが送信され、私のPostfixの設定ではtaro@homeに転送されます。
ここまで確認できたら、一旦サインアウトしましょう。そして新しく作成したユーザーhanako
宛のメールからパスワード変更し、サインインできる事を確認しておきます。
LDAP
公式ドキュメントはこちら。
基本的には、前回の私の設定を踏襲します。我が家の設定だと下記のような感じです。
LDAP_SERVER=primary.home
LDAP_PORT=636
cd /tmp
mkdir gitlab_ldap
cd gitlab_ldap
なお、LDAPサーバーへアクセスする為のユーザーbind_dn
とそのパスワードpassword
はここでは設定しません。ここだと平文になってしまって危険ですので。
cat >gitlab_ldap.patch <<___
502c502
< # gitlab_rails['ldap_enabled'] = false
---
> gitlab_rails['ldap_enabled'] = true
506,511c506,511
< # gitlab_rails['ldap_servers'] = YAML.load <<-'EOS'
< # main: # 'main' is the GitLab 'provider ID' of this LDAP server
< # label: 'LDAP'
< # host: '_your_ldap_server'
< # port: 389
< # uid: 'sAMAccountName'
---
> gitlab_rails['ldap_servers'] = YAML.load <<-'EOS'
> main: # 'main' is the GitLab 'provider ID' of this LDAP server
> label: 'LDAP'
> host: '$LDAP_SERVER'
> port: $LDAP_PORT
> uid: 'uid'
514,526c514,526
< # encryption: 'plain' # "start_tls" or "simple_tls" or "plain"
< # verify_certificates: true
< # smartcard_auth: false
< # active_directory: true
< # allow_username_or_email_login: false
< # lowercase_usernames: false
< # block_auto_created_users: false
< # base: ''
< # user_filter: ''
< # ## EE only
< # group_base: ''
< # admin_group: ''
< # sync_ssh_keys: false
---
> encryption: 'simple_tls' # "start_tls" or "simple_tls" or "plain"
> verify_certificates: true
> smartcard_auth: false
> active_directory: false
> allow_username_or_email_login: false
> lowercase_usernames: false
> block_auto_created_users: false
> base: 'ou=people,dc=home'
> user_filter: ''
> ## EE only
> group_base: ''
> admin_group: ''
> sync_ssh_keys: false
548c548
< # EOS
---
> EOS
___
lxc file pull $CONTAINER_NAME/etc/gitlab/gitlab.rb .
patch gitlab.rb <gitlab_ldap.patch
lxc file push gitlab.rb $CONTAINER_NAME/etc/gitlab/
次に、LDAPサーバーにアクセスするユーザー名とパスワードを、暗号化して保存します。
lxc shell $CONTAINER_NAME
gitlab-rake gitlab:ldap:secret:edit EDITOR=vim
これでvim
が起動しますので、下記の内容を入力します。
ユーザー名とパスワードは何でもOKです。
今回は、こういう時の為に用意している(と思われる)ユーザーを使用します。
main:
password: 'readonly_password'
bind_dn: 'cn=readonly,dc=home'
入力したら保存してエディタ終了。コンテナから抜けます。
exit
ところで我が家のLDAPは、オレオレ認証局で証明書を作っているのでした。これを信用させなければなりません。認証局の鍵のありかは下記の通りです。
- 公開鍵
/home/cert/demoCA/pki/ca.crt
sudo -u cert cp -p /home/cert/demoCA/pki/ca.crt /tmp/demoCA.crt
sudo chown $USER: /tmp/demoCA.crt
chmod 644 /tmp/demoCA.crt
lxc file push /tmp/demoCA.crt $CONTAINER_NAME/etc/gitlab/trusted-certs/
rm /tmp/demoCA.crt
GitLabへの反映のオマジナイ。
lxc exec $CONTAINER_NAME gitlab-ctl reconfigure
これでLDAPと連携するようになりました。ブラウザでhttps://gitlab.example.com/
にアクセスしてみて下さい。
LDAPユーザーtaro
(パスワードMa9H%6jg
)でサインインできる事を確認します。taro
の設定を確認できたら、一旦サインアウトして、LDAPではなくて標準タブの方から先程のユーザーhanako
でも引き続きサインインできる事を確認しましょう。
確認できたら後始末。
cd ..
rm -r gitlab_ldap
仕舞い
これでGitLabの設定が完了しました。我が家のプロジェクト管理はこれで決まり!