2年近くproxyすらないネットに繋がらない環境にいて、少し前にようやくパブリッククラウドの自由ないんたーねっとを手に入れたぜうっひょーと思ったら、今度はついにproxy環境での検証をすることになったので、自宅ラボにも似たような構成作れないか、Squidでproxyサーバーを立ててみました。
せっかくなのでDockerで。
完成予定図はこんな感じ。
- Squidを手作業で動かしてみる on Docker
- 制限ネットワークからproxy設定してwebアクセス
- Squidバージョン
- イメージ作成
- Docker Hubから
- 課題 (ログ)
- おまけ (9/6追記)
Squidを手作業で動かしてみる on Docker
なんとなくCentOS 7で、検証用コンテナを起動。
どうせ8080/TCP使うだろうから、publishもしておく。
[zaki@manager-dev squid]$ sudo docker run -p 8080:8080 -it centos:7 bash [root@0e3f3daa90ba /]#
Squidインストール
[root@0e3f3daa90ba /]# yum install squid : : Installed: squid.x86_64 7:3.5.20-15.el7_8.1 Dependency Installed: groff-base.x86_64 0:1.22.2-8.el7 libecap.x86_64 0:1.0.0-1.el7 libtool-ltdl.x86_64 0:2.4.2-22.el7_3 perl.x86_64 4:5.16.3-295.el7 perl-Carp.noarch 0:1.26-244.el7 perl-Compress-Raw-Bzip2.x86_64 0:2.061-3.el7 perl-Compress-Raw-Zlib.x86_64 1:2.061-4.el7 perl-DBI.x86_64 0:1.627-4.el7 perl-Data-Dumper.x86_64 0:2.145-3.el7 perl-Digest.noarch 0:1.17-245.el7 perl-Digest-MD5.x86_64 0:2.52-3.el7 perl-Encode.x86_64 0:2.51-7.el7 perl-Exporter.noarch 0:5.68-3.el7 perl-File-Path.noarch 0:2.09-2.el7 perl-File-Temp.noarch 0:0.23.01-3.el7 perl-Filter.x86_64 0:1.49-3.el7 perl-Getopt-Long.noarch 0:2.40-3.el7 perl-HTTP-Tiny.noarch 0:0.033-3.el7 perl-IO-Compress.noarch 0:2.061-2.el7 perl-Net-Daemon.noarch 0:0.48-5.el7 perl-PathTools.x86_64 0:3.40-5.el7 perl-PlRPC.noarch 0:0.2020-14.el7 perl-Pod-Escapes.noarch 1:1.04-295.el7 perl-Pod-Perldoc.noarch 0:3.20-4.el7 perl-Pod-Simple.noarch 1:3.28-4.el7 perl-Pod-Usage.noarch 0:1.63-3.el7 perl-Scalar-List-Utils.x86_64 0:1.27-248.el7 perl-Socket.x86_64 0:2.010-5.el7 perl-Storable.x86_64 0:2.45-3.el7 perl-Text-ParseWords.noarch 0:3.29-4.el7 perl-Time-HiRes.x86_64 4:1.9725-3.el7 perl-Time-Local.noarch 0:1.2300-2.el7 perl-constant.noarch 0:1.27-2.el7 perl-libs.x86_64 4:5.16.3-295.el7 perl-macros.x86_64 4:5.16.3-295.el7 perl-parent.noarch 1:0.225-244.el7 perl-podlators.noarch 0:2.5.1-3.el7 perl-threads.x86_64 0:1.87-4.el7 perl-threads-shared.x86_64 0:1.43-6.el7 squid-migration-script.x86_64 7:3.5.20-15.el7_8.1 Complete! [root@0e3f3daa90ba /]#
使い方を確認
[root@0e3f3daa90ba /]# squid --help squid: invalid option -- '-' Usage: squid [-cdhvzCFNRVYX] [-n name] [-s | -l facility] [-f config-file] [-[au] port] [-k signal] -a port Specify HTTP port number (default: 3128). -d level Write debugging to stderr also. -f file Use given config-file instead of /etc/squid/squid.conf -h Print help message. -k reconfigure|rotate|shutdown|restart|interrupt|kill|debug|check|parse Parse configuration file, then send signal to running copy (except -k parse) and exit. -n name Specify service name to use for service operations default is: squid. -s | -l facility Enable logging to syslog. -u port Specify ICP port number (default: 3130), disable with 0. -v Print version. -z Create missing swap directories and then exit. -C Do not catch fatal signals. -D OBSOLETE. Scheduled for removal. -F Don't serve any requests until store is rebuilt. -N No daemon mode. -R Do not set REUSEADDR on port. -S Double-check swap during rebuild. -X Force full debugging. -Y Only return UDP_HIT or UDP_MISS_NOFETCH during fast reload. [root@0e3f3daa90ba /]#
--help
じゃなくて-help
らしい。
まぁそれは置いておいて、設定は/etc/squid/squid.conf
# Squid normally listens to port 3128 http_port 3128
設定で「おや?」と思ったのはここ。
てっきり8080/TCPだと思ったけど、Squidのデフォルトは3128らしい。
Dockerの起動オプションで8080にしてしまったのでちょっと変更。
[root@0e3f3daa90ba /]# sed -ie 's/3128/8080/' /etc/squid/squid.conf
とりあえず起動してみる。
[root@0e3f3daa90ba /]# squid squid[86]: Squid Parent: will start 1 kids squid[86]: Squid Parent: (squid-1) process 88 started [root@0e3f3daa90ba /]#
あら、バックグラウンドで起動するらしい
-N No daemon mode.
これかな。
[root@0e3f3daa90ba /]# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 11828 1956 pts/0 Ss 12:07 0:00 bash root 86 0.0 0.0 83808 3704 ? Ss 12:19 0:00 squid squid 88 0.1 4.1 670380 160864 ? S 12:19 0:00 (squid-1) squid 89 0.0 0.0 27440 1244 ? S 12:19 0:00 (logfile-daemon) /var/log/squid/access.log root 93 0.0 0.0 51756 1720 pts/0 R+ 12:20 0:00 ps aux [root@0e3f3daa90ba /]# [root@0e3f3daa90ba /]# [root@0e3f3daa90ba /]# [root@0e3f3daa90ba /]# kill $(cat /var/run/squid.pid)
しばらく待つと停止する。
[root@0e3f3daa90ba /]# squid[86]: Squid Parent: (squid-1) process 88 exited with status 0 [root@0e3f3daa90ba /]# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 11828 1964 pts/0 Ss 12:07 0:00 bash root 100 0.0 0.0 51756 1708 pts/0 R+ 12:22 0:00 ps aux
気を取り直して-N
付与して、
[root@0e3f3daa90ba /]# squid -N
ホストOSで見ると以下の通り。
[zaki@manager-dev ~]$ ss -anptl | grep 8080 LISTEN 0 128 [::]:8080 [::]:* [zaki@manager-dev ~]$
ちなみにこの状態で8080にブラウザでアクセスするとこんな感じ。
制限ネットワークからproxy設定してwebアクセス
[zaki@centos1 ~]$ curl www.google.com curl: (7) Failed to connect to 2404:6800:4004:81e::2004: ネットワークに届きません [zaki@centos1 ~]$ curl www.yahoo.co.jp curl: (7) Failed connect to www.yahoo.co.jp:80; ホストへの経路がありません [zaki@centos1 ~]$
この通り繋がらないネットワークになってる。
ここでproxy指定すると
[zaki@centos1 ~]$ curl -I https://www.yahoo.co.jp -x 172.29.0.11:8080 HTTP/1.1 200 Connection established HTTP/1.1 200 OK Content-Length: 0 Content-Type: text/html; charset=utf-8 Date: Fri, 04 Sep 2020 12:31:05 GMT Etag: W/"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk" Set-Cookie: B=dgpradhfl4cs9&b=3&s=m0; expires=Mon, 05-Sep-2022 12:31:05 GMT; path=/; domain=.yahoo.co.jp Vary: Accept-Encoding X-Vcap-Request-Id: 892db93b-de68-434b-7b62-9414b8a950c5 X-Xss-Protection: 1; mode=block Age: 0 Connection: keep-alive Via: http/1.1 edge2503.img.umd.yahoo.co.jp (ApacheTrafficServer [c sSf ]) Server: ATS [zaki@centos1 ~]$ [zaki@centos1 ~]$ [zaki@centos1 ~]$ curl -I https://www.google.com -x 172.29.0.11:8080 HTTP/1.1 200 Connection established HTTP/1.1 200 OK Content-Type: text/html; charset=ISO-8859-1 P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info." Date: Fri, 04 Sep 2020 12:31:12 GMT Server: gws X-XSS-Protection: 0 X-Frame-Options: SAMEORIGIN Transfer-Encoding: chunked Expires: Fri, 04 Sep 2020 12:31:12 GMT Cache-Control: private [...] [zaki@centos1 ~]$
つながった。
Squidバージョン
[root@0e3f3daa90ba /]# squid -v Squid Cache: Version 3.5.20 Service Name: squid configure options: '--build=x86_64-redhat-linux-gnu' '--host=x86_64-redhat-linux-gnu' '--program-prefix=' '--prefix=/usr' '--exec-prefix=/usr' '--bindir=/usr/bin' '--sbindir=/usr/sbin' '--sysconfdir=/etc' '--datadir=/usr/share' '--includedir=/usr/include' '--libdir=/usr/lib64' '--libexecdir=/usr/libexec' '--sharedstatedir=/var/lib' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--disable-strict-error-checking' '--exec_prefix=/usr' '--libexecdir=/usr/lib64/squid' '--localstatedir=/var' '--datadir=/usr/share/squid' '--sysconfdir=/etc/squid' '--with-logdir=$(localstatedir)/log/squid' '--with-pidfile=$(localstatedir)/run/squid.pid' '--disable-dependency-tracking' '--enable-eui' '--enable-follow-x-forwarded-for' '--enable-auth' '--enable-auth-basic=DB,LDAP,MSNT-multi-domain,NCSA,NIS,PAM,POP3,RADIUS,SASL,SMB,SMB_LM,getpwnam' '--enable-auth-ntlm=smb_lm,fake' '--enable-auth-digest=file,LDAP,eDirectory' '--enable-auth-negotiate=kerberos' '--enable-external-acl-helpers=file_userip,LDAP_group,time_quota,session,unix_group,wbinfo_group,kerberos_ldap_group' '--enable-cache-digests' '--enable-cachemgr-hostname=localhost' '--enable-delay-pools' '--enable-epoll' '--enable-ident-lookups' '--enable-linux-netfilter' '--enable-removal-policies=heap,lru' '--enable-snmp' '--enable-ssl-crtd' '--enable-storeio=aufs,diskd,rock,ufs' '--enable-wccpv2' '--enable-esi' '--enable-ecap' '--with-aio' '--with-default-user=squid' '--with-dl' '--with-openssl' '--with-pthreads' '--disable-arch-native' 'build_alias=x86_64-redhat-linux-gnu' 'host_alias=x86_64-redhat-linux-gnu' 'CFLAGS=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fpie' 'LDFLAGS=-Wl,-z,relro -pie -Wl,-z,relro -Wl,-z,now' 'CXXFLAGS=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fpie' 'PKG_CONFIG_PATH=:/usr/lib64/pkgconfig:/usr/share/pkgconfig'
ビルドオプションが表示されている。
イメージ作成
Dockerfile
チューニングとかそういのは全て置いておいて、「動かす」という1点を目的としてこんな感じ。
FROM centos:7 RUN yum install -y squid; \ sed -ie 's/3128/8080/' /etc/squid/squid.conf CMD ["/usr/sbin/squid", "-N"]
build
squid:3.5.20-centos7
というタグを設定してる。
[zaki@manager-dev 3.5.20-centos7]$ sudo docker build -t squid:3.5.20-centos7 . Sending build context to Docker daemon 2.048kB Step 1/3 : FROM centos:7 ---> 7e6257c9f8d8 Step 2/3 : RUN yum install -y squid; sed -ie 's/3128/8080/' /etc/squid/squid.conf ---> Running in e3e319e63db8 Loaded plugins: fastestmirror, ovl Determining fastest mirrors * base: ftp-srv2.kddilabs.jp * extras: ftp-srv2.kddilabs.jp * updates: ftp-srv2.kddilabs.jp [...] Step 3/3 : CMD ["/usr/sbin/squid", "-N"] ---> Running in 63f1b7b50b0a Removing intermediate container 63f1b7b50b0a ---> d7e39d9a875b Successfully built d7e39d9a875b Successfully tagged squid:3.5.20-centos7 [zaki@manager-dev 3.5.20-centos7]$
[zaki@manager-dev 3.5.20-centos7]$ sudo docker images squid REPOSITORY TAG IMAGE ID CREATED SIZE squid 3.5.20-centos7 d7e39d9a875b 28 seconds ago 345MB
できた。
run
[zaki@manager-dev 3.5.20-centos7]$ sudo docker run -d --rm -p 8080:8080 squid:3.5.20-centos7 bbd567a53fc6fdd50fce1a14873098f9e9e5db7327ec8d818ba32f2c433df2ed
この状態でリモートからproxy経由でHTTPアクセス。
[zaki@centos1 ~]$ curl -I https://www.google.com -x 172.29.0.11:8080 HTTP/1.1 200 Connection established HTTP/1.1 200 OK Content-Type: text/html; charset=ISO-8859-1 P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info." Date: Fri, 04 Sep 2020 12:50:49 GMT Server: gws X-XSS-Protection: 0 X-Frame-Options: SAMEORIGIN Transfer-Encoding: chunked Expires: Fri, 04 Sep 2020 12:50:49 GMT Cache-Control: private [...]
ちゃんと動いた。
Docker Hubから
キャッシュ消して最低限軽量化したイメージを公開しました。
次のコマンドで動きます。
$ sudo docker run -d --rm -p 8080:8080 zakihmkc/squid:3.5.20-centos7
ソースはこちら
Squidコンテナ停止中はこの通り。
[zaki@centos1 ~]$ curl -I https://www.google.com -x 172.29.0.11:8080 curl: (7) Failed connect to 172.29.0.11:8080; ホストへの経路がありません
関連ってわけじゃないけど、proxyじゃなくてルーティングするならこちら
課題 (ログ)
stdoutへ書き込み不可
ログファイルのこと忘れてて、デフォルトのまま/var/log/squid
に出力してる。
そして少し調べた感じだと、squidユーザーで動いている関係で、/dev/stdout
(これは/proc/self/fd/1
にリンクされている)への書き込みがうまくいかない。
また、動作を見る感じだと、squidプロセスが上がった後はログファイルは開きっぱなしなので、あとから/var/log/squid/access.log
をsymlinkとかに差し替えても機能しない。
ボリュームでホストOSにマウントするか、ログ出力はオフにしてsyslog転送とかにしないとコンテナは難しいかな?
メモ » logging needs to be redirected to stdout and stderr · Issue #5 · scbunn/docker-squid https://t.co/d5LDyoCEWh
— z a k i (@zaki_hmkc) 2020年9月5日
syslogは試してないけどhelpにこんなのがある。
-s | -l facility Enable logging to syslog.
syslog転送まわりはこちら
Squidのログ設定周りはここ。
SquidFaq/SquidLogs - Squid Web Proxy Wiki
出力ファイルパスを変更する場合はsquid.confで
access_log /dev/stdout
とか書く(が、動作しなかった。/tmp/squid.log
とかだと有効だけど)
回避策 (9/6追記)
コンテナ自体は(通常)rootで実行されるが、/usr/sbin/squid
を実行するとSquidプロセスはsquid
ユーザーで動くため/dev/stdout
などへ書き込み権限がないのがまずかった模様(きっちりとは調べてない)
で、単純にDockerfile
内でchmod
やchown
しても、ビルドコンテナの設定は実行時のコンテナに引き継がれないっぽいため、CMD
で実行するコマンドをsquid
でなく起動用スクリプトを用意し、その中で権限変更とSquidの起動を行うように変更。
これでstdoutへの書き込みがSquidプロセスからできるようになり、コンテナ内のログファイルをやめてdocker logs
でログが見れるようにできた。
一応、chmod
で動くのを確認してchown
に変更してみたんだけど、OpenShiftみたいにコンテナ内の実行権限は非固定にする環境もあるし、どっちがいいんだろうなぁ。
おまけ (9/6追記)
Alpineベースのイメージも作りました。
イメージサイズが、277MBだったCentOS 7ベースから15.8MBまで小さくなってワロタ…
# docker run --name squid -d --rm -p 8080:8080 zakihmkc/squid
これで動くよ。