おうちサーバー構築報告：nginxでリバースプロキシ

## 能書き

[おうちサーバー構築報告：予告](https://qiita.com/katz_engineer/items/471408eda1d09507c451)からのおうちサーバー構築の続きです。

今後、家庭内サーバーとして様々なWebサービスを立ち上げるつもりです。立ち上がるといいな… とりあえずGitLabが立ち上がる事は確定事項です。

複数のWebサーバーを立ち上げる場合には、リバースプロキシを設定しバーチャルホストの形で運用するのが定番でしょう。家庭内で私一人が使うならポート番号を振り分けても良いんですが、折角なので勉強を兼ねて、リバースプロキシに挑戦してみます。

と言っても難しい事は無いですし、記事のネタとしても同案多数のようですし、[以前も同じ事をやった](https://qiita.com/katz_engineer/items/d05537ffd9a8212c59be)のですが。今回は[以前](https://qiita.com/katz_engineer/items/d05537ffd9a8212c59be)と違ってDockerコンテナではありません。[ProxmoxVEのシステムコンテナ](https://qiita.com/katz_engineer/items/471408eda1d09507c451#%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2)で動かす事が前提になります。

### 目標

- リバースプロキシを立てる
    - リバースプロキシの動作確認の為に、Webサーバーを2つ立てて表示内容で区別できるようにする

### 参考文献

- [私的サーバー構築日誌：nginx on docker でリバースプロキシ - Qiita](https://qiita.com/katz_engineer/items/d05537ffd9a8212c59be)
- [ソフトウェア - おうちサーバー構築報告：予告 - Qiita](https://qiita.com/katz_engineer/items/471408eda1d09507c451#%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2)
- [おうちサーバー構築報告：LAN内DNSサーバー Unbound - Qiita](https://qiita.com/katz_engineer/items/f05186fab0f8971e5348)
- [おうちサーバー構築報告：コンテナ on Proxmox VE with ZFS - Qiita](https://qiita.com/katz_engineer/items/3cf9a545d4c8b7c77206)
- [設定 - 内向きDNS - おうちサーバー構築報告：LAN内DNSサーバー Unbound - qiita](https://qiita.com/katz_engineer/items/f05186fab0f8971e5348#%E8%A8%AD%E5%AE%9A)
- [[nginx]設定の反映 - Qiita](https://qiita.com/WisteriaWave/items/fa2e7f4442aee497fe46)

## 動作確認用Webサーバ構築

### 専用コンテナを構築

新しいコンテナ`nginx`(`172.16.1.105`)を立ち上げます。手順の詳細は[以前の記事](https://qiita.com/katz_engineer/items/3cf9a545d4c8b7c77206)を参照して下さい。GUIは手順の記載が面倒なんです…

- ホスト名: nginx
- リソースプール: all
- パスワード: （適当なパスワードを設定）
- SSH公開鍵: （適当なマシンのSSH公開鍵を設定）
- テンプレート: ubuntu-24.04-standard_24.04-2_amd64.tar.zst
- ディスクサイズ: 8GiB
- CPUコア: 1
- メモリ: 512MiB
- スワップ: 512MiB
- IPv4/CIDR: 172.16.1.105/16 （我が家のIPアドレス体系に沿って決定）
- ゲートウェイ: 172.16.2.1 （我が家のゲートウェイアドレス）
- DNSドメイン: （空欄のまま）
- DNSサーバ: 172.16.1.101 （[以前](https://qiita.com/katz_engineer/items/f05186fab0f8971e5348)構築した家庭内DNSサーバ）

その後、このコンテナにnginxをインストールします。

```console:サーバー172.16.1.105:ユーザーroot
apt update
apt upgrade -y
```

```console:サーバー172.16.1.105:ユーザーroot
apt install -y nginx
```

### サイト1

```console:サーバー172.16.1.105:ユーザーroot
mkdir /var/www/_1
cat <<___ >/var/www/_1/index.html
<!DOCTYPE html>
<html lang="ja">
 <head>
 <meta charset="UTF-8" />
 <title>hello</title>
</head>
<body>
 <h1>1st</h1>
 <p>hello, world</p>
</body>
</html>
___
```

```console:サーバー172.16.1.105:ユーザーroot
cat <<___ >/etc/nginx/sites-available/_1.conf
server {
    listen        20080;
    server_name   _;
    server_tokens off;

    location / {
        root   /var/www/_1;
        index  index.html index.htm;
    }
}
___
cd /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/_1.conf _1.conf
```

### サイト2

```console:サーバー172.16.1.105:ユーザーroot
mkdir /var/www/_2
cat <<___ >/var/www/_2/index.html
<!DOCTYPE html>
<html lang="ja">
 <head>
 <meta charset="UTF-8" />
 <title>hello</title>
</head>
<body>
 <h1>2nd</h1>
 <p>hello, world</p>
</body>
</html>
___
```

```console:サーバー172.16.1.105:ユーザーroot
cat <<___ >/etc/nginx/sites-available/_2.conf
server {
    listen        30080;
    server_name   _;
    server_tokens off;

    location / {
        root   /var/www/_2;
        index  index.html index.htm;
    }
}
___
cd /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/_2.conf _2.conf
```

### nginx設定の反映

チェック。

```console:サーバー172.16.1.105:ユーザーroot
nginx -t
```

チェックに成功したら、設定を反映します。下記コマンドなら瞬断せずに反映するとの事。

```console:サーバー172.16.1.105:ユーザーroot
nginx -s reload
```

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

### nginxのインストールと設定

いよいよ本命のプロキシサーバー`172.16.1.103`の設定です。

```console:サーバー172.16.1.103:ユーザーroot
apt update
apt upgrade -y
```

```console:サーバー172.16.1.103:ユーザーroot
apt install -y nginx
```

```console:サーバー172.16.1.103:ユーザーroot
HOST_IPADDR=172.16.1.105
```

```console:サーバー172.16.1.103:ユーザーroot
cd /etc
svn st | grep "^?" | cut -b9- | sudo xargs -I{} find {} -type f -or -type d -or -type l | xargs -rt svn add
svn ci -m"install nginx"

cat <<___ >/etc/nginx/sites-available/1st.conf
server {
    listen        80;
    server_name   1st.local;
    server_tokens off;

    location / {
        proxy_pass http://$HOST_IPADDR:20080;
    }
}
___
cat <<___ >/etc/nginx/sites-available/2nd.conf
server {
    listen        80;
    server_name   2nd.local;
    server_tokens off;

    location / {
        proxy_pass http://$HOST_IPADDR:30080;
    }
}
___
cd /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/1st.conf 1st.conf
ln -s /etc/nginx/sites-available/2nd.conf 2nd.conf

nginx -s reload
```

### 家庭内DNSの設定

[家庭内DNSを設定](https://qiita.com/katz_engineer/items/f05186fab0f8971e5348#%E8%A8%AD%E5%AE%9A)します。

`1st.local`と`2nd.local`を追記します。Webサーバーを立てていない`3rd.local`も追記している点に注意。後で動作確認する時に使います。

```console:サーバー172.16.1.101ユーザーroot
PROXY_IPADDR=172.16.1.103
```

```console:サーバー172.16.1.101ユーザーroot
cd /etc/unbound/unbound.conf.d/
cat >>machines.list <<___
local-data: "1st.local. 3600000 IN A $PROXY_IPADDR"
local-data: "2nd.local. 3600000 IN A $PROXY_IPADDR"
local-data: "3rd.local. 3600000 IN A $PROXY_IPADDR"
___
```

念の為に文法チェック。

```console:サーバー172.16.1.101ユーザーroot
unbound-checkconf
```

```Unbound```に設定を読み込ませます。

```console:サーバー172.16.1.101ユーザーroot
systemctl restart unbound
```

## 動作確認

動作確認は、`172.16.1.105`に`curl`コマンドをインストールして実施します。

```console:サーバー172.16.1.105ユーザーroot
apt install -y curl
```

### サイト1

```console:サーバー172.16.1.105ユーザーroot
curl -s http://1st.local/ | diff -s --label curl - /var/www/_1/index.html
```

`1st.local`に設定した`index.html`が`curl`コマンドで取得され、配置しておいた`index.html`と一致します。

```console:サーバー172.16.1.105ユーザーroot
# curl -s http://1st.local/ | diff -s --label curl - /var/www/_1/index.html
Files curl and /var/www/_1/index.html are identical
```

### サイト2

```console:サーバー172.16.1.105ユーザーroot
curl -s http://2nd.local/ | diff -s --label curl - /var/www/_2/index.html
```

`1st.local`とは別に立てたWebサイト`2nd.local`へアクセスしています。

```console:サーバー172.16.1.105ユーザーroot
# curl -s http://2nd.local/ | diff -s --label curl - /var/www/_2/index.html
Files curl and /var/www/_2/index.html are identical
```

### 知らないサイト

proxyを設定していないドメインを指定されたら、proxyのデフォルト設定に従ったデフォルトサイトが表示されます。

```console:サーバー172.16.1.105ユーザーroot
curl http://3rd.local/
```

```console:サーバー172.16.1.105ユーザーroot
# curl http://3rd.local/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
```

# 仕舞い

今回は実験だけです。動作確認が終わったら、各設定を削除しましょう。

```console:サーバー172.16.1.101ユーザーroot
cd /etc/unbound/unbound.conf.d
sed -i -e"/1st.local./d" -e"/2nd.local./d" -e"/3rd.local./d" machines.list
systemctl restart unbound
```

```console:サーバー172.16.1.103:ユーザーroot
cd /etc/nginx/sites-enabled
rm 1st.conf 2nd.conf
cd /etc/nginx/sites-available
rm 1st.conf 2nd.conf
nginx -s reload
```

- ProxmoxVEでコンテナ`172.16.1.105`をシャットダウンして削除