Ligações HTTPS sobre servidores 'proxy'
é possível ter ligações HTTPS por servidores 'proxy'? Em caso afirmativo, que tipo de servidor proxy permite isso?
duplicado com Como usar o proxy Socks 5 com o Apache HTTP Client 4?
8 answers
O TLS / SSL (O S em HTTPS) garante que não há escutas entre si e o servidor que está a contactar, ou seja, não há proxies. Normalmente, usa CONNECT
para abrir uma conexão TCP através do proxy. Neste caso, o proxy não será capaz de cache, ler ou modificar a conexão, e portanto inútil.
Se quiser que o proxy seja capaz de ler informação, pode seguir a seguinte abordagem:
- O cliente inicia a sessão do HTTPS
- Proxy intercepta de forma transparente a ligação e devolve um gerado ad-hoc (possivelmente certificado K a , assinado por uma autoridade de certificação que é incondicionalmente confiável por cliente.
- O 'Proxy' inicia a sessão do HTTPS para o alvo
- O Proxy verifica a integridade do SSL o certificado; mostra um erro se o o cert não é válido.
- conteúdo de transmissões por 'Proxy', descodificando-o e re-encripta-o com K a
- O Cliente mostra coisas
Um exemplo é Lombo de Lula . Da mesma forma, o burp pode ser configurado para fazer isto. Este também foi usado num contexto menos benigno por um ISP Egípcio.
Note que os sites e navegadores modernos podem empregarhpkp oupinos de certificados embutidos que derrotam esta abordagem.
Tanto quanto me lembro, você precisa usar uma consulta HTTP CONNECT no proxy. isto irá converter a ligação do pedido para um túnel TCP/IP transparente.
Por isso, precisa de saber se o servidor 'proxy' que usa suporta este protocolo.
Para responder à segunda parte da Pergunta:
Em caso afirmativo, que tipo de servidor proxy permite isto?
Fora da caixa, a maioria dos servidores 'proxy' serão configurados para permitir as ligações dos 'HTTPS' apenas ao porto 443, para que os 'https' com portas personalizadas não funcionem. Isto é geralmente configurável, dependendo do servidor proxy. Lula e A TinyProxy suporta isso, por exemplo.
A resposta curta é: é possível, e pode ser feito com um proxy HTTP especial ou um proxy SOCKS.
Em primeiro lugar, os HTTPS utilizam SSL/TLS que, por projecto, garantem a segurança extremo-a-extremo através do estabelecimento de um canal de comunicação seguro sobre um canal inseguro. Se o proxy HTTP é capaz de ver o conteúdo, então é um bisbilhoteiro man-in-the-middle e isso derrota o objetivo do SSL/TLS. Então deve haver alguns truques sendo jogados se quisermos proxy através de um HTTP simples procuracao.
O truque é transformar um 'proxy' HTTP num 'proxy' TCP com um comando especial chamadoCONNECT
. Nem todos os proxies HTTP suportam este recurso, mas muitos o fazem agora. O proxy TCP não pode ver o conteúdo HTTP sendo transferido em texto claro, mas isso não afeta sua capacidade de encaminhar pacotes para trás e para a frente. Desta forma, Cliente e servidor podem se comunicar entre si com a ajuda do proxy. Esta é a forma segura de fornecer dados HTTPS.
Há também um caminho inseguro. de fazê-lo, em que o proxy HTTP se torna um man-in-the-middle. Ele recebe a conexão iniciada pelo cliente, e então 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. Então o cliente tem que confiar no proxy ignorando o aviso para que as coisas funcionem. Depois disso, o proxy simplesmente descriptografa dados de uma conexão, reencriptografa e alimenta-os na outra.
Finalmente, podemos representar HTTPS através de um proxy SOCKS, porque o proxy SOCKS funciona a um nível inferior. Você pode pensar que um proxy SOCKS é tanto um proxy TCP quanto um UDP.
Aqui está o meu código Java completo que suporta tanto os pedidos HTTP como 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);
}
}
}
Podes conseguir isto usando técnicas man-in-the-middle com uma geração dinâmica SSL. Dê uma olhada em mitmproxy - é um proxy MITM baseado em Python, capaz de SSL.
Tunelamento 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 fazes em localhost. então:
target_domain.com is accessible from localhost browser.
Eu tinha tentado
- começa a escavar. {[[0]}
- Configurar o 'proxy' na configuração do firefox como
localhost:12345
- e assinalar "use este' proxy 'para todos os protocolos"
Mas isto resultou no erro "ligação insegura" sempre que tentei ligar-me a um site da https.
A solução foi para
- "untick" o "use este' proxy 'para todos os protocolos"
- Defina o 'proxy' "localhost:12345" apenas como um 'proxy' SOCKS E vai-te embora. o 'proxy' de HTTP, 'proxy' de SSL, 'proxy' de FTP
Referência da documentação digital do Oceano
Como encaminhar o tráfego Web de forma segura sem um VPN usando um túnel SOCKS