É possível ter conexões HTTPS em servidores proxy? Se sim, que tipo de servidor proxy permite isso?
Duplicado com Como usar o proxy Socks 5 com Apache HTTP Client 4?
É possível ter conexões HTTPS em servidores proxy? Se sim, que tipo de servidor proxy permite isso?
Duplicado com Como usar o proxy Socks 5 com Apache HTTP Client 4?
Respostas:
TLS / SSL (O S em HTTPS) garante que não haja bisbilhoteiros entre você e o servidor que está contatando, ou seja, sem proxies. Normalmente, você usa CONNECT
para abrir uma conexão TCP por meio do proxy. Nesse caso, o proxy não será capaz de armazenar em cache, ler ou modificar nenhuma solicitação / resposta e, portanto, será bastante inútil.
Se quiser que o proxy possa ler as informações, você pode seguir a seguinte abordagem:
Um exemplo é o aumento de SSL do Squid . Da mesma forma, o arroto pode ser configurado para fazer isso. Isso também foi usado em um contexto menos benigno por um ISP egípcio .
Observe que os sites e navegadores modernos podem empregar HPKP ou pinos de certificado embutidos que contrariam essa abordagem.
Unconditionally trusted
refere-se a um certificado CA. Certos de CA não têm domínios. Eu alterei a resposta com dois exemplos em que isso funciona / funcionou na prática, sem nenhum alerta para o usuário.
A resposta curta é: É possível e pode ser feito com um proxy HTTP especial ou um proxy SOCKS.
Em primeiro lugar, HTTPS usa SSL / TLS que, por design, garante segurança ponta a ponta, estabelecendo um canal de comunicação seguro em vez de um inseguro. Se o proxy HTTP é capaz de ver o conteúdo, então ele é um bisbilhoteiro man-in-the-middle e isso vai contra o objetivo do SSL / TLS. Portanto, deve haver alguns truques sendo jogados se quisermos proxy através de um proxy HTTP simples.
O truque é transformar um proxy HTTP em um proxy TCP com um comando especial chamado CONNECT
. Nem todos os proxies HTTP oferecem suporte a esse recurso, mas muitos o fazem agora. O proxy TCP não pode ver o conteúdo HTTP sendo transferido em texto não criptografado, mas isso não afeta sua capacidade de encaminhar pacotes para frente e para trás. Dessa forma, o cliente e o servidor podem se comunicar com a ajuda do proxy. Esta é a maneira segura de fazer proxy de dados HTTPS.
Também existe uma maneira insegura de fazer isso, em que o proxy HTTP se torna um intermediário. Ele recebe a conexão iniciada pelo cliente e, em seguida, inicia outra conexão com o servidor real. Em um SSL / TLS bem implementado, o cliente será notificado de que o proxy não é o servidor real. Portanto, o cliente precisa confiar no proxy, ignorando o aviso para que as coisas funcionem. Depois disso, o proxy simplesmente descriptografa os dados de uma conexão, criptografa novamente e os alimenta na outra.
Finalmente, podemos certamente fazer proxy HTTPS por meio de um proxy SOCKS , porque o proxy SOCKS funciona em um nível inferior. Você pode pensar em um proxy SOCKS como um proxy TCP e UDP.
tanto quanto me lembro, você precisa usar uma consulta HTTP CONNECT no proxy. isso converterá a conexão solicitada em um túnel TCP / IP transparente.
então você precisa saber se o servidor proxy que você usa suporta este protocolo.
Se ainda for de interesse, aqui está uma resposta a uma pergunta semelhante: Converter proxy HTTP em proxy HTTPS no Twisted
Para responder à segunda parte da pergunta:
Se sim, que tipo de servidor proxy permite isso?
Por padrão, a maioria dos servidores proxy será configurada para permitir conexões HTTPS apenas para a porta 443, portanto, URIs https com portas personalizadas não funcionarão. Isso geralmente é configurável, dependendo do servidor proxy. Squid e TinyProxy suportam isso, por exemplo.
Aqui está meu código Java completo que suporta solicitações HTTP e HTTPS usando o proxy SOCKS.
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);
}
}
}
tunelando HTTPS através de SSH (versão linux):
1) turn off using 443 on localhost
2) start tunneling as root: ssh -N login@proxy_server -L 443:target_ip:443
3) adding 127.0.0.1 target_domain.com to /etc/hosts
tudo o que você faz no localhost. então:
target_domain.com is accessible from localhost browser.
Eu tentei
ssh -N -D 12345 login@proxy_server
localhost:12345
mas isso resultava no erro "Conexão insegura" sempre que tentava me conectar a um site https.
A solução era
Referência da documentação digital do oceano
Como rotear o tráfego da Web com segurança sem VPN usando um túnel SOCKS
Não acho que "ter conexões HTTPS em servidores proxy" significa o tipo de ataque Man-in-the-Middle de servidor proxy. Acho que está perguntando se é possível conectar a um servidor proxy http por TLS. E a resposta é sim.
É possível ter conexões HTTPS em servidores proxy?
Sim, veja minha pergunta e resposta aqui. O servidor proxy HTTPs só funciona em SwitchOmega
Se sim, que tipo de servidor proxy permite isso?
O tipo de servidor proxy implanta certificados SSL, como fazem os sites comuns. Mas você precisa de um pac
arquivo para o navegador configurar a conexão proxy sobre SSL.