Windows下的代理配置分为三类:用户代理、计算机代理、系统代理,其中并没有“全局代理”这样的概念和功能,并且三种代理配置都不是“全局代理”。全局代理指的是Windows中所有的对外连接(注意是所有对外连接,不区分应用层协议甚至其下的协议层)都需要通过这个代理,而Windows并没有“全局代理”配置功能,真“全局代理”需要通过第三方工具实现,其基本原理和Linux下一样,需要新建TAP或TUN接口。至此,我们可以有几点结论:
- 全局代理并不是Windows原生支持的功能
- 从同样的角度出发,Linux等也并没有对全局代理的天然支持
- Windows下的三种代理配置完全可以满足我们的需求
1.用户代理
用户代理仅对当前用户有效。用户代理是最为常用,并且Windows 中存在多个入口可以设置用户代理。除了早期IE浏览器(『Internet 选项』 -> 『连接』 -> 『局域网设置』 -> 『代理服务』)就可以进行设置之外,通过控制面板当然也可以。在Windows 11下,多数情况下都是通过在『设置』面板中设置,其配置操作顺序为『开始』->『设置』->『网络和Internet』->『代理』。
在代理配置中,可以自动或手动设置代理,在『手动设置代理』选项处,点击『设置』即可打开代理编辑对话框。可以在此打开、关闭代理服务器,编辑代理IP、协议和端口,虽然windows 11仅提供了http代理的显式支持,但实际socks也是支持的,需要结合后面的内容进行指定并生效。
无论是IE设置、控制面板设置还是Windows 11下通过『设置』面板设置,其关联的三个注册表值如下所列。我们会看到注册表路径为HKEY_CURRENT_USER下,都是针对当前用户而言的,这里的所有设置都只对当前用户生效。Windows本身也将这里的代理定义为“用户代理”,而并非很多人以讹传讹所说的“系统代理”或“全局代理”。
计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings - ProxyEnable - ProxyServer - ProxyOverride
Windows下的配置并非“所见即所得”,通过『设置』面板只能配置http代理,输入过渡代理地址127.0.0.1或socks=127.0.0.1,也不会直接体现在注册表值中。因此,要配置socks代理,需要修改注册表值ProxyServer为正确的代理配置。注意,输入socks://127.0.0.1并不会生效,并且系统并不会添加ProxyServer注册表值。
打开注册表编辑器(win+r打开『运行』对话框,输入regedit后回车),定位到『计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings』,系统添加并设置了ProxyServer值为127.0.0.1:1080。
双击打开『ProxyServer』,编辑修改为socks5://127.0.0.1:1080或socks://127.0.0.1:1080后,点击『确定』保存生效。Windows 早就不再局限于仅支持socks4(A)了,国内很多平台上的垃圾教程还在继续发酵。
与cmd命令行使用如下命令指定edge浏览器使用的代理(注意使用了socks5协议)相比,以下命令行仅针对打开的edge有效,之前已经打开但没有指定代理的浏览器窗口/程序,是不会使用这条命令所指定的代理的。简言之,命令行调用msedge并指定代理是进程/程序层级有效,注册表指定ProxyServer是当前用户有效。这里还有一点是显而易见的,Microsoft Edge支持socks5协议代理,Windows系统怎么会不支持?!很多自媒体“写手”(老E认为真的就是写手)们脑壳让门挤扁了,太水了。
start msedge.exe --proxy-server="socks5://127.0.0.1:1080"
2.计算机代理
计算机代理对所有用户有效。如果需要设置对于所有登录到当前计算机的用户都生效的代理,就需要通过组策略进行配置,这样配置的代理Windows下称之为“计算机代理”。
打开组策略编辑器最快的方式为通过“Win+r”(即Windows徽标键+r)打开『运行』对话框后,输入gpedit.msc后回车,打开组策略编辑器。
在『本地计算机策略』下,展开『计算机配置』 -> 『管理模板』 -> 『Windows 组件』,找到『Internet Explorer』并双击展开。
『Internet Explorer』下,一般最后一项『按计算机(而不是按用户)进行代理设置』就是我们需要配置的策略内容。
从默认的「未配置」更改为「已启用」后,单击『确定』保存。这样,我们对代理配置的任何修改都是本机有效的,当然,也可以在域中配置、下发组策略。
3.系统代理
系统代理就需要使用命令行或者直接编辑注册表了。但是,我们所称的“系统代理”多是采用netsh进行WinHttp代理设置,从而对系统范围内通过WinHttp API实现的所有http会话都有效,望文生义,既然是winhttp api,那就不可能是囊括全协议的全局代理。
3.1 winhttp与wininet
winhttp是 Microsoft Windows HTTP Services的简称,Netsh.exe winhttp 全面替换了cfgproxy代理配置工具,Windows 10 1709及之后的版本,winhttp默认打开 。微软提供了非常多的和比较细分的网络服务、库和开发框架供开发人员使用,其中就包括Microsoft Windows HTTP Services(WinHttp) 和 Windows Internet(WinInet) 服务 。WinHttp提供HTTP客户端应用程序编程接口,以使通过HTTP协议将请求发送到其他HTTP服务器,这是我们通过winhttp配置代理的基础。WinHttp应用作为Windows服务时以Local System Account运行,无法访问HKEY_CURRENT_USER下的注册表值,需要使用netsh来配置系统代理,使其对于系统中所有调用WinHttp API的应用都生效。
WinINet 从 Windows NT 时代就存在,主要目的是允许应用程序与FTP和HTTP协议交互来访问网络资源。WinINet支持FTP协议,所以基于WinINet实现的IE天然支持ftp登录,这也是为什么任何版本的IE中输入ftp服务器地址能够直接登录,而其他浏览器(firefox、chrome)则会提示"选择用于打开ftp链接的应用程序”的原因。同时,WinINet支持凭据管理,也就是说支持http服务器身份验证和代理身份验证,并且能够以交互的方式要求用户输入身份验证凭据(即用户名和口令),本文不做展开。
3.2 netsh winhttp
非开发场景下,很少会使用Wininet api。winhttp的应用通过netsh winhttp实现,我们可以简单看下netsh winhttp的命令行参数提示。
netsh winhttp /? 下列指令有效: 此上下文中的命令: ? - 显示命令列表。 dump - 显示一个配置脚本。 help - 显示命令列表。 import - 导入 WinHTTP 代理服务器设置。 reset - 重置 WinHTTP 设置。 set - 配置 WinHTTP 设置。 show - 显示当前设置。 若需要命令的更多帮助信息,请键入命令,接着是空格, 后面跟 ?。
如下两条命令,netsh winhttp show proxy用于列出当前代理设置信息,第二条命令设置了http和https代理,同时配置*.example.com直接访问、不进行代理。bypass-list参数是一个逗号分隔的列表,也就是说可以指定多个不应通过代理访问的地址。最后一行则设置了指向本机9090端口的socks代理,注意scheme和ip地址之间使用“=”而非“//”。
netsh winhttp show proxy netsh winhttp set proxy proxy-server="http=127.0.0.1:1080;https=127.0.0.1:443" bypass-list="*.example.com" netsh winhttp set proxy proxy-server="socks=localhost:9090" bypass-list="localhost"
同样,在注册表编辑器中,HKEY_LOCAL_MACHINE下可以找到『WinHttpSettings』注册表值,类型为REG_BINARY的默认值“1800000000000000010000000000000000000000”标识直接访问或无代理。
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Connections -WinHttpSettings
3.3 netsh的其他应用
netsh命令还有很多强大的功能,例如,通过netsh interface portproxy可以实现作为 IPv4 和 IPv6 网络与应用程序之间的代理,简言之,可以实现端口转发。
netsh interface portproxy netsh interface portproxy show all netsh interface portproxy add v4tov4 listenport=22 connectaddress=<ip> connectport=<port> #netsh interface portproxy add v4tov4 listenaddress=1.1.1.1 listenport=80 connectaddress=127.0.0.1 connectport=5000 netsh interface portproxy delete v4tov4 listenport=<port> netsh interface portproxy show v4tov4
4.其他
- 环境变量
以下命令在cmd和powershell中分别设置了http_proxy和https_proxy环境变量,且仅在cmd窗口打开期间有效。
set http_proxy=http://127.0.0.1:1080 set https_proxy=http://127.0.0.1:1080 $env:HTTPS_PROXY="http://127.0.0.1:1080" $env:HTTP_PROXY="http://127.0.0.1:1080" $env:all_proxy="socks5://127.0.0.1:1081"
- 第三方工具与系统应用
全局代理的实现需要网路接口的创建和监听/嗅探,当然还涉及到数据包的默认路由,可以尝试使用proxifier或者clash。Windows下的UWP、应用商店、系统更新等也可以配置代理,在系统配置好代理的前提下,不同的软件可能需要进行额外指定,如git并不会引用或导入Windows系统的代理,而是需要在用户目录下找到隐含文件".gitconfig"进行编辑,添加如下内容:
[http] proxy = http://127.0.0.1:[端口号] [https] proxy = http://127.0.0.1:[端口号]
当然,更多的工具是通过GUI方式手动指定,不同工具的设置打开方式、界面都各不相同,但设置方法、内容基本都是一致的。
最后,当开启了多个代理的情况下,我们访问Web 时,该流量会通过哪个代理服务器不仅取决于访问web时使用的浏览器代理配置,也和系统代理设置相关联,多端配置不仅复杂,甚至还会导致连接失败(浏览器使用A为代理、系统配置B为代理)。因此,在Windows代理配置时务必确保系统、客户端/上网工具、浏览器及浏览器插件等没有重复、矛盾的配置项。少数情况下,由于缺乏GUI支持,被迫在本地机上的浏览器(插件)、代理工具(如SS)和代理客户端进行配置以构成一个顺畅的代理链条,以利用搭好的梯子上网,虽属无奈,老E认为,为什么那么抗拒sc方法呢?!
文章评论