apacheでリバースプロキシを立てる

# はじめに

ぱっとhttpのポート転送したいとき。
apacheでリバースプロキシを立てる。

端末　→　リバースプロキシ(apache) → Webサーバ の構成を想定。

OCI提供のoracle linuxを使っているため本質的でない手順(firewalld停止・SELLinux無効化)が挟まっていますがご了承ください。
名前解決はできるものとします。

# 準備

インスタンスを2つ用意する。


### Webサーバの作成

・OCIでOracle Linuxのイメージからインスタンスを作成する。

```shell
# OCI提供のoracle linux デフォルトイメージでは、firewalldが最初から有効になっている。
# ありがたいことなのだが検証用途では面倒なのでいったんOFFする
[root@web-server ~]# systemctl stop firewalld

# apacheを入れる
[root@web-server ~]# yum install httpd

# httpd サービスを起動する
[root@web-server ~]# systemctl start httpd

# 判別用のファイルを置いておく
[root@web-server ~]#  echo "you reached the Web server."  > /var/www/html/test.html

# この時点で自分自身からは正しく参照できる
[root@web-server ~]# curl http://localhost:80/test.html
you reached the Web server.
```

---

### プロキシサーバの作成

・同じくOCIでOracle Linuxのイメージからインスタンスを作成する。

・デフォルトでSELinuxがONになっているので無効化する。
　これを無効化しないとwebサーバに転送しようとした際に失敗して503エラーになる。
```shell
# デフォルトでSELinuxがONになっている
[root@proxy-server ~]# getenforce
Enforcing
[root@proxy-server ~]# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          disabled
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     actual (secure)
Max kernel policy version:      33

# SELinuxを無効化する。SELINUX=enforcingからdisabledに修正
[root@proxy-server ~]# vi /etc/sysconfig/selinux
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled　　★
# SELINUXTYPE= can take one of these three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

# 設定反映のためリブート
[root@proxy-server ~]# reboot

# SELinuxが無効化された
[root@proxy-server ~]# getenforce
Disabled
[root@proxy-server ~]# sestatus
SELinux status:                 disabled
```

・他、firewalldの無効化、httpdの起動は先ほどと同様。

```shell
# OCI提供のoracle linux デフォルトイメージでは、firewalldが最初から有効になっている。
# ありがたいことなのだが検証用途では面倒なのでいったんOFFする
[root@proxy-server ~]# systemctl stop firewalld

# apacheを入れる
[root@proxy-server ~]# yum install httpd

# httpd サービスを起動する
[root@proxy-server ~]# systemctl start httpd
```

### リバースプロキシのapacheの設定

本題。プロキシサーバにリバースプロキシとしてのapacheの設定を入れる。`/etc/httpd/conf/httpd.conf`に下記を追記。
・`curl http://proxy-server:8080/test.html`のリクエストを投げると、`http://web-server:80/test.html` に転送される設定になっている。

```shell
[root@proxy-server ~]# tail  /etc/httpd/conf/httpd.conf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
Listen 8080
<VirtualHost *:8080>
        ProxyPreserveHost On

        ProxyPass / http://web-server:80/
        ProxyPassReverse / http://web-server:80/
</VirtualHost>
```

以下を参考にさせていただいた。
https://rainbow-engine.com/apache-reverseproxy-howto/

・httpdサービスを再起動して反映する
```shell
# httpd再起動
[root@proxy-server ~]# systemctl restart httpd

# 転送用ポート8080がlistenされるようになった。
[root@proxy-server ~]# netstat -anp  | grep httpd
tcp6       0      0 :::8080                 :::*                    LISTEN      5636/httpd
tcp6       0      0 :::80                   :::*                    LISTEN      5636/httpd
unix  2      [ ACC ]     STREAM     LISTENING     52773    5638/httpd           /etc/httpd/run/cgisock.5636
unix  2      [ ]         DGRAM                    50844    5636/httpd
unix  3      [ ]         STREAM     CONNECTED     52736    5636/httpd
```

# 確認

無事ポート転送できた。

```
PS > curl http://proxy-server:8080/test.html


StatusCode        : 200
StatusDescription : OK
Content           : you reached the Web server.

RawContent        : HTTP/1.1 200 OK
                    Accept-Ranges: bytes
                    Content-Length: 28
                    Content-Type: text/html; charset=UTF-8
                    Date: Sun, 10 Dec 2023 01:55:27 GMT
                    ETag: "1c-60c1d8e0fe68c"
                    Last-Modified: Sun, 10 Dec 2023 01:15:...
Forms             : {}
Headers           : {[Accept-Ranges, bytes], [Content-Length, 28], [Content-Type, text/html; charset=UTF-8], [Date, Sun, 10 Dec 2023 01:55:27 GMT], [ETag, "1c-60c1d8e0fe68c"],
                     [Last-Modified, Sun, 10 Dec 2023 01:15:37 GMT], [Server, Apache/2.4.37 (Oracle Linux)]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 28
```


# 備考

仮に、「`curl http://proxy-server:8080/hoge/test.html`のリクエストを投げると、`http://web-server:80/fuga/test.html` に転送される」ようにしたい場合、以下のように設定する。

```shell
[root@proxy-server ~]# tail  /etc/httpd/conf/httpd.conf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
Listen 8080
<VirtualHost *:8080>
        ProxyPreserveHost On

        ProxyPass /hoge http://web-server:80/fuga
        ProxyPassReverse /hoge http://web-server:80/fuga
</VirtualHost>
```

```shell
[root@web-server ~]# echo "you reached the Web server:/fuga/test.html."  > /var/www/html/fuga/test.html
```

```
PS I> curl http://proxy-server:8080/hoge/test.html


StatusCode        : 200
StatusDescription : OK
Content           : you reached the Web server:/fuga/test.html.

RawContent        : HTTP/1.1 200 OK
                    Accept-Ranges: bytes
                    Content-Length: 44
                    Content-Type: text/html; charset=UTF-8
                    Date: Sun, 10 Dec 2023 02:06:15 GMT
                    ETag: "2c-60c1e3cf219d5"
                    Last-Modified: Sun, 10 Dec 2023 02:04:...
Forms             : {}
Headers           : {[Accept-Ranges, bytes], [Content-Length, 44], [Content-Type, text/html; charset=UTF-8], [Date, Sun, 10 Dec 2023 02:06:15 GMT], [ETag, "2c-60c1e3cf219d5"],
                     [Last-Modified, Sun, 10 Dec 2023 02:04:31 GMT], [Server, Apache/2.4.37 (Oracle Linux)]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 44
```