本ブログでは、ちょいちょいプロキシ環境下での設定方法を紹介しているが、
そういったプロキシ環境下での動作の検証のため、以下を満たすプロキシサーバーを立てたい。
- OS は Ubuntu 24.04
- squid によって 8080 ポートにて HTTP プロキシする
- bind9 によって自身のアドレスを proxy.example.com として名前解決する DNS サーバーとなる
とりあえず、 squid と bind9 をいれて、設定ファイルを必要最低限書き換えてみよう。
export CURRENT_IP_ADDRESS=`hostname -I | tr -s ' ' '\n' | tail -n 1`
sudo apt update
sudo apt -y install squid bind9 bind9utils
sudo sed -i -r -e 's/^(#\s?)?(http_access allow localnet)/\2/' -e 's/^http_port 3128/http_port 8080/' /etc/squid/squid.conf
sudo sed -i -e 's%^\s*\(//\)\?\s*forwarders {% forwarders {\n 8.8.8.8;\n };\n\0%' -e 's%^};%\0\nzone "proxy.example.com" in {\n type master;\n file "proxy.example.com.zone";\n};%' /etc/bind/named.conf.options
sudo tee /var/cache/bind/proxy.example.com.zone << EOF > /dev/null
\$TTL 86400
@ IN SOA proxy.example.com. root.proxy.example.com. (
2023070301 ;Serial
3600 ;Refresh
1800 ;Retry
604800 ;Expire
86400 ;Minimum TTL
)
@ IN NS proxy.example.com.
@ IN A $CURRENT_IP_ADDRESS
EOF
sudo systemctl restart squid named
これだけ。
解説
環境変数 CURRENT_IP_ADDRESS
は hostname -I
コマンドで自身の IPアドレス の一つを設定しているが、あらかじめアドレスがわかっているなら、手動で設定しても良い。
プロキシでの動作を検証したい VM と、上記のプロキシ VM を、(Hyper-V の場合)「内部ネットワーク」または「プライベートネットワーク」の仮想スイッチに接続させる。
検証対象 VM の IP アドレスは同じサブネットになるように設定し、 DNS のアドレスも上記プロキシ VM のものを設定する。
一方、プロキシ VM のほうは、 Default Switch と 前述の『「内部ネットワーク」または「プライベートネットワーク」』の両方の仮想スイッチに繋いで、直接インターネット側にも出られるようにしておく。
architecture-beta
service internet(cloud)[Internet]
group host(server)[Host PC]
service winnat(cloud)[WinNAT Default Switch] in host
internet:B -- T:winnat
group vms(database)[VMs] in host
service vm1(server)[proxy] in vms
service inlsw(cloud)[Internal Switch] in vms
service vm2(server)[target] in vms
winnat:B -- T:vm1
vm1:R -- L:inlsw
inlsw:R -- L:vm2
このように繋ぐことで、プロキシ経由を想定した通信のテストが行える。
検証したい VM の方は netplan などで、 DNS サーバーとして bind9 を入れたサーバーを指すように設定しておく。
sudo vim /etc/netplan/50-cloud-init.yaml
network:
ethernets:
eth0:
dhcp4: false
dhcp6: false
addresses:
# proxy を通した検証をしたい対象自身のアドレス
- 192.168.193.55/24
nameservers:
addresses:
# bind9 をいれたサーバーのアドレス
- 192.168.193.53
version: 2
vim で設定を書き換えたら netplan apply して有効にする。
sudo netplan apply
この状態で、以下のように実行し、
$ export http_proxy=http://proxy.example.com:8080; export https_proxy=$http_proxy
$ curl https://example.com/ -v
プロキシを通して https://example.com の HTML が返されれば成功だ。
* Uses proxy env variable https_proxy == 'http://proxy.example.com:8080'
* Host proxy.example.com:8080 was resolved.
...
* Connected to proxy.example.com (192.168.192.53) port 8080
* CONNECT tunnel: HTTP/1.1 negotiated
* allocate connect buffer
* Establish HTTP proxy tunnel to example.com:443
> CONNECT example.com:443 HTTP/1.1
> Host: example.com:443
> User-Agent: curl/8.5.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
<
...
<!doctype html>
<html>
<head>
<title>Example Domain</title>
...
なお、 Ubuntu で上述の target のようにオンライン状態になっていないネットワークにのみ繋がっていると、 OS 起動時に systemd-networkd-wait-online.service のチェックで強制的に2分待たされる。
これが鬱陶しい場合は、以下の記事のように systemd-networkd-wait-online の待機を回避すると良い。
応用① 多段プロキシ
もし、多段プロキシする場合、以下のように /etc/squid/squid.conf
に追記しよう。
dns_nameservers
にはアクセス可能なイントラネットの DNS アドレスを、 cache_peer
の第1引数と第3引数には親となるプロキシサーバーのアドレスとポートを、それぞれ指定する。
$ sudo tee -a /etc/squid/squid.conf << EOF > /dev/null
# for multi step proxy
dns_nameservers 8.8.8.8 8.8.4.4
cache_peer parent-proxy.example.com parent 8080 0 no-query
never_direct allow all
forwarded_for off
request_header_access Via deny all
request_header_access X-Forwarded-For deny all
request_header_access Cache-Control deny all
cache deny all
EOF
squid サービスを再起動すれば、設定が反映される。
(以降、 /etc/squid/squid.conf
を書き換える度同じ)
sudo systemctl restart squid
応用② ログの出力先と内容を変更する
ログの出力先を /var/log/squid/access.log
の代わりに journal に記録してみよう。
また、更にログの書式 (logformat
) をデフォルトの squid
から combined
にしたければ、以下のように /etc/squid/squid.conf
を書き換えよう。
sudo sed -i -r -e 's/^(#\s?)?(access_log daemon:.*$)/access_log syslog:local7.info combined/' /etc/squid/squid.conf
journal に記録したログは、 journalctl
を使って以下のようにリアルタイムでアクセスしている様子が見られる。
journalctl -u squid -f
デフォルト (squid
) では、
1733237904.267 552 192.168.192.55 TCP_TUNNEL/200 6035 CONNECT example.com:443 - HIER_DIRECT/93.184.215.14 -
のようなログ書式だったのが
192.168.192.55 - - [03/Dec/2024:14:56:34 +0000] "CONNECT example.com:443 HTTP/1.1" 200 6035 "-" "curl/8.5.0" TCP_TUNNEL:HIER_DIRECT
のような書式に変わる。
応用③ 複数のポートの待ち受け
更に /etc/squid/squid.conf
の設定を更に書き換えてカスタムな書式を設定すれば、ログにどのポートでアクセスされたのか書き出す事もできる。 1
http_port 8080
http_port 8081
http_port 8082
http_port 8083
logformat combined-with-client %>a %[ui %[un [%tl] %la:%lp "%rm %ru HTTP/%rv" %>Hs %<st "%{Referer}>h" "%{User-Agent}>h" %Ss:%Sh
access_log syslog:local7.info combined-with-client
cache deny all
squid は複数のポートで同時にプロキシを待ち受けられるので、 例えば「アプリケーションの設定ファイル」と「環境変数」で異なるポート番号でプロキシを設定しておき、 journalctl
でリアルタイムで監視しながら使用し、どちらの設定にてプロキシされているのか確認したり…といった使い方ができる。
-
デフォルトの書式や、カスタムフォーマット詳しい書式は squid : logformat configuration directive を参照。 ↩