HTTPプロキシを使った検証を行いたかったので、簡単に作成できるHTTP/HTTPSプロキシとしてSquidを設定しまし。そのときのメモになります。
TOC
Squidをインストール
バージョンにこだわりがないので、aptでインストールします。
sudo apt install squid
Squidの初期設定
初期設定は、/etc/squid/squid.conf
に記述されています。
$ cat /etc/squid/squid.conf | grep -v "^\s*#" | grep -v "^$"
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 \/(Packages|Sources)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims
refresh_pattern \/Release(|\.gpg)$ 0 0% 0 refresh-ims
refresh_pattern \/InRelease$ 0 0% 0 refresh-ims
refresh_pattern \/(Translation-.*)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims
refresh_pattern . 0 20% 4320
この状態だと、下記の2行によりローカルホストからのリクエストだけを許可しています。
http_access allow localhost
http_access deny all
Squidの簡単な設定
ローカルネットワークからの許可と受け付けるポートの変更を行います。
ローカルネットワークからの許可
LANのCIDRが192.168.11.0/24
なので、そのネットワークのみ許可するようにします。
acl lan src 192.168.11.0/24
http_access allow lan
上から評価されるので、http_access deny all
の前に挿入します。
受け付けるポートの変更
初期設定では下記の行で3128ポートで受け付けています。この数字を8080に変更することでポートを変更可能です。
http_port 3128
最終的な設定
上記を設定すると最終的な/etc/squid/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 lan src 192.168.11.0/24
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 lan
http_access deny all
http_port 8080
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 \/(Packages|Sources)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims
refresh_pattern \/Release(|\.gpg)$ 0 0% 0 refresh-ims
refresh_pattern \/InRelease$ 0 0% 0 refresh-ims
refresh_pattern \/(Translation-.*)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims
refresh_pattern . 0 20% 4320
設定の有効化と確認
サービスを再起動します。
sudo systemctl restart squid
続いて、状態を確認します。
sudo systemctl status squid
下記のようにactive (running)
となっていれば動作しています。
$ 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 Fri 2021-08-27 14:02:04 UTC; 16s ago
Docs: man:squid(8)
Process: 3285 ExecStartPre=/usr/sbin/squid --foreground -z (code=exited, status=0/SUCCESS)
Process: 3303 ExecStart=/usr/sbin/squid -sYC (code=exited, status=0/SUCCESS)
Main PID: 3309 (squid)
Tasks: 4 (limit: 4617)
Memory: 16.1M
CGroup: /system.slice/squid.service
├─3309 /usr/sbin/squid -sYC
├─3311 (squid-1) --kid squid-1 -sYC
├─3312 (logfile-daemon) /var/log/squid/access.log
└─3313 (pinger)
Aug 27 14:02:04 http-proxy squid[3311]: Max Swap size: 0 KB
Aug 27 14:02:04 http-proxy squid[3311]: Using Least Load store dir selection
Aug 27 14:02:04 http-proxy squid[3311]: Set Current Directory to /var/spool/squid
Aug 27 14:02:04 http-proxy squid[3311]: Finished loading MIME types and icons.
Aug 27 14:02:04 http-proxy squid[3311]: HTCP Disabled.
Aug 27 14:02:04 http-proxy squid[3311]: Pinger socket opened on FD 14
Aug 27 14:02:04 http-proxy squid[3311]: Squid plugin modules loaded: 0
Aug 27 14:02:04 http-proxy squid[3311]: Adaptation support is off.
Aug 27 14:02:04 http-proxy squid[3311]: Accepting HTTP Socket connections at local=[::]:8080 remote=[::] FD 12 flags=9
Aug 27 14:02:05 http-proxy squid[3311]: storeLateRelease: released 0 objects
また、受け付けているポートに8080も表示されているはずです。
~$ ss -tln
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 256 *:8080 *:*
LISTEN 0 128 [::]:22 [::]:*
Squidのテスト
curlを使って他のUbuntuホストから動作確認をします。
HTTPリクエスト
テスト用にhttp://httpbin.org
を使用しています。
- テストコマンド
http_proxy=http://192.168.11.31:8080 curl -vvv http://httpbin.org/user-agent
- テスト結果
$ http_proxy=http://192.168.11.31:8080 curl -vvv http://httpbin.org/user-agent
* Uses proxy env variable http_proxy == 'http://192.168.11.31:8080'
* Trying 192.168.11.31:8080...
* TCP_NODELAY set
* Connected to 192.168.11.31 (192.168.11.31) port 8080 (#0)
> GET http://httpbin.org/user-agent HTTP/1.1
> Host: httpbin.org
> User-Agent: curl/7.68.0
> Accept: */*
> Proxy-Connection: Keep-Alive
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Fri, 27 Aug 2021 14:13:45 GMT
< Content-Type: application/json
< Content-Length: 34
< Server: gunicorn/19.9.0
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true
< X-Cache: MISS from http-proxy
< X-Cache-Lookup: HIT from http-proxy:8080
< Via: 1.1 http-proxy (squid/4.10)
< Connection: keep-alive
<
{
"user-agent": "curl/7.68.0"
}
* Connection #0 to host 192.168.11.31 left intact
squidの動いているサーバにてアクセスログが/var/log/squid/access.log
で確認できます。
1630073622.294 336 192.168.11.21 TCP_MISS/200 371 GET http://httpbin.org/user-agent - HIER_DIRECT/3.232.173.151 application/json
ちなみに失敗した場合は下記のようになります。
$ http_proxy=http://192.168.11.31:8080 curl -vvv http://httpbin.org/user-agent
* Uses proxy env variable http_proxy == 'http://192.168.11.31:8080'
* Trying 192.168.11.31:8080...
* TCP_NODELAY set
* Connected to 192.168.11.31 (192.168.11.31) port 8080 (#0)
> GET http://httpbin.org/user-agent HTTP/1.1
> Host: httpbin.org
> User-Agent: curl/7.68.0
> Accept: */*
> Proxy-Connection: Keep-Alive
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 403 Forbidden
< Server: squid/4.10
< Mime-Version: 1.0
< Date: Fri, 27 Aug 2021 14:14:36 GMT
< Content-Type: text/html;charset=utf-8
< Content-Length: 3536
< X-Squid-Error: ERR_ACCESS_DENIED 0
< Vary: Accept-Language
< Content-Language: en
< X-Cache: MISS from http-proxy
< X-Cache-Lookup: NONE from http-proxy:8080
< Via: 1.1 http-proxy (squid/4.10)
< Connection: keep-alive
<
<snip>
ログは以下のようにです。
1630073676.818 0 192.168.10.32 TCP_DENIED/403 3912 GET http://httpbin.org/user-agent - HIER_NONE/- text/html
HTTPSについて
HTTPの部分をHTTPSに変更して実行します。
- テストコマンド
https_proxy=http://192.168.11.31:8080 curl -vvv https://httpbin.org/user-agent
- テスト結果
$ https_proxy=http://192.168.11.31:8080 curl -vvv https://httpbin.org/user-agent
* Uses proxy env variable https_proxy == 'http://192.168.11.31:8080'
* Trying 192.168.11.31:8080...
* TCP_NODELAY set
* Connected to 192.168.11.31 (192.168.11.31) port 8080 (#0)
* allocate connect buffer!
* Establish HTTP proxy tunnel to httpbin.org:443
> CONNECT httpbin.org:443 HTTP/1.1
> Host: httpbin.org:443
> User-Agent: curl/7.68.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
<
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CONNECT phase completed!
* CONNECT phase completed!
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=httpbin.org
* start date: Dec 21 00:00:00 2020 GMT
* expire date: Jan 19 23:59:59 2022 GMT
* subjectAltName: host "httpbin.org" matched cert's "httpbin.org"
* issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55e65ffb1e10)
> GET /user-agent HTTP/2
> Host: httpbin.org
> user-agent: curl/7.68.0
> accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200
< date: Fri, 27 Aug 2021 14:16:20 GMT
< content-type: application/json
< content-length: 34
< server: gunicorn/19.9.0
< access-control-allow-origin: *
< access-control-allow-credentials: true
<
{
"user-agent": "curl/7.68.0"
}
* Connection #0 to host 192.168.11.31 left intact
squidサーバでは下記のようなログがでます。
1630073780.444 707 192.168.11.21 TCP_TUNNEL/200 5717 CONNECT httpbin.org:443 - HIER_DIRECT/52.7.174.100 -
失敗の場合のログです。
$ https_proxy=http://192.168.11.31:8080 curl -vvv https://httpbin.org/user-agent
* Uses proxy env variable https_proxy == 'http://192.168.11.31:8080'
* Trying 192.168.11.31:8080...
* TCP_NODELAY set
* Connected to 192.168.11.31 (192.168.11.31) port 8080 (#0)
* allocate connect buffer!
* Establish HTTP proxy tunnel to httpbin.org:443
> CONNECT httpbin.org:443 HTTP/1.1
> Host: httpbin.org:443
> User-Agent: curl/7.68.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 403 Forbidden
< Server: squid/4.10
< Mime-Version: 1.0
< Date: Fri, 27 Aug 2021 14:17:58 GMT
< Content-Type: text/html;charset=utf-8
< Content-Length: 3494
< X-Squid-Error: ERR_ACCESS_DENIED 0
< Vary: Accept-Language
< Content-Language: en
< X-Cache: MISS from http-proxy
< X-Cache-Lookup: NONE from http-proxy:8080
< Via: 1.1 http-proxy (squid/4.10)
< Connection: keep-alive
<
* Received HTTP code 403 from proxy after CONNECT
* CONNECT phase completed!
* Closing connection 0
curl: (56) Received HTTP code 403 from proxy after CONNECT
ログは下記のとおりです。
1630073878.055 0 192.168.10.32 TCP_DENIED/403 3870 CONNECT httpbin.org:443 - HIER_NONE/- text/html