命令行设置代理原理详解
网上的教程大多只讲了想要在命令行中使用代理需要输入哪些命令,比如这个export http_proxy=http://127.0.0.1:8080
,通常情况下这应该已经可以用了,不过有时却不能成功完成任务。本文中,我想根据自己的一些粗浅的经验,讲讲其背后的原理是什么。(本文适用于类Unix系统)
一、环境变量
首先来说明一下环境变量是什么。在操作系统中有许多进程,进程之间进行信息交流的其中一种途径就是环境变量。环境变量是一个键值对的集合,进程从父进程中收到环境变量,可以添加或修改其中的一些值,再在创建子进程时将环境变量传给子进程。export
指令便是修改环境变量的指令,并且指定这个修改是要传给子进程的,如果不使用export
而单用key=value
这样一行指令,则仅修改当前Shell进程的环境变量而不传给子进程。
通过这样一条export
指令,现在只要是用当前Shell启动的子进程,便可以在自己的环境变量里看到http_proxy -> http://127.0.0.1:8080这样的一个映射关系了,其实这个环境变量就像是贴在墙上的小广告,上面写着【你想进行http
访问吗?如果你想的话,在127.0.0.1:8080这个位置有一个代理服务点,这个站点可以使用http代理协议】。子进程看到了它,可以选择尊重这个环境变量,在进行http访问的时候将流量交给127.0.0.1:8080转发。子进程也可以选择拒绝遵从这个环境变量,还是原样直接访问,但是一般的程序都会选择遵从的。
二、环境变量名
接下来讲解环境变量名,例子中是http_proxy
,它的含义是指示进程在进行http
协议访问时尽量走代理,请看下面的例子:
$ export http_proxy=http://127.0.0.1:8080
$ curl http://ip8.com/ip
<返回代理服务器的ip>
$ curl https://ip8.com/ip
<返回本机的ip>
在这个例子中,curl在进行http
访问时(curl http://ip8.com/ip)尊重了环境变量的指示,在进行https
访问时(curl https://ip8.com/ip)因为没有对应的指示,便直接连接了。
比较常用的环境变量名字有http_proxy
,https_proxy
,ftp_proxy
,all_proxy
,其中特殊的是all_proxy
,它指定了全部协议都可以通过这个代理,它的优先级要低于其他变量。
比如说http_proxy
和all_proxy
都有设置,curl在进行http
访问的时候会通过http_proxy指定的代理,在进行https_proxy访问的时候会首先尝试通过https_proxy
指定的代理,但是并没有设置,于是就去通过了all_proxy
指定的代理。
另外,有的应用可能会去读取HTTP_PROXY
等等大写的环境变量,而忽略小写环境变量,可能需要特别注意,可以大小写的同时设置保证兼容性。
三、代理协议
下面来说一下http://
的含义,它指示的是与代理服务通信时使用的协议,使用http代理协议并不是只能传递http协议请求,它就像是【http代理服务器您好,这里有一个https请求,地址是www.baidu.com,内容是...,请帮我转发】这样的句式,可以传递的内容是广泛的。
比较常见的代理协议有http:// https:// socks:// ss:// ssr:// vmess://
之类的。
绝大部分程序都会支持http://
协议的代理,大部分程序会支持socks://
协议,只有专用的软件才支持ss:// ssr:// vmess://
并经常把它们转接成http:// socks://
协议以供其他应用使用。
四、推荐配置
通过前面的讲解大概已经了解了命令行应用代理的工作原理,那么应该怎么设置呢?之前提到http代理协议的兼容性最好,所以访问http_proxy一般设为http代理,而socks协议用途最广,可以将all_proxy设为socks协议,socks协议还有一点注意的是,可以用socks5h://
来替代socks://
,这样可以让域名解析在代理服务器进行,防止DNS污染。
综上,我推荐的配置是:(端口与提供代理服务的软件开放的端口一致)
export http_proxy=http://127.0.0.1:8080
export HTTP_PROXY=http://127.0.0.1:8080
export https_proxy=http://127.0.0.1:8080
export HTTPS_PROXY=http://127.0.0.1:8080
export all_proxy=socks5h://127.0.0.1:1080
export ALL_PROXY=socks5h://127.0.0.1:1080
也可以将其写入~/.bashrc等文件来自动配置或配置一个alias来给这一大段命令一个别称,方便手动激活。
参考
https://unix.stackexchange.com/questions/71144/what-do-the-bash-builtins-set-and-export-do
https://github.com/urllib3/urllib3/issues/1035