在 Powershell Core 中绕过所有 Web 请求的代理

在 Powershell Core 中绕过所有 Web 请求的代理

我有一台在公司环境中运行 Windows 的工作计算机,它带有一个用于向外连接到互联网的身份验证代理服务器。我不知道它是如何配置的,但许多工具都无法连接,主要是 npm(Atom 编辑器中的包)、NuGet、PowerShellGet 等类型的工具。我甚至不得不配置我的浏览器(Vivaldi)以使用直接连接,因为我无法登录某些网站,即使它在 MS Edge 中可以正常工作。

HTTP 错误通常是(407) Proxy Authentication Required

Windows 中的系统范围的代理服务器正在由一些定期执行的脚本进行配置,我对此无能为力。

解决方案(或者说变通方法)是单独配置所有存在连接问题的应用程序以绕过代理(使用直接连接到互联网)。我已经设法为几乎所有需要的东西都做到了这一点,但到目前为止,我还没有在 Powershell Core 上取得成功。

顺便说一句,我不确定代理有什么意义,因为你可以简单地绕过它,它只是让那台计算机上的常规工作变得更加困难,浪费了我的时间和公司的金钱。

到目前为止,我发现了以下情况。

PowerShellGetFind-Module失败并出现以下错误:

无法解析包源“https://www.powershellgallery.com/api/v2”

一个简单的 Web 请求失败并显示错误“缓存访问被拒绝“:

Invoke-WebRequest https://google.com

但当强制绕过代理时就会成功:

Invoke-WebRequest https://google.com -NoProxy

netsh winhttp show proxy说“直接访问(无需代理服务器)。“,但以下命令返回实际的代理:

([System.Net.WebRequest]::GetSystemWebproxy()).GetProxy("https://google.com")

此外,以下命令返回false

([System.Net.WebRequest]::GetSystemWebproxy()).IsBypassed("https://google.com")

我做了相当广泛的研究,发现可以通过WebRequest将默认代理设置为空来配置使用直接连接,但这没有帮助:

[System.Net.WebRequest]::DefaultWebProxy = $null

如果有人有其他想法我将不胜感激。

更新

我发现我实际上可以使用我的域帐户在代理服务器上进行身份验证:

Invoke-WebRequest https://google.com -ProxyUseDefaultCredentials -Proxy http://proxy

因此,这将是代理绕过配置的替代方案。我只是不知道如何为 Powershell 发出的所有请求设置凭据。我不明白为什么 Windows 系统代理未配置为使用我的帐户进行身份验证。

我尝试过配置WebRequest::DefaultWebProxy使用代理服务器并使用我的域帐户凭据对其进行身份验证,但它不起作用:

[System.Net.WebRequest]::DefaultWebProxy 
    = New-Object System.Net.WebProxy('http://proxy')
[System.Net.WebRequest]::DefaultWebProxy.Credentials
    = [System.Net.CredentialCache]::DefaultNetworkCredentials

答案1

最后,经过几个小时的研究和折腾,我终于解决了我的问题,这要归功于此 GitHub 问题评论

我不知道背景,但看起来 Powershell Core 实际上正在使用System.Net.Http.HttpClient而不是System.Net.WebRequest发出网络请求。

当我了解到这一点时,配置起来相当容易HttpClient的默认代理

1. 手动配置HttpClient.DefaultProxy

代理绕过

要绕过代理(使用直接连接),请将其设置为null

[System.Net.Http.HttpClient]::DefaultProxy = New-Object System.Net.WebProxy($null)

我已经将它添加到我的Powershell 配置文件并且 Powershell 建立的所有连接开始工作。

配置特定代理服务器

要配置实际的代理服务器,请使用以下命令:

[System.Net.Http.HttpClient]::DefaultProxy = New-Object System.Net.WebProxy('http://proxy', $true)

配置代理身份验证

如果它是身份验证代理,则必须配置用于代理身份验证的凭据。以下命令将使用您当前登录 Windows 的域帐户的凭据:

[System.Net.Http.HttpClient]::DefaultProxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials

2. 使用环境变量配置默认代理

另一种解决方案是使用环境变量。根据文档HttpClient实际上是使用以下变量来初始化默认代理(如果已定义):

  • HTTP_PROXY对于 HTTP 请求
  • HTTPS_PROXY对于 HTTPS 请求
  • ALL_PROXY适用于 HTTP 和 HTTPS
  • NO_PROXY可能包含从代理中排除的主机名的逗号分隔列表

用法示例:

ALL_PROXY='http://proxy:1234'

如果您需要传递凭证:

ALL_PROXY='http://username:password@proxy:1234'

该解决方案得到了更广泛的应用程序的支持,因此它是否比以前的解决方案更好或更差取决于您到底想配置什么,仅仅是 Powershell 还是其他应用程序。

答案2

根据 David Ferenczy Rogožan 的出色回答和研究,我能够让它发挥作用,但就我而言,我必须这样做(请注意与上面的细微差别):

[System.Net.HttpWebRequest]::DefaultWebProxy = New-Object System.Net.WebProxy($null)

答案3

至于这个…… it should be possible to configure WebRequest to use the direct connection by setting the default proxy to null ,正如您所发现的,它不在您的公司基础设施中。

您拥有的是一个强制到您的工作站的 GPO,它强制所有互联网出口网络流量通过过滤/代理网关。

有关详细信息,请参阅如何通过组策略强制执行代理设置 - TechNet 文章 - 美国(英语) - TechNet Wiki(microsoft.com)。 https://social.technet.microsoft.com/wiki/contents/articles/5156.how-to-force-proxy-settings-via-group-policy.aspx

您的雇主正在控制和监控所有加入域的系统的所有入口/出口网络流量。

风险管理/安全政策将起主导作用。任何现代过滤网关都有特定的控制措施,您的组织/企业会出于其既定的风险控制原因使用这些措施。

因此,这不是 PowerShell 功能或代码问题;这是网络限制。所以,无法绕过它。无论您使用什么工具。您必须提供身份/凭据才能允许出站。

您可以查看浏览器设置以查看代理线人,或者他们也可能使用 PAC 文件。

请参阅:什么是 PAC 文件?(websense.com)了解详情。 https://www.websense.com/content/support/library/web/v76/pac_file_best_practices/PAC_explained.aspx

您在正常浏览时没有收到此提示的原因是使用了您的凭据/网络令牌。如果您尝试绕过该提示,则根据公司政策,您会收到提示。

试图规避雇主的风险管理/安全政策将会产生 RPE/CLM(简历生成事件/职业限制举措),并且可能采取法律行动,具体取决于您正在做的事情。

相关内容