CentOS Stream 9でのSquid Proxy Serverのインストールと設定ガイド:SELinuxとfirewalldを使った企業内ネットワークのインターネットアクセス制御

CentOS tutorial - IT technology blog
CentOS tutorial - IT technology blog

背景:企業がSquid Proxyを必要とする場面とは?

はじめてSquidに触れたのは、物流会社でsysadminをしていたころのことです。当時、ITチームはHRから「勤務中に社員がYouTubeを見ている、帯域を使い果たしてビデオ会議が常にラグる」というクレームを受けていました。そこで導入したのがSquid Proxyです——午前中のうちに問題を解決できました。

Squid Proxy Serverを使うと、通常のルーターではできないことが実現できます:

  • ドメインによるアクセス制御:リストに基づいてYouTube、Facebook、TikTokをブロックしたり、必要なサイトのみをホワイトリストで許可したりできる
  • 時間帯によるアクセス制御:昼休み中はSNSを許可し、それ以外の時間帯はブロックできる
  • コンテンツのキャッシュ:複数の端末が同じファイルをダウンロードしても、インターネットへのアクセスは1回だけ——帯域幅を大幅に節約できる
  • 詳細な監査ログ:どの端末のどのIPがいつ何のサイトにアクセスしたかを正確に把握できる
  • 内部IPの隠蔽:クライアントはプロキシのIPを経由してインターネットに出るため、社内ネットワークのトポロジーが外部に漏れない

弊社にはまだCentOS 7で動いているサーバーが数台あり、AlmaLinuxへの移行はすでに対応済みです。ただ、負荷の少ないプロキシサーバーについては、サポートサイクルが明確でRHELエコシステムとの互換性が高いという理由から、チームはCentOS Stream 9を選択し続けています。この記事では、Squidをゼロから構築する手順を解説します。SELinuxとfirewalldの設定も含みます——RHEL/CentOSに初めて触れるエンジニアが最も頭を抱えがちな部分です。

CentOS Stream 9へのSquidのインストール

ステップ1:システムのアップデートとSquidのインストール

まずシステムをアップデートし、CentOS Stream 9のデフォルトリポジトリからSquidをインストールします:

sudo dnf update -y
sudo dnf install squid -y

インストールしたバージョンを確認します:

squid -v

ビルド情報が出力され、Squid Cache: Version 5.xという行が含まれています。

ステップ2:サービスの起動と自動起動の有効化

sudo systemctl enable squid --now
sudo systemctl status squid

Active: active (running)と表示されていれば正常です。Squidはデフォルトでポート3128でリッスンします。

Squidの詳細設定

シンプルな設定ファイルの作成

デフォルトの/etc/squid/squid.confは約7000行ものコメントがあります。私はバックアップを取ってから、管理しやすいようにシンプルな設定ファイルを書き直すようにしています:

sudo cp /etc/squid/squid.conf /etc/squid/squid.conf.backup
sudo nano /etc/squid/squid.conf

企業環境向けの標準的な設定内容を貼り付けます:

# ============================================================
# Squid Proxy - エンタープライズ設定
# CentOS Stream 9
# ============================================================

# リッスンポート
http_port 3128

# === ACL:内部ネットワークの定義 ===
acl localnet src 192.168.0.0/16
acl localnet src 10.0.0.0/8
acl localnet src 172.16.0.0/12

# 標準ACL
acl SSL_ports port 443
acl Safe_ports port 80 443 8080 8443 21 70 210 280 488 591 777
acl CONNECT method CONNECT

# === ACL:ブロックするドメインリスト ===
acl blocked_sites dstdomain "/etc/squid/blocked_sites.txt"

# === ルール ===
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny blocked_sites
http_access allow localnet
http_access allow localhost
http_access deny all

# === キャッシュ ===
cache_dir ufs /var/spool/squid 1024 16 256
maximum_object_size 50 MB
cache_mem 256 MB

# === ログ ===
access_log /var/log/squid/access.log squid
cache_log /var/log/squid/cache.log

# サーバー情報を隠す
via off
forwarded_for off
httpd_suppress_version_string on

ブロックするウェブサイトリストの作成

sudo nano /etc/squid/blocked_sites.txt

設定例:

.youtube.com
.facebook.com
.tiktok.com
.netflix.com
.instagram.com

注意:ドメインの前にピリオド.を付けると、サブドメインも含めてブロックされます——例えば.youtube.comとすると、www.youtube.comm.youtube.commusic.youtube.comもすべてブロックされます。

勤務時間帯に基づいたACLの設定

実際のユースケース:昼休み(12時〜13時)はSNSを許可し、それ以外の時間帯はブロックする:

# squid.confに追加(ルールセクションの前)

# 勤務時間:月〜金、8時〜12時と13時〜18時
acl working_hours time MTWHF 08:00-12:00
acl working_hours time MTWHF 13:00-18:00

# 昼休み
acl lunch_break time MTWHF 12:00-13:00

# SNSドメイン
acl social_media dstdomain .facebook.com .youtube.com .tiktok.com

# 適用ルール:
http_access deny social_media working_hours
http_access allow social_media lunch_break localnet

SquidのSELinux設定

多くの人が見落として「設定は合っているのにSquidが動かない」と悩む部分がここです。CentOS Stream 9ではSELinuxがデフォルトでEnforcingモードになっています。

状態を確認します:

getenforce
# 出力:Enforcing

SquidにはいくつかのSELinux権限が必要です。ポート3128はデフォルトでSELinuxに許可されていますが、別のポート(例:8080)に変更したい場合:

# squid_port_tポリシーにポート8080を追加
sudo semanage port -a -t squid_port_t -p tcp 8080

# 再確認
sudo semanage port -l | grep squid

Squidが非標準ポート(例:上流プロキシ)に接続する必要がある場合は、このブール値を有効にします:

sudo setsebool -P squid_connect_any 1

permission deniedエラーが発生し、SELinuxが何をブロックしているか不明な場合は、次の方法で素早くデバッグできます:

# 最近のdenialのauditログを確認
sudo ausearch -c 'squid' --raw | audit2allow -M my-squid

# 作成したポリシーを適用
sudo semodule -i my-squid.pp

firewalldの設定

社内ネットワークのクライアントがプロキシに接続できるよう、ポート3128を開放します:

# firewalldに組み込みのsquidサービスを使う(より簡単)
sudo firewall-cmd --zone=internal --add-service=squid --permanent

# またはポートを直接開放する場合
sudo firewall-cmd --zone=internal --add-port=3128/tcp --permanent

# 反映
sudo firewall-cmd --reload

# internalゾーンを確認
sudo firewall-cmd --zone=internal --list-all

社内ネットワークのインターフェースがどのゾーンに属しているか確認し、必要であればinternalゾーンに移動します:

# 各インターフェースのゾーンを確認
sudo firewall-cmd --get-active-zones

# 例:eth1が内部ネットワークのインターフェースの場合
sudo firewall-cmd --zone=internal --add-interface=eth1 --permanent
sudo firewall-cmd --reload

設定の検証とSquidの再起動

再起動前に必ずシンタックスを確認しましょう——設定ミスでサービスが起動しなくなるのを防ぐためです:

# 設定ファイルを解析して確認
sudo squid -k parse

# エラーがなければ再起動
sudo systemctl restart squid

動作確認とモニタリング

クライアントからのプロキシ動作テスト

社内ネットワークのクライアント端末からcurlを使ってプロキシ経由でテストします(192.168.1.100をSquidが動いているサーバーの実際のIPに変更してください):

# 通常アクセスのテスト
curl -x http://192.168.1.100:3128 http://example.com -I
# 期待される結果:HTTP/1.1 200 OK

# ドメインブロックのテスト
curl -x http://192.168.1.100:3128 http://www.youtube.com -I
# 期待される結果:HTTP/1.1 403 Forbidden

リアルタイムのログ確認

Squidのアクセスログにはすべてのアクティビティが記録されます——監査における主要な情報源です:

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

各ログ行の形式は以下の通りです:

1720123456.789  1234 192.168.1.50 TCP_MISS/200 5432 GET http://example.com/ - DIRECT/93.184.216.34 text/html
  • 1720123456.789:Unixタイムスタンプ
  • 1234:処理時間(ミリ秒)
  • 192.168.1.50:クライアントIP
  • TCP_MISS/200:キャッシュミス、サーバーがHTTP 200を返した
  • GET http://example.com/:HTTPメソッドと完全なURL

Squidの統計情報の確認

# 概要統計
sudo squidclient -h localhost mgr:info

# キャッシュヒット率
sudo squidclient -h localhost mgr:counters | grep -i hit

アクセス数の多いドメインを調べるスクリプト

管理者への週次レポートを作成する際に便利です:

#!/bin/bash
# 現在のログでアクセス数の多いドメインTOP 10
cat /var/log/squid/access.log | \
  awk '{print $7}' | \
  sed 's|http[s]*://||' | \
  cut -d'/' -f1 | \
  sort | uniq -c | \
  sort -rn | \
  head -10

ログローテーションの設定

ユーザー数の多い環境では、Squidのログは数日で数GBに膨れ上がることがあります。logrotateを設定して自動クリーニングを行いましょう:

sudo nano /etc/logrotate.d/squid
/var/log/squid/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    postrotate
        /usr/sbin/squid -k rotate
    endscript
}

よくあるエラーと対処法

Squidが起動しない——permissionエラー:

# SELinuxがブロックしていないか確認
sudo ausearch -m avc -ts recent | grep squid

# クイックデバッグ:一時的にpermissiveに設定(テスト用のみ、本番環境では使用しないこと)
sudo setenforce 0
sudo systemctl restart squid
# 動作すればSELinuxが原因——audit2allowで正しく修正する
sudo setenforce 1

クライアントがプロキシ経由で接続できない:

# Squidがリッスンしているポートを確認
sudo ss -tlnp | grep squid

# ファイアウォールがブロックしていないか確認
sudo firewall-cmd --list-all --zone=internal

# クライアントからプロキシへtelnetで接続テスト
telnet 192.168.1.100 3128

Squidのセットアップが完了してシステムが安定稼働したら、次に私がよくやるのはtransparent proxyへの移行です——クライアント側でプロキシの設定が不要になり、iptablesのリダイレクトによってすべてのHTTPトラフィックが自動的にSquidを経由するようになります。ただし、これはHTTPSトラフィックをインスペクトするためのSSL bumpと組み合わせる必要があり、より複雑な話になります——別の記事でご紹介します。

Share: