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?
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?
Câu trả lời:
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:
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.
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.
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.
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.
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.
Đâ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);
}
}
}
đườ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.
Tôi đã thử
ssh -N -D 12345 login@proxy_server
localhost:12345
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à
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
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 pac
tệp cho trình duyệt để định cấu hình kết nối proxy qua SSL.