Est-il possible d'avoir des connexions HTTPS sur des serveurs proxy ? Si oui, quel type de serveur proxy le permet ?
Dupliqué avec Comment utiliser le proxy Socks 5 avec le client HTTP Apache 4 ?
Est-il possible d'avoir des connexions HTTPS sur des serveurs proxy ? Si oui, quel type de serveur proxy le permet ?
Dupliqué avec Comment utiliser le proxy Socks 5 avec le client HTTP Apache 4 ?
TLS/SSL (le S de HTTPS) garantit qu'il n'y a pas d'espions entre vous et le serveur que vous contactez, c'est-à-dire pas de proxies. Normalement, vous utilisez CONNECT
pour ouvrir une connexion TCP à travers le proxy. Dans ce cas, le proxy ne sera pas en mesure de mettre en cache, de lire ou de modifier les demandes/réponses, et sera donc plutôt inutile.
Si vous voulez que le mandataire soit capable de lire des informations, vous pouvez adopter l'approche suivante :
Un exemple est la méthode de Squid Bosse SSL . De même, le burp peut être configuré pour le faire. Cela a également été utilisé dans un contexte moins anodin par un ISP égyptien. .
Notez que les sites web et les navigateurs modernes peuvent utiliser HPKP o broches de certificat intégrées qui font échouer cette approche.
La réponse courte est la suivante : c'est possible, et cela peut être fait avec un proxy HTTP spécial ou un proxy SOCKS.
Tout d'abord, HTTPS utilise SSL/TLS qui, de par sa conception, assure une sécurité de bout en bout en établissant un canal de communication sécurisé sur un canal non sécurisé. Si le proxy HTTP est en mesure de voir le contenu, il s'agit alors d'une écoute de type man-in-the-middle, ce qui va à l'encontre de l'objectif de SSL/TLS. Il doit donc y avoir des astuces si l'on veut passer par un proxy HTTP ordinaire.
L'astuce consiste à transformer un proxy HTTP en proxy TCP avec une commande spéciale appelée CONNECT
. Tous les proxys HTTP ne prennent pas en charge cette fonctionnalité, mais beaucoup le font maintenant. Le proxy TCP ne peut pas voir le contenu HTTP transféré en texte clair, mais cela n'affecte pas sa capacité à transmettre les paquets dans les deux sens. De cette façon, le client et le serveur peuvent communiquer entre eux avec l'aide du proxy. Il s'agit de la manière sécurisée de transmettre des données HTTPS par proxy.
Il existe également un moyen peu sûr de le faire, dans lequel le proxy HTTP devient un intermédiaire. Il reçoit la connexion lancée par le client, puis lance une autre connexion vers le vrai serveur. Dans un système SSL/TLS bien implémenté, le client sera informé que le proxy n'est pas le vrai serveur. Le client doit donc faire confiance au proxy en ignorant l'avertissement pour que les choses fonctionnent. Ensuite, le proxy décrypte simplement les données d'une connexion, les réencrypte et les introduit dans l'autre.
Enfin, nous pouvons certainement proxy HTTPS par le biais d'un SOCKS car le proxy SOCKS fonctionne à un niveau inférieur. Vous pouvez penser qu'un proxy SOCKS est à la fois un proxy TCP et un proxy UDP.
Si cela vous intéresse toujours, voici une réponse à une question similaire : Convertir un proxy HTTP en proxy HTTPS dans Twisted
Pour répondre à la deuxième partie de la question :
Si oui, quel type de serveur proxy le permet ?
Par défaut, la plupart des serveurs proxy sont configurés pour n'autoriser les connexions HTTPS que sur le port 443, de sorte que les URI https avec des ports personnalisés ne fonctionnent pas. Ceci est généralement configurable, en fonction du serveur proxy. Squid et TinyProxy prennent en charge cette fonctionnalité, par exemple.
Voici mon code Java complet qui prend en charge les demandes HTTP et HTTPS à l'aide du 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);
}
}
}
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.