真実のニーズ#
自己ホストの Gitlab URL にポート番号を付けずにアクセスするための登録検査をバイパスする
問題#
Nginx を介したポート付き URL へのアクセスは、ポートなしの URL にリダイレクトされます
原因#
Nginx は gitlab.rb の設定に従ってユーザーを external_url にリダイレクトします。つまり、gitlab.rb の設定でポート付きの URL に変更すると問題が発生します(多くのリダイレクトが現代のブラウザでエラーを引き起こす)。
解決策#
Argo Tunnel を使用して組み込みの Nginx をバイパスし、直接 Gitlab Workhorse に接続します
原理#
Gitlab-CE のソースコードを分析することで、組み込みの Nginx の動作方法を特定できます
https://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/lib/support/nginx/gitlab-ssl
# 前略
upstream gitlab-workhorse {
# GitLab socket file,
# for Omnibus this would be: unix:/var/opt/gitlab/gitlab-workhorse/sockets/socket
server unix:/home/git/gitlab/tmp/sockets/gitlab-workhorse.socket fail_timeout=0;
}
# 中略
server {
#中略
location / {
client_max_body_size 0;
gzip off;
## https://github.com/gitlabhq/gitlabhq/issues/694
## Some requests take more than 30 seconds.
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade_gitlab_ssl;
proxy_pass http://gitlab-workhorse;
}
}
#後略
ほとんどのトラフィックを Gitlab Workhorse に処理させ、Nginx はリダイレクトと静的リソースの提供に責任を持っていることがわかります。両者はソケット接続を介して通信しています。
Argo Tunnel はローカルサービスをパブリックネットワークにマッピングしたり、ゲートウェイとしてトラフィックを転送したりすることができます。
したがって、Nginx の代わりに Argo Tunnel を使用することができます。
手順#
ステップ 1. Cloudflare アカウントを登録し、ドメインを Cloudflare に移管し、Zero Trust -> Access -> Tunnels を開きます
ステップ 2. Gitlab ホストに cloudflared をインストールし、Cloudflare の指示に従って接続を設定します。
ステップ 3. gitlab.rb を変更します
external_url 'https://git.targetdomain.com'
# 最終的に表示されるURLに変更します
gitlab_rails['trusted_proxies'] = ['0.0.0.0/0']
# ターゲットIPとGitlab Workhorseの接続を許可します
# 注意:Argo TunnelのリモートホストIPは固定されていないため、すべてのIP範囲をテストしていません(非常に多いです)。したがって、ここではすべてのホストが接続を確立できるようにしています。
# セキュリティ上の理由から、ローカルファイアウォールを設定して外部接続を禁止する必要があります(対応するポートを閉じる、つまりGitlab Workhorseがリッスンしているポートを閉じる)。Argo Tunnelはこれによって接続ができなくなることはありません(ローカルで作成されるため、自然に影響しません)
gitlab_workhorse['listen_network'] = "tcp"
gitlab_workhorse['listen_addr'] = "0.0.0.0:10080"
# Workhorseが10080でリッスンするようにします
# 先ほどの内容に基づいて、すべての外部ホストが10080ポートに接続できないようにする必要があります
# Unixソケットを使用することもできます
# gitlab_workhorse['listen_network'] = "unix"
# gitlab_workhorse['listen_addr'] = "...省略/socket"
# ソケットを使用する場合、ファイアウォールの設定は不要です
nginx['enable'] = false
# Gitlabの組み込みNginxを無効にします
ステップ 4. トンネルの設定
トンネル管理画面 -> パブリックホスト名でホスト名を作成します
Subdomain と Domain は必要に応じて入力し、gitlab.rb と一致する必要があります
サービスタイプは TCP を選択し、URL は localhost:10080 と入力します。同様に、gitlab.rb と一致する必要があります。例の設定ではポートは 10080 です。
注意:Unix ソケットを使用している場合、サービスタイプは UNIX を選択し、URL には絶対パスを入力する必要があります。
ステップ 5. Gitlab にアクセスすると、正常に動作し、すべての URL とリダイレクトが正しいことがわかります。