Squidによるインターネットアクセス制限

「直接インターネットには出ていって欲しくない。許可したURLにだけに絞って接続できるようにする。」と言った設定をしたいとします。

そんな時にSquidというものを使ってプロキシサーバーを構築すると手取り早くHTTP通信の制限ができます。

で、手取り早くやりたいが故に、Docker HubからSquidの公式イメージ取ってきて、色々検証してから導入したいですよね。

しかし、Docker Hubに公式イメージないんですよね。

なので色々なページを参考にDockerfileを作成しました。

今回作成したDockerfileですが、どういう仕様のSquidかというと、「whitelist」というファイルにURLを記載するだけで、URL制限できるホワイトリスト方式の設定が入ったSquidを作ったので記録として残していきたいと思います。

スポンサーリンク

準備

前提条件

「squid_dir」というディレクトリにDockfile、squid.conf、whitelistというファイルを用意します。

Dockerビルドするときはこのファイルがある前提でビルドします。

squid_dir
 L Dockerfile
 L squid.conf
 L whitelist

Dockerfileの作成

まずは、Dockerfileを作成していきます。

ベースは、centosです。

FROM centos:centos7

ENV TZ='Asia/Tokyo'

RUN yum update -y
RUN yum install -y squid
RUN yum install -y vim

COPY squid.conf /etc/squid/
COPY whitelist /etc/squid/

RUN /usr/sbin/squid -N -z

EXPOSE 3128
CMD ["/usr/sbin/squid", "-N", "-f", "/etc/squid/squid.conf"]

RUNの部分とかはイケていないかもしれませんが、そこは各々いい感じにしてください。

12行目:一回Squidを空回しします。これは、最初に起動時にキャッシュディレクトリを作ります。おまじない的な。

15行目:-fオプションでファイルsquid.confを指定して起動します。ここはファイル名がデフォルトのsquid.confなら不要ですが、あえて明示している感じです。

繰り返しになってしまいますが、ここで使っているSquidのオプションの簡単な説明をしますと

  • -N:デーモンプロセスにならないように起動
  • -z:スワップディレクトリ(キャッシュディレクトリ)を作成。初めてSquidを実行する時に実行必要あり。
  • -f {FILE_NAME}:指定した設定ファイルを利用して起動。デフォルトはsquid.conf

参考:3.7 Squidの起動時のオプションを教えてください。

squid.confの設定

続いてsquid.confの設定です。ビルド時にこのファイルがコピーされるので、必ずDockerfileと同じディレクトリに配置してください。

#
# Recommended minimum configuration:
#

# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localnet src 10.0.0.0/8	# RFC1918 possible internal network
acl localnet src 172.16.0.0/12	# RFC1918 possible internal network
acl localnet src 192.168.0.0/16	# RFC1918 possible internal network
acl localnet src fc00::/7       # RFC 4193 local private network range
acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines

acl SSL_ports port 443
acl Safe_ports port 80		# http
acl Safe_ports port 21		# ftp
acl Safe_ports port 443		# https
acl Safe_ports port 70		# gopher
acl Safe_ports port 210		# wais
acl Safe_ports port 1025-65535	# unregistered ports
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 CONNECT method CONNECT

#
# Recommended minimum Access Permission configuration:
#
# Deny requests to certain unsafe ports
http_access deny !Safe_ports

# Deny CONNECT to other than secure SSL ports
http_access deny CONNECT !SSL_ports

# Only allow cachemgr access from localhost
http_access allow localhost manager
http_access deny manager

# We strongly recommend the following be uncommented to protect innocent
# web applications running on the proxy server who think the only
# one who can access services on "localhost" is a local user
#http_access deny to_localhost

#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#
acl whitelist dstdomain "/etc/squid/whitelist"  # 追記:whitelist設定
http_access allow whitelist                     # 追記:whitelist設定

# Example rule allowing access from your local networks.
# Adapt localnet in the ACL section to list your (internal) IP networks
# from where browsing should be allowed
http_access deny !localnet    # 変更:http_access allow localnetから
http_access allow localhost

# And finally deny all other access to this proxy
http_access deny all

# Squid normally listens to port 3128
http_port 3128

# Uncomment and adjust the following to add a disk cache directory.
#cache_dir ufs /var/spool/squid 100 16 256

# Leave coredumps in the first cache dir
coredump_dir /var/spool/squid

#
# Add any of your own refresh_pattern entries above these.
#
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

基本的に、squid.confの内容をそのまま使っており、http_accessの部分だけ変更及び追記しました。この部分は、上から順番に評価指定行くので、他の設定をする場合は順番に注意して設定しましょう。

変更、追記した部分に関して、

52行目:ローカルネット以外のアクセスを制限しております。

このように記述することで、localnetをでない(!)を拒否する(deny)という意味になります。localnetとはなんぞやというと、acl部分で定義されております。すなわち8〜12行目で定義されており、内容を見るとlocalnetはローカルIPアドレスを持つIPと定義されております。

http_access allow|deny [!]acl

簡単に説明すると、alcで定義した範囲(もしくはそれ以外[!])ものをallowdenyか選択します。

55, 56行目:ホワイトリストファイルを用いた制限についての設定を付加しております。

上記で説明したようにaclでwhitelistがなんぞやを定義して、dstdomainは宛先ドメイン( destination domain)は、/etc/squid/whitelistに記載しているやつ見てねと記載しております。

そして、それを先ほどと同じようにhttp_accessにaclで定義したwhitelistは許可と設定を記載します。

これで、squid.confの設定はおしまいです。

ホワイトリストの設定

次に、ホワイトリストの設定です。

ホワイトリストは先ほどのdstdomainで定義したように許可したいドメインを一行ずつ記載していきましょう。

.google.com

.google.com」と記載すればサブドメインは指定せず許可する設定もできます。

ホワイトリストの設定はこれだけです。

スポンサーリンク

構築

いざ構築していきます。

先ほど作ったファイルを同じディレクトリに配置します。そしてビルドします。

イメージ作成

% docker build -t centos/squid .
---
[+] Building 2.2s (12/12) FINISHED                                              
 => [internal] load build definition from Dockerfile                       0.0s
 => => transferring dockerfile: 312B                                       0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s
 => [internal] load metadata for docker.io/library/centos:centos7          1.7s
 => [1/7] FROM docker.io/library/centos:centos7@sha256:0f4ec88e21daf75124  0.0s
 => [internal] load build context                                          0.0s
 => => transferring context: 2.60kB                                        0.0s
 => CACHED [2/7] RUN yum update -y                                         0.0s
 => CACHED [3/7] RUN yum install -y squid                                  0.0s
 => CACHED [4/7] RUN yum install -y vim                                    0.0s
 => [5/7] COPY squid.conf /etc/squid/                                      0.0s
 => [6/7] COPY whitelist /etc/squid/                                       0.0s
 => [7/7] RUN /usr/sbin/squid -N -z                                        0.3s
 => exporting to image                                                     0.1s
 => => exporting layers                                                    0.1s
 => => writing image sha256:6db5ab5fbe929672be17cf692c6f0105685bdff385263  0.0s
 => => naming to docker.io/centos/squid                                    0.0s

イメージ名は、centos/squidにしました。これのlatestがイメージとして作成されます。

コンテナ起動

% docker run -p 3128:3128 -itd --privileged centos/squid
---
7784d2517e6da404f9b4b0d4ee626a37b131a18e28af7542c853dbe5b3efd4a9

次に、centos/squidを起動してみます。その際、squid.confで定義したポートも空けて起動します。

これで完了です。docker psで確認してみると、squidが無事起動してそうです。

masaki@mini squid % docker ps
% docker ps
---
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
9e51e196aa57        centos/squid        "/usr/sbin/squid -N …"   4 minutes ago       Up 4 minutes        0.0.0.0:3128->3128/tcp   unruffled_joliot

動作確認

それではどんな挙動になるか動作確認していきます。

想定としては、プロキシを通さないと、いろんなwebサイトにアクセスできます。プロキシを通すとアクセスできるものとできないものが出てきます。

今回は、ホワイトリストに.google.comを記載しているので、これは通るはずです。それ以外は通らないはず。という想定です。まずは、curlコマンドで確認していきましょう。

プロキシを通さない場合

% curl https://www.google.com
---
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ja"><head><meta content="世界中のあらゆる情報を検索するため&#...以下省略

何かコンテンツが表示されています。

同様に他のURLも試してみましょう。

% curl https://www.google.co.jp
---
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ja"><head><meta content="???E???̂???????????????邽?߂̃c?[????񋟂??Ă??܂??B???܂??܂Ȍ????@?\?????p???āA???T???̏??????‚??Ă????????B" name="description"....以下省略

ちょっと文字化けしてますが、同じようにコンテンツが表示されていることが確認できます。

次に同じURLでプロキシを通した時にどうなるか確認していきましょう。

まずは、curlコマンドでプロキシを通す方法ですが、以下のようにオプションを付けます。

% curl {URL} -x {PROXY_SERVER}:{PORT}

-x {PROXY_SERVER}:{PORT}でプロキシサーバーを通すオプションとなります。

今回はdockerでローカルでポートは3128で起動しているので localhost:3128でプロキシを通すことになります。

プロキシ通した場合(ホワイトリストに登録されているURL)

% curl https://www.google.com -x localhost:3128
---
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ja"><head><meta content="世界中のあらゆる情報を検索するため&#...以下省略

無事表示できました。大丈夫そうですね。ホワイトリストに記載していたから、いつも通りコンテンツが表示されました。

では、ホワイトリストに登録されていないURLはどうなるでしょう。

プロキシを通した場合(ホワイトリストに登録されていないURL)

% curl https://www.google.co.jp -x localhost:3128
---
curl: (56) Received HTTP code 403 from proxy after CONNECT

はい、表示できませんでした。プロキシを通すことでホワイトリストをこのように仕分けてくれます。

このようにして、内部リソースからインターネットへの外部アクセスする際にアクセスを制限することができます。

以上、Squidによるインターネットアクセス制限でした。

コメント

タイトルとURLをコピーしました