アドネットワークからの侵略を防衛するでゲソ! ~Squidで広告ブロックプロキシを建てる~
Pi-hole による「ドメイン単位のブロックをすり抜けてくる広告」への対策として、URLフィルタリング機能があるプロキシサーバ「Squid」のインストールから設定・運用、デフォルトでは不可能な HTTPS URL フィルタリングへの対応(Squid + SSL Bump)について解説。

Windows 環境で行う場合は Proxydomo という選択も。Squid で HTTPS URL フィルタリング対応なプロキシを建てるよりは簡単かと。
正直、
- 常時実行用の OS 環境の用意
- SSL Bump 対応 Squid のビルド・インストール
- HTTPS URL フィルタリング対応への設定
- 自己署名証明書の生成、クライアント側で自己署名証明書のインポート
- URLブロッキングリストの作成とブロッキングの確認
等の作業が面倒かつ時間が掛かる為、
- 広告 消すべし 慈悲は無い
- 興味の無い広告の為に「帯域が喰われる」のは不愉快だ
- 不要不急の外出自粛で時間を持て余している
- 時間が掛かってもネットワーク単位での広告ブロック環境を構築したい
いずれかに当てはまる逸般人方にお勧め。
About Squid & SSL Bump
Squid とは?
Squid については以下参照。通常は「ネットワーク資源の共有による応答の高速化」を目的として使われるの処を、広告ブロック用プロクシとして使用する。
Squid(スクウィッド)はプロキシ (Proxy) サーバ、ウェブキャッシュサーバなどに利用されるフリーソフトウェア。GPLでライセンスされている。 Squidの用途は、重複リクエストに対したキャッシュ応答によるウェブサーバの高速化や、ネットワーク資源を共有する人々が行うWorld Wide WebやDNSなどの様々なネットワーククエリのキャッシュなど、多岐にわたる。元来はUnix系のコンピュータで動作させる目的で設計されている。
Squidは長く開発が続けられてきた。多様なプロトコルをサポートしているが、主にHTTPとFTPで利用される。 TLS/SSL、HTTPSなどのセキュリティで保護された通信のサポートも行われている
SSL Bump とは?
https:// で始まるURLのSSL(HTTPS)通信はサーバ・ブラウザ間で暗号化されている為、リクエスト先のURLはドメインまでしか判らない。
それをMITM(中間者攻撃)と同じ手法で「SSL(HTTPS)通信の途中に介入(Squid内部で暗号化を解除、中身を見た後に再度暗号化)」する事で、SSL(HTTPS)通信であってもリクエスト先のURLを取得する。
「Squid & SSL Bump対応済み」な経路を通した通信を行うと、ネットワーク管理者に対しいつ誰がどのサイトを訪れていたか筒抜けというプライバシーもへったくれもない状況が発生。又、それを利用するにはシステム or ブラウザ側で自己署名証明書のインポートする作業が必要な為、自身が管理し、自身のみが使用するネットワーク内のみでの使用を。
動作環境
使用時の快適さは財布に比例…… という現実はさておき、必要とされるスペック・コストパフォーマンス・設置スペースから個人用途としては Raspberry Pi 4 Model B/4GB を推奨。Raspberry Pi 3B+ でも試してみたもののLAN(有線)速度に難あり。快適さ優先なら「Raspberry Pi 4 Model B/8GB & SSD」という選択も。
仮想環境上に構築は、ディスクI/O周りで他の仮想マシンのパフォーマンスに影響が大きいため非推奨(動作検証用としてはOK)。
以下の環境で動作確認済み(2020/05/01)。
- OS
- Raspbian Buster(ARM / x86_64)
 
- ハードウェア
- Raspberry Pi 4 Model B/4GB or 仮想環境(VirtualBox)
 
前準備
作業前に
- OS(Debian系)インストール済み
- 最新のアップデート適応
- IPアドレス(IPv4)割り当てを固定
- root のパスワードをデフォルトから変更(セキュリティ的に)
- ターミナルからのSSHログイン or リモートデスクトップ接続を可能に(外部からの管理接続用)
が済んでいる事を確認の上、以下の手順へ。仮想環境の場合はこの段階でスナップショットを撮っておく事。
パッケージのアップデート
sudo apt update
sudo apt upgrade -y
sudo apt full-upgrade -y
sudo apt autoremove
sudo apt autoclean
スワップサイズの変更
デフォルト値(100)だとビルド中にフリーズする為、スワップサイズを100MBから2048MBに変更。SDカードから起動している場合は、ビルド終了後に元の値へ戻す。
テキストエディタでスワップサイズの設定ファイルを読み込み。
sudo nano /etc/dphys-swapfile
デフォルト値から変更。
# change : Swap Size 100 → 2048
CONF_SWAPSIZE=2048
変更した値を反映させる。
sudo systemctl stop dphys-swapfile
sudo systemctl start dphys-swapfile
apt source でソースをダウンロード可能にする
sources.list を変更。
sudo nano /etc/apt/sources.list
deb-src 行頭のコメントアウトを外す。複数ある場合はそれらも全て外す。
deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
deb-src http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free
sources.list の変更を反映させる。
sudo apt update
Squid をソースからビルドする
通常の apt install -y squid でインストールした場合は SSL Bump 未対応な為、ソースからビルドする。
ビルドに必要なパッケージをインストール
sudo apt install -y devscripts build-essential fakeroot debhelper cdbs
依存と推奨されるパッケージをインストール
Squid ビルドに必要なパッケージを一括でインストール。
sudo apt build-dep -y squid
crypto 関連のパッケージは apt build-dep -y squid でインストールされない為、追加でインストール。
# sudo ./configure >> configure: error: library 'crypto' is required for OpenSSL
sudo apt install -y libssl-dev
依存パッケージの確認は以下のコマンドで。
apt depends squid
Squid のソースを取得
# ビルド作業用のディレクトリィを作成
cd ~
mkdir -p Build
cd ./Build
# ソースを取得
sudo apt source squid
# 作成されたデレクトリィに移動
cd ./squid-*
./debian/rules にビルドパラメーターを追加
sudo nano ./debian/rules
DEB_CONFIGURE_EXTRA_FLAGS に以下のオプションを追加。追加前の最終行に改行文字(\)を入れるのを忘れない事。
--with-openssl \
--enable-ssl \
--enable-ssl-crtd
- 注意事項
- 追加前の最終行に改行文字(\)をコピペで追加したら debuild -us -uc -b実行時に警告発生。キーボード入力した方が無難?@2020/05/15
- Windows 環境からリモートでコピペすると \r\nが入る?@2020/05/27
 
- 追加前の最終行に改行文字(\)をコピペで追加したら 
ビルド
インストールに必要な環境変数やライブラリが正しく設定、設置されているか確認、問題が無ければ makefile が作成される。
sudo ./configure
正常に終了すれば処理最終行辺りが以下の様に。
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands
config.status: executing libtool commands
エラーが無ければビルドを実行。ビルド終了までは1時間半程(squid_5.7-2_arm64 のビルド、Raspberry Pi 4 Model B/4GBで107分)。
sudo debuild -us -uc -b
ビルド中、不足しているパッケージがあれば以下の様に error or warning の警告が出る為、その都度メッセージに従い必要なパッケージをインストール。
pi@raspberrypi:~/work/squid-4.6 $ sudo debuild -us -uc -b
dpkg-buildpackage -us -uc -ui -b
dpkg-buildpackage: info: source package squid
dpkg-buildpackage: info: source version 4.6-1+deb10u1
dpkg-buildpackage: info: source distribution buster-security
dpkg-buildpackage: info: source changed by Salvatore Bonaccorso <carnil@debian.org>
dpkg-source --before-build .
dpkg-buildpackage: info: host architecture armhf
dpkg-checkbuilddeps: error: Unmet build dependencies: libcppunit-dev libcap2-dev libdb-dev libecap3-dev (>= 1.0.1-2) libgnutls28-dev (>= 3.5) libkrb5-dev comerr-dev libldap2-dev libnetfilter-conntrack-dev libpam0g-dev libsasl2-dev libxml2-dev nettle-dev
dpkg-buildpackage: warning: build dependencies/conflicts unsatisfied; aborting
dpkg-buildpackage: warning: (Use -d flag to override.)
debuild: fatal error at line 1182:
dpkg-buildpackage -us -uc -ui -b failed
この時作成された deb ファイルは
- 「適当な名前 or ビルドした日付」を付けたディレクトリィにまとめる
- まとめたファイルを別マシンにバックアップ
何らかのトラブルが発生し、後で再インストールする場合に助かるかと(やらかした人)。
Squid のインストール
インストール
パッケージファイルが存在するフォルダに移動。
# インストール
sudo dpkg -i squid*.deb
# 依存関係の修復
sudo apt --fix-broken install -y
# 依存関係修復後、再度インストール
sudo dpkg -i squid*.deb
インストール終了後、Squid のバージョンとサービスの稼働状態を確認。
# バージョン情報
squid -v
# サービスの稼働状態を表示
sudo systemctl status squid.service
Squid を パッケージの更新から外す
このままだとパッケージ更新の際、 SSL Bump 未対応版に上書きされる為、更新の対象から外す必要が。以下のコマンドで Squid を apt upgrade の更新対象から外す。
sudo apt-mark hold squid
ホールド解除は、
sudo apt-mark unhold squid
ホールドしたパッケージの確認は以下のコマンドで。
apt-mark showhold
Squid の初期動作確認
Squid インストール直後の動作確認について。
インストール直後、iptables or セキュリティソフト・アンチウイルスソフト等でLAN内からの通信をブロックしていないのであれば、HTTP Port 3128 でのプロクシ接続を待ち受けている設定に。
Squid の設定
作業前に設定ファイルのバックアップを。
sudo cp /etc/squid/squid.conf /etc/squid/squid.conf.org
ディレクトリィ構成 & 設定ファイルの場所一覧。
/root
 |
 *--- /etc
 |     |
 |     *--- /squid
 |           |
 |           *--- /list
 |           |      |
 |           |      *--- allow_url_regex.txt
 |           |           allow_dstdomain.txt
 |           |           ip.txt
 |           |           domain.txt
 |           |           domain_regex.txt
 |           |           url_regex.txt
 |           |           path_regex.txt
 |           |
 |           *--- /ssl_cert
 |           |      |
 |           |      *--- SquidCA.pem
 |           |           SquidCA.der
 |           |
 |           *--- squid.conf
 |
 *--- /var
       |
       *--- /log
       |     |
       |     *--- /squid
       |           |
       |           *--- access.log
       |                cache.log
       |                deny.log
       |
       *--- /spool
              |
              *--- /squid
                    |
                    *--- /cache
                    |
                    *--- /ssl_db
設定(squid.conf)
Squid 4.6(SSL Bump 対応済み)をインストールしたとの前提で、
上の記事を参考に、以下の条件で設定(/etc/squid/squid.conf)を書き直してみた。
- DNSサーバはシステムが使用しているものとは別に指定(システムデフォルト使用の場合はコメントアウト)
- ファイルキャッシュは使用しない(SDカード上で動作している場合は、ファイルキャッシュ非推奨)
なお、この時点では匿名プロキシに準ずる程度。
# テキストエディタで設定ファイル(squid.conf)を読み込み。
sudo nano /etc/squid/squid.conf
# DNSサーバの指定 >> /etc/dhcpcd.conf とは別のDNSサーバを指定する場合は、各自環境用に書き換えてコメントアウトを外す
#dns_nameservers 192.168.0.110
# file descriptors(http://www.squid-cache.org/Doc/config/max_filedescriptors/)
max_filedescriptors 65536
# シャットダウンまでの待ち時間(http://www.squid-cache.org/Doc/config/shutdown_lifetime/)
shutdown_lifetime 5 seconds
# log format(http://www.squid-cache.org/Doc/config/logformat/)
logformat customlog %ts.%03tu [%{%Y/%m/%d %H:%M:%S}tl.%03tu] %6tr %>a %Ss/%03>Hs %<st %rm %ru %[un %Sh/%<a %mt
# -----------------------------------------------------------------------------------------------------------------------------
# ローカルネットワークの定義
acl localnet src 10.0.0.0/8      # RFC 1918 local private network (LAN)
acl localnet src 172.16.0.0/12   # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16  # RFC 1918 local private network (LAN)
acl localnet src 169.254.0.0/16  # RFC 3927 link-local (directly plugged) machines
acl localnet src fc00::/7        # RFC 4193 local private network range
acl localnet src fe80::/10       # RFC 4291 link-local (directly plugged) machines
# -----------------------------------------------------------------------------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------------------
# SSL接続時(HTTPS)に 443 ポート以外の CONNECT を拒否
acl SSL_ports port 443
acl CONNECT method CONNECT
http_access deny CONNECT !SSL_ports
# 接続先(HTTP)として指定されているポート以外を拒否
acl Safe_ports port 21          # ftp
acl Safe_ports port 70          # gopher
acl Safe_ports port 80          # http
acl Safe_ports port 210         # wais
acl Safe_ports port 443         # https
acl Safe_ports port 280         # http-mgmt
acl Safe_ports port 488         # gss-http
acl Safe_ports port 591         # filemaker
acl Safe_ports port 777         # multiling http
acl Safe_ports port 1025-65535  # unregistered ports
http_access deny !Safe_ports
# キャッシュの設定
http_access allow localhost manager
http_access deny manager
http_access allow localnet   # ローカルネットワークからのアクセスを許可
http_access allow localhost  # 自身からのアクセスを許可
http_access deny all         # ここまで一致しなかった場合は拒否
# -----------------------------------------------------------------------------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------------------
# プロキシの待ち受けポート、デフォルトの 3128 から 8080 へ変更
http_port 8080
# -----------------------------------------------------------------------------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------------------
# core 出力場所の設定
coredump_dir /var/spool/squid
# アクセスログの出力先を指定 >> SDカード延命対策で /dev/null に出力し、SDカードへの書き込み回数を減らす
#access_log daemon:/var/log/squid/access.log customlog
access_log daemon:/dev/null
# -----------------------------------------------------------------------------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------------------
fqdncache_size  8192  # メモリ上にキャッシュする FQDNキャッシュエントリ   の最大数、既定値は 1024
ipcache_size    8192  # メモリ上にキャッシュする DNS IPキャッシュエントリ の最大数、既定値は 1024
ipcache_high      95  # DNS IPキャッシュエントリの上限(%)、上限を超えるとアクセスされていないキャッシュを整理する
ipcache_low       90  # DNS IPキャッシュエントリの下限(%)、指定した値以下になると整理を停止する
# -----------------------------------------------------------------------------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------------------
# ファイルキャッシュ有効時、設定ファイル保存後に以下のスクリプトを実行 >> ファイルキャッシュ用ディレクトリィの初期化・作成
# sudo systemctl stop squid.service
# sudo squid -z
# sudo systemctl restart squid.service
#
# 以下の記述は「搭載メモリ6GB以上、ファイルキャッシュ用の割り当てサイズ 16GB以上」を前提とした設定
# ファイルキャッシュを無効にする。有効にする場合はコメントアウトする
no_cache deny all
# キャッシュを有効にする場合は以下のコメントアウトを外す
#cache_mem                      4096 MB               # キャッシュに使用するメモリサイズ
#maximum_object_size_in_memory  1024 KB               # メモリ上にキャッシュする最大サイズ
#maximum_object_size            2048 KB               # ディスク上にキャッシュする最大サイズ
#minimum_object_size               0 KB               # ディスク上にキャッシュする最小サイズ
#cache_dir aufs /var/spool/squid/cache  16384 16 256  # キャッシュのディスクサイズ(MB)、一次ディレクトリ数、二次ディレクトリ数
#cache_swap_high  95
#cache_swap_low   90
# キャッシュ更新間隔の設定(一日=1440, 三日=4320, 一週間=10080)
#refresh_pattern ^ftp:                                 1440  20%  10080
#refresh_pattern ^gopher:                              1440   0%   1440
#refresh_pattern -i (/cgi/|/cgi-bin/|\?)                  0   0%      0
#refresh_pattern -i \.(cgi|php)$                          0   0%      0
#refresh_pattern -i \.(ico|gif|jpe?g|png|svg|webp)$    4320  90%  10080  override-expire override-lastmod ignore-no-cache ignore-no-store ignore-private
#refresh_pattern -i \.(wav|mp3|m4a|mp4|mpeg|ts|webm)$  4300  90%  10000  override-expire override-lastmod ignore-no-cache ignore-no-store ignore-private
#refresh_pattern -i \.(js|css)$                        4320  40%  10080
#refresh_pattern -i \.(htm|html)$                      4320  40%  10080
#refresh_pattern .                                        0  40%   4320
# -----------------------------------------------------------------------------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------------------
# Squid のバージョンを表示しない
httpd_suppress_version_string off
# ローカルのホスト名を表示しない
visible_hostname unknown
# クライアントのIPアドレス or ホスト名を隠す
forwarded_for off
# プロクシ接続である事を隠す
request_header_access X-Forwarded-For deny all
request_header_access Via             deny all
request_header_access Cache-Control   deny all
reply_header_access X-Forwarded-For   deny all
reply_header_access Via               deny all
reply_header_access Cache-Control     deny all
# 診断くん(http://taruo.net/e/?) 対策
request_header_access CACHE-INFO        deny all
request_header_access CLIENT-IP         deny all
request_header_access IF-MODIFIED-SINCE deny all
reply_header_access   CACHE-INFO        deny all
reply_header_access   CLIENT-IP         deny all
reply_header_access   IF-MODIFIED-SINCE deny all
# -----------------------------------------------------------------------------------------------------------------------------
設定ファイル(squid.conf)にエラーがないか確認。
# 設定ファイルの確認。
sudo squid -k parse
エラーが無ければ変更された設定を反映させる。
# 変更された設定を反映させる
sudo systemctl restart squid.service
# サービスの稼働状態を確認
sudo systemctl status squid.service
Squid 経由でのアクセスを確認
Squid 経由でアクセスする場合のプロキシ設定については以下参照。ブラウザの通信を含めたシステム全体に反映される為、広告ブロックを目的とする場合はブラウザ拡張機能からプロクシの指定を。
- プロキシ設定
- ブラウザ拡張機能
プロキシ経由で通信しているかを確認するには、Windows なら netstatコマンド or TCP Monitor Plusのセッションモニター、Linux なら iftop(要インストール)、もしくはブラウザのデベロッパーツールから。
netstat(Windows)
逆引き禁止、TCPポート接続を3秒毎に表示。
netstat -n -p TCP 3

TCP Monitor Plus(Windows)
TCP Monitor Plus を起動後、セッションモニターのタブに移動し開始のボタンを押す(ホスト名の取得のチェックは外す)。

iftop(Linux)
逆引き禁止、接続ポートを表示。
sudo iftop -n -P

ブラウザのデベロッパーツールを使用
ブラウザのデベロッパーツールで接続先を確認するには、
- 任意ページを開いた状態で、右クリックからのプロパティメニューから、Chrome なら検証、Firefox なら要素の調査からデベロッパーツールを呼び出す。
- Network のタブに移動し Remote Address or リモート IP の項目を有効にする。
- ページをリロード

Squid で URL フィルタリング
Squid の URLフィルタリングで使う ACL(アクセス制御リスト)は主に以下の5種類。リスト作成・編集用の GUI は用意されていない為、ドメイン・サブドメイン単位のフィルタリングは Pi-hole に丸投げした方が楽かと。
| ACL要素 | 解説 | 応答速度 | 備考 | 
|---|---|---|---|
| dst | リクエスト先のIPアドレス/ネットマスク | slow | ネットマスク指定は省略可 | 
| dstdomain | リクエスト先のドメイン名 | fast | |
| dstdom_regex | リクエスト先のドメイン名を正規表現で表記 | fast | |
| url_regex | リクエスト先のURLを正規表現で表記 | fast | |
| urlpath_regex | リクエスト先のURLパス部分を正規表現で表記 | fast | 
ACL 指定時のオプションは以下参照。
acl aclname dst [-n] ip-address/mask ... # URL host's IP address [slow]
acl aclname dstdomain [-n] .foo.com ...
  # Destination server from URL [fast]
acl aclname dstdom_regex [-n] [-i] \.foo\.com ...
  # regex matching server [fast]
  #
  # For dstdomain and dstdom_regex a reverse lookup is tried if a IP
  # based URL is used and no match is found. The name "none" is used
  # if the reverse lookup fails.
acl aclname url_regex [-i] ^http:// ...
  # regex matching on whole URL [fast]
acl aclname urlpath_regex [-i] \.gif$ ...
  # regex matching on URL path [fast]
ブロックリストの作成
ブロックリスト用のファイルを作成。同階層にファイルが多数並んでいると判りづらいので /etc/squid/list 配下にまとめておく。
cd /etc/squid
sudo mkdir -p list
cd ./list
# 許可リスト
sudo touch allow_url_regex.txt
sudo touch allow_dstdomain.txt
# 拒否リスト
sudo touch ip.txt
sudo touch domain.txt
sudo touch domain_regex.txt
sudo touch url_regex.txt
sudo touch path_regex.txt
ブロックリスト(e.x. domian.txt for ACL type dstdomain)
ブロックドメインリストの生成スクリプトを unboundによるDNSブロッキング - それマグで! の記事を参考に書き換えてみた。
任意の場所(ディレクトリィ)に、ブロッキングリスト取得用(blocklists.txt) & amp; 生成用(blocklist.sh)のファイルを
# 任意の場所にディレクトリィを作成(ここではデスクトップ上に作成)
cd ~
cd ./Desktop
mkdir -p BlockList
cd ./BlockList
touch blocklist.sh
touch blocklists.txt
sudo chmod u+x  blocklist.sh
作成。
blocklists.txt(ドメインが列挙 or hosts形式のリストを指定)
https://adaway.org/hosts.txt
https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt
https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
https://v.firebog.net/hosts/AdguardDNS.txt
https://logroid.github.io/adaway-hosts/hosts_no_white.txt
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
https://raw.githubusercontent.com/multiverse2011/adawaylist-jp/master/hosts
https://sites.google.com/site/hosts2ch/ja
https://warui.intaa.net/adhosts/hosts.dos
https://mirror1.malwaredomains.com/files/justdomains
http://winhelp2002.mvps.org/hosts.txt
https://phishing.army/download/phishing_army_blocklist.txt
https://someonewhocares.org/hosts/zero/
http://sysctl.org/cameleon/hosts
https://pgl.yoyo.org/as/serverlist.php?hostformat=hosts&showintro=0&mimetype=plaintext
blocklist.sh
#!/bin/bash
BLOCKLIST='./blocklists.txt'
FILENAME='blocklist_domain.txt'
TMP='./tmp'
OUT='./out'
function init_environment(){
   local current=$(dirname $0)
   cd ${current}
   echo -n -e "\n"
   echo_color "Current Directory"; echo ": ${current}"
   if [ ! -e $TMP ]; then
      mkdir -p $TMP
   fi
   if [ ! -e $OUT ]; then
      mkdir -p $OUT
   fi
}
function download_blocklists(){
   local blocklists=$1
   # 区切り文字を改行コードに指定
   IFS=$'\n'
   # ファイルの読み込み
   local list=(`cat ${blocklists} | sed -e "s/\r//" | grep -v ^#`)
   local count=0
   for i in "${list[@]}"; do
      count=$(( count + 1 ))
      local num=$(printf %03d $count)
      local output=${TMP}/${num}.txt
      local url=${i}
      echo -n -e "\n"
      #echo ${num} ":" ${url}
      echo_color ${num}; echo " : ${url}"
      geneate_list ${url} ${output}
   done
   echo -n -e "\n"
}
function geneate_list(){
   local url=$1
   local output=$2
   curl -m 10 -L ${url}     \
      | sed -e "s/\r//"     \
      | grep -E "^[a-z0-9]" \
      | sort                \
      | uniq                \
      > ${output}
}
function combine_list(){
   local filename=$1
   cat ${TMP}/*.txt                        \
      | sed -E "s/\t/ /"                   \
      | sed -E "s/\s\s*/ /"                \
      | sed -E "s/^0\.0\.0\.0\s//"         \
      | sed -E "s/^127\.0\.0\.1\s//"       \
      | sed -E "s/^0\.0\.0\.0$//"          \
      | sed -E "s/#(.*)$//"                \
      | sed -E "s/local-data: \"//"        \
      | sed -E "s/\. IN A 0\.\0\.0\.0\"//" \
      | sed -E "s/^local$//"               \
      | sed -E "s/\s//"                    \
      | sed -E "s/^$//"                    \
      | sort                               \
      | uniq > ${OUT}/${filename}
   rm ${TMP}/*.txt
}
function echo_color(){
   local string=$1
   local color=$2
   local ESC_ON=$(printf '\033[')
   local ESC_OFF=$(printf '\033[m')
   if [ -z "${color}" ]; then
      color=94
   fi
   echo -n "${ESC_ON}${color}m${string}${ESC_OFF}"
}
function main(){
   init_environment
   download_blocklists $BLOCKLIST
   combine_list $FILENAME
}
main
以下のコマンドで実行すると out ディレクトリィ配下に dstdomain 形式のブロックリストが作成される。
# スクリプトの実行
sudo bash blocklist.sh
後は生成されたリスト(blocklist_domain.txt)の中身を、手動でdomain.txtにコピペする。面倒な場合は
sudo cp blocklist_domain.txt /etc/squid/list/domain.txt
参考:shell実行時に「コマンドが見つかりません」と表示されたとき - 組み込み技術を向上したい!!
ブロックリスト(e.x. url_regex.txt for ACL type url_regex)
以下は ACL要素 url_regex(ブロック対象のURLを正規表現で表記)用リストのサンプル。
# ACL : url_regex
# 行頭に http:// or https:// を付けなくても動作するが、警告が出るので付けておく@2019/10/26
# 広告パーソナライズ
^https://ipcheck.blogsys.jp/check.js
# ライブドアブログの「広告パーソナライズ or 効果測定のためクッキー許諾」対策
^https://parts.blog.livedoor.jp/js/jquery([\w-]+).js
# 広告配信
^http://blog.livedoor.jp/([\w-]+)/settings/ad.js
^https://parts.blog.livedoor.jp/js/
^https://jp.rakuten-static.com/1/grp/banner/js/create.js
# 広告配信 : ライブドアブログで独自ドメインなサイトが対象 >> urlpath_regex で指定した方が?@2020/05/03
^https?://[^/]+/settings/ad.js
# 逆アクセスランキング
^https://blogmaterial.nicoblomaga.jp/material/279/js/reverse_access.js
# 2chまとめ
^http://jin115.com/js/
^http://jin115.com/settings/ad.js
^http://blog.esuteru.com/([\w-]+).js
^http://blog.esuteru.com/js/
^http://blog.esuteru.com/settings/ad.js
^http://yaraon-blog.com/wp-includes/js/
^http://yaraon-blog.com/wp-content/plugins/contact-form-7/includes/js/jquery.form.min.js
^https://alfalfalfa.com/settings/ad.js
# 広告リダイレクト
^http://www.videoconverterhd.com
# マイクロソフトのサポート詐欺(https://news.microsoft.com/ja-jp/2017/04/26/170426-information-support/)
^http://www.support.microsoft([\w-]+).com.s3-website-ap-northeast-1.amazonaws.com
ブロックリストの変更を反映させる
変更された設定(ブロックリストの変更も含む)は自動的に反映されない為、手動で設定を再読み込みさせる。方法は二通りあるので好みの方を。
systemctl から
# Squid サービスの再起動
sudo systemctl restart squid.service
squid のコマンドラインから。
# 変更された設定を反映させる
sudo squid -k reconfigure
HTTPS の URL フィルタリングに対応するには
自己署名証明書の作成
- ConfigExamples/Intercept/SslBumpExplicit - Squid Web Proxy Wiki
- SSLサーバー証明書は2年物を買ってはいけない - orangeitems’s diary
# 自己署名証明書を置くためのディレクトリィを作成
cd /etc/squid
sudo mkdir -p ssl_cert
sudo chmod 700 /etc/squid/ssl_cert
# このままだと /etc/squid/ssl_cert に移動できない為、一時的に root へ移行
sudo -i
cd /etc/squid/ssl_cert
# 自己署名証明書の作成(有効期限の日数は -days で指定)
# 注 : 2020年9月移行、AppleのSafariでSSL証明書の最大有効期間を13か月(398日)内に設定されていないと接続エラーに
openssl req -new -newkey rsa:2048 -sha256 -days 3650 -nodes -x509 -extensions v3_ca -keyout SquidCA.pem -out SquidCA.pem -subj "/C=JP/ST=Kanagawa/L=Kurakama/O=uminoie/OU=umioie-lemon/CN=Squid Girl"
# ブラウザにインポートするための自己署名証明書を作成
openssl x509 -in SquidCA.pem -outform DER -out SquidCA.der
# SSLキャッシュディレクトリの作成 & 初期化
/usr/lib/squid/security_file_certgen -c -s /var/spool/squid/ssl_db -M 4MB
chown -R proxy /var/spool/squid/ssl_db
Squid 4.0.5 から ssl_crtd は security_file_certgen と名前変更。ネットのみを頼りにしているとここで躓く罠。公式で「変更履歴の確認」は大事……
2.4 Helper Binary Changes
The basic_msnt_multi_domain_auth helper has been removed. The basic_smb_lm_auth helper performs the same actions without extra Perl and Samba dependencies.
The cert_valid.pl testing helper has been renamed to security_fake_certverify, reflecting the Squid helper naming schema and that it does not actually perform any certificate checks.
The security_fake_certverify helper is also now built and installed by default. It is written in Perl so does not require OpenSSL dependencies for installation. But does use the Perl Crypt::OpenSSL::X509 module for execution. Building the helper can be controlled using the --enable-security-cert-validators="fake" option.
The ssl_crtd helper has been renamed to security_file_certgen and is now built and installed by default whenever OpenSSL support is enabled. Building the helper can be controlled using the --enable-security-cert-generators="file" option. NOTE: The --enable-ssl-crtd option is still required to enable the sslcrtd_program helper interface within Squid that uses the helper.
The ntlm_smb_lm_auth helper is now built using --enable-auth-ntlm="SMB_LM". Notice the upper case where it was previously a (wrongly) lower cased acronym.
2.4 Helper Binary Changes - Squid 4.0.5 release notes
自己署名証明書をインポート(仮)
- マニュアル作成用
Windows
システムにインストール。
Google Chrome for Linux
2)証明書を設定する - Google Chrome Enterprise ヘルプ
Mozilla Firefox for Linux
Android & iOS
スマートフォン(iOS、Android)にオレオレ証明書がインストールできない? - 世界一わかりやすいセキュリティ
設定(squid.conf)を SSL Bump 対応に書き換える
- ファイルキャッシュは使用しない
- HTTPとHTTPSのポートはそれぞれ別に待ち受ける
http_port 8080
の個所を、以下の様に書き換える。HTTPS用に待ち受けポートを別途用意する事で SSL Bump を使わない場合でも併用可能に。
http_port 8080
http_port 8090 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=/etc/squid/ssl_cert/SquidCA.pem
sslcrtd_children 32 startup=5 idle=3
acl step1 at_step SslBump1
ssl_bump peek step1
ssl_bump bump all
SSL Bump 対応設定(squid.conf)
# DNSサーバの指定 >> /etc/dhcpcd.conf とは別のDNSサーバを指定する場合は、各自環境用に書き換えてコメントアウトを外す
#dns_nameservers 192.168.0.110
# file descriptors(http://www.squid-cache.org/Doc/config/max_filedescriptors/)
max_filedescriptors 65536
# シャットダウンまでの待ち時間(http://www.squid-cache.org/Doc/config/shutdown_lifetime/)
shutdown_lifetime 5 seconds
# log format(http://www.squid-cache.org/Doc/config/logformat/)
logformat customlog %ts.%03tu [%{%Y/%m/%d %H:%M:%S}tl.%03tu] %6tr %>a %Ss/%03>Hs %<st %rm %ru %[un %Sh/%<a %mt
# -----------------------------------------------------------------------------------------------------------------------------
# ローカルネットワークの定義
acl localnet src 10.0.0.0/8      # RFC 1918 local private network (LAN)
acl localnet src 172.16.0.0/12   # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16  # RFC 1918 local private network (LAN)
acl localnet src 169.254.0.0/16  # RFC 3927 link-local (directly plugged) machines
acl localnet src fc00::/7        # RFC 4193 local private network range
acl localnet src fe80::/10       # RFC 4291 link-local (directly plugged) machines
# -----------------------------------------------------------------------------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------------------
# SSL接続時(HTTPS)に 443 ポート以外の CONNECT を拒否
acl SSL_ports port 443
acl CONNECT method CONNECT
http_access deny CONNECT !SSL_ports
# 接続先(HTTP)として指定されているポート以外を拒否
acl Safe_ports port 21          # ftp
acl Safe_ports port 70          # gopher
acl Safe_ports port 80          # http
acl Safe_ports port 210         # wais
acl Safe_ports port 443         # https
acl Safe_ports port 280         # http-mgmt
acl Safe_ports port 488         # gss-http
acl Safe_ports port 591         # filemaker
acl Safe_ports port 777         # multiling http
acl Safe_ports port 1025-65535  # unregistered ports
http_access deny !Safe_ports
# キャッシュの設定
acl manager proto cache_object
http_access allow localhost manager
http_access deny manager
# ブロックリスト
#
# 記述例 : acl 定義名 定義の種類 オプション リストファイル
# オプション -i : 大文字小文字を無視
# オプション -n : パラメータ(ドメイン名,IPアドレス)と指定したACLの定義が異なる場合、警告や逆引きをせずに不整合を宣言する(https://www.robata.org/docs/squid/Reference/squid3.4.0.3/acl.html)
# 許可リスト
acl allow_url_regex url_regex -i    "/etc/squid/list/allow_url_regex.txt"
acl allow_dstdomain dstdomain    -n "/etc/squid/list/allow_dstdomain.txt"
# 拒否リスト >> ファイルが空だと "squid -k parse" で "Warning: empty ACL" と警告が出るけど無視してOK
acl block_ip           dst              -n "/etc/squid/list/ip.txt"
acl block_domain       dstdomain        -n "/etc/squid/list/domain.txt"
acl block_domain_regex dstdom_regex  -i -n "/etc/squid/list/domain_regex.txt"
acl block_url_regex    url_regex     -i    "/etc/squid/list/url_regex.txt"
acl block_path_regex   urlpath_regex -i    "/etc/squid/list/path_regex.txt"
http_access allow allow_url_regex    # allow_url_regex    で定義したURLへのアクセスを許可
http_access allow allow_dstdomain    # allow_dstdomain    で定義したドメインへのアクセスを許可
http_access deny  block_ip           # block_ip           で定義したIPアドレスへのアクセスをブロック
http_access deny  block_domain       # block_domain       で定義したドメインへのアクセスをブロック
http_access deny  block_domain_regex # block_domain_regex で定義したドメインへのアクセスをブロック
http_access deny  block_url_regex    # block_url_regex    で定義したURLへのアクセスをブロック
http_access deny  block_path_regex   # block_path_regex   で定義したパスへのアクセスをブロック
http_access allow localnet   # ローカルネットワークからのアクセスを許可
http_access allow localhost  # 自身からのアクセスを許可
http_access deny  all        # ここまで一致しなかった場合は拒否
# -----------------------------------------------------------------------------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------------------
# プロキシの待ち受けポート、デフォルトの 3128 から 8080 へ変更
# プロキシの待ち受けポート、HTTP と HTTPS は別のポートで待ち受け
http_port 8080
http_port 8090 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=/etc/squid/ssl_cert/SquidCA.pem
sslcrtd_children 32 startup=5 idle=3
# 「error:141A318A:SSL routines:tls_process_ske_dhe:dh key too small」対策@2020/05/07
#tls_outgoing_options cipher=DEFAULT:@SECLEVEL=1
acl step1 at_step SslBump1
ssl_bump peek step1
ssl_bump bump all
# -----------------------------------------------------------------------------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------------------
# core 出力場所の設定
coredump_dir /var/spool/squid
# アクセスログの出力先を指定 >> SDカード延命対策で /dev/null に出力し、SDカードへの書き込み回数を減らす
#access_log daemon:/var/log/squid/access.log customlog
access_log daemon:/dev/null
# ブロックリストで deny したログを別途出力(デバック用、必要ない場合はコメントアウト)
#access_log daemon:/var/log/squid/deny.log customlog block_ip
#access_log daemon:/var/log/squid/deny.log customlog block_domain
#access_log daemon:/var/log/squid/deny.log customlog block_domain_regex
#access_log daemon:/var/log/squid/deny.log customlog block_url_regex
#access_log daemon:/var/log/squid/deny.log customlog block_path_regex
# -----------------------------------------------------------------------------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------------------
fqdncache_size  8192  # メモリ上にキャッシュする FQDNキャッシュエントリ   の最大数、既定値は 1024
ipcache_size    8192  # メモリ上にキャッシュする DNS IPキャッシュエントリ の最大数、既定値は 1024
ipcache_high      95  # DNS IPキャッシュエントリの上限(%)、上限を超えるとアクセスされていないキャッシュを整理する
ipcache_low       90  # DNS IPキャッシュエントリの下限(%)、指定した値以下になると整理を停止する
# -----------------------------------------------------------------------------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------------------
# ファイルキャッシュ有効時、設定ファイル保存後に以下のスクリプトを実行 >> ファイルキャッシュ用ディレクトリィの初期化・作成
# sudo systemctl stop squid.service
# sudo squid -z
# sudo systemctl restart squid.service
#
# 以下の記述は「搭載メモリ6GB以上、ファイルキャッシュ用の割り当てサイズ 16GB以上」を前提とした設定
# ファイルキャッシュを無効にする。有効にする場合はコメントアウトする
no_cache deny all
# キャッシュを有効にする場合は以下のコメントアウトを外す
#cache_mem                      4096 MB               # キャッシュに使用するメモリサイズ
#maximum_object_size_in_memory  1024 KB               # メモリ上にキャッシュする最大サイズ
#maximum_object_size            2048 KB               # ディスク上にキャッシュする最大サイズ
#minimum_object_size               0 KB               # ディスク上にキャッシュする最小サイズ
#cache_dir aufs /var/spool/squid/cache  16384 16 256  # キャッシュのディスクサイズ(MB)、一次ディレクトリ数、二次ディレクトリ数
#cache_swap_high  95
#cache_swap_low   90
# キャッシュ更新間隔の設定(一日=1440, 三日=4320, 一週間=10080)
#refresh_pattern ^ftp:                                 1440  20%  10080
#refresh_pattern ^gopher:                              1440   0%   1440
#refresh_pattern -i (/cgi/|/cgi-bin/|\?)                  0   0%      0
#refresh_pattern -i \.(cgi|php)$                          0   0%      0
#refresh_pattern -i \.(ico|gif|jpe?g|png|svg|webp)$    4320  90%  10080  override-expire override-lastmod ignore-no-cache ignore-no-store ignore-private
#refresh_pattern -i \.(wav|mp3|m4a|mp4|mpeg|ts|webm)$  4300  90%  10000  override-expire override-lastmod ignore-no-cache ignore-no-store ignore-private
#refresh_pattern -i \.(js|css)$                        4320  40%  10080
#refresh_pattern -i \.(htm|html)$                      4320  40%  10080
#refresh_pattern .                                        0  40%   4320
# -----------------------------------------------------------------------------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------------------
# Squid のバージョンを表示しない
httpd_suppress_version_string off
# ローカルのホスト名を表示しない
visible_hostname unknown
# クライアントのIPアドレス or ホスト名を隠す
forwarded_for off
# プロクシ接続である事を隠す
request_header_access X-Forwarded-For deny all
request_header_access Via             deny all
request_header_access Cache-Control   deny all
reply_header_access X-Forwarded-For   deny all
reply_header_access Via               deny all
reply_header_access Cache-Control     deny all
# 診断くん(http://taruo.net/e/?) 対策
request_header_access CACHE-INFO        deny all
request_header_access CLIENT-IP         deny all
request_header_access IF-MODIFIED-SINCE deny all
reply_header_access   CACHE-INFO        deny all
reply_header_access   CLIENT-IP         deny all
reply_header_access   IF-MODIFIED-SINCE deny all
# -----------------------------------------------------------------------------------------------------------------------------
カスタマイズ
- URL Blocking 時のレスポンスコード
- ニコニコ動画
トラブルシューティング
自己署名証明書更新以降、接続エラーが発生
Squid 側に更新前のSSLキャッシュが残っていると考えられる@要再検証@2020/05/30
# サービスの停止
sudo systemctl stop squid.service
# 以前に作成されたSSLキヤッシュを削除
cd /var/spool/squid
sudo rm -r ssl_db
# SSLキャッシュディレクトリの作成 & 初期化
sudo /usr/lib/squid/security_file_certgen -c -s /var/spool/squid/ssl_db -M 4MB
sudo chown -R proxy /var/spool/squid/ssl_db
# サービスの開始
sudo systemctl start squid.service
接続エラー
error:141A318A:SSL routines:tls_process_ske_dhe:dh key too small
The system returned:
(71) Protocol error (TLS code: SQUID_ERR_SSL_HANDSHAKE)
Handshake with SSL server failed: error:141A318A:SSL routines:tls_process_ske_dhe:dh key too small
[squidでhttpsプロキシ] dh key too small で発生したエラーの解消 - bashaway@Qiita
error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol
The system returned:
(71) Protocol error (TLS code: SQUID_ERR_SSL_HANDSHAKE)
Handshake with SSL server failed: error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol
CentOS8からTLS1.0, 1.1 に接続できない - kituneponyo@Qiita
SSL Certficate error: certificate issuer (CA) not known
The system returned:
(71) Protocol error (TLS code: X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
SSL Certficate error: certificate issuer (CA) not known: /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
[squidでhttpsプロキシ] 中間CA証明書をチェインしていないwebサーバへアクセスしたときのエラーを解消する - bashaway@Qiita
Tips
頻繁に使いそうなコマンドあれこれ
systemctl : Squid サービスの開始・停止・再起動・設定の再読み込み
コマンド中の squid.service は squid と省略可。
# サービスの開始
$ sudo systemctl start squid.service
# サービスの停止
$ sudo systemctl stop squid.service
# サービスの再起動
$ sudo systemctl restart squid.service
# 稼働中サービスの設定再読込
$ sudo systemctl reload squid.service
squid --help より
Usage: squid [-cdzCFNRVYX] [-n name] [-s | -l facility] [-f config-file] [-[au] port] [-k signal]
    -h | --help       Print help message.
    -v | --version    Print version details.
       -a port   Specify HTTP port number (default: 3128).
       -d level  Write debugging to stderr also.
       -f file   Use given config-file instead of
                 /etc/squid/squid.conf
       -k reconfigure|rotate|shutdown|restart|interrupt|kill|debug|check|parse
                 Parse configuration file, then send signal to
                 running copy (except -k parse) and exit.
       -n name   Specify service name to use for service operations
                 default is: squid.
       -s | -l facility
                 Enable logging to syslog.
       -u port   Specify ICP port number (default: 3130), disable with 0.
       -z        Create missing swap directories and then exit.
       -C        Do not catch fatal signals.
       -D        OBSOLETE. Scheduled for removal.
       -F        Don't serve any requests until store is rebuilt.
       -N        Master process runs in foreground and is a worker. No kids.
       --foreground
                 Master process runs in foreground and creates worker kids.
       --kid role-ID
                 Play a given SMP kid process role, with a given ID. Do not use
                 this option. It is meant for the master process use only.
       -R        Do not set REUSEADDR on port.
       -S        Double-check swap during rebuild.
       -X        Force full debugging.
       -Y        Only return UDP_HIT or UDP_MISS_NOFETCH during fast reload.
参考記事
Raspbian
パッケージのビルド
- deb
- Build
Squid
- Config
- ACL
- SSL Bump
- Tips
接続の確認
- netstat - ホストのネットワーク統計や状態を確認する - @IT
- Linux
- Windows
サーバー証明書
- SSLサーバ証明書
- 有効期限
- openssl
- インストール & アンインストール
TroubleShooting
- Squid 経由の接続でエラーが発生