はじめに
sslインターセプトするhttpsプロキシで使うためのホワイトリストの作成を少しちゃんとしてみました。
利用する環境は、前回構築した以下のものです。
squidでActiveDirectory連携とSSLインターセプトするProxyをdockerで手軽につくる
要するにどうすればいいのか
ホワイトリストやブラックリストのURLを url_regex で表現すると、以下となりました。
サブドメインを含む、特定のドメインを表現する場合
以下の例では、サブドメインを含む qiita.com というドメインを表現しています。
^(https*://)*([^/][^/]*\.)*qiita\.com(:443|:80)*(/.*)*$
サブドメインを含む、特定のドメインを表現する場合。で、複数のドメイン文字列に共通点があってまとめたい場合
以下の例では、サブドメインを含む slack.comもしくはslack-edge,com というドメインを表現しています。
^(https*://)*([^/][^/]*\.)*slack(-edge)*\.com(:443|:80)*(/.*)*$
上記ホワイトリストをテキストファイルで準備しておき、 squid.com
で url_regex として読み込めばOKです。
acl whitelist url_regex -i "/etc/squid/whitelist"
http_access allow whitelist
書き方を見つけるまでの過程
例:qiita.comの場合
fqdnだけをホワイトリストに書いても悪意に満ちたサイトへ接続できてしまう。
例えば、ホワイトリストにこう書いたとする。
qiita\.com
でもこれは、フルパスやサブドメインに同じ文字列があった場合にマッチしてしまう。
https://example.com/qiita.com/exploit.js
https://qiita.com.example.com/exploit.js
じゃあ、サブドメインを含めながら、特定のドメイン名を許可するために、先頭のプロトコルからの連続性を利用して、こう書いてみたらどうだろうか。
^https*://([^/][^/]*\.)*qiita\.com/
これではダメだった。
証明書をとるためだろうか、最初に qiita.com:443
というのに接続しにいっている。
TCP_DENIED/407 4054 CONNECT qiita.com:443 - HIER_NONE/- text/html
TCP_DENIED/407 4424 CONNECT qiita.com:443 - HIER_NONE/- text/html
TCP_DENIED/200 0 CONNECT qiita.com:443 PROSPER2\\USERNAME HIER_NONE/- -
先ほどのルールに、プロトコルとポート番号を考慮してみよう。どうせだからHTTPなら:80と入れても通信させてあげるようにしよう。
文字列の先頭は、プロトコル表記があってもなくてもマッチするようにし、FQDNの最後はポート番号があってもなくてもマッチするようにした。
^(https*://)*([^/][^/]*\.)*qiita\.com(:443|:80)*/
まだダメだった。
さっきと変わってない。ポート番号で終わっているから、最後のスラッシュが邪魔してマッチしないんだろう。
TCP_DENIED/407 4054 CONNECT qiita.com:443 - HIER_NONE/- text/html
TCP_DENIED/407 4424 CONNECT qiita.com:443 - HIER_NONE/- text/html
TCP_DENIED/200 0 CONNECT qiita.com:443 PROSPER2\\USERNAME HIER_NONE/- -
先ほどのルールに追加して、スラッシュがある、もしくは、スラッシュが無くポート番号もしくはFQDNで文字列の末尾になる。とした。
^(https*://)*([^/][^/]*\.)*qiita\.com(:443|:80)*(/.*)*$
ルートのサイトは、 https://qiita.com/
サブドメインのサイトは https://zine.qiita.com/
の両方で通信確認できた。
たぶんこれでOKだと思う。
例:slack.comの場合
同じようにslackのサイトも許可しておこう。
^(https*://)*([^/][^/]*\.)*slack\.com(:443|:80)*(/.*)*$
ログをみてみたところ、slack-edge.comっていうとこに通信しに行ってるな。
TCP_DENIED/407 4082 CONNECT a.slack-edge.com:443 - HIER_NONE/- text/html
TCP_DENIED/407 4452 CONNECT a.slack-edge.com:443 - HIER_NONE/- text/html
TCP_DENIED/407 4082 CONNECT a.slack-edge.com:443 - HIER_NONE/- text/html
TCP_DENIED/200 0 CONNECT a.slack-edge.com:443 PROSPER2\\USERNAME HIER_NONE/- -
ということは、 slack という文字列のあとに、 -edge という文字列が ある もしくは ない とすればよさそうだ。
^(https*://)*([^/][^/]*\.)*slack(-edge)*\.com(:443|:80)*(/.*)*$
さいごに
ホワイトリストやブラックリストには dstdomain を使ったほうが断然楽です
が、正規表現の勉強も兼ねて、ってことで試行錯誤してみました。