137 votes

Connexions HTTPS sur des serveurs proxy

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 ?

84voto

phihag Points 89765

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 :

  1. Le client démarre une session HTTPS
  2. Le proxy intercepte la connexion de manière transparente et renvoie un certificat K généré ad-hoc (éventuellement faible) K a , signé par une autorité de certification qui a la confiance inconditionnelle du le client.
  3. Le proxy démarre une session HTTPS vers la cible
  4. Le proxy vérifie l'intégrité du SSL et affiche une erreur si le certificat certificat n'est pas valide.
  5. Le proxy transmet le contenu en continu et le décrypte. et le ré-encrypte avec K a
  6. Le client affiche des trucs

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.

37voto

Cyker Points 660

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.

16voto

chburd Points 2902

Pour autant que je m'en souvienne, vous devez utiliser une requête HTTP CONNECT sur le proxy. Cela convertira la connexion de la requête en un tunnel TCP/IP transparent.

Vous devez donc savoir si le serveur proxy que vous utilisez supporte ce protocole.

10voto

Bruno Points 47560

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.

6voto

soulmachine Points 67

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.com

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.

Powered by:

X