一、发现问题

今天解决一下这几天git push报错的问题

1
2
3
4
5
6
$ git push
ssh: connect to host github.com port 22: Connection refused
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

ssh:连接到主机github.com端口22:连接被拒绝
致命:无法从远程存储库读取。
请确保您具有正确的访问权限
并且存储库存在。


二、分析解决

1. 网络原因?

我猜想是否因为没有挂代理,果然,我们家的 WiFi 用 Chrome 浏览器打不开GitHub,于是我挂上了代理,尝试重新推送。奇怪,依旧报这个错误。

那我换上手机流量开热点给电脑试试,依旧报错。

WiFi问题?代理的网速问题?流量+代理还不行?

2. 端口原因?

端口22可能被防火墙屏蔽了,可以尝试连接GitHub的443端口。

1
$ vim ~/.ssh/config

解决方案:给~/.ssh/config文件里添加如下内容,这样ssh连接GitHub的时候就会使用443端口。

1
2
3
Host github.com
Hostname ssh.github.com
Port 443

如果~/.ssh目录下没有config文件,新建一个即可。

修改完~/.ssh/config文件后,使用ssh -T git@github.com来测试和GitHub的网络通信是否正常,如果提示Hi xxxxx! You've successfully authenticated, but GitHub does not provide shell access. 就表示一切正常了

这个方案有效的前提是:执行命令ssh -T -p 443 git@ssh.github.com后不再提示connection refused,尝试这个方案的伙计先执行这条命令测试下。

3. DNS被污染?

既然和GitHub建立ssh连接的时候提示connection refused,那我们就详细看看建立ssh连接的过程中发生了什么,可以使用ssh -v命令,-v表示verbose,会打出详细日志。

1
2
3
4
5
6
7
8
$ ssh -vT git@github.com
OpenSSH_8.5p1, OpenSSL 1.1.1k 25 Mar 2021
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Connecting to github.com [::1] port 22.
debug1: connect to address ::1 port 22: Connection refused
debug1: Connecting to github.com [127.0.0.1] port 22.
debug1: connect to address 127.0.0.1 port 22: Connection refused
ssh: connect to host github.com port 22: Connection refused

从上面的信息马上就发现了诡异的地方,连接github.com的地址居然是::1127.0.0.1。前者是IPV6的localhost地址,后者是IPV4的localhost地址。

到这里问题就很明确了,是DNS解析出问题了,导致github.com域名被解析成了localhost的ip地址,就自然连不上GitHub了。

Windows下执行ipconfig /flushdns 清除DNS缓存后也没用。

查找github.com的ip地址可以使用 IPAddress.com 来查询,也可以使用nslookup命令(nslookup是域名解析工具):

1
nslookup github.com

查询结果如下,果然解析出了问题(默认使用电脑本地的IPV4 DNS服务器地址):

1
2
3
4
5
6
7
8
$ nslookup github.com
Non-authoritative answer:
Server: 192.***.**.*
Address: 192.***.**.*

Name: github.com
Addresses: ::1
127.0.0.1

那我添上8.8.8.8,它是Google的DNS服务器地址

1
nslookup github.com 8.8.8.8

然后就正常解析出来了:

1
2
3
4
5
6
7
$ nslookup github.com 8.8.8.8
Non-authoritative answer:
Server: dns.google
Address: 8.8.8.8

Name: github.com
Address: 20.205.243.166

看来确实是本地DNS解析被污染了,有2种可能:

  1. DNS解析被运营商劫持了
  2. 使用了科学上网工具

执行ping命令查看连接情况,上面谷歌DNS解析出的20.205.243.166连接不上,但通过 IPAddress.com 查询出的140.82.112.3能够正常ping通:

1
2
3
4
5
6
7
8
9
10
11
12
$ ping 140.82.112.3

Pinging 140.82.112.3 with 32 bytes of data:
Reply from 140.82.112.3: bytes=32 time=290ms TTL=42
Reply from 140.82.112.3: bytes=32 time=297ms TTL=42
Reply from 140.82.112.3: bytes=32 time=277ms TTL=42
Reply from 140.82.112.3: bytes=32 time=278ms TTL=42

Ping statistics for 140.82.112.3:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 277ms, Maximum = 297ms, Average = 285ms

(1) 编辑HOSTS文件

现在手动打开hosts文件的位置:C:\windows\system32\drivers\etc,文件夹中找到Hosts文件并用记事本打开:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host

# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost

按照注释提示,手动在末尾增加一条github.com的域名映射即可:

1
140.82.112.3          github.com

注意IP和域名之间至少要有一个空格,编辑完记得保存。

(2) 强制修改HOSTS文件

如果此文件受保护,无法在此更改,可以操作以下步骤进行强制修改:

  1. 用记事本打开hosts文件,Ctrl + A(全选),Ctrl + C(复制)
  2. 在桌面新建一个文本文档,Ctrl + V(粘贴),将刚复制到的文本粘贴进去
  3. 添加要编辑的内容,保存退出
  4. 将新建的文件拉进hosts所在目录,先将原来的hosts更名,再将新建文件更名为hosts即可,狸猫换太子,编辑成功。操作过程中若遇到权限提示弹窗,同意并给予此操作的账户权限即可。

现在检测一下:

1
2
3
4
5
6
7
8
$ nslookup github.com
Non-authoritative answer:
Server: 192.***.**.*
Address: 192.***.**.*

Name: github.com
Addresses: ::1
127.0.0.1

啊?不是吧,解析地址还是本地?

疑惑的我执行了一下git推送命令:

1
2
3
git add .
git commit -m "测试"
git push

推送成功,吓我一跳,总算松了一口气。


三、知识补充

1. 修改HOSTS的作用

  1. 加快域名解析

    对于要经常访问的网站,我们可以通过在Hosts中配置域名和IP的映射关系,这样当我们输入域名计算机就能很快解析出IP,而不用请求网络上的DNS服务器。

  2. 方便局域网用户

    在很多单位的局域网中,会有服务器提供给用户使用。但由于局域网中一般很少架设DNS服务器,访问这些服务要输入难记的IP地址,对不少人来说相当麻烦。现在可以分别给这些服务器取个容易记住的名字,然后在Hosts中建立IP映射,这样以后访问的时候我们输入这个服务器的名字就行了。

  3. 屏蔽网站

    现在有很多网站不经过用户同意就将各种各样的插件安装到你的计算机中,其中可能包含木马or病毒。对于这些网站我们可以利用Hosts把该网站的域名映射到错误的IP或自己计算机的IP,这样就不用访问了。比如不想访问 www.XXXX.com,那我们在Hosts写上以下内容:

    1
    2
    127.0.0.1 www.XXXX.com #屏蔽的网站
    0.0.0.0 www.XXXX.com #屏蔽的网站

    这样计算机解析域名就解析到本机或错误的IP,达到了屏蔽的目的。

  4. 顺利连接系统

    对于Lotus的服务器和一些数据库服务器,在访问时如果直接输入IP地址那是不能访问的,只能输入服务器名才能访问。那么我们配置好Hosts文件,这样输入服务器名就能顺利连接了。
    最后要指出的是,Hosts文件配置的映射是静态的,如果网络上的计算机更改了请及时更新IP地址,否则将不能访问。

  5. 强制指定某域名对应某IP地址

    新建的网站已经上传到服务器需要调试但是还不想外布访问,或者不想被蜘蛛抓取到时,可以修改本地hosts文件,这样只有自己的电脑能通过域名来访问网站。


参考内容: