LoginSignup
1
1

私的サーバー構築日誌:GitLabとリバースプロキシと Let's Encrypt

Last updated at Posted at 2023-12-20

能書き

私的サーバー構築日誌:仕切り直しからの自宅サーバー構築の続きです。

とても気になっているGitLabとMattermostです。以前一度インストールしたその後に、当時使っていたサーバーマシンが壊れてしまうという悲劇に見舞われて、そのままになってしまっていました。新しいサーバーでも、ようやくここまで追い付きました。

そのGitLabとMattermostのサーバーですが。私の環境では(そして大多数の方々の環境でも)GitLabとMattermostで1つのグローバルIPアドレスを共有する事になります。その他のサービスでも同じIPアドレスを共有せざるを得ない事も多いでしょう。しかしGitLabサーバーをリバースプロキシの後ろに立てると問題が発生しがちのようで、その解説や解決の記事が巷に氾濫しているようです。

今回の記事はその試行錯誤の結果になります。まずはGitLabが立ち上がったので、その手順についてまとめました。

※2023.12.28.追記
Mattermostは諦めました。
リバースプロキシの存在下でGitLabと連携させるのが難しい上、MattermostはWebSocketを使用しているのでリバースプロキシでその点も考慮する必要があります。
心が折れました…

目標

  • GitLabサーバーを立てます。
    • Let's Encrypt の証明書を取得してhttpsアクセスできるようにします。
    • LDAPと連携して、LDAP登録したユーザーでログインできるようにします。
  • リバースプロキシを立てます。

参考文献

公式ドキュメントです。

前回私が立てた際の記録記事です。今回はリバースプロキシを立てる都合で、結構な差異があります。

GitLabそのものではなく、その周辺の設定について、現在の私の環境です。

その他、参考にさせていただいた各種の設定情報など。

余談。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/にアクセスするとログイン画面が表示されます。

image.png

Username or primary email 欄はroot、パスワード欄には確認した初期パスワードを入力し、サインインします。

なにはともあれまずは日本語化です。

サイドバーの右上のアバターをクリックし、ドロップダウンメニューからPreferencesを選択します。

image.png

Preferences画面の下の方にLocalizationがあり、その中にLanguage欄があります。そのドロップダウンリストから Japanese - 日本語 を選択し、Save changes ボタンをクリックします。

image.png

そうしたら一度サインアウトします。

image.png

サインイン画面で、rootの初期パスワードを使用して再度サインインします。

image.png

画面が日本語になりました。

image.png

そして、画面上部にドキドキする警告文が表示されています。ここは勧めに従って、サインアップ制限しましょう。

まずは無効化ボタンをクリックします。すると管理者エリア>一般の、ユーザーが新しいアカウントを作成する方法の設定が表示されます。

ここで、私は下記のように設定しました。

  • 「サインアップは有効です」 →チェックを外す
  • 「新しいサインアップには管理者の承認が必要」 →チェックする
  • 「メールの確認設定」 →ハード

image.png

設定できたら、少し下の方にある 変更を保存 ボタンをクリックします。

次に、rootユーザーのパスワードを変更しましょう。アバターをクリックし、ドロップダウンメニューから設定を選択します。

image.png

サイドバー>ユーザー設定>パスワードを選択。

image.png

現在のパスワードと新しいパスワードを入れて、パスワードを保存ボタンをクリックして下さい。

image.png

するとサインイン画面に遷移し、また、パスワード変更の通知メールも届きますので確認します。以前設定したPostfixにより、taroユーザーに転送された筈です。

サインイン画面で新しいパスワードにてサインインしましょう。

image.png

そうしたら、rootのユーザー設定を一通り確認し、必要に応じて変更します。メールアドレスなどもあるので御注意ください。

rootの設定が一通り終わったら、ユーザー作成の際にメールが飛ぶ事も確認しましょう。

画面左上のタヌキロゴをクリックすると、GitLabへようこそ画面が表示されます。この一番下にある GitLabを調整する をクリックします。

image.png

管理者エリア>ユーザー

image.png

ユーザー画面が表示されるので、画面右上の 新しいユーザー ボタンをクリック。

image.png

新しいユーザー画面になります。必要事項を入力してユーザーの作成ボタンをクリックします。

image.png

すると新しく作成したユーザーの画面が表示され、同時に入力したメールアドレスへメールが送信され、私の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です。

今回は、こういう時の為に用意している(と思われる)ユーザーを使用します。

コンテナ内:vim
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/にアクセスしてみて下さい。

image.png

LDAPユーザーtaro(パスワードMa9H%6jgでサインインできる事を確認します。taroの設定を確認できたら、一旦サインアウトして、LDAPではなくて標準タブの方から先程のユーザーhanakoでも引き続きサインインできる事を確認しましょう。

確認できたら後始末。

ホスト側
cd ..
rm -r gitlab_ldap

仕舞い

これでGitLabの設定が完了しました。我が家のプロジェクト管理はこれで決まり!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1