【proxy教程】解决网页能访问git克隆失败、pip安装失败、apt更新失败等等网络问题

@


核心原因

能正常访问网站,是因为浏览器走了代理,但是apt、git、pip、conda等等没有走代理,所以就会出现这种情况。但是,一个个去设置代理又很麻烦,我们有两种解决方法:

1.在代理软件中启用虚拟网卡,让所有流量包括系统流量都走代理;
2.引入环境变量,让这些软件走代理,这也是本文的重点。

需要注意的是,SSH 命令(包括 scp)完全不看环境变量,所以必须修改 SSH 的配置文件 ~/.ssh/config,接下来也会讲到。

  • 工具代理兼容性一览表

~ 在 Linux 中代表 /home/用户名/,而在 Windows 中代表 C:\Users\用户名\

开发工具代理配置及文件位置全览

工具 识别环境变量 推荐做法 配置文件路径 (Linux/Windows)
ssh ❌ 否 必须在配置中设置 ProxyCommand ~/.ssh/config
git (SSH) ❌ 否 走 SSH 协议,与环境变量无关 ~/.ssh/config
git (HTTPS) ✅ 是 设置环境变量即可;永久设置需改文件 ~/.gitconfig
apt ❌ 否 apt -o一次性添加;或sudo -E继承;永久设置需改文件 /etc/apt/apt.conf.d/99proxy
pip ✅ 是 设置环境变量即可;sudo 时需加 -E ~/.pip/pip.conf / ~/AppData/Roaming/pip/pip.ini
conda ⚠️ 不稳定 若失败,则在文件中显式设置 proxy_servers ~/.condarc
curl ✅ 是 非常可靠,设置了环境变量通常不需改文件 ~/.curlrc

查看你的代理的地址和端口

自行查看你所使用的代理软件的地址和端口号,以下图片仅为示例。

设置环境变量

linux

把以下内容添加到~/.bashrc文件中,后文所有类似的ip地址和端口,都需要根据实际情况修改代理地址和端口号。

# Proxy Settings
alias setproxy='
    PROXY_ADDR="http://127.0.0.1:7897";
    export http_proxy="$PROXY_ADDR";
    export https_proxy="$PROXY_ADDR";
    export ftp_proxy="$PROXY_ADDR";
    export rsync_proxy="$PROXY_ADDR";
    export HTTP_PROXY="$PROXY_ADDR";
    export HTTPS_PROXY="$PROXY_ADDR";
    export FTP_PROXY="$PROXY_ADDR";
    export RSYNC_PROXY="$PROXY_ADDR";
    export no_proxy="localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,::1";
    export NO_PROXY="localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,::1";
    echo -e "\033[32m[+] Proxy set to: $PROXY_ADDR\033[0m"
'

alias unsetproxy='
    unset http_proxy https_proxy ftp_proxy rsync_proxy;
    unset HTTP_PROXY HTTPS_PROXY FTP_PROXY RSYNC_PROXY;
    unset no_proxy NO_PROXY;
    echo -e "\033[31m[-] Proxy Off\033[0m"
'

这样的话,你可以在某个shell窗口中输入setproxy来启动代理,输入unsetproxy来关闭代理,并且这个设置只对当前shell窗口有效,在这个shell窗口中进行的几乎所有活动都会走代理(除了 SSH 和 sudo 执行命令),非常方便。

为什么说 sudo 执行命令不走代理呢?假如你执行了指令setproxy你只是为当前shell的当前用户设置了环境变量,而你在同一个shell窗口中 sudo 执行命令,会忽略用户层级的环境变量。

如果你想让 sudo 也走代理,有以下两种办法:

1.用sudo再设置一遍:

sudo setproxy

2.在同一个窗口内使用sudo -E参数,例如:

sudo -E pip install ...

windows

PowerShell 的配置文件叫 $PROFILE,类似于 Linux 的 .bashrc

  • 打开配置文件:
if (!(Test-Path $PROFILE)) { New-Item -Type File -Path $PROFILE -Force }
notepad $PROFILE
  • 把以下内容添加到配置文件中。
# Proxy Settings
function setproxy {
    $proxyAddr = "http://127.0.0.1:7897"
    $noProxyList = "localhost,127.0.0.1,10.*,172.16.*,172.17.*,172.18.*,172.19.*,172.20.*,172.21.*,172.22.*,172.23.*,172.24.*,172.25.*,172.26.*,172.27.*,172.28.*,172.29.*,172.30.*,172.31.*,192.168.*,::1"
    
    # 设置当前会话环境变量
    $env:http_proxy = $proxyAddr
    $env:https_proxy = $proxyAddr
    $env:HTTP_PROXY = $proxyAddr
    $env:HTTPS_PROXY = $proxyAddr
    $env:no_proxy = $noProxyList
    $env:NO_PROXY = $noProxyList
    
    Write-Host "[+] HTTP/HTTPS Proxy On" -ForegroundColor Green
}

function unsetproxy {
    $env:http_proxy = $null
    $env:https_proxy = $null
    $env:HTTP_PROXY = $null
    $env:HTTPS_PROXY = $null
    $env:no_proxy = $null
    $env:NO_PROXY = $null
    
    Write-Host "[-] Proxy Off" -ForegroundColor Red
}

然后,同样可以使用setproxy命令来启动代理,使用unsetproxy命令来关闭代理。

windows中,管理员权限的PowerShell窗口和普通权限的PowerShell窗口是不同的,环境变量也是不一样的,所以如果你想让管理员权限的PowerShell窗口也走代理,需要在管理员权限的PowerShell窗口中也执行一次setproxy命令。

ssh设置

  • linux:
Host github.com
    Hostname ssh.github.com
    Port 443
    User git
    # socket5协议
    ProxyCommand nc -X 5 -v -x  127.0.0.1:7897 %h %p
    # http协议
    #ProxyCommand nc -X connect -v -x  127.0.0.1:7897 %h %p
  • windows:
Host github.com
    HostName ssh.github.com
    Port 443
    User git
    # socket5协议
    ProxyCommand connect -S 127.0.0.1:7897 %h %p
    # http协议
    #ProxyCommand connect -H 127.0.0.1:7897 %h %p

注意点:

  1. 默认情况下,SSH 协议使用 TCP 端口 22。许多公司、学校或公共 Wi-Fi 网络为了安全和限制非必要的流量,会完全阻止或过滤非标准端口(如 22 端口)的传出连接,所以这里使用443端口。
  2. 如果使用443端口,Hostname后面必须是ssh.github.com,不能是github.com
  3. 如果使用默认的22端口,即,不设置PortHostname后面就是github.com,不是ssh.github.com
  4. 两种协议只能选一种,不能同时启用。

apt代理设置

apt 设计上不直接读取 http_proxy 环境变量,主要出于以下三个考虑:

  1. 安全性(Security/Privilege Isolation)
    apt 通常以 root 权限运行。为了防止恶意用户通过修改普通用户的环境变量,诱导 root 权限的进程通过不可信的代理服务器下载恶意软件,apt 在设计上被设定为“环境隔离”。
  2. 稳定性(Service Consistency)
    apt 被视为系统级维护工具。如果它依赖用户的环境变量,那么当不同用户执行更新时,或者在自动化脚本(如 Cron 任务)中运行时,表现会不一致。它更倾向于通过自己的配置文件(/etc/apt/apt.conf)来获取确定的配置。
  3. 权限切换(User Switching)
    当你运行 apt 时,它内部实际上会创建几个低权限的子进程(例如 _apt 用户)来处理网络下载(这就是你之前看到那个 N: Download is performed unsandboxed 提示的原因)。普通用户的环境变量很难稳定地传递给这些特定的子进程。

使用 sudo -E apt update 会走代理吗?

结论是:理论上可行,但不稳定。

  • 为什么说“理论上可行”?

sudo -E 的作用是 “保留当前环境中的所有环境变量”。如果你在终端里跑了 setproxy,然后运行 sudo -E apt update,那么 http_proxy 变量确实会被带入 sudo 启动的那个进程空间。

  • 为什么说“经常失败/不推荐”?
  1. apt 内部逻辑过滤:即便变量进去了,apt 的核心程序(二进制代码)在初始化时可能根本就不去读取环境变量。
  2. 子进程丢失:如前所述,apt 会切换到 _apt 用户进行下载。虽然 sudo -E 保留了变量给 apt 主进程,但当 apt 调用 _apt 用户去连接服务器时,这些变量往往会丢失。
  3. 协议头敏感apt 对代理字符串的格式要求非常严苛。如果环境变量里少了一个斜杠或协议头不对,它会直接无视。
  • 最佳实践:如何让 apt 稳如泰山地走代理?

一次性配置(推荐做法)

sudo apt -o Acquire::http::Proxy="http://127.0.0.1:7897/" -o Acquire::https::Proxy="http://127.0.0.1:7897/" update

固定配置

  1. 创建或编辑专用配置文件:
sudo gedit /etc/apt/apt.conf.d/99proxy
  1. 写入以下内容:
Acquire::http::Proxy "http://127.0.0.1:7897/";
Acquire::https::Proxy "http://127.0.0.1:7897/";

注意:一定要有最后的 /;

可选:git代理设置

一次性设置(仅对当前命令有效)

  • 格式:git -c http.proxy="代理地址" clone 仓库地址
git -c http.proxy="http://127.0.0.1:7897" -c https.proxy="http://127.0.0.1:7897" clone ...

永久设置

linux下,打开~/.gitconfig文件;windows下,打开C:\Users\你的用户名\.gitconfig文件。

  • 针对github.com的socket代理:
[user]
	name = Han Xu
	email = <填入你的邮箱>
[http "http://github.com/"]
	proxy = socks5://127.0.0.1:7897
[https "https://github.com/"]
	proxy = socks5://127.0.0.1:7897
  • 针对github.com的ttp代理:
[user]
	name = Han Xu
	email = <填入你的邮箱>
[http "http://github.com/"]
	proxy = http://127.0.0.1:7897
[https "https://github.com/"]
	proxy = http://127.0.0.1:7897
  • 若需要针对所有域名设置代理:
[user]
	name = Han Xu
	email = <填入你的邮箱>
[http]
	proxy = http://127.0.0.1:7897
[https]
	proxy = http://127.0.0.1:7897

可选:conda代理设置

针对 Conda 的代理设置,虽然它理论上会读取系统环境变量,但由于 Conda 经常需要处理复杂的 SSL 证书和多个通道(Channels),手动显式配置通常是最稳妥的做法。

创建或编辑配置文件:

  • Linux/macOS: ~/.condarc
  • Windows: C:\Users\用户名\.condarc

在文件中添加或修改:

proxy_servers:
  http: http://127.0.0.1:7897
  https: http://127.0.0.1:7897

测试连接并尝试clone

(base) han@ASUS-TUF-Gaming-F15-FX507ZR:~$ ssh -T git@github.com
Connection to ssh.github.com 443 port [tcp/https] succeeded!
Hi UnderTurrets! You've successfully authenticated, but GitHub does not provide shell access.
$ git clone https://github.com/catsout/wallpaper-engine-kde-plugin.git
正克隆到 'wallpaper-engine-kde-plugin'...
remote: Enumerating objects: 7491, done.
remote: Counting objects: 100% (1538/1538), done.
remote: Compressing objects: 100% (492/492), done.
remote: Total 7491 (delta 1026), reused 1402 (delta 995), pack-reused 5953
接收对象中: 100% (7491/7491), 5.43 MiB | 971.00 KiB/s, 完成.
处理 delta 中: 100% (4687/4687), 完成.

成功!

posted @ 2024-09-01 13:31  UnderTurrets  阅读(93)  评论(0)    收藏  举报