proxy

squidでフォワードプロキシを構築する

こんにちは、こんばんは鹿せんべいです。

squidを用いてラズパイにフォワードプロキシを構築してみた。

ラズパイでは色々遊んでいるので興味がある人は関連の記事もどうぞ。

背景

特に背景らしい背景もないのだが、強いていうならセキュリティの向上だろうか。

自宅のIPを固定にしたので、あまり外部に自宅のIPを漏らしたくない、という想いがあった。

そしてwebサーバーなどを外部に公開している訳ではないので、リバースプロキシではなくまずはフォワードプロキシの構築を試みた次第だ。

apacheのmod_proxyを用いるかsquidを用いるかを少し悩んだ。squidがシンプルそうだったので、squidを選択した。

できたこと、できなかったこと

まずはじめにできたことを述べようと思う。なぜならば僕がやりたかったことの20%くらいしか達成できていないため、タイトルだけだと誤解を招く恐れがあるからである。

  • できたこと
    ・HTTP通信に対応したプロキシの構築
  • できなかったこと
    ・HTTPS通信に対応したプロキシの構築
    ・自宅のIPの隠蔽

まあご覧の通りほとんど何もできていない。今後の活動に期待を寄せるばかりである。

得られた知見としては、まず自宅のIPを隠蔽したいのであれば、自宅のネットワーク外にプロキシサーバを構築しなければならないということ。当然である。企業などで接続するサイトの制限やアクセスログなどを取りたい場合には同じネットワーク内でいい。僕の目的に照らした場合、自宅のネットワーク内に構築したとて、プロキシサーバのIPは隠せないので意味がないのである。

またプロキシを挟んだHTTPS通信はやや手間がかかりそうである。しかし不可能ではなさそうだ。気が向いたら、構築したい。

このご時世にHTTPにのみ対応したプロキシを構築したいという酔狂な方はなかなか稀有だと思われるが、もし該当する場合は引き続き読んでほしい。

環境

  • プロキシサーバ:ラズパイ(Raspberry Pi 4 Model B)
    • OS: Raspbian3.3.1
  • squid:version4.6
  • クライアント側:MacBook Pro
    • プロセッサ名: Intel Core i5
    • メモリ: 8 GB
    • OS: version10.13.6

構築

squidのインストール

早速ラズパイにsquidをインストールする。

pi@raspberrypi:~ $ sudo apt-get update
pi@raspberrypi:~ $ sudo apt-get upgrade
pi@raspberrypi:~ $ sudo apt-get install squid

squid.confの初期設定

/etc/squid/のディレクトリにあるsquid.confファイルに設定を加えていく。

・・・わけなんだけれども、恐ろしいくらいこのファイルには記述がある。ほとんどは説明でコメントアウトされているのだが。この説明さえ読めば設定ができると思う。

だが記述を加えるためには見にくいことこの上ない。コメントアウトされている行は全て削除する。

pi@raspberrypi:~ $ vi /etc/squid/squid.conf

viのコマンドでファイルの編集に入る。

以下のコマンドを入力し”#”から始まる行≒コメントアウトされている行を全て空行に変換する。

:%s/#.*

続いて以下のコマンドを入力し、空行を全て削除する。

:v/\S/d

すると以下のように実にスッキリしたファイルになる。

acl localnet src 0.0.0.1-0.255.255.255  # RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8             # RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10          # RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16         # RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12          # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16         # RFC 1918 local private network (LAN)
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
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
include /etc/squid/conf.d/*
http_access allow localhost
http_access deny all
http_port 3128
coredump_dir /var/spool/squid
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

いくつか設定を加えていく。順番に設定を加えて変化を見ていくので、手っ取り早く設定したい場合は最後まで飛ばした方がいいかもしれない。

まずは”http_access allow localnet”の設定を加える。

acl localnet src 0.0.0.1-0.255.255.255  # RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8             # RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10          # RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16         # RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12          # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16         # RFC 1918 local private network (LAN)
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
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
include /etc/squid/conf.d/*
http_access allow localhost

# 追加ここから
http_access allow localnet
# 追加ここまで

http_access deny all
http_port 3128
coredump_dir /var/spool/squid
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

まあ見たまんまだがlocalnetのアクセスを許可する。具体的にはファイルの初めの8行の設定に関して許可をする。

acl localnet src 0.0.0.1-0.255.255.255 # RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8 # RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10 # RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16 # RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12 # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16 # RFC 1918 local private network (LAN)
acl localnet src fc00::/7 # RFC 4193 local private network range
acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines

またファイルにはhttp_portとして3128番が設定されている。必要に応じて変更してほしい。※今回は変更しない。

http_port 3128

なんとこれで最低限の設定は完了した。

viから:wqなどで上書き保存し、閉じる。

squidを再起動させ、今加えたsquid.confの設定を読み込ませる。

pi@raspberrypi:~ $ sudo systemctl restart squid

そもそも起動していない場合は以下のコマンド。

pi@raspberrypi:~ $ sudo systemctl start squid

statusのコマンドを入力し、以下のようにActive:active(running)となっていればsquidが起動している。

pi@raspberrypi:~ $ sudo systemctl status squid
● squid.service - Squid Web Proxy Server
   Loaded: loaded (/lib/systemd/system/squid.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2020-07-xx 17:55:55 JST; 4h 12min ago

Mac側の設定

ネットワーク環境設定を開く。

Wi-Fiを選択し、詳細…をクリック。

プロキシのタブからWebプロキシ(HTTP)を選択。WebプロキシサーバのIPアドレス(僕の場合はラズパイのサーバーのアドレス)とportの番号を入力する。入力できたら、右下のOKをクリック。

適用をクリックする。

Mac側の設定は完了した。

動作の確認

プロキシの確認のためには診断くん(http://taruo.net/e/)を利用する。よく使うサイトは確認くん(https://www.ugtop.com/spill.shtml)だが、HTTPSに対応しているため、今回の構築範囲ではプロキシを確認することができない。

アクセスすると以下のような情報が表示される。

中程のHTTP_VIAを見ると、ラズパイのsquidを通ってサイトにアクセスしていることがわかる。

squidのアクセスログでも確認ができる。

pi@raspberrypi:~ $ tail -f /var/log/squid/access.log

上記コマンドを入力した後、再度診断くんにアクセスすると、以下のようなアクセスログが増えるのがわかる。

192.168.0.105 TCP_REFRESH_MODIFIED/200 4226 GET http://taruo.net/e/? - HIER_DIRECT/59.106.174.199 text/html

これで最低限のプロキシの設定は完了した。ここからはプロキシへのアクセス元(ここでは僕のMac)の情報を隠蔽していこう。

情報の秘匿の設定

まずはモロに出ている情報を消していきたい。

HTTP_X_FORWARDED_FOR 192.168.0.105
HTTP_VIA 1.1 raspberry(squid/4.6)

の2つの情報だ。これは同一のネットワーク内のアクセスのためローカルIPが見えているが、別のネットワークのプロキシサーバにアクセスしている場合は、グローバルIPが見えてしまっていることになる。なんのためのプロキシなのかさっぱりわからないという状況になる。

情報を隠すために以下の記述を/etc/squid/squid.confに加える。

request_header_access X-Forwarded-For deny all
request_header_access Via deny all
acl localnet src 0.0.0.1-0.255.255.255  # RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8             # RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10          # RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16         # RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12          # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16         # RFC 1918 local private network (LAN)
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
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
include /etc/squid/conf.d/*
http_access allow localhost
http_access allow localnet
http_access deny all
http_port 3128
coredump_dir /var/spool/squid
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
# 追加ここから
request_header_access X-Forwarded-For deny all
request_header_access Via deny all
# 追加ここまで

squidを再起動しconfの更新を読み込ませ、診断くんにアクセスする。

無事に情報が消えている。

HTTP_CACHE_CONTROLの情報も隠すことができるらしいので、その設定も追加する。

request_header_access Cache-Control deny all
acl localnet src 0.0.0.1-0.255.255.255  # RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8             # RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10          # RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16         # RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12          # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16         # RFC 1918 local private network (LAN)
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
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
include /etc/squid/conf.d/*
http_access allow localhost
http_access allow localnet
http_access deny all
http_port 3128
coredump_dir /var/spool/squid
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
request_header_access X-Forwarded-For deny all
request_header_access Via deny all
# 追加ここから
request_header_access Cache-Control deny all
# 追加ここまで

squidを再起動しconfの更新を読み込ませ、診断くんにアクセスする。

消えた。

HTTP_USER_AGENTの情報も隠すことができるそうだ。

ミニマリストもびっくりの断捨離具合である。

request_header_access user-agent deny all
acl localnet src 0.0.0.1-0.255.255.255  # RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8             # RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10          # RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16         # RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12          # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16         # RFC 1918 local private network (LAN)
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
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
include /etc/squid/conf.d/*
http_access allow localhost
http_access allow localnet
http_access deny all
http_port 3128
coredump_dir /var/spool/squid
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
request_header_access X-Forwarded-For deny all
request_header_access Via deny all
request_header_access Cache-Control deny all
# 追加ここから
request_header_access user-agent deny all
# 追加ここまで

squidを再起動しconfの更新を読み込ませ、診断くんにアクセスする。

消えた。ここまでスッキリしたら、洗濯機や冷蔵庫なども捨ててしまう過激派のミニマリストもにっこりだろう。

十分に隠蔽できることはわかったが、色々調べて出てきた設定もまじないとして加えておく。

暇があったら、検証してみたい。

acl localnet src 0.0.0.1-0.255.255.255  # RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8             # RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10          # RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16         # RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12          # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16         # RFC 1918 local private network (LAN)
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
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
include /etc/squid/conf.d/*
http_access allow localhost
http_access allow localnet
http_access deny all
http_port 3128
coredump_dir /var/spool/squid
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

request_header_access X-Forwarded-For deny all
request_header_access Via deny all
request_header_access Cache-Control deny all
request_header_access user-agent deny all
# 追加ここから
request_header_access referer deny all

reply_header_access X-Forwarded-For deny all
reply_header_access Via deny all
reply_header_access Cache-Control deny all

visible_hostname unknown
# 追加ここまで

まとめ

HTTPのプロキシサーバを構築したわけだが、僕の使用用途に置いて自宅のネットワーク内に構築することは全く意味のないことだということがわかった。

VPN経由で自宅のネットワークにアクセスし、再度インターネットに抜ける際にはプロキシサーバを経由しないこともわかった。

今後の課題として以下をあげる。

  • HTTPSの通信に対応すること
  • 自宅のネットワーク外にプロキシサーバを構築し、本来の目的を達成すること
  • VPN経由でアクセスした際にもプロキシを通ってインターネットアクセスしたい。

ガシガシ対応していきたい。以上だ。

よければtwitterのフォローください。