Amazon EC2(Amazon Linux2) でWeb Proxy(squid利用）を構築する

そこそこのIT環境がある企業だとWebアクセスにProxyを利用しているところも多いと思います。最近だとi-fileterやZscalerなんかのクラウド型Proxyが流行りみたいですが、なかなか良いお値段します...そこでさくっとお試しできるOSSのProxyサービスのsquidを設定・検証してみます。

# squidとは
>Squid（スクウィッド）とは、HTTP/1.0と、（ほぼ全ての）HTTP/1.1 の仕様を満たし、HTTP、HTTPS、FTPなどをサポートするオープンソースのWebプロキシサーバです。
>Squidは、複数のWebサーバの前段に配置し、クライアントからの重複したリクエストをキャッシュし、Webサーバの代わりにレスポンスを行うことでサーバの負荷を分散させ、クライアントの要求に対して高速で安定したパフォーマンスを提供することができます。
また、ネットワーク内のクライアントからのアクセスを、Squidが中継することによって、アクセス制御や、ロギング環境を提供します。

[出典]



[Squid とは？](https://openstandia.jp/oss_info/squid/)

# 今回のゴール
- クライアントのWebアクセスをsquidを設定したサーバ経由にする（フォワードプロキシ）
- クライアントのWebアクセスのログを取得する
- クライアントから特定のサイトへのアクセスをブロックする

# イメージ図
![squid_構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/448e3010-6c3a-35c4-f3d9-ba7e6268f952.png)

EC2(proxy)=10.0.0.202
EC2(クライアント)=10.0.0.27


# 前提条件
- squidを設定するサーバはEC2(Amazon Linux2)
- クライアントはEC2（windowsOS）とする
- squidのバージョンはv3.5
- squidを設定するEC2はパブリックサブネットにデプロイする
- クライアントからのWebアクセスがsquidを経由しているかはアクセスソースIPがsquidを設定したEC2のグローバルIPかで判断する


# 手順
① squidを設定するEC2(Amazon Linux2)をパブリックサブネットへデプロイする
② Proxy用のEC2にsquidをインストールし、設定する
③ クライアント用別EC2(WindowsOS)を同一VPCにデプロイする
④ クライアントからWebアクセスし、アクセス元ソースIPおよびログを確認する 

# 実際にやってみた
①は他に詳しい記事がありますので本記事では割愛します。とりあえずEC2へSSHでき、Rootに昇格できればOKです。
それでは②から開始します。

    #まずはsquid をインストールする
    yum -y install squid

    #squidを起動
    systemctl start squid

    #squidを起動時に自動起動するように設定
    systemctl enable squid

    #squidが動作しているか、利用ポート番号（デフォルトでは3128）を確認
    lsof -i:3128
    COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    squid   5549 squid   11u  IPv6  58260      0t0  TCP *:squid (LISTEN)
    上記のように3128ポートでsquid(LISTEN)で表示されていればOK

これでsquidのインストールは完了です。続いてsquidのデフォルト設定から試験用に何個か設定を修正していきます。
## squidの設定ファイルの修正
squidの設定ファイルは/etc/squid/squid.confなので、このファイルを修正していきます。

    vim /etc/squid/squid.conf

    1 # Recommended minimum configuration
    2 #
    3
    4 # Example rule allowing access from your local networks.
    5 # Adapt to list your (internal) IP networks from where browsing
    6 # should be allowed
    7 acl localnet src 10.0.0.0/8     # RFC1918 possible internal network
    8 #acl localnet src 172.16.0.0/12 # RFC1918 possible internal network
    9 #acl localnet src 192.168.0.0/16        # RFC1918 possible internal network
    10 acl localnet src fc00::/7       # RFC 4193 local private network range
    11 acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines
    12
    13 acl SSL_ports port 443
    14 acl Safe_ports port 80          # http
    15 acl Safe_ports port 21          # ftp
    16 acl Safe_ports port 443         # https
    17 acl Safe_ports port 70          # gopher
    18 acl Safe_ports port 210         # wais
    19 acl Safe_ports port 1025-65535  # unregistered ports
    20 acl Safe_ports port 280         # http-mgmt
    21 acl Safe_ports port 488         # gss-http
    22 acl Safe_ports port 591         # filemaker
    23 acl Safe_ports port 777         # multiling http
    24 acl CONNECT method CONNECT
    25
    26
    27
    28 #
    29 # Recommended minimum Access Permission configuration:
    30 #
    31 # Deny requests to certain unsafe ports
    32 http_access deny !Safe_ports
    33
    34 # Deny CONNECT to other than secure SSL ports
    35 http_access deny CONNECT !SSL_ports
    36
    37 # Only allow cachemgr access from localhost
    38 http_access allow localhost manager
    39 http_access deny manager
    40
    41 # We strongly recommend the following be uncommented to protect innocent
    42 # web applications running on the proxy server who think the only
    43 # one who can access services on "localhost" is a local user
    44 #http_access deny to_localhost
    45
    46 #
    47 # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
    48 #
    49
    50 # Example rule allowing access from your local networks.
    51 # Adapt localnet in the ACL section to list your (internal) IP networks
    52 # from where browsing should be allowed
    53 http_access allow localnet
    54 http_access allow localhost
    55
    56 # And finally deny all other access to this proxy
    57 http_access deny all
    58
    59 # Squid normally listens to port 3128
    60 http_port 3128
    61                                                          
    62 # Uncomment and adjust the following to add a disk cache directory.
    63 cache_dir ufs /var/spool/squid 100 16 256
    64
    65 # Leave coredumps in the first cache dir
    66 coredump_dir /var/spool/squid
    67
    68 #
    69 # Add any of your own refresh_pattern entries above these.
    70 #
    71 refresh_pattern ^ftp:           1440    20%    10080
    72 refresh_pattern ^gopher:        1440   0%      1440
    73 refresh_pattern -i (/cgi-bin/|\?) 0     0%     0
    74 refresh_pattern .               0       20%    4320

【変更した箇所】
8行目と9行目：今回のNWは10.0.0.0/24なので172.160.0/12や192.168.0.0/16からのアクセス許可は不要ですので先頭に[#]を付けてコメントアウトさせておきます。
63行目：cashを使えるように先頭の[#]を消しておきます。

これだけでとりあえずはproxyとして利用することはできるようになりました。

だたこれだけだとproxyを利用できるソースIPを「acl localnet src 10.0.0.0/8」で10.0.0.0/8に制限しただけで、この範囲のホストであればproxy経由でhttpおよびhttpsでどこにでもアクセスできてしまいます。今回はブラックリスト型のウェブアクセスフィルターを設定して、特定のドメインにだけアクセスできないようにしたいと思います。

## ブラックリスト型ウェブフィルターの設定
試しにyahoo.co.jpへのアクセスを制限する設定をしたいと思います。/etc/squid/squid.confに直接ブラックリストを記入してもいいですが、ブラックリストで指定したいドメインが増えるとそれをすべて記載しないといけないので、別途「blacklist」というファイルを作り、それを参照してアクセス制限するようにしたいと思います。
    
    #/etc/squid/squid.confを修正
    vi /etc/squid/squid.conf

    ~~~最上位に以下を追記~~
    #ブラックリストファイル（/etc/squid/blacklist）を参照するように設定
    acl blacklist dstdomain "/etc/squid/blacklist"

    #blacklist内ドメインへのアクセスを拒否  
    http_access deny blacklist

    #すべてのアクセスを許可  
    http_access allow all  

aclは上から順番に評価されていきます。必要なソースからアクセスが許可されるようにaclを登録してください。

イメージ図
![スライド4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/583703a8-bd20-7962-b5ca-1362d951cf62.png)

次に/etc/squid/blacklistを作成して、yahoo.co.jpを禁止ドメインとして記載します。
    
    #/etc/squid/へ移動
    cd /etc/squid/

    #blacklistというファイルを作成
    touch blacklist

    #blacklistの中身を記述
    vi blacklist
     ~以下を記載~
    .yahoo.co.jp

先頭に「.」を付けてサブドメインも含む形にします。

記載が完了したら設定反映のためsquidをサービス再起動します。

    systemctl restart squid

続いて③のクライアント用別EC2(WindowsOS)を同一VPCにデプロイですが、これも特に変わった設定はないので割愛します。

最後に④クライアントからWebアクセスし、アクセス元ソースIPおよびログの確認をしてみます。
まず③で作成したクライアント用別EC2(WindowsOS)にRDPして、Webブラウザーにproxyの設定を投入します。
Googlechrom では以下のように設定します。

![スライド2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/9bd55db6-e585-5a5f-a6c3-0755cd6a129e.png)

アドレスはsquidを設定したEC2のもの
ポート番号はlsofコマンドで表示された番号（デフォルトで3128）
上記proxyの設定が完了した状態で、Webブラウザーを起動すればproxy経由でアクセスされるはずです。

## 設定の確認
proxy経由でアクセスされていることを確認するため、ブラウザーアクセスのソースIPがどこになっているか確認したいと思います。
方法は単純で、クライアント用別EC2のWebブラウザーで「https://www.cman.jp/network/support/go_access.cgi」 にアクセスしてください。
ソースIPが表示されるので、そのIPがクライアント用別EC2(WindowsOS)のElaticIPではなく、squidを設定したEC2のElaticIPであればちゃんとproxy経由でアクセスされています。

イメージ図
![スライド1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/e15b7a9e-7583-ab62-4c96-16b776a06355.png)

またブラックリスト登録したyahoo.co.jpにアクセスしてみましょう。おそらく「このサイトにアクセスできません」的なメッセージが表示されれると思います。

## squidのログの確認
squidのログはデフォルトで「/var/log/access.log」になります。
catコマンドで普通に開くと膨大な量が表示されるので、yahoo.co.jpへのアクセスが拒否されたログだけ表示させたいと思います。

    #/var/log/access.logから「TCP_DENIED」となったログをピックアップ
    cat /var/log/access.log | grep TCP_DENIED

以下のようにアクセス拒否のログが出てくると思います。
![squid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/77837034-9282-3b7f-003c-086a3387af5e.png)

# 最後に
有料ライセンス製品ではないので困ったときに問い合わせできる窓口がないのは辛いですが、最低限の設定だけなら何とかなりそうな気もしますね。まぁ夏休みの自由研究がてら、ぼちぼち勉強するしかないか...


# 参考にしたサイト
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/networking_guide/configuring-the-squid-caching-proxy-server

https://nwengblog.com/squidfilter/