2017.5.28

Debian プロキシサーバー Squid くコ:くコ:くコ:彡。゜゜。。

HTTPS透過プロキシで折れる(前編): ProxyⅣ

### First,please visit -----------
Introduction & INDEX コチラから
------------------------------ ###

今回はHTTPSの透過プロシキですが、通常のSquidでは成立しません。
ソースを入手し、"--enable-ssl, --enable-ssl-crtd"オプションを付与したうえで再ビルドします。
自己署名のCAルート証明書を使用する(いわゆるオレオレですが)、まさに俺折れ状態でした。
オフィスネットークで、外向けのHTTPSをプロキシインターセプトする必要性が本当にあるのか、
その目的があやふやなら他の手法で構成したほうが良いような気もします( '_')?。。。
まあ、それでも何かに役立つかもしれないし、果敢にチャレンジです。

■ INDEX
• Squidでインターネットへのアクセス制限を試してみる: ProxyⅠ
• クライアント側のプロキシ設定: ProxyⅡ
• 透過プロキシ&iptablesで凹む: ProxyⅢ
• HTTPS透過プロキシで折れる: ProxyⅣ

■ WARNING
HTTPS通信を代行受信することには、理解しておくべき倫理的および法的な問題があります。
ここで示されている例について適合性の保証はありません。
もし試してみようと思う方がいれば自己責任でお願いします。
本章で参考にしたサイト:
  squid-cache wiki(http://wiki.squid-cache.org/ConfigExamples/Intercept/SslBumpExplicit)


< 環 境 >
squid3.4.8-6+deb8u4 amd64  as of May 5, 2017

ROUTER: 192.168.1.1
netmask: 255.255.255.0
PROXY_SERVER  eth0: 192.168.1.101gateway = $ROUTER
eth1: 192.168.20.254proxy port = 58080(HTTP)
proxy port = 58088(HTTPS)
CLIENT: 192.168.20.31
gateway = 192.168.20.254
*クライアント側でのプロキシ設定は必要ない。

< 手 順 >
1.必要なパッケージを入手する
2.リビルドする
3.自己署名証明書を発行する
4.設定ファイル編集
5.iptablesのルール編集
6.クライアント側での証明書インポート
7.通信テスト
*第Ⅲ章までの設定が済んでいることを前提とします


[ 1 ] 必要なパッケージを入手する

▼ 現状パッケージの確認
$ dpkg -l | grep squid
---suqid-langpack, squid3, squid3-common
$ whereis squid-langpack squid3
$ sudo squid3 -v | grep enable-ssl
---オプションが適用されていないので何も表示されない
▼ 必要なパッケージをインストールする
$ aptitude show openssl devscripts build-essential fakeroot libssl-dev
---持っていないものがあればインストールする
▼ ソースを入手する
$ mkdir package_squid
$ cd package_squid
$ sudo apt-get source squid3
$ ls -l
drwxr-xr-x 20 root root squid3-3.4.8
-rw-r--r--  1 root root squid3_3.4.8-6+deb8u4.debian.tar.xz
-rw-r--r--  1 root root squid3_3.4.8-6+deb8u4.dsc
-rw-r--r--  1 root root squid3_3.4.8.org.tar.bz2
$ grep Depends squid3_3.4.8-6+deb8u4.dsc
---Squid3のビルドに必要な一覧が表示
$ sudo apt-get build-dep squid3
---上記一覧がまるっとインストールされるはず...


[ 2 ] Squidのリビルド

▼ パッケージのリビルド操作
$ cd squid3-3.4.8/
$ sudo vi debian/rules

17
18 DED_CONFIGURE_EXTRA_FLAGES := --datadir=/usr/share/squid3 \
19             --sysconfdir=/etc/squid3 \
20             --mandir=/usr/share/man \
21             --enable-inline \
## この下行あたりに"--enable-ssl --enable-ssl-crtd"を追記しておく 他はデフォルトのまま
22             --enable-ssl \
23             --enable-ssl-crtd \

$ sudo ./configure
---ダ〜ッと流れる エラーでなければOK
---config.status: creating Makefile
---config.status: creating config.h
---config.status: executing depfiles commands
---config.status: executing libtool commands
$ sudo debuild -us -uc -b
---時間がかかるようだ。。(;-_-)旦~~
---終了すると親ディレクトリにバイナリパッケージファイルが出力される
$ cd ../
$ ls -l
-rw-r--r--  1 root root squid-cgi_3.4.8-6+deb8u4_amd64.deb
-rw-r--r--  1 root root squid-purge_3.4.8-6+deb8u4_amd64.deb
drwxr-xr-x 20 root root squid3-3.4.8
-rw-r--r--  1 root root squid3-common_3.4.8-6+deb8u4_all.deb
-rw-r--r--  1 root root squid3-dbg_3.4.8-6+deb8u4_amd64.deb
-rw-r--r--  1 root root squid3_3.4.8-6+deb8u4.debian.tar.xz
-rw-r--r--  1 root root squid3_3.4.8-6+deb8u4.dsr
-rw-r--r--  1 root root squid3_3.4.8-6+deb8u4_amd64.build
-rw-r--r--  1 root root squid3_3.4.8-6+deb8u4_amd64.changes
-rw-r--r--  1 root root squid3_3.4.8-6+deb8u4_amd64.deb
-rw-r--r--  1 root root squid3_3.4.8.org.tar.bz2
-rw-r--r--  1 root root squidclient_3.4.8-6+deb8u4_amd64.deb

▼ NEWパッケージのインストール
$ sudo systemctl stop squid3.service
---既存squidサービスを停止
$ sudo dpkg -i squid3_3.4.8-6+deb8u4_amd64.deb squid3-common_3.4.8-6+deb8u4_all.deb
Configration file '/etc/squid3/squid.conf'
==> Modified (by you or by a script) since installation.
==> Package distributor has shipped an updated version.
  What would you like to do about it ? Your options are:
   Y or I : install the package maintainer's version
   N or O : keep your currently-installed version
     D   : show the differences between the version
     Z   : start a shell to examine the situation
The default action is to keep your current version.
*** squid.conf (Y/I/N/O/D/Z) [default=N] ? Y
---これでリビルドされた新しいパッケージがインストールされた

$ sudo squid3 -v | grep enable-ssl
---enabel-ssl enable-ssl-crtdを含めてオプションが表示される
$ echo squid3 hold | sudo dpkg --set-selections
---apt-get upgradeで元パッケージに入れ替わってしまうので取り敢えずホールドしておく
---squid3-common squid-langpackも同様に
$ dpkg --get-selections | gerp squid


[ 3 ] 自己署名証明書を発行する

ここがややこしい。Opensslはオプションが複雑で、なかなか使いこなせないのでス Orz。。
自己署名によるCAルート証明書を発行します。いわゆるオレオレです。内輪でしか通用しません。
▼ 設定ファイルを編集
$ sudo cp /etc/ssl/openssl.cnf /etc/ssl/default_openssl.cnf
---念の為、コピーしておきます
$ sudo vi /etc/ssl/openssl.cnf

164 [ usr_cert ]
## このセクションは全てデフォルトのまま
171 basicConstraints=CA:FALSE
177 # nsCertType = server
180 # nsCertType = objsign
183 # nsCertType = client, email
186 # nsCertType = client, email, objsign
192 # KeyUsage = nonRepudiation, digtalSignature, keyEncipherment
217
218 [ v3_req ]
## ここのセクションも全てデフォルトのまま
222 basicConstraints = CA:FALSE
223 KeyUsage = nonRepudiation, digtalSignature, keyEncipherment
224
225 [ v3_ca ]
## この行はデフォルトのまま: true
241 basicConstraints = CA:true
242
243 # Key usage; this is typical for a CA certificate. however since it will
245 # prevent it being used as an self-signed certificate it is best
246 # left out by default
## この行のコメントアウト"#"を削って有効にする 発行後は元に戻しておく
247 # keyUsage = cRLSign, keyCertSign
248 keyUsage = cRLSign, keyCertSign
## 他は全てデフォルトのまま
249
250 # Some might want this also
251 # nsCertType = sslCA, emailCA
252

▼ 自己署名入りCAルート証明書の発行
$ sudo mkdir /etc/squid3/ssl_cert
$ cd /etc/squid3/ssl_cert
$ sudo openssl req -new -newkey rsa:2048 -sha256 -days 3650 -nodes -x509 \
-extensions v3_ca -keyout myProxyCA.key -out myProxyCA.pem
---キーペア(PrivateKey)作成と、そのKeyで自己署名した証明書作成を一度に行う
---PrivateKeyは、プロキシ起動時に読み込めるように暗号化しない: -nodes
---CAルート証明書作成の[v3_ca]を見る様にCAフラグを立てる: -extensions v3_ca

Country Name: JP ↵
State or Province Name: Miyagi ↵
Locality Name: [任意] 
Organization Name[ここの名前が発行者と表示されるようだ]: Green-pen ↵
Organization Unit Name: [任意] 
Common Name[必須 keyと同じ名前が無難でしょう]: myProxyCA ↵
Email Address: [任意] 

$ sudo openssl x509 -in myProxyCA.pem -outform DER -out myProxyCA.der
---DER形式の証明書に変換する
---このDER形式証明書をクライアントに渡す
$ sudo chmod 700 ./


[ 4 ] Squid設定ファイルの編集

第Ⅲ章で設定したsquid.confファイル内容に、次を加筆編集します。
$ sudo vi /etc/squid3/squid.conf

1645 # TAG: https_port
1770#Default:
1771# none
1772https_port 58088 intercept ssl-bump generate-host-certificates=on \
dynamic_cert_mem_cache_size=4MB cert=/etc/squid3/ssl_cert/myProxyCA.pem \
key=/etc/squid3/ssl_cert/myProxyCA.key
1773
2098# TAG: sslproxy_options
2121#Default:
2122# none
##### コンマ","区切りで指定
2123sslproxy_options NO_SSLv2,NO_SSLv3,SINGLE_DH_USE
2124
2144# TAG: ssl_bump
2195#Default:
2196# Dose not bump inless rules are present in squid.conf
2197ssl_bump none localhost
2198ssl_bump server-first all
2199
2332# TAG: sslcrtd_program
2337#Default: コメントアウト"#"削除し有効化
2338# sslcrtd_program /usr/lib/squid3/ssl_crtd -s /var/lib/ssl_db -M 4MB
2339sslcrtd_program /usr/lib/squid3/ssl_crtd -s /var/lib/ssl_db -M 4MB
2340

$ sudo /usr/lib/squid3/ssl_crtd -c -s /var/lib/ssl_db
$ sudo chown -R proxy:proxy /var/lib/ssl_db/
---上のコマンド2行を省いてハマってしまったのです

$ sudo squid3 -k parse
---内容を確認してエラーがなければOK
$ sudo systemctl restart squid.service
---設定を反映
$ sudo systemctl status squid.service
---ステータス確認
$ sudo tail -n 30 /var/log/squid3/cache.log
---キャシュログ確認しておく


[ 5 ] iptablesのルール編集

第Ⅲ章のiptables設定に以下ルールを加減します。
$ sudo iptables -A INPUT -s 192.168.20.31 -i eth1 -p tcp --dport 58088 -j ACCEPT
$ sudo iptables -A OUTPUT -d 192.168.20.31 -o eth1 -p tcp --sport 58088 -m state \
--state RELATED,ESTABLISHED -j ACCEPT
$ sudo iptables -t nat -A PREROUTING -s 192.168.20.31 -i eth1 -p tcp --dport 443 \
-j REDIRECT --to-port 58088

$ sudo iptables -D FORWARD -s 192.168.20.31 -i eth1 -o eth0 -p tcp --dport 443 -j ACCEPT
$ sudo iptables -D FORWARD -d 192.168.20.31 -i eth0 -o eth1 -p tcp --sport 443 -m state \
--state RELATED,ESTABLISHED -j ACCEPT


疲れたので、本日はここまで。残りの手順は、あと少し。
後編へ続く。。。


HTTPS透過プロキシで折れる(後編): ProxyⅣ

[ 6 ] クライアント側での証明書インポート

DER形式として発行した証明書: myProxyCA.derをクライアントへ配布し、そのマシンの任意場所に保管します。
Web Browserで、その証明書をインポートします。
e.g. WebBrowser: Firefox

①右上の三本線マーク--->設定(オプション)②サイドバー詳細--->証明書タブ--->証明書を表示
ca01  ca02
 
③認証局証明書タブ--->インポート④保管の場所--->証明書選択--->開く
ca03  ca04
 
⑤Webサイトの識別を信頼にチェック⑥インポート内容確認しOKで閉じる
ca05  ca06

クライアントWebBrowserでのプロキシ設定は必要ありません。


[ 7 ] 通信テスト

OS: Debian8.8 jessie
WebBrowser: Firefox-ESR
概ねのHTTPSサイトはつながりましたが、例えば"Wikipedia"など一部のサイトは警告画面が表示されブロックされます。 2017.5.現在、各主要ブラウサーでは、SHA-1を使ったHTTPSサイトを表示した場合、警告画面が表示されるようになっていますが、 まさかWikiが使っているとも思えませんので、何か設定に足りない部分があるのでしょう。
ンなことから、当初の目的でもあるプロキシホワイトリストを用いたアクセス制限の試みは、透過型のHTTPS接続に少し未達感を残すこととなりました /(=_= ;)。。。

▼ ログをみる
$ sudo tail -f /var/log/squid3/access.log
$ sudo tail -f /var/log/squid3/cache.log
▼ WebサイトのSSL/TLS構成状況を確認する
$ openssl s_client -connect example.com:443 < /dev/null
---options: -ssl3, -tls1, -tls1_1, tls1_2 プロトコルバーションを指定
$ curl -s -v https://example.com < /dev/null
---options: --sslv3, --tlsv1, --tlsv1.1, --tlsv1.2 プロトコルバーションを指定
▼ 接続するプロトコルバーションを制限する
file: squid.conf // TAG: sslproxy_version
      1.automatic
      2.SSLv2 only
      3.SSLv3 only
      4.TLS1.0 only
      5.TLS1.1 only
      6.TLS1.2 only
e.g. sslproxy_version 6
▼ 最近のDH鍵交換を利用する
$ openssl dhparam -outform PEM -out dhparam.pem 2048
$ sudo vi /etc/squid3/squid.conf
## TAG: https_port
## warning: この場合EDH暗号は暗黙的に無効になる
https_port 58088 intercept ssl-bump generate-host-certificates=on \
dynamic_cert_mem_cache_size=4MB cert=/etc/squid3/ssl_cert/myProxyCA.pem \
key=/etc/squid3/ssl_cert/myProxyCA.key options=NO_SSLv3 \
dhparams=/etc/squid3/ssl_cert/dhparam.pem
▼ Squidバージョンについて
今回運用したSquid3.4のIntercept Https with SSL-Bumpでは、
証明書の取扱いに関わる部分で少し制約があるようです。
e.g. "sslproxy_foreign_intermediate_certs" This directive is not avilable in the 3.4 version


第Ⅰ~Ⅳ章までダラダラと書いてしまいましたが、飽きずにお読み頂きましてありがとうございます。
そんな訳で、「Squidでプロキシサーバー」の巻はおしまいです m(_ _)m。。。


Copyright(C) green-pen miyagi