「直接インターネットには出ていって欲しくない。許可した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
で定義した範囲(もしくはそれ以外[!]
)ものをallow
かdeny
か選択します。
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によるインターネットアクセス制限でした。
コメント