HTTPS-соединения через прокси-серверы - PullRequest
77 голосов
/ 05 февраля 2009

Возможно ли иметь HTTPS-соединения через прокси-серверы? Если да, то какой прокси-сервер позволяет это?

Дублируется с Как использовать прокси Socks 5 с Apache HTTP Client 4?

Ответы [ 8 ]

46 голосов
/ 05 февраля 2009

TLS / SSL (S в HTTPS) гарантирует, что между вами и сервером, с которым вы обращаетесь, нет перехватчиков, то есть прокси-серверов. Обычно вы используете CONNECT, чтобы открыть TCP-соединение через прокси. В этом случае прокси не сможет кэшировать, читать или изменять соединение, и поэтому бесполезно.

Если вы хотите, чтобы прокси мог читать информацию, вы можете воспользоваться следующим подходом:

  1. Клиент запускает сеанс HTTPS
  2. Прокси прозрачно перехватывает соединение и возвращает сгенерированный ad-hoc (возможно слабый) сертификат К а , подписан центром сертификации которому безусловно доверяют клиент.
  3. Прокси-сервер запускает сеанс HTTPS для цели
  4. Прокси проверяет целостность SSL сертификат; отображает ошибку, если Сертификат недействителен.
  5. Прокси-потоки контента, расшифровывает его и повторно зашифровывает его K а
  6. Клиент отображает вещи

Примером является Squid SSL bump . Аналогично, burp можно настроить для этого. Это также использовалось в менее благоприятном контексте египетским интернет-провайдером .

Обратите внимание, что современные веб-сайты и браузеры могут использовать HPKP или встроенные выводы сертификата , которые побеждают этот подход.

14 голосов
/ 05 февраля 2009

Насколько я помню, вам нужно использовать HTTP-запрос CONNECT на прокси. это преобразует соединение запроса в прозрачный туннель TCP / IP.

, поэтому вам нужно знать, поддерживает ли используемый вами прокси-сервер этот протокол.

12 голосов
/ 30 ноября 2016

Краткий ответ: это возможно и может быть сделано с помощью специального HTTP-прокси или SOCKS-прокси.

Прежде всего, HTTPS использует SSL / TLS, который по своей конструкции обеспечивает сквозную безопасность, устанавливая безопасный канал связи по небезопасному каналу. Если прокси-сервер HTTP может видеть содержимое, то это перехватчик типа «человек посередине», и это противоречит цели SSL / TLS. Поэтому, если мы хотим использовать прокси через простой HTTP-прокси, должны выполняться некоторые трюки.

Хитрость в том, что мы превращаем HTTP-прокси в TCP-прокси с помощью специальной команды с именем CONNECT. Не все HTTP прокси поддерживают эту функцию, но многие делают это сейчас. TCP-прокси не может видеть содержимое HTTP, передаваемое в виде открытого текста, но это не влияет на его способность пересылать пакеты назад и вперед. Таким образом, клиент и сервер могут связываться друг с другом с помощью прокси. Это безопасный способ передачи HTTPS-данных.

Существует также небезопасный способ сделать это, когда HTTP-прокси становится посредником. Он получает инициированное клиентом соединение, а затем инициирует другое соединение с реальным сервером. В хорошо реализованном SSL / TLS клиент будет уведомлен о том, что прокси не является реальным сервером. Таким образом, клиент должен доверять прокси, игнорируя предупреждение о том, что все работает. После этого прокси-сервер просто расшифровывает данные из одного соединения, повторно шифрует и передает их в другое.

Наконец, мы, безусловно, можем прокси HTTPS через прокси SOCKS , потому что прокси SOCKS работает на более низком уровне. Вы можете думать, что SOCKS-прокси является TCP и UDP-прокси.

9 голосов
/ 06 июля 2010

Если это все еще интересно, вот ответ на аналогичный вопрос: Конвертировать HTTP-прокси в HTTPS-прокси в Twisted

Чтобы ответить на вторую часть вопроса:

Если да, то какой прокси-сервер позволяет это?

Изначально большинство прокси-серверов будут настроены на разрешение HTTPS-подключений только к порту 443, поэтому URI-адреса https с пользовательскими портами не будут работать. Обычно это настраивается в зависимости от прокси-сервера. Например, Squid и TinyProxy поддерживают это.

5 голосов
/ 03 сентября 2015

Вот мой полный код Java, который поддерживает запросы HTTP и HTTPS с использованием прокси 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);
        }
    }
}
2 голосов
/ 01 декабря 2014

туннелирование HTTPS через SSH (версия 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

все, что вы делаете на localhost. то:

target_domain.com is accessible from localhost browser.
2 голосов
/ 06 июня 2013

Вы можете сделать это, используя методы «человек посередине» с динамической генерацией SSL. Взгляните на mitmproxy - это MITM-прокси на основе Python с поддержкой SSL.

1 голос
/ 14 сентября 2017

Я пытался

  • начать туннелирование: ssh -N -D 12345 login@proxy_server
  • Установка прокси в настройках Firefox как localhost:12345
    • и отметка «использовать этот прокси для всех протоколов»

но это приводило к ошибке «Небезопасное соединение» при каждой попытке подключиться к веб-сайту https.

Решение было

  • «убрать галочку» с «использовать этот прокси для всех протоколов»
  • установить прокси "localhost: 12345" только как прокси SOCKS
  • и оставьте HTTP-прокси, SSL-прокси, FTP-прокси пустым

Справка из цифровой океанской документации

Как безопасно маршрутизировать веб-трафик без VPN с использованием туннеля SOCKS

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...