Kết nối HTTPS qua máy chủ proxy


103

Có thể có kết nối HTTPS qua máy chủ proxy không? Nếu có, loại máy chủ proxy nào cho phép điều này?

Sao chép với Cách sử dụng proxy Socks 5 với Apache HTTP Client 4?


Tôi nghĩ rằng nó không bị trùng lặp với stackoverflow.com/questions/22937983/…
Trận đấu nhanh

Có, nó có thể. Xem các ví dụ thực tế tại đây stackoverflow.com/questions/56981993/…
Rick,

Câu trả lời:


66

TLS / SSL (Chữ S trong HTTPS) đảm bảo rằng không có kẻ nghe trộm giữa bạn và máy chủ mà bạn đang liên hệ, tức là không có proxy. Thông thường, bạn sử dụng CONNECTđể mở kết nối TCP thông qua proxy. Trong trường hợp này, proxy sẽ không thể lưu vào bộ nhớ cache, đọc hoặc sửa đổi bất kỳ yêu cầu / phản hồi nào và do đó nó khá vô dụng.

Nếu bạn muốn proxy có thể đọc thông tin, bạn có thể thực hiện theo cách sau:

  1. Khách hàng bắt đầu phiên HTTPS
  2. Proxy chặn kết nối một cách minh bạch và trả về chứng chỉ K a được tạo đặc biệt (có thể yếu) , được ký bởi tổ chức phát hành chứng chỉ được khách hàng tin cậy vô điều kiện.
  3. Proxy bắt đầu phiên HTTPS để nhắm mục tiêu
  4. Proxy xác minh tính toàn vẹn của chứng chỉ SSL; hiển thị lỗi nếu chứng chỉ không hợp lệ.
  5. Proxy truyền trực tuyến nội dung, giải mã và mã hóa lại bằng K a
  6. Khách hàng hiển thị nội dung

Một ví dụ là vết sưng SSL của Squid . Tương tự, ợ có thể được cấu hình để thực hiện việc này. Điều này cũng đã được sử dụng trong bối cảnh ít lành tính hơn bởi một ISP Ai Cập .

Lưu ý rằng các trang web và trình duyệt hiện đại có thể sử dụng HPKP hoặc các chân chứng chỉ tích hợp sẵn để đánh bại phương pháp này.


13
Điều này có thể hoạt động về nguyên tắc, nhưng đó không phải là cách trình duyệt nói chuyện với proxy HTTP cho các yêu cầu HTTPS. Cách nó được mô tả ở đây ngụ ý rằng máy chủ proxy thực sự là một Người ở giữa (vì vậy sẽ phải đáng tin cậy).
Bruno

5
Mực làm được điều này. Nó được gọi là SSL Bump .
Adam Mackler

3
Sẽ không hoạt động với nhiều cảnh báo cho người dùng cuối. "được khách hàng tin tưởng vô điều kiện" - không có chuyện đó. Ngay cả khi chứng chỉ là hoàn hảo-AAA +++, nó vẫn hiển thị miền khác không khớp với những gì người dùng cuối yêu cầu, điều này sẽ khiến bất kỳ trình duyệt lành mạnh nào (không có nghĩa là IE ở đây ...) phải nhảy lên và hét lên. Tất nhiên, có thể sử dụng wget với các tham số vô hiệu hóa kiểm tra SSL, nhưng hãy đoán xem? kết nối này không thể được đặt tên là "SSL" nữa sau khi các kiểm tra bảo mật cốt lõi của nó bị tắt.
Van Jone

1
@Van Jone Unconditionally trustedđề cập đến chứng chỉ CA. Chứng chỉ CA không có miền. Tôi đã sửa đổi câu trả lời bằng hai ví dụ trong đó điều này hoạt động / hoạt động trong thực tế mà không có bất kỳ cảnh báo nào cho người dùng.
phihag

6
Câu trả lời của tôi dựa trên cái mà bạn gọi là "CA không có thật". Chứng chỉ của CA được tin cậy vô điều kiện, do người dùng (hoặc phần mềm trên máy tính của họ, ví dụ như cấu hình doanh nghiệp hoặc phần mềm độc hại) đã định cấu hình nó theo cách đó hoặc vì CA được lấy từ một trong những CA được các trình duyệt chính tin cậy, như trong trường hợp MCS. Proxy tạo ra một chứng chỉ hợp lệ mới cho mọi miền mà khách hàng yêu cầu, vì vậy nếu không có các phương tiện chống MITM được đề cập ở cuối câu trả lời, khách hàng sẽ không nhận thấy.
phihag

22

Câu trả lời ngắn gọn là: Có thể và có thể được thực hiện với proxy HTTP đặc biệt hoặc proxy SOCKS.

Đầu tiên và quan trọng nhất, HTTPS sử dụng SSL / TLS theo thiết kế đảm bảo tính bảo mật đầu cuối bằng cách thiết lập một kênh giao tiếp an toàn thay vì một kênh không an toàn. Nếu proxy HTTP có thể nhìn thấy nội dung, thì đó là một kẻ nghe trộm trung gian và điều này đánh bại mục tiêu của SSL / TLS. Vì vậy, phải có một số thủ thuật đang được thực hiện nếu chúng ta muốn proxy thông qua một proxy HTTP đơn giản.

Bí quyết là, chúng tôi biến một proxy HTTP thành một proxy TCP với một lệnh đặc biệt có tên CONNECT. Không phải tất cả proxy HTTP đều hỗ trợ tính năng này nhưng nhiều proxy hiện đã hỗ trợ. Proxy TCP không thể thấy nội dung HTTP đang được chuyển ở dạng văn bản rõ ràng, nhưng điều đó không ảnh hưởng đến khả năng chuyển tiếp các gói qua lại của nó. Bằng cách này, máy khách và máy chủ có thể giao tiếp với nhau với sự trợ giúp của proxy. Đây là cách an toàn để ủy quyền dữ liệu HTTPS.

Cũng có một cách không an toàn để làm như vậy, trong đó proxy HTTP trở thành người trung gian. Nó nhận kết nối do máy khách khởi tạo và sau đó bắt đầu một kết nối khác đến máy chủ thực. Trong SSL / TLS được triển khai tốt, máy khách sẽ được thông báo rằng proxy không phải là máy chủ thực. Vì vậy, khách hàng phải tin tưởng proxy bằng cách bỏ qua cảnh báo để mọi thứ hoạt động. Sau đó, proxy chỉ cần giải mã dữ liệu từ một kết nối, mã hóa lại và đưa nó vào kết nối kia.

Cuối cùng, chúng tôi chắc chắn có thể proxy HTTPS thông qua proxy SOCKS , vì proxy SOCKS hoạt động ở cấp thấp hơn. Bạn có thể nghĩ proxy SOCKS vừa là proxy TCP vừa là proxy UDP.


Việc sử dụng CONNECT có gây ra cảnh báo bảo mật như đã đề cập trong stackoverflow.com/a/3118759/632951 không?
Pacerier

@Pacerier Tôi không nghĩ vậy. Trong chế độ CONNECT, proxy hoạt động ở lớp truyền tải.
Cyker

Vì vậy, bằng phương pháp CONNECT, bất kỳ dữ liệu https từ máy khách nào không được chuyển đến cấp ứng dụng của proxy trung gian? Và chỉ được đánh giá ở mức TCP của proxy và chuyển tiếp trực tiếp đến máy chủ từ xa ?
zzinny

15

Theo như tôi có thể nhớ, bạn cần sử dụng truy vấn HTTP CONNECT trên proxy. điều này sẽ chuyển đổi kết nối yêu cầu thành một đường hầm TCP / IP trong suốt.

vì vậy bạn cần biết máy chủ proxy bạn sử dụng có hỗ trợ giao thức này hay không.


3
Thật vậy, máy khách sử dụng động từ CONNECT để sử dụng https: // URI thông qua máy chủ proxy HTTP. Trong trường hợp này, kết nối được tạo đường hầm thông qua proxy, vì vậy việc xác minh chứng chỉ được thực hiện như bình thường, như thể máy khách đang nói chuyện trực tiếp với máy chủ cuối.
Bruno

1
@chburd, Nhưng các proxy có thường hỗ trợ HTTP CONNECT không?
Pacerier

9

Nếu nó vẫn còn quan tâm, đây là câu trả lời cho một câu hỏi tương tự: Chuyển đổi HTTP Proxy thành HTTPS Proxy trong Twisted

Để trả lời phần thứ hai của câu hỏi:

Nếu có, loại máy chủ proxy nào cho phép điều này?

Ngoài ra, hầu hết các máy chủ proxy sẽ được định cấu hình để chỉ cho phép kết nối HTTPS với cổng 443, do đó, các URI https với các cổng tùy chỉnh sẽ không hoạt động. Điều này thường có thể định cấu hình, tùy thuộc vào máy chủ proxy. Ví dụ, Squid và TinyProxy hỗ trợ điều này.


5

Đây là mã Java hoàn chỉnh của tôi hỗ trợ cả yêu cầu HTTP và HTTPS sử dụng 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);
        }
    }
}

3

Bạn có thể thực hiện điều này bằng cách sử dụng kỹ thuật man-in-the-middle với tạo SSL động. Hãy xem mitmproxy - đó là một proxy MITM có khả năng SSL, dựa trên Python.


3

đường hầm HTTPS thông qua SSH (phiên bản 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

mọi thứ bạn làm trên localhost. sau đó:

target_domain.com is accessible from localhost browser.

1

Tôi đã thử

  • bắt đầu đào hầm: ssh -N -D 12345 login@proxy_server
  • Đặt proxy trong cài đặt firefox là localhost:12345
    • và đánh dấu "sử dụng proxy này cho tất cả các giao thức"

nhưng điều này dẫn đến lỗi "Kết nối không an toàn" bất cứ khi nào tôi cố gắng kết nối với trang web https.

Giải pháp là

  • "bỏ chọn" "sử dụng proxy này cho tất cả các giao thức"
  • đặt proxy "localhost: 12345" chỉ làm proxy SOCKS
  • và để trống proxy HTTP, proxy SSL, proxy FTP

Tham khảo từ tài liệu đại dương kỹ thuật số

Cách định tuyến lưu lượng truy cập web an toàn mà không cần VPN bằng đường hầm SOCKS


1

Tôi không nghĩ rằng "có kết nối HTTPS qua máy chủ proxy" có nghĩa là kiểu tấn công Man-in-the-Middle của máy chủ proxy. Tôi nghĩ nó đang hỏi liệu người ta có thể kết nối với máy chủ proxy http qua TLS hay không. Và câu trả lời là có.


Có thể có kết nối HTTPS qua máy chủ proxy không?

Có, hãy xem câu hỏi và câu trả lời của tôi ở đây. Máy chủ proxy HTTPs chỉ hoạt động trong SwitchOmega

Nếu có, loại máy chủ proxy nào cho phép điều này?

Loại máy chủ proxy triển khai chứng chỉ SSL, giống như cách các trang web thông thường làm. Nhưng bạn cần một pactệp cho trình duyệt để định cấu hình kết nối proxy qua SSL.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.