プロキシサーバーを介したHTTPS接続は可能ですか?はいの場合、どの種類のプロキシサーバーがこれを許可しますか?
プロキシサーバーを介したHTTPS接続は可能ですか?はいの場合、どの種類のプロキシサーバーがこれを許可しますか?
回答:
TLS / SSL(HTTPSのS)は、ユーザーと接続しているサーバーの間に盗聴者、つまりプロキシがないことを保証します。通常はCONNECT
、プロキシを介してTCP接続を開くために使用します。この場合、プロキシは要求/応答をキャッシュ、読み取り、または変更することができないため、かなり役に立たなくなります。
プロキシーが情報を読み取れるようにしたい場合は、以下のアプローチをとることができます。
SquidのSSLバンプがその例です。同様に、げっぷはこれを行うように構成できます。これは、エジプトのISPによって、より無害なコンテキストでも使用されています。
最新のWebサイトおよびブラウザーは、このアプローチを無効にするHPKPまたは組み込みの証明書ピンを使用できることに注意してください。
Unconditionally trusted
はCA証明書を指します。CA証明書にはドメインがありません。これは、ユーザーへの警告なしに実際に機能する、または機能しない2つの例で回答を修正しました。
簡単に言えば、これは可能であり、特別なHTTPプロキシまたはSOCKSプロキシを使用して実行できます。
何よりもまず、HTTPSはSSL / TLSを使用します。これは、設計上、安全でない通信チャネル上に安全な通信チャネルを確立することにより、エンドツーエンドのセキュリティを保証します。HTTPプロキシがコンテンツを見ることができる場合、それは中間者盗聴者であり、これはSSL / TLSの目標を打ち破ります。したがって、プレーンなHTTPプロキシを介してプロキシする場合は、いくつかのトリックが実行されている必要があります。
コツは、という名前の特別なコマンドを使用して、HTTPプロキシをTCPプロキシに変換することCONNECT
です。すべてのHTTPプロキシがこの機能をサポートしているわけではありませんが、現在多くのプロキシがサポートしています。TCPプロキシはHTTPコンテンツがクリアテキストで転送されているのを確認できませんが、パケットを前後に転送する機能には影響しません。このようにして、クライアントとサーバーはプロキシの助けを借りて相互に通信できます。これは、HTTPSデータをプロキシする安全な方法です。
これを行うには、HTTPプロキシが中間者になる安全でない方法もあります。クライアントが開始した接続を受信し、実サーバーへの別の接続を開始します。適切に実装されたSSL / TLSでは、プロキシは実サーバーではないことがクライアントに通知されます。したがって、クライアントは、正常に機能するための警告を無視して、プロキシを信頼する必要があります。その後、プロキシは1つの接続からのデータを復号化し、再暗号化してもう一方にフィードします。
最後に、我々は通じHTTPSプロキシ確かにすることができますSOCKSプロキシSOCKSために低いレベルでのプロキシ作品。SOCKSプロキシは、TCPプロキシとUDPプロキシの両方と考えることができます。
私が覚えている限り、プロキシでHTTP CONNECTクエリを使用する必要があります。これにより、要求接続が透過的なTCP / IPトンネルに変換されます。
そのため、使用するプロキシサーバーがこのプロトコルをサポートしているかどうかを知る必要があります。
まだ興味がある場合は、同様の質問に対する回答を示し ます。TwistedでHTTPプロキシをHTTPSプロキシに変換します。
質問の2番目の部分に答えるには:
はいの場合、どの種類のプロキシサーバーがこれを許可しますか?
デフォルトでは、ほとんどのプロキシサーバーはポート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生成で中間者手法を使用して実現できます。mitmproxyを見てください。これは、PythonベースのSSL対応MITMプロキシです。
私は試しました
ssh -N -D 12345 login@proxy_server
localhost:12345
しかし、これにより、https Webサイトに接続しようとすると、常に「安全でない接続」というエラーが発生しました。
解決策は
デジタルオーシャンドキュメンテーションからの参照
「プロキシサーバーを介してHTTPS接続を行う」とは、中間者攻撃タイプのプロキシサーバーを意味するとは思いません。TLS経由でhttpプロキシサーバーに接続できるかどうかを尋ねていると思います。そして答えはイエスです。
プロキシサーバーを介したHTTPS接続は可能ですか?
はい、私の質問と回答をご覧ください。HTTPsプロキシサーバーはSwitchOmegaでのみ機能します
はいの場合、どの種類のプロキシサーバーがこれを許可しますか?
この種のプロキシサーバーは、通常のWebサイトと同様にSSL証明書を展開します。ただしpac
、SSL経由のプロキシ接続を構成するためのファイルが必要です。