当前位置:  开发笔记 > 运维 > 正文

代理服务器上的HTTPS连接

如何解决《代理服务器上的HTTPS连接》经验,为你挑选了5个好方法。

是否可以通过代理服务器建立HTTPS连接?如果是,那什么样的代理服务器允许这个?

与如何在Apache HTTP Client 4中使用Socks 5代理重复?



1> phihag..:

TLS/SSL(HTTPS中的S)保证您和您正在联系的服务器之间没有窃听者,即没有代理.通常,您使用CONNECT通过代理打开TCP连接.在这种情况下,代理将无法缓存,读取或修改连接,因此无用.

如果希望代理能够读取信息,可以采用以下方法:

    客户端启动HTTPS会话

    代理透明地拦截连接并返回由客户端无条件信任的证书颁发机构签名的ad-hoc生成的(可能是弱的)证书K a.

    代理启动HTTPS会话到目标

    代理验证SSL证书的完整性; 如果证书无效,则显示错误.

    代理流内容,解密并用K a重新加密

    客户端显示内容

一个例子是Squid的SSL凹凸.同样,burp 可以配置为执行此操作.这也被埃及ISP用于不太良好的环境中.

请注意,现代网站和浏览器可以使用HPKP或内置证书引脚,这会破坏这种方法.


这可能原则上有效,但这不是浏览器与HTTP代理谈论HTTPS请求的方式.这里描述的方式意味着代理服务器实际上是一个中间人(因此必须相应地信任).
我的回答依赖于你所谓的"虚假CA".CA**的证书是无条件信任的,因为用户(或他的计算机上的软件,例如企业配置或恶意软件)以这种方式配置它,或者因为CA是从其中一个受信任的CA获得的.主流浏览器,如MCS案例.代理为客户端请求的每个域生成新的有效证书,因此,如果没有在答案结尾处提到的反MITM设施,客户端将不会注意到.
鱿鱼这样做.它被称为[SSL Bump](http://wiki.squid-cache.org/Features/SslBump).
不会对最终用户提供大量警报."无条件地受到客户的信任" - 没有这样的事情.即使证书是完美的 - AAA +++,它仍然显示不同的域与最终用户要求的不匹配,这将使任何理智的浏览器(不是意味着IE在这里......)尖叫着跳来跳去.当然,可以使用wget参数禁用SSL检查,但猜猜是什么?在禁用核心安全检查后,此连接不能再命名为"SSL".

2> Cyker..:

简短的回答是:可以使用特殊的HTTP代理或SOCKS代理来完成.

首先,HTTPS使用SSL/TLS,它通过在不安全的通道上建立安全通信通道来确保端到端的安全性.如果HTTP代理能够看到内容,那么它就是一个中间人窃听者,这会破坏SSL/TLS的目标.因此,如果我们想要通过普通的HTTP代理进行代理,那么必须有一些技巧.

诀窍是,我们使用名为的特殊命令将HTTP代理转换为TCP代理CONNECT.并非所有HTTP代理都支持此功能,但现在很多都支持.TCP代理无法以明文形式查看正在传输的HTTP内容,但这不会影响其来回转发数据包的能力.通过这种方式,客户端和服务器可以在代理的帮助下相互通信.这是代理HTTPS数据的安全方式.

还有一种不安全的方法,即HTTP代理成为中间人.它接收客户端发起的连接,然后启动到真实服务器的另一个连接.在良好实施的SSL/TLS中,将通知客户端代理不是真实服务器.因此,客户端必须通过忽略对工作的警告来信任代理.之后,代理只需解密来自一个连接的数据,重新加密并将其提供给另一个连接.

最后,我们当然可以通过SOCKS代理代理HTTPS ,因为SOCKS代理工作在较低级别.您可以将SOCKS代理视为TCP和UDP代理.



3> chburd..:

据我所知,您需要在代理上使用HTTP CONNECT查询.这会将请求连接转换为透明的TCP/IP隧道.

所以你需要知道你使用的代理服务器是否支持这个协议.


实际上,客户端使用CONNECT动词通过HTTP代理服务器使用https:// URI.在这种情况下,连接通过代理进行隧道传输,因此证书验证照常完成,就像客户端直接与终端服务器通信一样.

4> Bruno..:

如果它仍然有用,这里是一个类似问题的答案: 将HTTP代理转换为Twisted中的HTTPS代理

要回答问题的第二部分:

如果是,那什么样的代理服务器允许这个?

开箱即用,大多数代理服务器将配置为仅允许HTTPS连接到端口443,因此具有自定义端口的https URI将不起作用.这通常是可配置的,具体取决于代理服务器.例如,Squid和TinyProxy支持这一点.



5> soulmachine..:

这是我的完整Java代码,它使用SOCKS代理支持HTTP和HTTPS请求.

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

import org.apache.http.HttpHost;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;

/**
 * How to send a HTTP or HTTPS request via SOCKS proxy.
 */
public class ClientExecuteSOCKS {

    public static void main(String[] args) throws Exception {
        Registry reg = RegistryBuilder.create()
            .register("http", new MyHTTPConnectionSocketFactory())
            .register("https", new MyHTTPSConnectionSocketFactory(SSLContexts.createSystemDefault
                ()))
            .build();
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(reg);
        try (CloseableHttpClient httpclient = HttpClients.custom()
            .setConnectionManager(cm)
            .build()) {
            InetSocketAddress socksaddr = new InetSocketAddress("mysockshost", 1234);
            HttpClientContext context = HttpClientContext.create();
            context.setAttribute("socks.address", socksaddr);

            HttpHost target = new HttpHost("www.example.com/", 80, "http");
            HttpGet request = new HttpGet("/");

            System.out.println("Executing request " + request + " to " + target + " via SOCKS " +
                "proxy " + socksaddr);
            try (CloseableHttpResponse response = httpclient.execute(target, request, context)) {
                System.out.println("----------------------------------------");
                System.out.println(response.getStatusLine());
                System.out.println(EntityUtils.toString(response.getEntity(), StandardCharsets
                    .UTF_8));
            }
        }
    }

    static class MyHTTPConnectionSocketFactory extends PlainConnectionSocketFactory {
        @Override
        public Socket createSocket(final HttpContext context) throws IOException {
            InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socks.address");
            Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr);
            return new Socket(proxy);
        }
    }

    static class MyHTTPSConnectionSocketFactory extends SSLConnectionSocketFactory {
        public MyHTTPSConnectionSocketFactory(final SSLContext sslContext) {
            super(sslContext);
        }

        @Override
        public Socket createSocket(final HttpContext context) throws IOException {
            InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socks.address");
            Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr);
            return new Socket(proxy);
        }
    }
}

推荐阅读
ifx0448363
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有