短縮版:
承認された* SSL証明書のみを使用するホストへのアウトバウンドSSL接続を許可するプロキシまたはファイアウォールデバイスを知っていますか?
ロングバージョン:
次のシナリオを検討してください。
ファイアウォールによってインターネットから保護されているサーバーファームがあります。 HTTPSがインターネットから許可されているが、ファイアウォールがこれらのマシンからインターネットへのアウトバウンドアクセスをブロックしているとしましょう。私は私のサーバー管理者が退屈してサーフィンをしたくない/。データセンターから、そしてマルウェアや悪意のあるアクターが違反の際にアウトバウンドに簡単に接続できるようにしたくありません。
私はsomeのアウトバウンドアクセスを許可したいのですが。たとえば、Windowsサーバーがwindowsupdate.Microsoft.comにアクセスできるようにするとします。 windowsupdateで使用されているIPを特定できる場合は、問題なくファイアウォールで開きます。
しかし、それらのIPが知られていない、または知らない場合はどうなりますか?具体的には、MicrosoftがAkamaiまたは別の [〜#〜] cdn [〜#〜] を使用してファイルを提供しているとします。連絡するIPアドレスは事前に判断するのが難しく、定期的に変更されます。その場合、IPでホワイトリストに登録できません。
洗練されたソリューションの1つ-SSLで保護されたサービスに連絡していると想定-は、IPアドレスではなくホワイトリストSSL証明書に基づいてをホワイトリストに登録することです。したがって、サーバー証明書が* .windowsupdate.Microsoft.comで、有効なCAによって署名されている場合は、接続を許可します。 * .windowsupdate.Microsoft.comでない場合、またはSnakeOilによって署名されている場合は、接続を拒否します。
(承認済み証明書は、いくつもの柔軟なものを意味する可能性があります。名前と信頼できるCA、名前と特定のCA、特定のCA署名付き証明書など)
コントロールポイントを内部サーバーに置くことはできません。悪意のある攻撃者がコントロールポイントにアクセスした場合、この保護を無効にすることはできません。 IPホワイトリストと同様に、プロキシまたはファイアウォールデバイスとしての境界に対する制御を削除することは理にかなっています。
それはrightのやり方のように思えます。このようにするための私の選択肢は何ですか?これは、誰もがこれまでに実装したパラダイム、無料、または商用ですか?私が知っている他のパラダイムは、最新の(Akamai、AWS、Dyn-ish)動的サービスに対応する柔軟で強力な方法で発信アクセスを制限できるか?
助けてくれてありがとう!
考えられることは2つあり、どちらも法案に完全には適合していません。また、議会が必要です。
squid
with sslBump および SSL Server Certificate Validator これは基本的にMITM SSLプロキシ構成であり、通常の拡張を行う外部「ヘルパー」を提供します検証。障害には、証明書の信頼と独自のCA /証明書の管理が含まれます。私はこれを使ったことがありません。
Apache httpd
をフォワードプロキシとして、mod_rewrite
、mod_proxy
および外部検証スクリプトを使用します。ここでのアプローチは、mod_rewrite
プログラムマップを使用して、アクセスを許可する前にターゲットの証明書を事前検証することです。
Apacheオプションは簡単にテストできます:httpd.conf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule rewrite_module modules/mod_rewrite.so
[...]
Listen 10.0.0.16:3128
<VirtualHost 10.0.0.16:3128>
ServerName proxy.domain.com
ErrorLog ...
CustomLog ...
ProxyRequests on
RewriteEngine on
RewriteMap sslval prg:/usr/local/Apache2/bin/sslval
<Proxy>
RewriteEngine on
## parse CONNECT
RewriteCond %{THE_REQUEST} "^(CONNECT) ([^:]+)(:([0-9]+))? HTTP/" [NC]
RewriteRule . - [env=CHOST:%2,env=CPORT:%4]
## hand over to sslval
RewriteCond ${sslval:%{ENV:CHOST}:%{ENV:CPORT}} ok
RewriteRule . - [P,L]
RewriteRule . - [F]
</Proxy>
</VirtualHost>
これは、証明書キャッシュのサポートによりgnutls-cli
を使用する外部「sslval」スクリプトであり、期待する証明書をexactlyに指定できます。
#!/bin/bash
export HOME=/usr/local/Apache2
while read key; do
timeout 10 gnutls-cli --tofu \
--port=${key##*:} ${key%%:*} >/dev/null 2>&1 <<<Q
[ $? = 0 ] && echo ok || echo fail
done
あとは、必要な証明書を~Apache/.gnutls/known_hosts
にgnutls-cli --tofu ...
とインタラクティブに追加し、「y」を入力して確認するだけです。
このtrust on first useメソッドはおなじみのように見えるかもしれませんが、OpenSSHのknown_hosts
とまったく同じです。このアプローチは OpenVPN's--tls-verify
オプションと同じです。
sslval
スクリプトのバリエーションを使用して、選択したCAデータベースをチェックできます。 OpenSSLのs_client
および.pem
CAファイルのデータベース(c_rehash
で管理)を使用して、たとえば:
timeout 10 openssl s_client \
-connect "$key" -servername "${key%%:*}" \
-verify 5 -CApath /usr/local/etc/CA <<< Q |
gawk '/Verify return code: (19|0) /{ok=1}
END{print ok?"ok":"fail"}'
エラーチェック、ロック、構成とアクセス制御、キャッシング、およびそれらすべての素晴らしいことは、読者の練習です... ;-)
Apache(2.2.2x)を使用すると、通常のリクエスト(非CONNECT)のプロキシが上記のmod_rewriteテクニックの影響を受けることがわかりました。そのためには、2番目のVirtualHostが必要になります。
Spuratic氏がよく説明しているように、SSL終了プロキシを使用して証明書でフィルタリングできます。
ただし、SSLパススループロキシをSSL終了プロキシに変換することは非常に大きな問題であり、概説する動機だけで行うものではありません。
あなたの最良の実用的なオプションは、ホスト名でフィルタリングすることです。
Blue Coat ProxySGは、これのすべてではありませんが、ほとんどを実行できます。
これを正しく理解している場合は、DNSポイズニングと証明書の偽造に基づく攻撃のリスクから保護する必要があります。
Mr spuraticによって説明されているSquidメソッドの問題は、偽の証明書をクライアントに送り返すことです。デーモンプロセスの場合、ブラウザが醜い警告メッセージを表示する一方で接続を拒否する必要があります(そして接続に失敗します) HSTSを実装しているサイト)unlessまた、クライアントにスネークオイルCA証明書をインストールします。これは、セキュリティの観点からはおそらく良い考えではありません。
私がこれを実装しようとしていた場合、サーバー証明書が解決されたIPアドレスからポーリングされている間、CONNECTリクエストを保留できるカスタムプロキシを使用します(opensslでスクリプトを取得して操作し、証明書を取得して操作します)。 。これは、mr spuraticがApacheを使用して説明しているようです-しかし、私がmod_rewrite/gnutlsについて十分に詳しくないので、これが当てはまるかどうか、彼のアプローチが有効かどうかはわかりません。
これに加えて、証明書の有効期限に対応する必要性、および特定のホスト名(特にMicrosoftのような大規模組織)に対して複数の有効な証明書が存在する可能性があり、これはかなり複雑な演習のように見えます。
私が最初に考えたのは、証明書に対してより広範な検証を適用するよりも、DNSデータの保護に集中する方が効果的かもしれないということです。明白な解決策はDNSSECを使用することですが、マイクロソフトはDNSSECクライアントサポートを提供していますが、それは サーバーに実装されていないようです であることがわかります。
おそらくより実用的な解決策は、問題のホストのDNSデータをローカルでTTLよりもはるかに長く維持することでしょうか?