HTTPS connections over proxy servers

前端 未结 9 1013
你的背包
你的背包 2020-11-28 18:48

Is it possible to have HTTPS connections over proxy servers? If yes, what kind of proxy server allows this?

Duplicated with How to use Socks 5 proxy with Apache HTT

相关标签:
9条回答
  • 2020-11-28 19:27

    You can accomplish this using man-in-the-middle techniques with dynamic SSL generation. Take a look at mitmproxy - it's a Python based, SSL-capable MITM proxy.

    0 讨论(0)
  • 2020-11-28 19:31

    If it's still of interest, here is an answer to a similar question: Convert HTTP Proxy to HTTPS Proxy in Twisted

    To answer the second part of the question:

    If yes, what kind of proxy server allows this?

    Out of the box, most proxy servers will be configured to allow HTTPS connections only to port 443, so https URIs with custom ports wouldn't work. This is generally configurable, depending on the proxy server. Squid and TinyProxy support this, for example.

    0 讨论(0)
  • 2020-11-28 19:31

    Here is my complete Java code that supports both HTTP and HTTPS requests using SOCKS proxy.

    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<ConnectionSocketFactory> reg = RegistryBuilder.<ConnectionSocketFactory>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);
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-28 19:32

    I had tried

    • start tunneling: ssh -N -D 12345 login@proxy_server
    • Setting the proxy in the firefox settings as localhost:12345
      • and ticking "use this proxy for all protocols"

    but this resulted in the error "Insecure connection" whenever I tried to connect to an https website.

    The solution was to

    • "untick" the "use this proxy for all protocols"
    • set the proxy "localhost:12345" only as a SOCKS proxy
    • and leave the HTTP proxy, SSL proxy, FTP proxy blank

    Reference from digital ocean documentation

    How To Route Web Traffic Securely Without a VPN Using a SOCKS Tunnel

    0 讨论(0)
  • 2020-11-28 19:35

    TLS/SSL (The S in HTTPS) guarantees that there are no eavesdroppers between you and the server you are contacting, i.e. no proxies. Normally, you use CONNECT to open up a TCP connection through the proxy. In this case, the proxy will not be able to cache, read, or modify any requests/responses, and therefore be rather useless.

    If you want the proxy to be able to read information, you can take the following approach:

    1. Client starts HTTPS session
    2. Proxy transparently intercepts the connection and returns an ad-hoc generated(possibly weak) certificate Ka, signed by a certificate authority that is unconditionally trusted by the client.
    3. Proxy starts HTTPS session to target
    4. Proxy verifies integrity of SSL certificate; displays error if the cert is not valid.
    5. Proxy streams content, decrypts it and re-encrypts it with Ka
    6. Client displays stuff

    An example is Squid's SSL bump. Similarly, burp can be configured to do this. This has also been used in a less-benign context by an Egyptian ISP.

    Note that modern websites and browsers can employ HPKP or built-in certificate pins which defeat this approach.

    0 讨论(0)
  • 2020-11-28 19:35

    I don't think "have HTTPS connections over proxy servers" means the Man-in-the-Middle attack type of proxy server. I think it's asking whether one can connect to a http proxy server over TLS. And the answer is yes.


    Is it possible to have HTTPS connections over proxy servers?

    Yes, see my question and answer here. HTTPs proxy server only works in SwitchOmega

    If yes, what kind of proxy server allows this?

    The kind of proxy server deploys SSL certificates, like how ordinary websites do. But you need a pac file for the brower to configure proxy connection over SSL.

    0 讨论(0)
提交回复
热议问题