Ubuntu 19.10 Eoan Ermine の Apache 2.4 でリバースプロキシする

## 概要

- Ubuntu に apache2 パッケージをインストール
- a2enmod コマンドで mod_proxy と mod_http を有効化
- https へリバースプロキシする場合は a2enmod コマンドで mod_ssl を有効化

## Apache をインストール

apache2 パッケージをインストール。

```
$ sudo apt install apache2
```

バージョンを確認。

```
$ /usr/sbin/apachectl -v
Server version: Apache/2.4.41 (Unix)
Server built:   Nov  9 2019 07:53:54
```

## mod_proxy と mod_proxy_http を有効化

http サイトにリバースプロキシするために必要なモジュールを有効化する。

a2enmod コマンドで Apache モジュールを有効にする。
a2enmod コマンドに proxy_http を指定すると mod_proxy_http と依存関係にある mod_proxy が有効になる。

```
$ sudo a2enmod proxy_http
Considering dependency proxy for proxy_http:
Enabling module proxy.
Enabling module proxy_http.
To activate the new configuration, you need to run:
  systemctl restart apache2
```

有効になった Apache モジュールは /etc/apache2/mods-enabled/ に設置される。

```
$ ls -la /etc/apache2/mods-enabled/ | grep proxy
lrwxrwxrwx 1 root root   28  1月 27 12:37 proxy.conf -> ../mods-available/proxy.conf
lrwxrwxrwx 1 root root   28  1月 27 12:37 proxy.load -> ../mods-available/proxy.load
lrwxrwxrwx 1 root root   33  1月 27 12:48 proxy_http.load -> ../mods-available/proxy_http.load
```

[mod\_proxy \- Apache HTTP サーバ バージョン 2\.4](https://httpd.apache.org/docs/2.4/ja/mod/mod_proxy.html)

> このモジュールは Apache のプロキシ/ゲートウェイ機能を実装しています。 AJP13 (Apache JServe Protocol version 1.3), FTP, CONNECT (SSL 用), HTTP/0.9, HTTP/1.0, HTTP/1.1 のプロキシ機能を実装しています。これらのプロトコルやその他のプロトコル用の プロキシ機能を持った、他のモジュールに接続するようにも設定できます。
> 
> Apache のプロキシ機能は mod_proxy の他に、 いくつかのモジュールに分割されています: mod_proxy_http, mod_proxy_ftp, mod_proxy_ajp, mod_proxy_balancer, mod_proxy_connect です。ですから、 特定のプロキシの機能を使いたい場合は、mod_proxy と 該当するモジュールをサーバに (コンパイル時に静的に行なうか LoadModule で動的に読み込むかして) 組み込む必要があります。

## https サーバへリバースプロキシする場合は mod_ssl も有効化

a2enmod ssl で mod_ssl が有効になり、依存関係で mod_setenvif と mod_mime と mod_socache_shmcb も有効になる。

```
$ sudo a2enmod ssl
Considering dependency setenvif for ssl:
Module setenvif already enabled
Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Enabling module socache_shmcb.
Enabling module ssl.
See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates.
To activate the new configuration, you need to run:
  systemctl restart apache2
```

## 設定ファイルを設置

今回は /etc/apache2/sites-available ディレクトリにある 000-default.conf ファイルをコピーして my-proxy.conf というファイルを作成する。

```
$ sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/my-proxy.conf
```

my-proxy.conf ファイルの中身を修正する。

```
$ sudo vim /etc/apache2/sites-available/my-proxy.conf
```

my-proxy.conf ファイルを以下の内容に置き換える。

```my-proxy.conf
<VirtualHost *:80>

  # /etc/apache2/sites-available/000-default.conf からコピーした内容
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/html
  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined

  # localhost:8888 へリバースプロキシする
  ProxyPass /foo/ http://127.0.0.1:8888/foo/
  ProxyPassReverse /foo/ http://127.0.0.1:8888/foo/

  # http サイトへリバースプロキシする
  ProxyPass /bar/ http://example.com/bar/
  ProxyPassReverse /bar/ http://example.com/bar/

  # https サイトへリバースプロキシする
  SSLProxyEngine On
  ProxyPass /baz/ https://example.org/baz/
  ProxyPassReverse /baz/ https://example.org/baz/

</VirtualHost>
```

## my-proxy.conf を有効化して 000-default.conf を無効化

a2ensite コマンドで my-proxy.conf を有効にする。

```
$ sudo a2ensite my-proxy
Enabling site my-proxy.
To activate the new configuration, you need to run:
  systemctl reload apache2
```

a2dissite コマンドで 000-default.conf を無効にする。

```
$ sudo a2dissite 000-default
Site 000-default disabled.
To activate the new configuration, you need to run:
  systemctl reload apache2
```

## Apache を再起動して設定を反映する

```
$ sudo systemctl restart apache2
```

curl コマンド等でリバースプロキシが動作しているのを確認できる。

```
$ curl -i http://localhost/foo/
HTTP/1.1 200 
Date: Mon, 27 Jan 2020 11:19:56 GMT
Server: Apache/2.4.41 (Ubuntu)
Content-Type: text/html;charset=UTF-8
Content-Language: ja-JP
Vary: Accept-Encoding
Transfer-Encoding: chunked

<html><body>Hello, world.</body></html>
```

## エラーについて

思ったように動作しない場合は /var/log/apache2/error.log に出力されるエラーメッセージを調べると良い。

### mod_proxy だけ導入して mod_proxy_http を導入していない場合のエラー

```
AH01144: No protocol handler was valid for the URL /foo/ (scheme 'http'). If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule.
```

### mod_ssl を導入していない場合のエラー

```
AH01961: SSL Proxy requested for your.example.net:80 but not enabled [Hint: SSLProxyEngine]
```

```
AH00961: HTTPS: failed to enable ssl support for XXX.XXX.XXX.XXX:443 (example.org)
```

## 参考資料

- [mod\_proxy \- Apache HTTP サーバ バージョン 2\.4](https://httpd.apache.org/docs/2.4/ja/mod/mod_proxy.html)
- [mod\_proxy\_http \- Apache HTTP Server Version 2\.4](https://httpd.apache.org/docs/2.4/ja/mod/mod_proxy_http.html)
- [mod\_ssl \- Apache HTTP Server Version 2\.4](http://httpd.apache.org/docs/2.4/ja/mod/mod_ssl.html)
- [Ubuntu 19\.10 Eoan Ermine に Apache 2\.4 をインストールして CGI を動かす \- Qiita](https://qiita.com/niwasawa/items/485628158ba2eca03fa4)
- [Apache 2\.4 から https サーバへリバースプロキシする \- Qiita](https://qiita.com/niwasawa/items/c66cc35b52c1445d0157)