はじめに
細かな動作については未検証のため、本番ネットワークに組み込む際は十分検証の上実装してください。
記載されている内容を実施して事故っても(インターネットに繋がらないなど)責任を負いかねます。
環境
- サーバ冗長化はしない
- サーバにはLinux OSを使用
- ネットワーク的にはすべて同セグにする
- DHCPサーバにはラズパイ4を使用(部屋の中で転がってたやつ)
- DHCPサーバとHTTPサーバ(
proxy.pac
配るだけ)は同じラズパイ上で動作 - 処理を軽くするためHTTPサーバはnginx
- Proxyサーバはキャッシュしたりさせるので、RAM/SSD容量そこそこ積んだ元デスクトップPC
- DHCPサーバ: Linux/Ubuntu/5.4.0-1122-raspi/isc-dhcpd-4.4.1 with nginx/1.18.0
$ dhcpd --version isc-dhcpd-4.4.1 $ nginx -v nginx version: nginx/1.18.0 (Ubuntu)
- Proxyサーバ: Linux/Almalinux/4.18.0-553.37.1.el8_10.x86_64/squid-4.15
$ squid -v Squid Cache: Version 4.15
- Proxyサーバにしているサーバでは他にもいろんなプロセスが動いているが割愛
通信イメージ
実際にはもっと細かいですがだいぶ端折ってます
Client Server
-------- --------
| |
[1] | -----------------> |
| (DHCP Discover) |
| |
[2] | <----------------- |
| (DHCP Offer) |
| |
[3] | -----------------> |
| (DHCP Request) |
| |
[4] | <----------------- |
| (DHCP ACK) |
| \ (Option 252) |
| |
[5] | -----------------> |
| (HTTP REQUEST) |
| \ (GET proxy.pac) |
| |
[6] | <----------------- |
| (HTTP Response) |
| \ (proxy.pac) |
| |
[7] | <----------------> |
| (via Proxy) |
| |
サーバ
インストールは割愛。
苦じゃないはずなのでパッケージ管理ツールごとのやつで入れればいいかと。
DHCPサーバの設定
-
#
以降はコメント -
DHCP Option 252は標準で設定項目として無い?ので項目を定義(未確認)
(option wpad-proxy-server code 252 = text;
)
- iOS系(Apple OS)は
Option 252
ではなく、Option 128
やOption 66
,Option 120
らしい。 - Option 128は
echo "192.168.1.25" | openssl enc -base64
のように BASE64 でエンコードする必要があるらしい
- Proxyサーバのアドレス+ファイルパスをDHCP Option 252(If: Windows)で通知
(option wpad-proxy-server "http://172.18.3.10/proxy.pac";
) - 登録外のMACアドレスにはアドレスを配らないよう設定
(deny unknown-clients;
) - 自称権威DHCPサーバとして設定
(authoritative;
) - DDNSはそもそもDNSサーバ動いてないので無し
(ddns-update-style none;
) - tftpとかvoipの設定はもう使ってないけど残してる(過去にIP-PBX立ててた)
(option tftp-server-name "172.18.3.1";
)
(option voip-tftp-server 172.18.3.1;
)
もともと定義されていないDHCP Optionは定義すれば使えそう
使いそうなのは、Option 82(DHCP Relay-agent)とか Option 150(Cisco Voip-TFTP-Address)
/etc/dhcp/dhcpd.conf
#
# DHCP Server Configuration file.
# see /usr/share/doc/dhcp*/dhcpd.conf.example
# see dhcpd.conf(5) man page
#
# Config files test command is dhcpd -t
#
default-lease-time 86400; # 1 day
max-lease-time 259200; # 3 days
#log-facility daemon;
log-facility local1;
ddns-update-style none;
authoritative;
option voip-tftp-server code 150 = { ip-address };
option wpad-proxy-server code 252 = text;
option domain-name-servers 1.1.1.1, 1.0.0.1;
subnet 172.17.0.0 netmask 255.255.0.0 {
# Docker network
not authoritative;
}
subnet 172.18.0.0 netmask 255.255.252.0 {
# Honban network
range dynamic-bootp 172.18.0.1 172.18.0.254;
#option routers 172.18.0.1;
option routers 172.18.3.254;
option broadcast-address 172.18.3.255;
option domain-name "n138.local";
option domain-name-servers 1.1.1.1, 1.0.0.1; #Cloudflare(master), Cloudflare(backup)
option netbios-name-servers 172.18.3.1;
option wpad-proxy-server "http://172.18.3.10/proxy.pac";
option log-servers 172.18.3.1;
option tftp-server-name "172.18.3.1";
option voip-tftp-server 172.18.3.1;
deny unknown-clients;
}
# known-clients
host apple_iPhone-01 { hardware ethernet F4:BE:EC:00:00:01; }
host apple_iPhone-02 { hardware ethernet F4:BE:EC:00:00:02; }
HTTPサーバの設定
- nginxインストールしてサービス自動起動するようしただけ
systemctl enable --now nginx
- 特に設定していない
プロキシ自動設定ファイル proxy.pac
-
FindProxyForURL()
関数の名前は固定(大文字小文字区別するので正しく記述)-
isPlainHostName()
はURIのホスト名部分(http://www.google.com/hoge/foo/index.html)にピリオド(.
)がないとTrue
(isFQDN()みたいな?)-
http://www.google.com/hoge/foo/index.html
->False
-
http://www/hoge/foo/index.html
->True
-
-
isInNet()
はセグメント単位でチェックしマッチすればTrue
- CIDRのような形式でなくてもOK(bit 1が連続しなくてもOK)
-
isInNet(host, "192.168.0.0", "255.255.15.0)
でも良いらしい - 管理しやすくするならサブネットマスクと同じ形式を個人的に推奨
-
- CIDRのような形式でなくてもOK(bit 1が連続しなくてもOK)
-
- Javascript形式で記述
- その他の定義済みの関数は下記ページ参照
/var/www/html/proxy.pac
function FindProxyForURL(url, host)
{
if (isPlainHostName (host)) {
return "DIRECT";
}
if (isInNet(host, "172.16.0.0", "255.240.0.0")) {
/* Local-Class-B 172.16.0.0/12 **/
return "DIRECT";
}
return "PROXY 172.18.3.1:3128";
}
Proxyサーバの設定
- デフォルトの設定にキャッシュの設定など追加しただけ。
cache_mem 8 GB
coredump_dir /var/spool/squid
- DHCP連携の設定は無い(DHCPサーバの設定が主)
- squidGuard連携してたりするけど、今回の記事の内容から外れるので割愛
url_rewrite_program /usr/bin/squidGuard -c /etc/squid/squidGuard.conf
/etc/squid/squid.conf
#
# 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 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
(以下略)
Refs