是否可以在代理服务器上建立HTTPS连接?如果是,哪种代理服务器支持此功能?
是否可以在代理服务器上建立HTTPS连接?如果是,哪种代理服务器支持此功能?
CONNECT
来打开通过代理的TCP连接。在这种情况下,代理将无法缓存、读取或修改任何请求/响应,因此没有什么用处。CONNECT
的特殊命令将HTTP代理转换为TCP代理。并非所有HTTP代理都支持此功能,但现在许多代理都支持。TCP代理无法看到以明文传输的HTTP内容,但这并不影响其转发数据包的能力。通过这种方式,客户端和服务器可以借助代理相互通信。这是代理HTTPS数据的安全方式。
还有一种不安全的方法,就是HTTP代理成为中间人。它接收客户端发起的连接,然后再向真实服务器发起另一个连接。在良好实现的SSL/TLS中,客户端将被通知代理不是真实服务器。因此,客户端必须通过忽略警告来信任代理以使其正常工作。之后,代理只需解密一个连接的数据,重新加密并将其馈送到另一个连接中。
最后,我们当然可以通过SOCKS代理代理HTTPS,因为SOCKS代理在更低的层次上工作。您可以将SOCKS代理视为TCP和UDP代理。
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);
}
}
}
Turn off using 443 on localhost
.
Start tunneling as root:
ssh -N login@proxy_server -L 443:target_ip:443
Adding 127.0.0.1 target_domain.com
to /etc/hosts
.
无论您在本地主机上做什么。
然后:target_domain.com
可以从 localhost
浏览器访问。
是否可以在代理服务器上拥有HTTPS连接?
是的,请参见我的问题和答案这里.
如果可以,什么样的代理服务器允许这样做?
部署SSL证书的代理服务器,就像普通的网站一样。但是,您需要一个pac文件来配置浏览器通过SSL连接代理。
ssh -N -D 12345 login@proxy_server
localhost:12345
但是每当我尝试连接到 https 网站时,都会出现“不安全的连接”错误。
解决方法是:
参考自 digital ocean 文档