DebianにフォワードプロキシSquidを入れてWebフィルタリングをしよう

# あらすじ

[Debian](https://sources.debian.org/) 10 に [Squid](https://github.com/squid-cache/squid) 4.6 を HTTPS対応でインストールしようじゃなイカ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134703/cfacc1ef-6629-d5b1-0a14-2a8ddafc5601.png)


# モチベーション

先日、CentOSが終了するとの話がありました。これはイカがいたしましょう。今まで CentOS でフォワードプロキシを運用していましたが、この機会に[Debian](https://sources.debian.org/)に引っ越しすることにします。[Debian](https://sources.debian.org/)は、[Ubuntu](https://ubuntu.com/)や[Kali](https://www.kali.org/)、[Raspbian](https://www.raspbian.org/)のベースになっています。

※フォワードプロキシはウェブ利用のクライアント側に位置し、ウェブサービスユーザーの身代わりになるものです。Webフィルタリングのサーバーとして機能させることが出来ます。ちなみに逆はリバースプロキシで、ウェブサービスのサーバーの身代わりになるものです。HTTPにSSLを付けるだけだったり、いろいろします。どちらもイカしてますね！

今までCentoOSだった人が、DebianでProxyを使い始める話をするだけです。

::: note alert
引っ越しと書きましたが、設定引継のガイドではありません。
:::

::: note
いろいろ調べると、CentOS の移行先は <a href="https://www.centos.org/centos-stream/">CentOS Stream</a> のほうが良さそうです。イカようにも出来そうですね。
:::

# そもそもフォワードプロキシのメリット

企業では、NAT 機能で、社内ネットワーク内からインターネットにアクセスする設定が多いです。NAT では、悪質なサイトなどへのアクセスを IP アドレスでしかブロックできないことがあります。

「別にいいんじゃなイカ？」という声もありそうですが、これでは上手くイカない事例があるわけです。

IP アドレスでブロックすると、AWS や Akamai といった CDN まで対象に含めてしまうことになります。これにより、まったく関係のないサイトで利用されている CSS、JavaScript ファイルまでブロックしてしまい、様々なページでの閲覧に支障が出てくることがあります。これはイカんですね。

そこで Squid の出番です。 Webプロキシなので、アプリケーション層で動作し、IP アドレスではなく FQDN でブロックが可能なのです。昨今の CDN を多用する Web サービスを安全に利用できます。 また、FQDN で接続ログが残るのもCSIRT的に好都合です。

また、Webにはインターネット閲覧はさせたくないが、ソフトウェア更新はしたいといった内容にも応えてくれます。
このように、フォワードプロキシはイカしたシステムなのです。

# HTTPS・SSL

Googleの透明性レポート「[ウェブ上での HTTPS 暗号化](https://transparencyreport.google.com/https/overview?hl=ja)」をみても分かるように、Google主導の取り組みによって HTTPS 化が進んでいます。squid で SSL が扱えるようにすることは必須と言えます。

ところが2021年、現在のStableバージョンsquid4.6ではSSLは無効化されております。そのため、少々お手数がかかります。そのあたりのお話もしていきましょう。

# 待って！インストールしないで！

いきなり`apt install`しようとしましたか？ちょっと待ってください。それはイカんです。
その方法でインストールしたsquidにはSSLの機能がありません。

「そんなわけないじゃなイカ！？」って人は一度インストールしてみて、
次のコマンドを実行してみてください。

```
squid -v
```

configure options パラメータの値に `--enable-ssl-crtd` および `--with-openssl` が含まれていればそのまま使えます。
無ければ、使えないのです。SSL機能が。

なんと、ソースコードからビルドする前にオプション設定が必要です。そのため、自分でビルドする必要があります。ビルドしてからインストールしましょう。イカにしてビルドするのでしょうか？

# ビルドしよう

まずはアーカイバをインストールします。

```
 sudo apt install dpkg-dev
```

これで、ソースコードの圧縮ファイルをダウンロード後に解凍してくれます。
次に、ソースコードをダウンロードします。

```
cd ~
sudo apt source squid
```

そうすると、`~/squid-4.6`というフォルダが出来上がります。
これがプロジェクトフォルダです。
この中にあるビルド設定ファイル`rules`を書き換えます。

```
sudo nano -l ~/squid-4.6/debian/rules
```

私はnanoエディターが好きなのでnanoで編集します。

::: note
nano エディター起動オプションに<code>-l</code>を付与して行番号を表示しています。<code>rules</code>ファイルは大きいため行番号が分かると便利です。
:::

`DEB_CONFIGURE_EXTRA_FLAGS := `という部分があるので、そこに、下記を追加します。

```
--with-openssl \
--enable-ssl \
--enable-ssl-crtd \
```

書き換えが終わったら、今の設定を反映します。

```
~/squid-4.6/configure
```

依存関係を一気に入れます。

```
sudo apt install devscripts build-essential fakeroot libssl-dev libldap2-dev libpam0g-dev libdb-dev cdbs libsasl2-dev debhelper libcppunit-dev libkrb5-dev comerr-dev libcap2-dev libecap3-dev libexpat1-dev libxml2-dev pkg-config libnetfilter-conntrack-dev nettle-dev libgnutls28-dev dh-apparmor ed
```

依存関係がインストールできたら、
ビルドを行います。

```
cd ~/squid-4.6
sudo debuild -us -uc -b
```

ビルドが終わると、`~`ディレクトリに`*.deb`のファイルが増えているはずです。
これをインストールしてあげます。

```
sudo dpkg -i ~/squid*.deb
```

インストールエラーになります。依存関係を修復します。

```
sudo apt --fix-broken install
```

もう一度インストールします。

```
sudo dpkg -i ~/squid*.deb
```

# サービスにする

Squid サービスを自動起動設定に追加します。

```
sudo systemctl enable squid
```

Squid サービスを開始します。

```
sudo service squid start
```

Squid サービスのステータスを確認します。この操作には、次のコマンドを実行します：

```
sudo service squid status
```

Active パラメータの値に active (running) が含まれていればOKです。

# SSL Bump の設定

HTTPSのWebページが見れるように設定を加えていきます。

## 自己署名 SSL 証明書の作成

まずは、いわゆる「オレオレ証明書」を作成します。Lets'Encryptなどを使って生成しても良いのではなイカと思います。

Squid サービスのディレクトリに移動します。

```
cd /etc/squid
```

自己署名 SSL 証明書を作成します。

```
sudo openssl req -new -newkey rsa:2048 -days <証明書の有効期間の日数> -nodes -x509 -keyout bump.key -out bump.crt
```

これにより、自己署名 SSL 証明書の各項目を対話形式で入力します。
その結果、証明書ファイル `bump.crt` と秘密鍵ファイル `bump.key` が作成されます。

::: note warn
不正アクセスを防ぐため、秘密鍵ファイルは安全な場所に保存しましょう。
:::

証明書ファイルを DER 形式に変換して、信頼する証明書としてブラウザーにインポートできるようにします。

```
sudo openssl x509 -in bump.crt -outform DER -out bump.der
```

その後、クライアント側のコンピューターで、信頼されたルート証明機関のリストに `bump.der` ファイルをインポートします。
特定のブラウザー（Mozilla Firefox など）を使用する場合は、ブラウザーの保管領域にも証明書を追加する必要があります。

# bump設定

Squid サービスで SSL Bump を設定していきます。

そもそも Squid サービスが必要なオプションをサポートしていることを確認します。

```
sudo squid -v
```

`configure options` パラメータの値に `--enable-ssl-crtd` および `--with-openssl` が含まれていればOKです。

別途用意した場合は、ここでPEM 形式の SSL 証明書を `/etc/squid/bump.crt` に配置します。
また、PEM 形式の秘密鍵を `/etc/squid/bump.key` に配置します。
Diffie-Hellman アルゴリズムの設定ファイルを生成します。

```
sudo openssl dhparam -outform PEM -out /etc/squid/bump_dhparam.pem 2048
```

SSL 証明書ファイルを使用するための権限を設定します。

```
sudo chown proxy:proxy /etc/squid/bump*
sudo chmod 400 /etc/squid/bump*
```

squid サービスが実行中の場合は停止します。

```
sudo service squid stop
```

証明書データベース用のディレクトリを作成して、データベースを初期化します。

```
sudo mkdir -p /var/lib/squid
sudo rm -rf /var/lib/squid/ssl_db
sudo /usr/lib/squid/security_file_certgen -c -s /var/lib/squid/ssl_db -M 20MB
sudo chown -R proxy:proxy /var/lib/squid
```

/etc/squid/squid.conf 設定情報ファイルを次のように変更します。
ファイルの先頭または 1 つ目の `http_access` の前に次を追加します。

```
acl intermediate_fetching transaction_initiator certificate-fetching
http_access allow intermediate_fetching
```

ファイルの末尾に以下を追加します。

```
sslcrtd_program /usr/lib/squid/security_file_certgen -s /var/lib/squid/ssl_db -M 20MB
sslproxy_cert_error allow all
ssl_bump stare all
```

`http_port` で始まる行を以下で置き換えます。

```
http_port 3128 tcpkeepalive=60,30,3 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=20MB tls-cert=/etc/squid/bump.crt tls-key=/etc/squid/bump.key cipher=HIGH:MEDIUM:!LOW:!RC4:!SEED:!IDEA:!3DES:!MD5:!EXP:!PSK:!DSS options=NO_TLSv1,NO_SSLv3,SINGLE_DH_USE,SINGLE_ECDH_USE tls-dh=prime256v1:/etc/squid/bump_dhparam.pem
```

::: note warn
<code>3128</code>は Well known port です。安全性を高める場合はこの時点で<code>3128</code>以外の数字に書き換えます。
:::

squid サービスを再起動します。

```
sudo service squid restart
```

# 自動アップデートから除外

自動アップデートされてしまうと、SslBump設定が消えます。それは困るので例外設定を入れておきます。

```
echo squid* hold | sudo dpkg --set-selections
```

squidの更新が無いか、定期的にGithubを確認しなければいけませんね。気が向いたらIFTTTで設定しましょうかね。

# アクセス制御設定

そのままだと利用環境にあった設定になっていません。特に、ACL（Access Control List）の設定が不十分です。

```
sudo nano /etc/squid/squid.conf
```

`nano`などのエディターを使って、`squid.conf`の中の`acl`で始まる部分を環境に合わせて書き換えます。

書き終えたら、squidを再起動します。

```
sudo service squid restart
```

もしここで`squid.conf`の文法エラーなどがあると、squidの起動に失敗します。
その時は、慌てず`squid.conf`の中身を変更前の状態に戻してみます。
そうするとsquidは起動するので、リラックスして思考できます。

お好みの`squid.conf`になるまで何度再起動しても構いません。

::: note
<code>squid -k check</code>や<code>squid -k debug</code>というコマンドを使うと、squid を再起動しなくても設定ファイルの静的解析ができるので便利です。
:::

# squid.conf

私の場合、環境に合わせて２か所変更しました。

まず、`from where browsing should be allowed`というコメントの下に、
`http_access allow localnet`がコメントアウトされているので、先頭の`#`を消して機能させます。

```
# from where browsing should be allowed

http_access allow localnet
http_access allow localhost
```

次に`acl localnet src`で始まる行が複数記述されている部分を見つけます。
これらすべての先頭にに`#`を付けてコメントアウトします。

その下に行を追加し、下記のように必要なネットワークを追加しました。

```
acl localnet src　192.168.0.0/24 # Aビル3F

acl localnet src　192.168.1.0/24 # Aビル3F

acl localnet src　192.168.2.0/24 # Aビル3F

```

とりあえずこれで、LAN内からアクセスできることは確認できました。イカがでしたか？

# ネットワーク構成

イメージです。なんとなく伝わるんじゃなイカと思います。いずれ、もう少し詳しい図に変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134703/a6601a10-7d8f-e2c8-3441-befed25678bc.png)



# 参考

こちらのイカしたサイトもぜひご覧ください！

https://qiita.com/subaru44k/items/9adf2142fcc677108a13

https://qiita.com/noraworld/items/9f1a28c13a48da336d1c

https://qiita.com/worldmotor/items/e5823d03c52b55a86f9d

https://qiita.com/mascii/items/400a0ecab61d885ac2a8

https://qiita.com/yangniao23/items/a48931d79a171b835845

https://wiki.squid-cache.org/SquidFaq/CompilingSquid

# まとめ

これからはHTTPSが標準の時代です。
もう少ししたらsquidもデフォルトでSSL対応してくれるかもしれませんね。
それでは、「ぬりたく～る…テンタクル！！」

**Excelsior!**