はじめに
個人的にSquidとc-icapを連携させる機会があり、その際に手間取ったので作業メモとして記事を書きます。
設定内容としては、Squidに2台のc-icapを設定しFailoverと負荷分散(Load Distribution)を設定します。
概要
SquidはOSSのプロキシサーバーであり、c-icapはOSSのICAPサーバになります。
プロキシサーバとはHTTPリクエストの中継サーバとして使用され、ICAPサーバはプロキシサーバの機能拡張として使用されます。
例えば、プロキシサーバとICAPサーバを連携させることで、プロキシサーバ経由時にウイルススキャンを実施する等の仕組み(Server world : Squid + SquidClamav)が実現可能です。
本記事では、Squidに2台のc-icapを設定しFailoverと負荷分散(Load Distribution)を実現する設定方法を記載します。
以下、システム構成。
(本記事の最後のほうに使用したDockerfileを置いておきます。ご参考までに・・・)
Squidとc-icapを1対1で連携する
最初にSquidとc-icapを1対1で連携させてみます。
また、連携時の疎通確認方法も併せて記載いたします。
設定方法
Squidとc-icapの連携を参考に作成しました。
c-icapをインストールし起動するとicap側で/echo
が使用できます。
そのため、squid.confに以下設定を入れるだけで間単にsquidとc-icapの動作が確認できました。
icap_enable on
icap_service service_req1 reqmod_precache bypass=0 icap://icap1:1344/echo
adaptation_access service_req1 allow all
疎通確認方法
疎通確認方法としては以下の3種類かと思います。
- squid側でc-icapへのアクセスを確認する方法
- c-icap側でsquidからのアクセスを確認する方法
- c-icapの起動を状態を確認する方法
squid側でc-icapへの通信ログを確認する方法
squid側でc-icapとの連携を確認するためには、squid.confにicap_logを設定しログを出力させる必要があります。
以下設定例。
logformat icap_squid %ts.%03tu %6icap::tr %>a %icap::to/%03icap::Hs %icap::rm %icap::ru %un %icap::<A
icap_log /usr/local/squid/var/logs/icap_log icap_squid
c-icap側でsquidからのアクセスログを確認する方法
c-icap側に通信が来ていることはアクセスログを参照すれば可能です。
アクセスログの出力先がデフォルトであれ以下でコマンドで確認可能です。
[root@89c0fa076328 /]#tail -f /usr/local/c-icap/var/log/access.log
c-icapの起動を状態を確認する方法
icapが起動していることは以下コマンドで確認可能です。
[root@89c0fa076328 /]# /usr/local/c-icap/bin/c-icap-client
ICAP server:localhost, ip:127.0.0.1, port:1344
OPTIONS:
Allow 204: Yes
Preview: 1024
Keep alive: Yes
ICAP HEADERS:
ICAP/1.0 200 OK
Methods: RESPMOD, REQMOD
Service: C-ICAP/0.5.6 server - Echo demo service
ISTag: CI0001-XXXXXXXXX
Transfer-Preview: *
Options-TTL: 3600
Date: Sat, 06 Feb 2021 16:02:59 GMT
Preview: 1024
Allow: 204
X-Include: X-Authenticated-User, X-Authenticated-Groups
Encapsulated: null-body=0
[root@89c0fa076328 /]#
Squidとc-icapを1対2で連携する
1対2で連携する際の通信方法としてFailover方式や負荷分散方式を設定したいケースがあるかと思います。
それぞれの設定方法を記載します。
Failover方式を設定
squidは基本的にc-icap1のみと通信を行い、c-icap1が死んだ場合のみc-icap2と通信を行う設定になります。
squid.confにadaptation_service_setを設定すればFailoverとなります。
以下設定例
icap_service service_req1 reqmod_precache bypass=0 icap://c-icap1:1344/echo
icap_service service_req2 reqmod_precache bypass=0 icap://c-icap2:1344/echo
adaptation_service_set icapset1 service_req1 service_req2
adaptation_access icapset1 allow random2
負荷分散方式を設定
squidがc-icap1とc-icap2に通信を分散させる方式になります。
squid.confにrandom ACLを設定すれば負荷分散方式となります。
以下設定例
acl random1 random 1/2
acl random2 random 1/1
icap_service service_req1 reqmod_precache bypass=0 icap://c-icap1:1344/echo
adaptation_access service_req1 allow random1
icap_service service_req2 reqmod_precache bypass=0 icap://c-icap2:1344/echo
adaptation_access service_req2 allow random2
random ACLの設定はSquid random outgoing IP address on each requestを参考にしました。
ただ、上記の設定の場合、c-icapが片方でもダウンした際にはクライアントにInternal Server Errorが返されます。
個人的には片系がダウンした際には、もう片方に通信を降ってほしいので以下のような設定としました。
(オリジナルなので不安ですが、たぶんうまく動作するはず・・・)
acl random1 random 1/2
acl random2 random 1/1
icap_service service_req1 reqmod_precache bypass=0 icap://c-icap1:1344/echo
icap_service service_req2 reqmod_precache bypass=0 icap://c-icap2:1344/echo
adaptation_service_set icapset1 service_req1 service_req2
adaptation_service_set icapset2 service_req2 service_req1
adaptation_access icapset1 allow random1
adaptation_access icapset2 allow random2
squidとc-icap連携に関するsquid.confのパラメタ
squidのFailoverと負荷分散(Load Distribution)に関係しそうなsquid側のパラメタをまとめてみました。
内容に誤り等あれば指摘いただけれると嬉しいです。。。
項目 | デフォルト | ざっくり概要 |
---|---|---|
icap_connect_timeout | none | SquidからICAP Serverへのリクエストを出してTCPコネクションが完了するまでタイムアウト。 c-icapが死んでてもこの時間は待つ。 |
icap_io_timeout | Use read_timeout | SquidとICAP Server間がEstablishedとなっている状態で発生したI/Oのタイムアウト。 |
icap_service_failure_limit | 10 | ICAPが死んでると判断するまでの回数。 |
icap_service_revival_delay | 180 | OPTIONSリクエストが失敗した際の再トライ間隔(?)。最小値は30秒。 |
設定例は以下のような感じ。
icap_service_failure_limit 1
icap_service_revival_delay 30
icap_connect_timeout 2 seconds
icap_io_timeout 1500 seconds
まとめ
この記事ではsquidとc-icapを連携(Failover/負荷分散)させる方法を記載いたしました。
また、その設定に関連しそうなsquid.confのパラメタも併せて記載いたしました。
ただ、分からなかったこともありました。
具体的には、squidとc-icap間で不定期に実行されるOPTIONS通信です。
たぶんc-icapが生きているかどうかを監視している通信(ヘルスチェック?)と考えているのですが、実行間隔やトリガー、仕組み等がよく分かりませんでした。
参考文献等ご存じの方がいれば教えていただければ幸いです。
付録:Dockerfile
squidとc-icapのDockerfileを置いておきます。
どちらもソースからインストールする方法で作成しております。
squidに関してはyumでインストールした方が100倍速いです。
squid
FROM centos:7
# system update
RUN yum -y update && yum clean all
# set locale
RUN yum reinstall -y glibc-common && yum clean all
RUN unlink /etc/localtime && ln -s /usr/share/zoneinfo/Japan /etc/localtime
RUN yum -y install make gcc perl openssl-devel gcc-c++
RUN yum install -y wget && wget -P /opt http://www.squid-cache.org/Versions/v3/3.5/squid-3.5.27.tar.gz && wget -P /opt https://www.openssl.org/source/old/1.0.2/openssl-1.0.2u.tar.gz
RUN tar zxvf /opt/squid* -C /opt && tar zxvf /opt/openssl* -C /opt
RUN cd /opt/openssl-1.0.2u && ./config --openssldir=/usr/local/ssl -fPIC shared && make && make install && make clean
RUN sed -i "1i\/usr\/local\/ssl\/lib" /etc/ld.so.conf ; ldconfig
RUN useradd squid
RUN cd /opt/squid-3.5.27 && ./configure --prefix=/usr/local/squid --with-openssl=/usr/local/ssl --with-default-user=squid && make && make install && make clean
RUN chown -R root:squid /usr/local/squid && chmod -R 775 /usr/local/squid
#COPY ./etc/squid.conf /usr/local/squid/etc/
RUN mkdir -p /oss/squid/log && chown -R squid:squid /oss/squid
EXPOSE 3128
CMD ["/usr/local/squid/sbin/squid","-N"]
c-icap
FROM centos:7
# system update
RUN yum -y update && yum clean all
RUN yum reinstall -y glibc-common && yum clean all
RUN unlink /etc/localtime && ln -s /usr/share/zoneinfo/Japan /etc/localtime
RUN yum -y install make gcc perl openssl-devel gcc-c++
RUN yum install -y wget && wget --content-disposition -P /opt https://sourceforge.net/projects/c-icap/files/latest/download
RUN tar zxvf /opt/c_icap-* -C /opt && cd /opt/c_icap-0.5.6/ && ./configure --prefix=/usr/local/c-icap && make && make install && make clean
EXPOSE 1344
CMD ["/usr/local/c-icap/bin/c-icap","-D","-N"]