GitHub からの clone でエラーが出たので対処した

# GitHub からの clone でエラーが出たので対処した

GitHub 上のレポジトリを、手元の Linux(CentOS6) に clone しようとしたら `error:  while accessing https://github.com/XXX/XXX.git/info/refs` のようなエラーが出て、 clone に失敗しました。

エラーメッセージ:

```terminal
Initialized empty Git repository in /XXX/.git/
error:  while accessing https://github.com/XXX/XXX.git/info/refs

fatal: HTTP request failed
```

# 環境

+ GitHub
+ CentOS 6


# 2018/10/21追記: 根本的な対処方法

本件は、**NSS と curl を update すれば直る** が正解でした。 [本件と同様の事例](https://qiita.com/murai-taisuke/items/173b3cbbd697e630047d) の記事を参照したら、curl のほか NSS も update 対象にあげられていました。 ※なぜ前回調べて回った時に見落としたのだろう…?

さっそく検証してみました。当方の環境で NSS を update し(※curl は update 済み)、git config の `http.sslVersion` 設定を削除したうえで git clone を試したところ、**問題なく clone できました**。

問題なく clone できたときの、各パッケージのバージョンは以下の通りです。

```text

  nss.x86_64 0:3.36.0-9.el6_10
  nss-softokn.x86_64 0:3.14.3-23.3.el6_8
  nss-softokn-freebl.i686 0:3.14.3-23.3.el6_8
  nss-softokn-freebl.x86_64 0:3.14.3-23.3.el6_8
  nss-sysinit.x86_64 0:3.36.0-9.el6_10
  nss-tools.x86_64 0:3.36.0-9.el6_10
  nss-util.x86_64 0:3.36.0-1.el6

  curl-7.19.7-53.el6_9.x86_64
  libcurl-7.19.7-53.el6_9.x86_64

  git2u-core-2.16.4-1.ius.centos6.x86_64
  git2u-2.16.4-1.ius.centos6.x86_64
```

今回参照した文献:

* [突然GitHubとhttps通信できなくなったときの解決メモ - Qiita](https://qiita.com/murai-taisuke/items/173b3cbbd697e630047d)
* [CentOS 6 の Git で SSL connect error にハマった (NSS error -12286)](https://mseeeen.msen.jp/git-ssl-or-nss-connect-error-in-centos-6/)
* [Github unable to access SSL connect error - Stack Overflow](https://stackoverflow.com/questions/48938385/github-unable-to-access-ssl-connect-error)
* [cURL doesn't connect to HTTPS while wget does (NSS error -12286) - Unix & Linux Stack Exchange](https://unix.stackexchange.com/questions/280548/curl-doesnt-connect-to-https-while-wget-does-nss-error-12286)


…なので、以下の `http.sslVersion` 設定による対処は、**回避策**という位置付けとし、記録として残しておきます。

----

# 対処: うまくいったもの &　だめだったもの

手元の Linux 側で、git が使用する SSL/TLS バージョンを `TLS 1.x` に指定することで、 clone 出来るようになりました。

```shell-session
$ git config --global --add http.sslVersion tlsv1
```

結果: **成功しました**

```shell-session
$ git clone https://github.com/XXX/XXX.git
Cloning into 'XXX'...
remote: Enumerating objects: 40, done.
remote: Counting objects: 100% (40/40), done.
remote: Compressing objects: 100% (34/34), done.
remote: Total 40 (delta 10), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (40/40), done.
$
```

※[git - SourceTree error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version - Stack Overflow](https://stackoverflow.com/questions/48944875/sourcetree-error1407742essl-routinesssl23-get-server-hellotlsv1-alert-protoc) の、 bsh 氏の回答を参考にしました。ありがとう! > bsh


※厳密に `TLS 1.2` を明示指定したら失敗しました。なぜだろう?

```shell-session
$ git config --global --add http.sslVersion tlsv1.2
$ git clone https://github.com/XXX/XXX.git
Cloning into 'XXX'...
warning: unsupported ssl version tlsv1.2: using default
fatal: unable to access 'https://github.com/XXX/XXX.git/': SSL connect error
$
```


# どういうこと?

あまりよく調べていませんが…

GitHub は、 [TLS 1.0/TLS 1.1 のアクセスを禁止した(2018年2月8日付)](https://githubengineering.com/crypto-removal-notice/) らしいです。Linux 側の git コマンドで使用する SSL/TLS のバージョンが、この制限に引っかかった…のだと思います。

`man git-config` に、 `http.sslVersion` に指定できる値は `sslv2`, `sslv3`, `tlsv1`, `tlsv1.0`, `tlsv1.1`, `tlsv1.2` とありました。

今更 SSL は無いし、TLS 1.0/1.1 は禁止されているので、選択肢は次の2つです。

+ `tlsv1`
+ `tlsv1.2`

前述の通り、 `tlsv1.2` を指定したらうまくいかず、 `tlsv1` を指定して成功しました。

※`tlsv1.2` の指定でも上手くいく環境もあると思います。


# その他にやるべきこと & やったこと

[HTTPS cloning errors - User Documentation](https://help.github.com/articles/https-cloning-errors/) を見ると、次のようなことが書いてあります。

+ Git のバージョンを確認しろ
+ リモートレポジトリの指定が正しいか確認しろ
+ アクセストークンを提供しろ
+ パーミッションを確認しろ
+ 代りに SSH プロトコルを使え

これを受け、当方では `git`, `curl`, `ca-certificate` をバージョンアップしました。

| ソフトウェア | バージョン |
|:---|:---|
|git | 2.16.4 |
|curl | 7.19.7 |
|CA 証明書 | ca-certificates-2018.2.22-65.1.el6.noarch |

しかし、これらのバージョンアップだけでは効果は無く…前述のとおり、 `git config` コマンドで解決をみました。

なお、 git コマンドのバージョンアップには、 [`IUS`](https://ius.io/) を利用しました。 CentOS6 の yum レポジトリが提供する git は、バージョン 1.7.1-9 と古いため。


## git コマンドは、内部で libcurl を使用している(らしい)

`man git-config` によると、 

+ git コマンドは、内部で `libcurl` を使用している
+ 使用する SSL/TLS のバージョンは、内部的に `CURLOPT_SSL_VERSION` で設定される
+ 環境変数 `GIT_SSL_VERSION` で上書き指定できる

とありました(意訳)。

curl をバージョンアップしたのは、このためです。なぜか上手くいかなかった `tlsv1.2` の指定は、 `libcurl` で使われるのだと推測します。 

いま思えば、git は [`IUS`](https://ius.io/) 由来、`libcurl`  は CentOS6 yum レポジトリ由来なので、ライブラリとの連携に何か問題があるのかもしれません(未調査)。


# 資料

## GitHub への SSL/TLS 接続試験

curl で TLS バージョンを指定して GitHub に接続してみました。

結果: オプションに **`--tlsv1.2` を指定したときだけ**、接続に成功しました。

GitHub に HTTPS 接続できるのは TLS 1.2 だけ、なのは本当のようです。

```shell-session

$ curl --verbose https://github.com
* About to connect() to github.com port 443 (#0)
*   Trying 192.30.255.113... connected
* Connected to github.com (192.30.255.113) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* NSS error -12190
* Closing connection #0
* SSL connect error
curl: (35) SSL connect error                              # デフォルトで失敗
$
$ curl --tlsv1.0 --verbose https://github.com
* About to connect() to github.com port 443 (#0)
*   Trying 192.30.255.113... connected
* Connected to github.com (192.30.255.113) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* NSS error -12190
* Closing connection #0
* SSL connect error
curl: (35) SSL connect error                              # --tlsv1.0 で失敗
$
$ curl --tlsv1.1 --verbose https://github.com
* About to connect() to github.com port 443 (#0)
*   Trying 192.30.255.112... connected
* Connected to github.com (192.30.255.112) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* NSS error -12190
* Closing connection #0
* SSL connect error
curl: (35) SSL connect error                              # --tlsv1.1 で失敗
$
$ curl --tlsv1.2 --verbose https://github.com
* About to connect() to github.com port 443 (#0)
*   Trying 192.30.255.113... connected
* Connected to github.com (192.30.255.113) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* Server certificate:                                     # --tlsv1.2 で成功
*       subject: CN=github.com,O="GitHub, Inc.",L=San Francisco,ST=California,C=US,serialNumber=5157550,incorporationState=Delaware,incorporationCountry=US,businessCategory=Private Organization
*       start date: May 08 00:00:00 2018 GMT
*       expire date: Jun 03 12:00:00 2020 GMT
*       common name: github.com
*       issuer: CN=DigiCert SHA2 Extended Validation Server CA,OU=www.digicert.com,O=DigiCert Inc,C=US
> GET / HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: github.com
> Accept: */*
>
< HTTP/1.1 200 OK

    : 以降略
```

## `http.sslVersion` について、man git-config の記載

```text
       http.sslVersion
           The SSL version to use when negotiating an SSL connection, if
           you want to force the default. The available and default
           version depend on whether libcurl was built against NSS or
           OpenSSL and the particular configuration of the crypto library
           in use. Internally this sets the CURLOPT_SSL_VERSION option;
           see the libcurl documentation for more details on the format
           of this option and for the ssl version supported. Actually the
           possible values of this option are:

           ?   sslv2

           ?   sslv3

           ?   tlsv1

           ?   tlsv1.0

           ?   tlsv1.1

           ?   tlsv1.2
               Can be overridden by the GIT_SSL_VERSION environment
               variable. To force git to use libcurl's default ssl
               version and ignore any explicit http.sslversion option,
               set GIT_SSL_VERSION to the empty string.
```

# 参考文献

1. [git - SourceTree error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version - Stack Overflow](https://stackoverflow.com/questions/48944875/sourcetree-error1407742essl-routinesssl23-get-server-hellotlsv1-alert-protoc)
2. [git pull が急にできなくなったときの解決模索記録](https://qiita.com/TYuko/items/04c26073bc83efbdd009)
3. [HTTPS cloning errors - User Documentation](https://help.github.com/articles/https-cloning-errors/)
* [突然GitHubとhttps通信できなくなったときの解決メモ - Qiita](https://qiita.com/murai-taisuke/items/173b3cbbd697e630047d)
* [CentOS 6 の Git で SSL connect error にハマった (NSS error -12286)](https://mseeeen.msen.jp/git-ssl-or-nss-connect-error-in-centos-6/)
* [Github unable to access SSL connect error - Stack Overflow](https://stackoverflow.com/questions/48938385/github-unable-to-access-ssl-connect-error)
* [cURL doesn't connect to HTTPS while wget does (NSS error -12286) - Unix & Linux Stack Exchange](https://unix.stackexchange.com/questions/280548/curl-doesnt-connect-to-https-while-wget-does-nss-error-12286)