V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
AllenHua
V2EX  ›  程序员

[2022-03] GitHub 加速终极教程

  •  6
     
  •   AllenHua · 144 天前 · 5877 次点击
    这是一个创建于 144 天前的主题,其中的信息可能已经有所发展或是发生改变。

    时常看到 V 站吐嘈 git clone 慢的帖子,本人写了这篇文章,推荐 阅读原文


    本文意图解决使用 GitHub 访问( https) 或者 git clone ( https or ssh )慢的问题。在此分享我的方法,我所了解的 GitHub 加速最佳方案。

    前提是,你的木弟子应该还行,木弟子越好,GitHub 体验越好

    很多文章没有讲全面,只讲了 http proxy ,而没有讲 ssh proxy 。事实上大部分程序员使用 GitHub 都会使用 SSH keys (普通用户可能就不会了),在本机生成 rsa 公私钥(其他的类型还有 dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk),然后把公钥内容拷贝、设置进 GitHub 。

    设置 Http Proxy

    $ git config --global http.proxy socks5://127.0.0.1:7890
    

    事实上使用 socks5h 更佳,即

    $ git config --global http.proxy socks5h://127.0.0.1:7890
    

    h 代表 host ,包括了域名解析,即域名解析也强制走这个 proxy 。另外不需要配置 https.proxy,git 不认的(关于这一点我认识不是很清晰,希望有人解惑)。

    推荐使用 socks5 代理,因为 socks5 包含 http(s)。而且 socks5 代理工作在 osi 七层模型中的会话层(第五层),https/http 代理工作在 osi 七层模型的应用层(第七层), socks 代理更加底层。所以就没必要配置 git config --global http.proxy http://127.0.0.1:7890 了。

    这样配置的话会使本机所有的 git 服务都走了代理,假如你在良心云上(国内主机)部署了自己的 gitea ,域名 https://gitea.example.com,那么可以只配置 GitHub 的 http proxy ,即

    $ git config --global http.https://github.com.proxy socks5://127.0.0.1:7890
    

    设置 SSH Proxy

    Linux & macOS

    配置文件在用户家目录下的 .ssh/config 其中 nc 程序位于 /usr/bin/nc

    $ cat ~/.ssh/config
    
    Host github.com
     Hostname ssh.github.com
     IdentityFile /xxx/.ssh/github_id_rsa
     User git
     Port 443
     ProxyCommand nc -v -x 127.0.0.1:7890 %h %p
    

    nc 就是 netcat ,引用一段描述

    netcat is a simple unix utility which reads and writes data across network connections, using TCP or UDP protocol. It is designed to be a reliable "back-end" tool that can be used directly or easily driven by other programs and scripts. At the same time, it is a feature-rich network debugging and exploration tool, since it can create almost any kind of connection you would need and has several interesting built-in capabilities. Netcat, or "nc" as the actual program is named, should have been supplied long ago as another one of those cryptic but standard Unix tools.

    译文: netcat 是一个简单的 unix 实用程序,它使用 TCP 或 UDP 协议跨网络连接读取和写入数据。 它被设计成一个可靠的“后端”工具,可以直接使用或由其他程序和脚本轻松驱动。 同时,它还是一个功能丰富的网络调试和探索工具,因为它几乎可以创建您需要的任何类型的连接,并且具有几个有趣的内置功能。Netcat ,或实际程序命名的“nc”,早就应该作为另一种神秘但标准的 Unix 工具提供。

    Windows

    Win 下与之对应的 netcat 程序是 connect.exe,程序位于 Git 安装路径 C:\Program Files\Git\mingw64\bin,win 下推荐使用 Git Bash ,路径也是 Linux style

    $ cat ~/.ssh/config
    
    Host github.com
     Hostname ssh.github.com
     IdentityFile /c/users/xxx/.ssh/github_id_rsa
     User git
     Port 443
     ProxyCommand "C:\Program Files\Git\mingw64\bin\connect.exe" -S 127.0.0.1:7890 %h %p
    

    补充信息

    为什么 hostname 是 ssh.github.com,为什么要用 443 端口,ssh 默认不是 22 端口么?

    因为有些木弟子对于 22 端口做了限制,要么禁止了,要么有些抽风,这时经常会遇到如下错误

    kex_exchange_identification: Connection closed by remote host

    所以如果 22 端口不畅就使用 443 ,安全可靠。ps: 22 端口时 hostname 请填 github.com。这部分请扩展阅读 此文

    至于网页访问 GitHub ,借助木弟子访问已然是日常,要么浏览器扩展 SwitchyOmega,要么系统代理,要么直接使用 Clash 的分流策略等等。我的习惯还是使用 Switchy Omega 。

    这样配置之后 git clone https://github.com/xxx/yyy.git 或者 git clone [email protected]:xxx/yyy.git 以及 git pullgit push 等等操作都很快了,除非科学的工具不行。

    难免有误,欢迎大家补充和纠正。

    第 1 条附言  ·  143 天前

    关于 Windows 这边使用 connect.exe 建立 ssh 的 proxy 通道,ProxyCommand 命令的写法我更正一下

    $ cat ~/.ssh/config
    
    Host github.com
     Hostname ssh.github.com
     IdentityFile /c/users/xxx/.ssh/github_id_rsa
     User git
     Port 443
     ProxyCommand connect -S 127.0.0.1:7890 %h %p
    

    更加详细的说明请看 原文

    47 条回复    2022-03-29 21:19:31 +08:00
    oott123
        1
    oott123  
       144 天前   ❤️ 5
    写得很不错,网上确实缺乏一篇这样完整的教程。GitHub 居然还可以用 443 访问 ssh ,挺有意思的
    leeyuzhe
        2
    leeyuzhe  
       144 天前
    学习了,我之前一直不知道 ssh 方式 clone 怎么走代理
    ChaosesIb
        3
    ChaosesIb  
       144 天前
    直接用环境变量 http_proxy 不行吗
    XIU2
        4
    XIU2  
       144 天前
    以前上 Github 没啥问题的时候,当时为了解决 Github 各种文件下载速度慢的问题,我还写了个油猴脚本( Github 增强 - 高速下载)聚合了一些下载 /镜像加速源。

    直到去年初观测到 Github 被 SNI 干扰了(当时我还在这里首发了篇简单报告及稳定复现步骤),我这个脚本就显得有多少有点鸡肋了,毕竟现在很多人访问网页都要挂梯子,也就不需要担心文件下载速度慢的问题了。。。
    missdeer
        5
    missdeer  
       144 天前
    原来还有 connect.exe 可以用啊,之前一直只知道 nc
    tankeco
        6
    tankeco  
       144 天前
    再配上 redsocks 和 iptables... 可以让不支持代理的程序上 github (说的就是你 copilot
    bootvue
        7
    bootvue  
       144 天前
    proxifier
    AllenHua
        8
    AllenHua  
    OP
       144 天前
    @ChaosesIb #3 这种只对 http 有效,使用 ssh 协议 clone 项目时不会读到这个变量的(读到了也不会用)
    @XIU2 #4 互联网越来越小
    @missdeer #5 我发现 Git Bash 对于路径中的空格处理有 bug ,所以 windows 下使用 Git Bash 按照正文中的配置无法使用,还得调整一下。认证文件改成 c:\users\xxx\.ssh\github_id_rsa 的形式 使用 cmd 和 powershell 是可以借助 connect 程序走代理 clone 的
    @tankeco #6 感谢补充。还没用过这个
    AllenHua
        9
    AllenHua  
    OP
       144 天前
    @bootvue #7 这个确实可以,下载使用过。
    Kinnice
        10
    Kinnice  
       144 天前
    tun 模式 /透明代理更加舒服
    lazydao
        11
    lazydao  
       144 天前   ❤️ 1
    友情提示,这里没有梯子这种敏感词。
    devcat9
        12
    devcat9  
       144 天前
    @lazydao +1 友情提示:V2EX 本身就需要「梯子」访问。
    1002xin
        13
    1002xin  
       144 天前
    对于我来说,一个稳定的代理基本上解决了这几年 GitHub (不仅仅是 GitHub ) 网络的问题
    mschultz
        14
    mschultz  
       144 天前 via iPhone
    👍 不错,很全面了


    @oott123 #1 我最近也是发现工作用的服务器屏蔽了 SSH 22 端口对外连接,进而才找到这个 443 端口的方案。GitLab 、Bitbucket 等均有类似方案。

    服务器(包括梯子)防火墙屏蔽 22 端口对外连接的情况还挺常见的,有的可能是出于安全原因,比如避免用户恶意扫描别人
    ab
        15
    ab  
       144 天前
    收藏一贴
    AllenHua
        16
    AllenHua  
    OP
       144 天前
    @Kinnice #10 透明代理确实很舒服。我在家里用 N1 做了个,体验良好。但是之前 iptables 有些配置不太会,总是遇到小问题,现在已经比较稳定了。透明代理很香,OpenWrt 将 DHCP 的网关和 dns 两个 option 改成 N1 的 IP ,局域网设备默认获得 IP 地址时自动设置 N1 的网关和 dns 。
    @1002xin #13 这个钱还是不能省
    AllenHua
        17
    AllenHua  
    OP
       144 天前
    @lazydao #11 知道了。但是有其他敏淦词,所以我宁愿自我审查,不然有时候点击 Publish 提示我不准发布…… 然后 403 了,得换个 IP 才能继续访问,这个体验我有过好几次了,实在是不爽,于是预防性自我审查…… 哎
    Uplay
        18
    Uplay  
       144 天前
    @devcat9 不需要了,我现在就是裸连
    aaa5838769
        19
    aaa5838769  
       144 天前
    学习了
    wonderfulcxm
        20
    wonderfulcxm  
       144 天前 via iPhone
    为什么配置了终端代理,curl 可以自动走这个代理,ssh 还要另外设定?
    Huelse
        21
    Huelse  
       144 天前
    @devcat9 不一定,如果用自建的 dns 服务就可以直连,目前我就是这样访问的
    ruixue
        22
    ruixue  
       144 天前   ❤️ 1
    @AllenHua #17 楼主你这么做还是有用的,v2ex 如果主帖内容里包含“梯子”或“科学上网”等词,虽然不会发不出去甚至 ban ip ,但是会导致不登录的情况下访问帖子直接跳转首页,改成木弟子就不会了
    brust
        23
    brust  
       144 天前
    你都用梯子了,为什么不让 github 走梯子呢
    brust
        24
    brust  
       144 天前
    @brust 23
    我指的是梯子的 pac 规则增加 github
    AllenHua
        25
    AllenHua  
    OP
       144 天前 via iPhone   ❤️ 1
    @wonderfulcxm #20 因为 curl 是纯 http 服务,ssh 有不止于 http 应用层的服务(如上文 http 代理工作在应用层)

    SSH 协议框架中最主要的部分是三个协议:

    传输层协议( The Transport Layer Protocol ):传输层协议提供服务器认证,数据机密性,信息完整性等的支持。
    用户认证协议( The User Authentication Protocol ):用户认证协议为服务器提供客户端的身份鉴别。
    连接协议( The Connection Protocol ):连接协议将加密的信息隧道复用成若干个逻辑通道,提供给更高层的应用协议使用。 (摘自维基百科 Secure SHell 词条)

    所以 ssh 需要更加底层的代理,你看 nc 和 connect 就是基于 TCP 和 UDP (第四层:传输层)做的一个工具。(手机打字和排版,见谅)
    lostberryzz
        26
    lostberryzz  
       144 天前   ❤️ 2
    有些回复看着真是血压高,生怕别人不知道他有个梯子似的。。

    楼主的信息还是非常有用的,特别是 443 端口这一点,以前应该没在 V 站上看过,很有用的功能
    wonderfulcxm
        27
    wonderfulcxm  
       144 天前
    @AllenHua #25 不是很能信服,首先 cURL 支持的通信协议不止 HTTP ,还有 FTP 、SCP 、Telnet 、HTTP 、HTTPS 等等,别的不说,只说 HTTPS ,HTTPS 并不是一个单独的协议,而是对工作在一加密连接( TLS 或 SSL )上的常规 HTTP 协议。而 TLS 本身就是 传输层安全性协议 Transport Layer Security 的缩写,那它就是传输层的协议。从这点来说 https 也不止是于应用层的服务,这点跟 ssh 好像也没区别。。。
    forcecharlie
        28
    forcecharlie  
       144 天前   ❤️ 1
    如果对编程比较熟,可以自己写一个 hook 掉 git ,比如我就写过 tunnelssh https://github.com/balibuild/tunnelssh ,tunnelssh 根据你本机的代理设置自动让 git 走代理,无需修改任何配置,关闭代理同样可以访问。

    git tunnel clone [email protected]:balibuild/tunnelssh.git
    ysc3839
        29
    ysc3839  
       144 天前 via Android
    使用 socks5 代理时请注意,因为 git 使用 curl 请求 http ,而 curl 的 socks5://会使用本地 DNS 进行解析
    ysc3839
        30
    ysc3839  
       144 天前 via Android   ❤️ 1
    @ysc3839 要使用 socks5h://才是远程解析
    https://curl.se/libcurl/c/CURLOPT_PROXY.html

    这也是我推荐使用 http 代理的原因。除此之外 Git Credential Manager 似乎不支持 socks5 代理,不能自动保存密码。以及有许多别的命令行程序是不支持 sock5 代理的,但大多数都支持 http 。
    xxb
        31
    xxb  
       143 天前
    proxychains4 秒杀一切
    AllenHua
        32
    AllenHua  
    OP
       143 天前
    @wonderfulcxm #27 确实,是我没有做好准备就回答了。查了下,curl 居然支持这么多协议:有 DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTMPS, RTSP, SCP, SFTP, SMB, SBMS, SMTP, SMTPS, TELNET 和 TFTP 。但这些应该都是应用层协议…… 至于你说的 “从这点来说 https 也不止是于应用层的服务” 确实有道理。可能是 ssh 建立连接和通讯的过程比起 http 更加依赖应用层以下的网络数据包的封装。
    AllenHua
        33
    AllenHua  
    OP
       143 天前
    @brust #24 pac 文件依然不能保证 git clone ssh 协议的 git 仓库时能够使用代理。
    @forcecharlie #28 感谢
    @ysc3839 #30 学习了
    Spoience
        34
    Spoience  
       143 天前
    Clash 的 TUN 模式会很舒服,无需配置其他代理,但是楼主写的确实很详细,收藏了
    plko345
        35
    plko345  
       143 天前
    请教 OP 一个问题, docker pull 我理解应该走的是 https, 但设置了 https_proxy/http_proxy/all_proxy 却一点用没有, 访问 google.com 是正常的
    anubu
        36
    anubu  
       143 天前
    @plko345 docker pull 的代理需要设置在 docker daemon 上,可以参考官方文档进行设置。
    AllenHua
        37
    AllenHua  
    OP
       143 天前
    @Spoience #34 感谢
    @plko345 #35 修改文件 /etc/docker/daemon.json 使用 key registry-mirrors 指定一个国内镜像了 docker hub 的 registry ,目的就是从国内服务器拉镜像,更快些。所以 docker pull 不需要 http 或者 socks 代理的,和 Linux Distro 换源原理类似。

    ```
    "registry-mirrors": [
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com"
    ]
    ```

    但有些 registry 不再提供服务了,或者变私有了,可参考 https://yeasy.gitbook.io/docker_practice/install/mirror#bu-zai-ti-gong-fu-wu-de-jing-xiang
    20210610204811
        38
    20210610204811  
       143 天前
    不知墙为何物。
    tkl
        39
    tkl  
       143 天前
    这会话层从哪来的???

    rfc 里面没这么写

    https://datatracker.ietf.org/doc/html/rfc1928

    The protocol described here is designed to provide a framework for
    client-server applications in both the TCP and UDP domains to
    conveniently and securely use the services of a network firewall.
    The protocol is conceptually a "shim-layer" between the application
    layer and the transport layer, and as such does not provide network-
    layer gateway services, such as forwarding of ICMP messages.
    AllenHua
        40
    AllenHua  
    OP
       143 天前
    @tkl #39 rfc 里这句话说

    “该协议在概念上是应用层和传输层之间的“填充层”,因此不提供网络层网关服务,例如转发 ICMP 消息。”

    看上去是没有明确表示是表示层(第 6 层)和传输层(第 4 层)之间的第五层,但是这个“填充层” SOCKS 条目的 wikipedia 中有补充是会话层(第 5 层)。见 https://en.wikipedia.org/wiki/SOCKS

    SOCKS performs at Layer 5 of the OSI model (the session layer, an intermediate layer between the presentation layer and the transport layer). A SOCKS server accepts incoming client connection on TCP port 1080, as defined in RFC 1928.

    所以应该还是有些道理的。
    zh4710jj
        41
    zh4710jj  
       143 天前   ❤️ 1
    并不能算是终极教程
    少了一个 git protocol 的协议的处理 也就是类似 git:// 的协议
    这种并不能用 http proxy 或者 ssh config 来解决
    参考 里的最后一段
    AllenHua
        42
    AllenHua  
    OP
       143 天前
    @zh4710jj #41 感谢补充,这个 gist 不错。见过 git:// 这样的字符串,但是这个大部分人应该都没有用过。
    AmaQuinton
        43
    AmaQuinton  
       143 天前
    收藏了. 目前一直在用 clash for windows ,感觉提交代码到 Github 还是有些不稳定.
    bigbigpark
        44
    bigbigpark  
       143 天前
    收藏一波
    sakuraSou
        45
    sakuraSou  
       143 天前 via iPhone
    反代
    anubu
        46
    anubu  
       142 天前   ❤️ 1
    @plko345
    @AllenHua #37 关于“所以 docker pull 不需要 http 或者 socks 代理的”,做一点补充说明。

    registry-mirror 仅能对 docker hub 这个 registry 起作用,对比较常用的 gcr.io\quay.io 或其它自建 registry 不起作用,另外部分企业需要代理才能访问外网,这时候还是需要 docker pull 代理。这个代理需要配置在 dockerd 上,可以借助 systemd 来控制。

    参考: https://docs.docker.com/config/daemon/systemd/
    AllenHua
        47
    AllenHua  
    OP
       142 天前
    @anubu #46 感谢补充(你说的 gcr.io/ quay.io 都没用过 2333 ;然后自建 registry 一般在公司内网或者国内所以一般速度都是快的。
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2552 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 12:06 · PVG 20:06 · LAX 05:06 · JFK 08:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.