hana_shinのLinux技術ブログ

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

Nginxをリバースプロキシサーバとして動かす方法



1 はじめに

Nginxをhttpdのリバースプロキシサーバとして動かしてみます。

2 検証環境

2.1 ネットワーク構成

サーバ1とサーバ2の2台構成です。()内はTCPポート番号を表します。図中の(1),(2),(3)の意味は次のとおりです。
(1) : httpクライアントからnginxへのアクセス
(2),(3):nginxがバックエンドのhttpdにHTTPアクセスの振り分け

+--------- server1 --------+           +---- server2 ---+
|                          |           |                |
| nginx(8888)    httpd(80) |           |    httpd(80)   |
|    A   |  |     A(2)     |           |       A(3)     |
|    |   |  |     |        |           |       |        |
|    |   |  +-----+        |           |       |        |
|    |   +-----+           |           |       |        |
|    |         |           |           |       |        |
|    |         |           |           |       |        |
|    +----+    | CentOS7.9 |           |   CentOS7.9    |
|         |    |           |           |       |        |
|         |    |           |           |       |        |
|         |    |           |           |       |        |
+------------ ens33 -------+           +----- ens33 ----+
          |    | .105                          | .100
          |    |                               |
          |    +-------------------------------+
          |
         (1)

2.2 版数

CentOS版数は、サーバ1、サーバ2ともに下記版数です。

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

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

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

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

3.1 サーバ1

httpdパッケージをインストールします。

[root@server1 ~]# yum -y install httpd

httpdの版数を確認します。

[root@server1 ~]# httpd -v
Server version: Apache/2.4.6 (CentOS)
Server built:   Jan 25 2022 14:08:43

次にnginxパッケージをインストールします。nginxパッケージは、epelリポジトリにあるので、epel-releaseパッケージをインストールします。

[root@server1 ~]# yum -y install epel-release

nginxパッケージをインストールします。

[root@server1 ~]# yum -y install nginx

nginxの版数を確認します。

[root@server1 ~]# nginx -v
nginx version: nginx/1.20.1

3.2 サーバ2

httpdパッケージをインストールします。

[root@server2 ~]# yum -y install httpd

httpdの版数を確認します。

[root@server2 ~]# httpd -v
Server version: Apache/2.4.6 (CentOS)
Server built:   Jan 25 2022 14:08:43

4 Nginxの設定ファイル編集

4.1 backend.confの編集

インストール直後はbackend.confが存在しないので作成します。作成したbackend.confにバックエンドのhttpdサーバの設定をします。

  • server:バックエンドサーバ(httpd)のIPアドレスとポート番号を指定する
  • weight:アクセスする割合を指定する
  • listen:nginxがListenするポート番号を指定する
  • server_name:nginxのIPアドレスを設定する

下記設定は1対1の割合でバックエンドサーバにアクセスする設定になっています。

[root@server1 ~]# vi /etc/nginx/conf.d/backend.conf
[root@server1 ~]# cat /etc/nginx/conf.d/backend.conf
upstream backend {
    server 192.168.2.105:80 weight=1;
    server 192.168.2.100:80 weight=1;
}

server {
    listen  8888;
    server_name  192.168.0.105;

    location / {
        proxy_pass http://backend;
    }
}

4.2 nginx.confの編集

httpdとnginxが同じポート番号(80)を使うのを避けるため、nginxのポート番号をデフォルトの80から8888に変更します。
オリジナルの設定ファイルをバックアップします。

[root@server1 ~]# cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.org

設定ファイルを編集します。

[root@server1 ~]# vi /etc/nginx/nginx.conf

修正内容は以下のとおりです。

[root@server1 ~]# diff -Nur /etc/nginx/nginx.conf.org /etc/nginx/nginx.conf
--- /etc/nginx/nginx.conf.org   2022-03-22 20:07:41.266691802 +0900
+++ /etc/nginx/nginx.conf       2022-03-22 20:09:01.146714312 +0900
@@ -36,8 +36,8 @@
     include /etc/nginx/conf.d/*.conf;

     server {
-        listen       80;
-        listen       [::]:80;
+        listen       8888;
+        listen       [::]:8888;
         server_name  _;
         root         /usr/share/nginx/html;

5 Nginx,httpdの起動

5.1 サーバ1

サーバ1のindex.htmlを作成します。

[root@server1 ~]# vi /var/www/html/index.html
[root@server1 ~]# cat /var/www/html/index.html
server1

httpdサービスを起動します。

[root@server1 ~]# systemctl start httpd

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

[root@server1 ~]# lsof -c httpd -a -i -a -nP
COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
httpd   1948   root    4u  IPv6  30085      0t0  TCP *:80 (LISTEN)
httpd   1949 apache    4u  IPv6  30085      0t0  TCP *:80 (LISTEN)
httpd   1950 apache    4u  IPv6  30085      0t0  TCP *:80 (LISTEN)
httpd   1951 apache    4u  IPv6  30085      0t0  TCP *:80 (LISTEN)
httpd   1952 apache    4u  IPv6  30085      0t0  TCP *:80 (LISTEN)
httpd   1953 apache    4u  IPv6  30085      0t0  TCP *:80 (LISTEN)

次にnginxサービスを起動します。しかし、SELinuxが有効だと、以下のようにnginxサービスの起動が失敗します。

[root@server1 ~]# systemctl start nginx
Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details.

nginxサービス起動失敗時のログ(/var/log/audit/audit.log)から、サービス起動を許可するルールを作成します。なお、SELinuxの使い方は、SELinux - Qiitaを参照してください。

[root@server1 ~]# audit2allow -M nginx < /var/log/audit/audit.log
******************** IMPORTANT ***********************
To make this policy package active, execute:

semodule -i nginx.pp

audit2allowコマンドで作成したファイルを確認します。

[root@server1 ~]# ls nginx.*
nginx.pp  nginx.te

作成したnginx.teの中身を確認します。

[root@server1 ~]# cat nginx.te

module nginx 1.0;

require {
        type httpd_t;
        type unreserved_port_t;
        class tcp_socket name_bind;
}

#============= httpd_t ==============

#!!!! This avc can be allowed using the boolean 'nis_enabled'
allow httpd_t unreserved_port_t:tcp_socket name_bind;

作成したポリシーモジュールをインストールします。

[root@server1 ~]# semodule -i nginx.pp

nginxサービスを起動します。

[root@server1 ~]# systemctl start nginx

nginxサービスの状態を確認します。今度は、エラーなく起動することができました。

[root@server1 ~]# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: active (running) since 火 2022-03-22 20:29:43 JST; 34min ago
  Process: 1772 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
  Process: 1769 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
  Process: 1767 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
 Main PID: 1774 (nginx)
   CGroup: /system.slice/nginx.service
           tq1774 nginx: master process /usr/sbin/nginx
           tq1775 nginx: worker process
           tq1776 nginx: worker process
           tq1777 nginx: worker process
           mq1778 nginx: worker process

 3月 22 20:29:43 server1 systemd[1]: Starting The nginx HTTP and reverse proxy server...
 3月 22 20:29:43 server1 nginx[1769]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
 3月 22 20:29:43 server1 nginx[1769]: nginx: configuration file /etc/nginx/nginx.conf test is successful
 3月 22 20:29:43 server1 systemd[1]: Started The nginx HTTP and reverse proxy server.

nginxが使用するポート番号を確認します。nginxがTCPの8888番ポートを使用していることがわかります

[root@server1 ~]# lsof -c nginx -a -i -a -nP
COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx   1774  root    6u  IPv4  22402      0t0  TCP *:8888 (LISTEN)
nginx   1774  root    7u  IPv6  22403      0t0  TCP *:8888 (LISTEN)
nginx   1775 nginx    6u  IPv4  22402      0t0  TCP *:8888 (LISTEN)
nginx   1775 nginx    7u  IPv6  22403      0t0  TCP *:8888 (LISTEN)
nginx   1776 nginx    6u  IPv4  22402      0t0  TCP *:8888 (LISTEN)
nginx   1776 nginx    7u  IPv6  22403      0t0  TCP *:8888 (LISTEN)
nginx   1777 nginx    6u  IPv4  22402      0t0  TCP *:8888 (LISTEN)
nginx   1777 nginx    7u  IPv6  22403      0t0  TCP *:8888 (LISTEN)
nginx   1778 nginx    6u  IPv4  22402      0t0  TCP *:8888 (LISTEN)
nginx   1778 nginx    7u  IPv6  22403      0t0  TCP *:8888 (LISTEN)

5.2 サーバ2

サーバ2のindex.htmlを作成します。

[root@server2 ~]# vi /var/www/html/index.html
[root@server2 ~]# cat /var/www/html/index.html
server2

httpdサービスを起動します。

[root@server2 ~]# systemctl start httpd

httpdが使用するポート番号を確認します。httpdTCPの80番ポートを使用していることがわかります。

[root@server2 ~]# lsof -c httpd -a -i -a -nP
COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
httpd   1773   root    4u  IPv6  31019      0t0  TCP *:80 (LISTEN)
httpd   1774 apache    4u  IPv6  31019      0t0  TCP *:80 (LISTEN)
httpd   1775 apache    4u  IPv6  31019      0t0  TCP *:80 (LISTEN)
httpd   1776 apache    4u  IPv6  31019      0t0  TCP *:80 (LISTEN)
httpd   1777 apache    4u  IPv6  31019      0t0  TCP *:80 (LISTEN)
httpd   1778 apache    4u  IPv6  31019      0t0  TCP *:80 (LISTEN)

6 ポート番号の解放

6.1 サーバ1

httpdがListenする80番ポートを解放します。なお、firewall-cmdコマンドの使い方は、firewall-cmdの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server1 ~]# firewall-cmd --add-port=80/tcp
success

nginxがListenする8888番ポートを解放します。

[root@server1 ~]# firewall-cmd --add-port=8888/tcp
success

ポート番号の状態を確認します。80番ポートと8888番ポートが解放されたことがわかります。

[root@server1 ~]# firewall-cmd --list-ports
80/tcp 8888/tcp

6.2 サーバ2

httpdがListenする80番ポートを解放します

[root@server2 ~]# firewall-cmd --add-port=80/tcp
success

ポート番号の状態を確認します。80番ポートが解放されたことがわかります。

[root@server2 ~]# firewall-cmd --list-ports
80/tcp

7 動作確認

server1でnginxにアクセスします。nginxにアクセスすると、サーバ1、サーバ2から交互にindex.htmlの中身が返信されていることがわかります。

[root@server1 ~]# curl http://192.168.2.105:8888
server2
[root@server1 ~]# curl http://192.168.2.105:8888
server1
[root@server1 ~]# curl http://192.168.2.105:8888
server1
[root@server1 ~]# curl http://192.168.2.105:8888
server2

Z 参考情報

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