프록시 서버를 통해 HTTPS 연결이 가능합니까? 그렇다면 어떤 종류의 프록시 서버가이를 허용합니까?
프록시 서버를 통해 HTTPS 연결이 가능합니까? 그렇다면 어떤 종류의 프록시 서버가이를 허용합니까?
답변:
TLS / SSL (HTTPS의 S)은 사용자와 연결중인 서버 사이에 도청자가 없음을 보장합니다. 즉, 프록시가 없습니다. 일반적으로 CONNECT
프록시를 통해 TCP 연결을 여는 데 사용 합니다. 이 경우 프록시는 요청 / 응답을 캐시, 읽기 또는 수정할 수 없으므로 다소 쓸모가 없습니다.
프록시가 정보를 읽을 수 있도록하려면 다음 접근 방식을 사용할 수 있습니다.
예는 Squid의 SSL bump 입니다. 마찬가지로 트림 을 구성 하여이를 수행 할 수 있습니다 . 이것은 또한 이집트 ISP에 의해 덜 양성적인 맥락에서 사용 되었습니다 .
최신 웹 사이트와 브라우저는 HPKP 또는 이 접근 방식을 무력화하는 내장 인증서 핀 을 사용할 수 있습니다 .
Unconditionally trusted
은 CA 인증서를 나타냅니다. CA 인증서에는 도메인이 없습니다. 사용자에게 알리지 않고 실제로 작동하는 두 가지 예를 사용하여 답변을 수정했습니다.
짧은 대답은 다음과 같습니다. 가능하며 특수 HTTP 프록시 또는 SOCKS 프록시를 사용하여 수행 할 수 있습니다.
무엇보다도 HTTPS는 SSL / TLS를 사용합니다. SSL / TLS는 설계 상 안전하지 않은 통신 채널을 통해 보안 통신 채널을 설정하여 종단 간 보안을 보장합니다. HTTP 프록시가 콘텐츠를 볼 수 있다면 중간자 도청 자이며 이것은 SSL / TLS의 목표를 무력화시킵니다. 따라서 일반 HTTP 프록시를 통해 프록시하려면 몇 가지 트릭이 있어야합니다.
트릭은라는 특수 명령을 사용하여 HTTP 프록시를 TCP 프록시로 전환하는 것 CONNECT
입니다. 모든 HTTP 프록시가이 기능을 지원하는 것은 아니지만 현재 많은 프록시가 지원합니다. TCP 프록시는 일반 텍스트로 전송되는 HTTP 콘텐츠를 볼 수 없지만 패킷을 앞뒤로 전달하는 기능에는 영향을주지 않습니다. 이러한 방식으로 클라이언트와 서버는 프록시를 사용하여 서로 통신 할 수 있습니다. 이것은 HTTPS 데이터를 프록시하는 안전한 방법입니다.
HTTP 프록시가 중간자 (man-in-the-middle)가되는 안전하지 않은 방법도 있습니다. 클라이언트가 시작한 연결을 수신 한 다음 실제 서버에 대한 다른 연결을 시작합니다. 잘 구현 된 SSL / TLS에서 클라이언트는 프록시가 실제 서버가 아니라는 알림을받습니다. 따라서 클라이언트는 작업에 대한 경고를 무시하여 프록시를 신뢰해야합니다. 그 후 프록시는 한 연결에서 데이터를 해독하고 다시 암호화하여 다른 연결로 공급합니다.
마지막으로 SOCKS 프록시가 낮은 수준에서 작동하기 때문에 SOCKS 프록시를 통해 HTTPS를 확실히 프록시 할 수 있습니다 . SOCKS 프록시를 TCP 및 UDP 프록시로 생각할 수 있습니다.
내가 기억할 수있는 한 프록시에서 HTTP CONNECT 쿼리를 사용해야합니다. 그러면 요청 연결이 투명한 TCP / IP 터널로 변환됩니다.
따라서 사용하는 프록시 서버가이 프로토콜을 지원하는지 알아야합니다.
여전히 관심이 있다면 유사한 질문에 대한 답변입니다. Twisted에서 HTTP 프록시를 HTTPS 프록시로 변환
질문의 두 번째 부분에 답하려면 :
그렇다면 어떤 종류의 프록시 서버가이를 허용합니까?
기본적으로 대부분의 프록시 서버는 포트 443에만 HTTPS 연결을 허용하도록 구성되므로 사용자 지정 포트가있는 https URI는 작동하지 않습니다. 일반적으로 프록시 서버에 따라 구성 할 수 있습니다. 예를 들어 Squid와 TinyProxy는이를 지원합니다.
다음은 SOCKS 프록시를 사용하여 HTTP 및 HTTPS 요청을 모두 지원하는 완전한 Java 코드입니다.
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);
}
}
}
동적 SSL 생성과 함께 중간자 (man-in-the-middle) 기술을 사용하여이를 수행 할 수 있습니다. mitmproxy를 살펴보십시오 -Python 기반의 SSL 지원 MITM 프록시입니다.
SSH를 통한 HTTPS 터널링 (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.
나는 시도했다
ssh -N -D 12345 login@proxy_server
localhost:12345
하지만 이로 인해 https 웹 사이트에 연결할 때마다 "안전하지 않은 연결"오류가 발생했습니다.
해결책은
디지털 오션 문서에서 참조
"프록시 서버를 통한 HTTPS 연결 있음"은 중간자 공격 유형의 프록시 서버를 의미하지 않습니다. TLS를 통해 http 프록시 서버에 연결할 수 있는지 묻는 것 같습니다. 그리고 대답은 '예'입니다.
프록시 서버를 통해 HTTPS 연결이 가능합니까?
예, 여기에서 내 질문과 답변을 참조하십시오. HTTPs 프록시 서버는 SwitchOmega에서만 작동합니다.
그렇다면 어떤 종류의 프록시 서버가이를 허용합니까?
프록시 서버의 종류는 일반 웹 사이트와 마찬가지로 SSL 인증서를 배포합니다. 하지만 pac
브라우저가 SSL을 통한 프록시 연결을 구성하려면 파일 이 필요 합니다.