🛡

パスワード認証つきプロキシサーバーを経由して443番ポートでGitHub/BitBucket/GitLabにssh接続する

2024/05/25に公開

先行研究として

https://qiita.com/pinemz/items/4be98d4ff446e7fd023b

https://qiita.com/306_san/items/28c36e52346f315d0860

などがあるが、プロキシへの接続にユーザー名 + パスワードで認証が必要な場合(つまり、例えばhttp://username:password@proxy.example.com:80みたいなURLをhttp_proxyhttps_proxyにセットして使うような環境)では追加で工夫が必要になったためメモしておく。

WSLなどが使える前提として、Linux環境での設定について記述する。

(なお、検証はWSL2のUbuntu24.04とBitBucketを使って実施した)

結論

netcat系のコマンドのオプションで頑張る

1. nc(netcat-openbsd)を使う場合

Ubuntu24.04(noble)などではたぶんデフォルトで入っているので手軽

man page:

https://man.openbsd.org/nc.1

以下の内容を~/.ssh/configに追記する

~/.ssh/config
# GitHub/BitBucket/GitLabについて必要なものを選んで追記する

# GitHub
Host github.com
    HostName ssh.github.com
    User git
    Port 443
    # ↓各自の環境で適当に変える
    identityFile ~/path/to/git_secret_key
    # ↓各自の環境に合わせて<>部分は適宜置き換える
    ProxyCommand nc -X connect -x <プロキシのDNS名 or IPアドレス>:<ポート番号> -P <プロキシ認証のユーザー名> %h %p
    # 環境変数https_proxyが設定されている場合、↓でもおそらく可
    # ProxyCommand nc -X connect -x $(echo $https_proxy | awk -F"@" '{print $2}') -P $(echo $https_proxy | awk -F":" '{print $2}' | awk -F"//" '{print $2}') %h %p

# BitBucket
Host bitbucket.org
    HostName altssh.bitbucket.org
    User git
    Port 443
    # ↓各自の環境で適当に変える
    identityFile ~/path/to/git_secret_key
    # ↓各自の環境に合わせて<>部分は適宜置き換える
    ProxyCommand nc -X connect -x <プロキシのDNS名 or IPアドレス>:<ポート番号> -P <プロキシ認証のユーザー名> %h %p
    # 環境変数https_proxyが設定されている場合、↓でもおそらく可
    # ProxyCommand nc -X connect -x $(echo $https_proxy | awk -F"@" '{print $2}') -P $(echo $https_proxy | awk -F":" '{print $2}' | awk -F"//" '{print $2}') %h %p

# GitLab
Host gitlb.com
    HostName altssh.gitlab.com
    User git
    Port 443
    # ↓各自の環境で適当に変える
    identityFile ~/path/to/git_secret_key
    # ↓各自の環境に合わせて<>部分は適宜置き換える
    ProxyCommand nc -X connect -x <プロキシのDNS名 or IPアドレス>:<ポート番号> -P <プロキシ認証のユーザー名> %h %p
    # 環境変数https_proxyが設定されている場合、↓でもおそらく可
    # ProxyCommand nc -X connect -x $(echo $https_proxy | awk -F"@" '{print $2}') -P $(echo $https_proxy | awk -F":" '{print $2}' | awk -F"//" '{print $2}') %h %p

ただし、ncコマンドでは認証パスワードをオプションなどで設定出来ないため都度プロキシ認証のパスワードを入力しないといけない。

awkを使ったワンライナー部分について、こっちを使うとあらゆる環境で使いまわしが出来る一方、プロキシ認証のユーザー名およびパスワードに:@が入っているとうまく動かない可能性もあるので注意。

2. ncat(nmap-ncat)を使う場合

https://nmap.org/ncat/

apt install ncatdnf install nmap-ncatでインストールできる。

後発な分高機能なようで、こちらはオプションでパスワードまで設定できるので便利

ncatを使う場合は以下の内容を~/.ssh/configに追記

~/.ssh/config
# GitHub/BitBucket/GitLabについて必要なものを選んで追記する

# GitHub
Host github.com
    HostName ssh.github.com
    User git
    Port 443
    # ↓各自の環境で適当に変える
    identityFile ~/path/to/git_secret_key
    # ↓各自の環境に合わせて<>部分は適宜置き換える
    ProxyCommand ncat --proxy-type http --proxy <プロキシのDNS名 or IPアドレス>:<ポート番号> --proxy-auth <プロキシ認証のユーザー名>:<プロキシ認証のパスワード> %h %p
    # 環境変数https_proxyが設定されている場合、↓でもおそらく可
    # ProxyCommand ncat --proxy-type http --proxy $(echo $https_proxy | awk -F"@" '{print $2}') --proxy-auth $(echo $https_proxy | awk -F":" '{print $2}' | awk -F"//" '{print $2}'):$(echo $https_proxy | awk -F":" '{print $3}' | awk -F"@" '{print $1}') %h %p

# BitBucket
Host bitbucket.org
    HostName altssh.bitbucket.org
    User git
    Port 443
    # ↓各自の環境で適当に変える
    identityFile ~/path/to/git_secret_key
    # ↓各自の環境に合わせて<>部分は適宜置き換える
    ProxyCommand ncat --proxy-type http --proxy <プロキシのDNS名 or IPアドレス>:<ポート番号> --proxy-auth <プロキシ認証のユーザー名>:<プロキシ認証のパスワード> %h %p
    # 環境変数https_proxyが設定されている場合、↓でもおそらく可
    # ProxyCommand ncat --proxy-type http --proxy $(echo $https_proxy | awk -F"@" '{print $2}') --proxy-auth $(echo $https_proxy | awk -F":" '{print $2}' | awk -F"//" '{print $2}'):$(echo $https_proxy | awk -F":" '{print $3}' | awk -F"@" '{print $1}') %h %p

# GitLab
Host gitlb.com
    HostName altssh.gitlab.com
    User git
    Port 443
    # ↓各自の環境で適当に変える
    identityFile ~/path/to/git_secret_key
    # ↓各自の環境に合わせて<>部分は適宜置き換える
    ProxyCommand ncat --proxy-type http --proxy <プロキシのDNS名 or IPアドレス>:<ポート番号> --proxy-auth <プロキシ認証のユーザー名>:<プロキシ認証のパスワード> %h %p
    # 環境変数https_proxyが設定されている場合、↓でもおそらく可
    # ProxyCommand ncat --proxy-type http --proxy $(echo $https_proxy | awk -F"@" '{print $2}') --proxy-auth $(echo $https_proxy | awk -F":" '{print $2}' | awk -F"//" '{print $2}'):$(echo $https_proxy | awk -F":" '{print $3}' | awk -F"@" '{print $1}') %h %p

先ほどと同様で、awkを使ったワンライナー部分について、こっちを使うとあらゆる環境で使いまわしが出来る一方、プロキシ認証のユーザー名およびパスワードに:@が入っているとうまく動かない可能性もあるので注意。

ちょっとだけ補足

前提として、SaaS版(グローバルに使われてる方)のGitHub/BitBucket/GitLabは443番ポートでsshできるための代替のDNS名を持っている。

GitHub: ssh.github.com

https://docs.github.com/ja/authentication/troubleshooting-ssh/using-ssh-over-the-https-port

BitBucket: altssh.bitbucket.org

https://ja.confluence.atlassian.com/bbkb/bitbucket-cloud-ssh-host-key-rotation-faq-1235851234.html

↑直接的な記述は無いが、

  1. Q: I’m using port 443 instead of default port 22 to connect to bitbucket.org over SSH and run my connection via altssh.bitbucket.org to connect to Bitbucket. (...)

などと書いてある

GitLab: altssh.gitlab

https://about.gitlab.com/blog/2016/02/18/gitlab-dot-com-now-supports-an-alternate-git-plus-ssh-port/

ここで、GitHub/BitBucket/GitLabにおけるssh接続を使った場合のgitリモートリポジトリのURLは基本的に

  • GitHub: git@github.com:<ユーザー名やプロジェクト名>/<リポジトリ名>.git
  • BitBucket: git@bitbucket.org:<ユーザー名やプロジェクト名>/<リポジトリ名>.git
  • GitLab: git@gitlab.com:<ユーザー名やプロジェクト名>/<リポジトリ名>.git

のようになっている。

これに対して先程書いたような内容でsshconfig(~/.ssh/config)を設定すると、
上記URLは一切変更せずとも、実際に接続しにいくときはURLとポート番号を443接続用の方に変えられる、というのが大まかな仕組み。

Host <任意の名前>
    HostName <実際のDNS名>
    # その他sshのオプションに対応したあらゆる設定

と書いておくと、ssh <任意の名前>とすると実際にはssh <もろもろのオプション> <実際のDNS名>に変換されるため、
Hostにbitbucket.org、HostNameにaltssh.bitbucket.orgを設定しておくとbitbucket.orgへのsshは適当なオプションを設定したaltssh.bitbucket.orgへのsshへと上書きされるようになる。

ここで、おそらくオンプレ環境などで自前で立てたGitLabだったり、GitHub Enterpriseなどでは相当する仕組みを自分で作らないと同じことは出来ないので注意。

その他

プロキシと闘う(?)ノウハウとして、

https://zenn.dev/junkor/articles/ca961ca70f441a

なども参考

GitHubで編集を提案

Discussion