Dive into Ofuton

お布団に飛び込もう

【GitLab】 HTTPSでclone/pushできるようにする

はじめに

GitHubだとプライベートリポジトリの数に制限がある(学生向けに暫くの間いくつかタダで作れる)けど, 自分でGitLabを運用すればVPS代だけでリポジトリ作り放題だぜヒャッハァアアというわけで,GitLabを運用してます.

GitLab大好きです.素晴らしいです.けど,今までどうしてもSSHでしかclone,pushが出来ないんですよ.

これは気持ち悪いなー,なんとかしてHTTPSでもできるようにしたいなーと思ってました.

それで,原因について探っていると,cloneしようとするときHTTPSでエラーが出るのはGitLabのせいではないようでした.

HTTPSで接続する場合は,gitの方で証明書をチェックして怪しい証明書(認証局による署名がされていないもの)の場合は弾くようになっているようです.

だから,SSL用の証明書の類をうまいことやれば弾かれずに済むんじゃないかなーと思って設定していった結果,無事gitに弾かれないようにになったので,それらについて書いていきます.

結論から言うと,git -c http.sslVerify=false clone https://…でよいのですが,それはなんか気持ち悪い人は続きをどうぞ.

なぜHTTPSでclone/pushする必要があるの?

時間の無駄だと思ったがHTTPS欲を抑えきれなかった.

環境

  • さくらのVPS 1GB
  • Ubuntu 12.04 LTS
  • GitLab 6.7.3

多分そんなに関係ないと思う.

手順

認証局作成

まず,/etc/ssl/myCA以下に認証局を作成していきます.

cd /etc/ssl
sudo mkdir myCA
cd myCA

CA.shという認証局生成用のスクリプトを使うと今後楽なのでコピーします.

sudo cp /usr/lib/ssl/misc/CA.sh . #CA.shの位置は,"locate CA.sh"とかで調べる

openssl.cnfをコピーします.

sudo cp /etc/ssl/openssl.cnf  .

CA.shを編集

#60行目くらいに二行追加
SSLEAY_CONFIG="-config /etc/ssl/myCA/openssl.cnf"
CATOP="/etc/ssl/myCA"

#有効期間を10年に変更
CADAYS="-days 3650"   # 10 years

openssl.cnfを編集

#42行目
dir           = /etc/ssl/myCA

#73, 75行目
default_days  = 3650                  # how long to certify for
default_md    = sha256                # use public key default MD

#106行目
default_bits          = 2048

#129-140行目
countryName_default           = JP
stateOrProvinceName_default   = Kanagawa #適当に
localityName_default    = Yokohama    #適当に追加
0.organizationName_default    =  適当に

#188行目のコメントイン
keyUsage = nonRepudiation, digitalSignature, keyEncipherment

#215行目
extendedKeyUsage = critical,timeStamping, serverAuth

#245行目
keyUsage = cRLSign, keyCertSign

シリアルナンバーを初期化

証明書に付けられるシリアルナンバーです.指定しない場合には乱数っぽいものに初期化されます.証明書を発行する度に1ずつ増えていきます.

echo "01" | sudo tee /etc/ssl/myCA/serial

公開鍵,秘密鍵自己署名証明書の生成

sudo ./CA.sh -newca

CA certificate filename (or enter to create) 空でよい
Enter PEM pass phrase:(署名時に使用するパスフレーズ)
# countryNameやらはopenssl.cnfで指定した値がデフォルトで入っているので楽です.
sudo mv careq.pem certs/01.pem

秘密鍵はroot以外からは見られないようにします.

sudo chmod 700 private
sudo chmod 600 private/01.pem
  • cacert.pem, newcert/01.pem (CA証明書)
  • certs/01.pem (CA証明書発行要求)
  • private/cakey.pem  (CA秘密鍵

GitLab用サーバー証明書を発行

https://gitlab.example.com用の証明書を発行します.

$ cd /etc/ssl/myCA
$ sudo ./CA.sh -newreq
Generating a 2048 bit RSA private key
.......................+++
...........................................................................+++
writing new private key to 'newkey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [JP]:
State or Province Name (full name) [Kanagawa]:
Locality Name (eg, city) [Yokohama]:
Organization Name (eg, company) [HogeHoge]:
Organizational Unit Name (eg, section) []:GitLab
Common Name (e.g. server FQDN or YOUR name) []:gitlab.example.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Request is in newreq.pem, private key is in newkey.pem

newreq.pem, newkey.pemができるので,独自CAで署名をする.

sudo ./CA.sh -sign
Using configuration from /etc/ssl/myCA/openssl.cnf
Enter pass phrase for /etc/ssl/myCA/private/cakey.pem:
…
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
…
-----END CERTIFICATE-----
Signed certificate is in newcert.pem

newcerts/内の一番数字がでかいやつが今回作成した署名付きの証明書になります.

ls newcerts
01.pem  02.pem #02.pemがhttps://gitlab.example.com用の証明書
sudo mv newreq.pem certs/02.pem #lsで確認したファイル名にする
sudo mv newkey.pem private/02.pem #同上
sudo rm newcert.pem #newcerts/02.pemと同一ファイルなので削除して良い

Apacheで使える形にする.

sudo openssl x509 -in newcerts/02.pem -out gitlab.crt 
sudo openssl rsa -in private/02.pem -out gitlab.key #パスワードを埋め込む

gitlab.crt, gitlab.keyを,適当なディレクトリに配置して, Apacheで設定を行う

SSLCertificateFile /hogehoge/piyopiyo/gitlab.crt
SSLCertificateKeyFile /hogehoge/piyopiyo/gitlab.key

認証局証明書をインポートする

認証局証明書が出来上がっているので,これをPCにインポートするとよいです.以下はローカルPCでの作業になります.
/etc/ssl/myCA/cacert.pemをscpなりcatで表示してコピペするなりして,ローカルに持ってきます.
以下環境ごとのインポート方法です.

Ubuntuの場合

cacert.crtを作成

openssl x509 -in cacert.pem -out cacert.crt

/usr/local/share/ca-certificates 以下にcacert.crtを配置し,

update-ca-certificates

Cygwin

\usr\share\pki\ca-trust-source\anchors 以下にcacert.pemを配置

sudo update-ca-trust

これで,

git clone https://gitlab.example.com/hoge/piyo.git

とかができるようになりますできませんでした.

GitLabの設定

GitLab側でも,認証局証明書を指定する必要があります.
普通にGitLabをインストールしているのであれば,gitlab-shell/config.ymlを編集します.

http_settings:
#  user: someone
#  password: somepass
  ca_file: /etc/ssl/myCA/cacert.pem  # 作成した認証局証明書を指定する
#  ca_path: /etc/pki/tls/certs
  self_signed_cert: true

これで,sudo service gitlab restartすれば晴れて,HTTPSSSH両方でGitLab上のリポジトリをclone/push出来ます.

その他

HTTPSでエラーを吐かずにgitを使うようにするには証明書のインストールが必要なので,結局git -c http.sslVerify=false clone https://gitlab.example.com/hoge/piyo.gitのようにするのが一番手っ取り早い.
普段はあまり意識していないけど,HTTPSで通信するときは認証局とか証明書とかそういうやつが裏で使われているんですねーということがよく分かりました.

これとは別の話なんだけど,最近VPSにファイルをアップしたいときにscpが使えなくなってしまっていて悲しい.

参考

オレオレ認証局の作り方~SSL証明書を無料で作る方法 on CentOS 5 | OPTPiX Labs Blog

Linux - 独自SSLサーバ認証局(CA)作成とサーバ証明書発行 - Qiita

6-6(1)CAの構築 : 基礎から学ぶ無線LANの設定と設計

Cloning via HTTPS fails because of server certificate verification failure. · Issue #4272 · gitlabhq/gitlabhq · GitHub

何かの会長のブログ: gitlabの設定でハマった点