LinuxにSquidプロキシサーバーを構築する:アクセス制御・コンテンツフィルタリング・帯域幅キャッシュ

Networking tutorial - IT technology blog
Networking tutorial - IT technology blog

なぜネットワークにプロキシが必要なのか、そしてなぜSquidなのか

数年前、私は小さなオフィスネットワークを管理していました。スタッフが同じ大きなソフトウェアアップデートサーバーに何度もアクセスし、各マシンが同一ファイルを個別にダウンロードし続けていたのです。通信費は膨らみ、レスポンスタイムは悪化し、何にアクセスされているかまったく把握できない状況でした。これこそフォワードプロキシが解決すべき問題であり、私の場合はSquidがその答えとなりました。

Squidは1990年代中頃から存在するオープンソースのキャッシング・フォワーディングHTTPプロキシです。クライアントとインターネットの間に位置し、アウトバウンドのリクエストをインターセプトします。2台のマシンが同じリソースをリクエストした場合、Squidはリモートサーバーに再アクセスせず、キャッシュされたコピーを2台目のマシンに返します。キャッシュ機能だけでなく、アクセスポリシーの適用も可能です。サイトのカテゴリのブロック、IPレンジによるアクセス制限、時間帯によるトラフィック制限、そして監査目的のすべてのログ記録が行えます。

このガイドでは、Ubuntu/DebianへのSquidの完全なセットアップを解説します。インストール、ACL設定、キャッシュのチューニング、監視まで、実際に本番環境で運用するために必要なすべてを網羅しています。

インストール

Ubuntu/DebianへのSquidのインストール

Squidはデフォルトのリポジトリに含まれているため、インストールは簡単です:

sudo apt update
sudo apt install squid -y

RHEL/CentOS/Rocky Linuxの場合:

sudo dnf install squid -y

インストール後、サービスを有効化して起動します:

sudo systemctl enable squid
sudo systemctl start squid
sudo systemctl status squid

デフォルトでは、Squidはポート3128でリッスンします。正しくバインドされているか確認します:

ss -tlnp | grep 3128

0.0.0.0:3128または:::3128でSquidがリッスンしているのが確認できるはずです。

ファイアウォールの設定

クライアントがプロキシポートにアクセスできるようにします:

# UFW(Ubuntu)
sudo ufw allow 3128/tcp

# firewalld(RHEL/Rocky)
sudo firewall-cmd --permanent --add-port=3128/tcp
sudo firewall-cmd --reload

設定

メインの設定ファイルは/etc/squid/squid.confです。ファイルは大きく、コメントも充実していますが、基本的な動作に必要なのはごく一部のディレクティブだけです。変更前にバックアップを取っておきましょう:

sudo cp /etc/squid/squid.conf /etc/squid/squid.conf.bak

プロキシ利用者の定義(ACL)

Squidのアクセス制御はACLを中心に構成されています。名前付きの条件を定義し、それをallow/denyルールで参照します。設定ファイルを開きます:

sudo nano /etc/squid/squid.conf

ACLセクションを見つけて、ネットワーク範囲を追加します。LANが192.168.1.0/24の場合:

# ローカルネットワークを定義する
acl localnet src 192.168.1.0/24

# そのネットワークを許可する
http_access allow localnet

# それ以外をすべて拒否する(末尾に既に記載されているはず)
http_access deny all

順序が重要です。Squidはhttp_accessルールを上から順に処理し、最初にマッチした時点で停止します。deny allは必ず末尾に置いてください。

コンテンツフィルタリング:ドメインとカテゴリのブロック

特定のドメインをブロックするにはdstdomain ACLを作成します:

# 業務時間中にSNSをブロックする
acl social_media dstdomain .facebook.com .twitter.com .instagram.com .tiktok.com

# 業務時間を定義する
acl work_hours time MTWHF 08:00-18:00

# 業務時間中にSNSをブロックする
http_access deny social_media work_hours

# ローカルネットワークからのその他すべてを許可する
http_access allow localnet

数百〜数千のドメインを含む大規模なブロックリストは外部ファイルに記述します:

# /etc/squid/blocklist.txt — 1行に1ドメイン
.gambling.com
.malware-domain.net
.phishing-example.org

squid.confでそのファイルを参照します:

acl blocklist dstdomain "/etc/squid/blocklist.txt"
http_access deny blocklist

URLパターンマッチングで、ドメインリストでは捕捉できないものをブロックできます:

acl bad_words url_regex -i torrent piracy crack keygen
http_access deny bad_words

帯域幅最適化のためのキャッシュ設定

帯域幅の節約効果が実際に現れるのはここです。私の経験では、適切なキャッシュチューニングにより、ソフトウェアのダウンロード、パッケージの更新、またはメディアアセットが繰り返し取得される環境では、アウトバウンド帯域幅を20〜40%削減できます。

チューニングすべき主なキャッシュディレクティブ:

# キャッシュの保存場所とサイズ(この例では10GB)
cache_dir ufs /var/spool/squid 10240 16 256

# メモリキャッシュ(RAM)— 利用可能なRAMの約25%に設定
cache_mem 512 MB

# キャッシュするオブジェクトの最大サイズ(巨大ファイルはキャッシュしない)
maximum_object_size 100 MB

# オブジェクトの最小サイズ(キャッシュのメリットがない小さなオブジェクトはスキップ)
minimum_object_size 0 KB

# 明示的な有効期限ヘッダーがない場合のオブジェクト保持期間
refresh_pattern ^ftp:           1440    20%     10080
refresh_pattern ^gopher:        1440    0%      1440
refresh_pattern -i (/cgi-bin/|\?) 0     0%      0
refresh_pattern .               0       20%     4320

キャッシュ設定を変更した後、キャッシュディレクトリを初期化します:

sudo squid -z
sudo systemctl restart squid

認証(任意だが推奨)

IPベースのアクセス制御は良い出発点です。ユーザーごとのトラッキングや個別のアカウンタビリティがログに必要な場合は、Basic認証を追加しましょう:

# htpasswdのためにapache2-utilsをインストール
sudo apt install apache2-utils -y

# パスワードファイルを作成する
sudo htpasswd -c /etc/squid/passwd john
sudo htpasswd /etc/squid/passwd jane

次にSquidで使用するよう設定します:

auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwd
auth_param basic realm Squid Proxy
auth_param basic credentialsttl 2 hours

acl authenticated proxy_auth REQUIRED
http_access allow authenticated
http_access deny all

ログの設定

デフォルトではSquidは/var/log/squid/access.logにログを記録します。各行にはタイムスタンプ、レスポンスタイム、クライアントIP、結果コード、転送バイト数、HTTPメソッド、URLなどが含まれます。フォーマットは設定可能です:

# デフォルトの複合フォーマットを使用する
access_log /var/log/squid/access.log squid

# またはパフォーマンスが重要な環境ではログを無効化する
# access_log none

検証と監視

プロキシのテスト

クライアントマシンからプロキシの環境変数を設定し、curlでテストします:

# このシェルセッションにプロキシを設定する
export http_proxy="http://192.168.1.100:3128"
export https_proxy="http://192.168.1.100:3128"

# プロキシ経由で接続をテストする
curl -v http://example.com

# 送信元IPを確認する(プロキシサーバーのIPになっているはず)
curl http://ifconfig.me

ブロックが期待どおりに機能しているか確認します:

curl -v http://facebook.com
# 期待する結果:403 Forbidden(アクセス拒否)

キャッシュヒット率の確認

最も重要な指標はキャッシュヒット率です。Squidはキャッシュマネージャー経由でリアルタイムの統計を公開しています:

# プロキシサーバー自身からキャッシュ統計を確認する
squidclient -h 127.0.0.1 -p 3128 mgr:info

# またはヒット関連のカウンターだけを絞り込む
squidclient -h 127.0.0.1 -p 3128 mgr:counters | grep hit

一般的な企業環境では、キャッシュが温まった後のヒット率は20〜50%程度が目安です。最も効果的なチューニングポイントはrefresh_patternの調整です。apt/yumのアップデートが多いネットワークでは、.deb.rpmPackages.gzファイル向けの専用パターンを追加するだけで、ヒット率が15%から40%以上に向上することもあります。

アクセスログのリアルタイム確認

トラフィックをリアルタイムで監視します

sudo tail -f /var/log/squid/access.log

各行はこのような形式になっています:

1712550000.123    245 192.168.1.42 TCP_MISS/200 15234 GET http://example.com/ - DIRECT/93.184.216.34 text/html

TCP_MISSはオブジェクトがキャッシュされておらず、オリジンから取得されたことを意味します。TCP_HITはキャッシュから提供されたことを意味します。キャッシュが蓄積されるにつれて、この2番目の値が増えていくのを観察しましょう。

awkによるログ分析

リクエスト数の多いドメインを素早く集計します:

sudo awk '{print $7}' /var/log/squid/access.log | \
  grep -oP '(?<=://)([^/]+)' | \
  sort | uniq -c | sort -rn | head -20

IPアドレス別の帯域幅消費量トップ:

sudo awk '{print $3, $5}' /var/log/squid/access.log | \
  awk '{arr[$1]+=$2} END {for (i in arr) print arr[i], i}' | \
  sort -rn | head -10

再起動なしで設定をリロードする

squid.confを編集した後は、適用前に必ず構文を検証します:

# 設定の構文を検証する
sudo squid -k parse

# 接続を切らずにリロードする
sudo squid -k reconfigure

# またはsystemctlを使う
sudo systemctl reload squid

よくあるつまずきポイント

  • HTTPS透過インターセプトにはSSLバンプと認証局のセットアップが必要で、通常のHTTPプロキシよりもはるかに複雑なプロセスです。また、多くの地域で法的・プライバシー上の問題もあります。本当に必要かどうかをよく検討してから進めましょう。
  • キャッシュディレクトリのパーミッション:Squidはproxyユーザーとして動作します。cache_dirにカスタムパスを指定する場合は、Squid起動前にchown proxy:proxy /your/cache/pathを実行してください。そうしないとキャッシュへの書き込みがサイレントに失敗します。
  • MTUの不一致:クライアントの断続的な接続障害はMTUの問題が原因であることがあります。ip link show eth0で確認し、必要に応じてip link set eth0 mtu 1400で調整してください。
  • パッケージマネージャー向けのrefresh_pattern:apt/yumリポジトリをキャッシュする場合は、.deb.rpmPackages.gzファイル向けの専用パターンをより長いTTLで追加してください。デフォルトのパターンでは、これらを十分にキャッシュしてくれません。
Share: