hana_shinのLinux技術ブログ

Linuxの技術情報を掲載しています。特にネットワークをメインに掲載していきます。

Proxyサーバの構築手順



1 はじめに

Proxyサーバとは、内部ネットワークからインターネットへの接続を中継するサーバです。Proxyサーバの役割としては、以下のようなものがあります。

  • キャッシュによるトラフィック削減とパフォーマンス向上
  • アクセス制御(例:マルウェアがアクセスするC&Cサーバへのアクセス禁止)

ここでは、Squidを使ってProxyサーバを構築してみます。また、パスワード認証を設定して、その動作確認をしてみます。

2 検証環境

2.1 ネットワーク構成

サーバとクライアントの2台構成です。以下の図は、クライアントのcurlコマンドからSquidを経由して、インターネット上のwebサーバにアクセスしていることを表しています。なお、図中のens33はNICの名前、()内はポート番号を表しています。

   client                     server
+-----------+             +-----------+
|           |             |           |
| CentOS7.9 |             | CentOS7.9 |
|           |             |           |
|           |             |           |
|   curl    |             |   Squid   |
|      *    |             |   (3128)  |
|      |    |             |  A     *  |
|      |    |             |  |     |  |
|      |    |             |  |     |  |
+-- ens33 --+             +-- ens33 --+
.105 | |                     |.100 |
     | |                     |  |  |
     | +---------------------+  |  +-------------------------->
     |                          |
------------------------------------------------ router ------- Internet
           192.168.2.0/24                     .1

2.2 版数

CentOS版数は、サーバ、クライアントともに下記版数です。

[root@server ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

カーネル版数は以下のとおりです。

[root@server ~]# uname  -r
3.10.0-1160.el7.x86_64

3 squid パッケージのインストール方法

サーバでsquidパッケージをインストールします。

[root@server ~]#  yum -y install squid

squidの版数を確認します。

[root@server ~]# squid -v
Squid Cache: Version 3.5.20
-snip-

4 ポート番号の開放

squidは3128番ポートでListenするので、3128番ポートへのアクセスを開放します。firewall-cmdの詳細な使い方は、firewall-cmdの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# firewall-cmd --add-port=3128/tcp
success

ポートの状態を確認します。3128番ポートへのアクセスが開放されていることがわかります。

[root@server ~]# firewall-cmd --list-ports
3128/tcp

5 サーバ側の設定

5.1 user1のパスワード認証設定

user1のパスワード認証を設定します。パスワードはtestにします。設定したユーザ名とパスワードは、/etc/squid/.htpasswd に保存します。

[root@server ~]# htpasswd -c /etc/squid/.htpasswd user1
New password:
Re-type new password:
Adding password for user user1

設定したパスワードを確認します。

[root@server ~]# cat /etc/squid/.htpasswd
user1:$apr1$Swlhgg64$GvTKTx7mK8cNRmURCA7Un0

5.2 squidの設定

次に、squidの設定をします。squidの設定ファイルは、/etc/squid/squid.confです。squid.confへのディレクティブ設定は、下記ページを参考にしました。
Squid 3.5.19 Configuration File: auth_param

[root@server ~]# diff -Nur /etc/squid/squid.conf.org /etc/squid/squid.conf
--- /etc/squid/squid.conf.org   2022-01-30 20:52:48.291362442 +0900
+++ /etc/squid/squid.conf       2022-01-30 20:54:17.753122927 +0900
@@ -24,6 +24,12 @@
 acl Safe_ports port 777                # multiling http
 acl CONNECT method CONNECT

+auth_param basic program /usr/lib64/squid/basic_ncsa_auth /etc/squid/.htpasswd
+auth_param basic children 5 startup=5 idle=1
+auth_param basic realm Squid proxy-caching web server
+auth_param basic credentialsttl 2 hours
+acl staff proxy_auth REQUIRED
+
 #
 # Recommended minimum Access Permission configuration:
 #
@@ -45,6 +51,8 @@
 #
 # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
 #
+http_access allow staff
+

 # Example rule allowing access from your local networks.
 # Adapt localnet in the ACL section to list your (internal) IP networks

なお、Squidのアクセス制御の設定は、次の2段階で行います。
(1)aclディレクティブで制御対象を定義する。

acl acl名 aclタイプ 引数

(2)http_accessディレクティブでアクセス対象への許可あるいは拒否を設定する。

http_access allow|deny acl名

5.3 squidの起動

squidを起動します。

[root@server ~]# systemctl start squid

squidの状態を確認します。squidが起動していることがわかります。

[root@server ~]# systemctl is-active squid.service
active

squidがListenするポート番号を確認します。squidが3128番ポートでListenしていることがわかります。lsofコマンドの使い方は、lsofコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# lsof -c squid -a -i -a -P
COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
squid   3086 squid    6u  IPv6  45903      0t0  UDP *:46800
squid   3086 squid    8u  IPv4  45904      0t0  UDP *:43314
squid   3086 squid   21u  IPv6  46175      0t0  TCP *:3128 (LISTEN)

6 クライアント側の設定

6.1 ユーザ登録

user1とuser2を登録します。まず。user1を登録します。

[root@client ~]# useradd user1

登録したユーザを確認します。user1が登録されたことがわかります。

[root@client ~]# id user1
uid=1000(user1) gid=1000(user1) groups=1000(user1)

次にuser2を登録します。

[root@client ~]# useradd user2

登録したユーザを確認します。user2が登録されたことがわかります。

[root@client ~]# id user2
uid=1001(user2) gid=1001(user2) groups=1001(user2)

6.2 user1の環境変数設定

user1は以下のように設定しました。.bashrc.orgは設定変更前の.bashrcです。

[user1@client ~]$ diff -Nur .bashrc.org .bashrc
--- .bashrc.org 2022-01-30 21:15:24.483426325 +0900
+++ .bashrc     2022-01-30 21:14:53.173160602 +0900
@@ -9,3 +9,5 @@
 # export SYSTEMD_PAGER=

 # User specific aliases and functions
+export http_proxy=http://user1:test@192.168.2.100:3128
+export https_proxy=http://user1:test@192.168.2.100:3128

設定した環境変数をシステムに反映します。

[user1@client ~]$ source .bashrc

環境変数(http_proxy)を確認します。

[user1@client ~]$ echo $http_proxy
http://user1:test@192.168.2.100:3128

環境変数(https_proxy)を確認します。

[user1@client ~]$ echo $https_proxy
http://user1:test@192.168.2.100:3128

6.3 user2の環境変数設定

user2はパスワード認証の設定はしないので、環境変数は以下のようになります。.bashrc.orgは設定変更前の.bashrcです。

[user2@client ~]$ diff -Nur .bashrc.org .bashrc
--- .bashrc.org 2022-01-30 21:25:26.264549157 +0900
+++ .bashrc     2022-01-30 21:25:56.798812471 +0900
@@ -9,3 +9,5 @@
 # export SYSTEMD_PAGER=

 # User specific aliases and functions
+export http_proxy=http://192.168.2.100:3128
+export https_proxy=http://192.168.2.100:3128

設定した環境変数をシステムに反映します。

[user2@client ~]$ source .bashrc

環境変数(http_proxy)を確認します。

[user2@client ~]$ echo $http_proxy
http://192.168.2.100:3128

環境変数(https_proxy)を確認します。

[user2@client ~]$ echo $https_proxy
http://192.168.2.100:3128

7 動作確認

下記2つのユーザを使って、Squid経由で首相官邸のWebサーバにアクセスしてみます。

  • user1:ID/PASS登録済
  • user2:ID/PASS未登録

7.1 user1の動作確認

user1で首相官邸のWebサーバにアクセスしてみます。正常にアクセスできていることがわかります。なお、curlコマンドの使い方は、curlコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[user1@client ~]$ curl -I https://www.kantei.go.jp/
HTTP/1.1 200 Connection established

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 12662
Connection: keep-alive
x-amz-id-2: q2Bw7D5pVTWS7awAgjYr8IQ2eYpkoEmnrqy2P8bpWDs0/yYxH0znCof/t17DQPgNxcE1CMZhtno=
x-amz-request-id: 740C5YS5R8E3ZS22
x-amz-replication-status: COMPLETED
Last-Modified: Sun, 30 Jan 2022 04:17:10 GMT
x-amz-server-side-encryption: AES256
x-amz-meta-user-agent: AWSTransfer
x-amz-meta-user-agent-id: kantei-prd-apn01-sftpuser-kantei01-alaya01@s-c73fde2b48d346ed8
x-amz-version-id: ct7vdLxON78bKPP6Y3hiF_RmRedHdv_q
Accept-Ranges: bytes
Server: none
Date: Sun, 30 Jan 2022 12:49:42 GMT
ETag: "14eb9600cea18c4569fa4e1b5abfb275"
X-Cache: Hit from cloudfront
Via: 1.1 25caeecf79d1babf9c1aeb8ae41d4e36.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: NRT57-C1
X-Amz-Cf-Id: bOuJhXW64-NLQxIo65MM4vCk0vPILZeznqgljBUPyKXg6Ojf64yuPw==

次に、サーバでログを確認します。user1がcurlを実行するとTCP_TUNNELと表示され、首相官邸のWebサーバにアクセスが許可されていることがわかります。

[root@server ~]# tail -f /var/log/squid/access.log
1643547511.698   5288 192.168.2.105 TCP_TUNNEL/200 4146 CONNECT www.kantei.go.jp:443 user1 HIER_DIRECT/2600:9000:221b:d200:0:e7be:3c80:93a1 -

なお、TCP_TUNNELは、HTTPS通信をSquidで復号することなく、そのまま首相官邸のWebサーバにトンネルすることを意味します。つまり、下記の動作になります。HTTPS通信を復号しないため、ウィルスチェックは行えません。

       <--------------- HTTPS --------------->
client ------------ Proxy(Squid) ------------- Web server
                     ↑HTTPSをそのままトンネル

ウィルスチェックを行うためには、下記のようにProxyサーバHTTPSを復号/暗号化する必要があります。その際、Proxyサーバサーバ証明書をインストールする必要があります。

       <-- HTTPS -->             <-- HTTPS -->
client ------------ Proxy(Squid) ------------- Web server
                     ↑HTTPSの復号/暗号化

7.2 user2の動作確認

次にuser2で首相官邸のWebサーバにアクセスしてみます。squidがHTTP/1.1 407 Proxy Authentication Requiredと認証情報の入力を求めていることがわかります(期待値)。

[user2@client ~]$ curl -I https://www.kantei.go.jp/
HTTP/1.1 407 Proxy Authentication Required
Server: squid/3.5.20
Mime-Version: 1.0
Date: Sun, 30 Jan 2022 13:04:38 GMT
Content-Type: text/html;charset=utf-8
Content-Length: 3538
X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
Vary: Accept-Language
Content-Language: en
Proxy-Authenticate: Basic realm="Squid proxy-caching web server"
X-Cache: MISS from server
X-Cache-Lookup: NONE from server:3128
Via: 1.1 server (squid/3.5.20)
Connection: keep-alive

curl: (56) Received HTTP code 407 from proxy after CONNECT

次に、サーバでログを確認します。user2がcurlを実行するとTCP_DENIEDと表示され、首相官邸のWebサーバへのアクセスが拒否されていることがわかります。

[root@server ~]# tail -f /var/log/squid/access.log
1643548149.487      0 192.168.2.105 TCP_DENIED/407 3998 CONNECT www.kantei.go.jp:443 - HIER_NONE/- text/html

Z 参考情報

私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ