> For AI agents: the complete documentation index is available at /resource/ucidm/docs/on-premise/dev/llms.txt, the full documentation bundle is available at /resource/ucidm/docs/on-premise/dev/llms-full.txt.

# Reverse Proxy

UCIDM API や管理画面にアクセスするときに HTTPS で通信するためのリバースプロキシを設定します。プロキシサーバーには [Apache](https://httpd.apache.org/) を使います。

あらかじめ、お客様のドメイン向けの SSL/TLS サーバー証明書をご用意ください。

サーバー証明書の自動更新を行う場合は [証明書の自動更新](/resource/ucidm/docs/on-premise/dev/tech/mod_md.md) もあわせてご参照ください。

## インストール \{#installation}

```bash
# dnf install -y httpd mod_ssl
```

### SELinux の設定 \{#selinux-settings}

SELinux が有効な場合はリバースプロキシの振る舞いを許可する必要があります。

SELinux が有効かどうかは次のコマンドで調べられます。

```bash
# getenforce
Enforcing  # SELinux 有効
```

`httpd_can_network_connect` を有効にします。

```bash
# setsebool -P httpd_can_network_connect on
# getsebool httpd_can_network_connect
httpd_can_network_connect --> on
```

SELinux を有効にした状態で通信できないときは `/var/log/audit/audit.log` にログがでていないかをチェックしてください。

### SELinux で許可されているポート番号一覧を調べる \{#selinux-allowed-ports}

UCIDM API で使う 8443 番ポートは、SELinux の既定のポリシーで httpd に許可されています (`http_port_t`)。
特定のポート番号で通信できないときは許可されているポート番号を試してみてください。

```bash
# dnf install -y policycoreutils-python-utils
# semanage port -l | grep http
```

## Apache の設定 \{#apache-settings}

UCIDM パッケージ (`osstech-ucidm-common`) は、Apache の設定のサンプルを `/opt/osstech/share/ucidm/httpd/conf.d/` に配置します。
UCIDM だけを動かすサーバー向けのサンプルです。

| ファイル                   | 内容                                                                       |
| ---------------------- | ------------------------------------------------------------------------ |
| `ucidm.conf`           | Web UI (443) と UCIDM API (8443) の VirtualHost、セキュリティヘッダー、ログの書式、サーバー全体の設定 |
| `trusted-origins.conf` | クロスオリジンリクエストを許可するオリジン                                                    |

2つのファイルを `/etc/httpd/conf.d/` にコピーします。

```bash
# cp /opt/osstech/share/ucidm/httpd/conf.d/*.conf /etc/httpd/conf.d/
```

> \[!WARNING]
> `cp -a` や `mv` で配置すると、コピー元の SELinux のコンテキストが残ります。
> コピーには `cp` を使ってください。
> `cp -a` や `mv` で配置してしまった場合は、`restorecon -Rv /etc/httpd/conf.d` を実行してコンテキストを既定に戻してください。

`/etc/httpd/conf/httpd.conf` と `/etc/httpd/conf.d/ssl.conf` は変更しません。
どちらも httpd と mod_ssl のパッケージが管理する設定ファイルで、置き換えると httpd のアップデートで配布される変更が反映されなくなるためです。
443 番ポートの Listen は `ssl.conf` が、8443 番ポートの Listen は `ucidm.conf` が設定します。

`ucidm.conf` には、`ServerTokens`、`ServerSignature`、`TraceEnable`、`AllowMethods` のようにサーバー全体に効く設定も含まれています。
同じサーバーで UCIDM 以外のサイトも公開する場合は、これらの設定がそのサイトにも効くことに注意してください。

80 番ポートから 443 番ポートへのリダイレクトはサンプルに含めていません。
必要な場合は追加してください。

### VirtualHost の設定 \{#virtualhost-settings}

`/etc/httpd/conf.d/ucidm.conf` の [VirtualHost ディレクティブ](https://httpd.apache.org/docs/2.4/mod/core.html#virtualhost) で、UCIDM の各サービスのポート番号へプロキシします。

- ID 連携管理画面やユーザープロファイル画面といった Web UI のプロキシ
- UCIDM API のプロキシ

2つの VirtualHost の `ServerName` を、UCIDM にアクセスするときのホスト名に変更してください。
アクセス元を制限する場合は、[Location ディレクティブ](https://httpd.apache.org/docs/2.4/mod/core.html#location) ごとに `Require` を変更します。

プロキシ先のポート番号は、`/opt/osstech/etc/ucidm/common.env` の既定値 (`UCIDM_UI_PORT=5030`、`ADMIN_UI_PORT=3030`、`API_PORT=18080`) に合わせています。
`common.env` のポート番号を変更した場合は、こちらも合わせて変更してください。

#### Web UI のプロキシ \{#web-ui-proxy}

```conf
<VirtualHost *:443>
  ServerName ucidm.example.com
  ...

  <Location "/ui">
    ProxyPass http://localhost:5030/ui retry=10
    ProxyPassReverse http://localhost:5030/ui
    Require all granted
  </Location>

  <Location "/ui/user">
    ProxyPass http://localhost:5030/ui/user retry=10
    ProxyPassReverse http://localhost:5030/ui/user
    Require all granted
  </Location>

  <Location "/ui/admin">
    ProxyPass http://localhost:5030/ui/admin retry=10
    ProxyPassReverse http://localhost:5030/ui/admin
    Require all granted
  </Location>

  <Location "/sys">
    ProxyPass http://localhost:3030/sys retry=10
    ProxyPassReverse http://localhost:3030/sys
    Require all granted
  </Location>

  RewriteRule ^/$ /ui [R=301,L]
</VirtualHost>
```

#### API サーバーのプロキシ \{#api-server-proxy}

```conf
<VirtualHost *:8443>
  ServerName ucidm.example.com
  ...

  <Location "/">
    ProxyPass http://localhost:18080/ retry=10
    ProxyPassReverse http://localhost:18080/
    Require all granted
  </Location>
</VirtualHost>
```

#### SSL/TLS サーバー証明書の設定 \{#ssl-tls-certificate}

`ucidm.conf` は、疎通確認のための自己署名の証明書を参照しています。
この証明書と秘密鍵は、UCIDM パッケージのインストール時に作られます。

| ファイル                              | パーミッション |
| --------------------------------- | ------- |
| `/etc/pki/tls/certs/sample.crt`   | 644     |
| `/etc/pki/tls/private/sample.key` | 600     |

証明書は、インストールした時点のホスト名に対して発行されます。
有効期限は 365 日です。
2つのファイルがあれば作り直さないため、UCIDM パッケージをアップデートしても内容は変わりません。
ホスト名を変更したときや有効期限が切れたときは、次のコマンドで作り直してください。

```bash
# /opt/osstech/bin/ucidm-httpd-gencerts --force
# systemctl reload httpd
```

本番環境では、お客様でご用意いただいた SSL/TLS サーバー証明書に差し替えてください。
サーバー証明書は `/etc/pki/tls/certs/`、秘密鍵は `/etc/pki/tls/private/` に、任意のファイル名で配置します。
どちらも RHEL で証明書と秘密鍵を置く標準のディレクトリで、`cp` で配置すれば SELinux のコンテキストは既定のままで httpd から読めます。
`/etc/pki/tls/private/` のパーミッションは 755 のため、秘密鍵のファイルは root だけが読めるように 600 にしてください。

```bash
# cp server.crt /etc/pki/tls/certs/
# cp server.key /etc/pki/tls/private/
# chmod 600 /etc/pki/tls/private/server.key
```

`ucidm.conf` の2つの VirtualHost で、次の設定を配置したファイルに変更します。

```
SSLCertificateFile /etc/pki/tls/certs/server.crt
SSLCertificateKeyFile /etc/pki/tls/private/server.key
```

`sample.crt` と `sample.key` は UCIDM パッケージが管理するファイルで、UCIDM パッケージをアンインストールすると削除されます。
本番環境の証明書には、これらのファイル名を使わないでください。

### Trusted Origins の設定 \{#trusted-origins}

クロスオリジンリクエストを許可する信頼済みオリジンを `/etc/httpd/conf.d/trusted-origins.conf` に設定します。
サンプルは、設定がコメントアウトされた状態になっています。

少なくとも `TRUSTED_ORIGIN_0` を定義する必要があります。
定義しない場合、httpd は起動時に以下のエラーとなり起動に失敗します。

```
At least TRUSTED_ORIGIN_0 must be defined in /etc/httpd/conf.d/trusted-origins.conf
```

`TRUSTED_ORIGIN_0` には UCIDM にアクセスするオリジン (スキームとホスト名) を設定します。

```conf
## /etc/httpd/conf.d/trusted-origins.conf
Define TRUSTED_ORIGIN_0 "https://ucidm.example.com"
```

複数のオリジンを許可する場合は連番で追加します。
`ucidm.conf` が読み込むのは `TRUSTED_ORIGIN_2` までです。

```conf
Define TRUSTED_ORIGIN_0 "https://ucidm.example.com"
Define TRUSTED_ORIGIN_1 "https://sub.example.com"
Define TRUSTED_ORIGIN_2 "https://partner.example.co.jp"
```

`ucidm.conf` はこのファイルで定義した値を読むため、`ucidm.conf` より先に読み込まれる必要があります。
`/etc/httpd/conf.d/` のファイルは名前の順に読み込まれるので、ファイル名は `trusted-origins.conf` のままにしてください。

### 設定の確認とサービスの起動 \{#verify-and-start-service}

httpd の設定内容が正しいかをチェックします。

```bash
# systemctl start httpd-init
# apachectl configtest
Syntax OK
```

`ssl.conf` が参照する `/etc/pki/tls/certs/localhost.crt` は、httpd の初回起動の直前に `httpd-init` サービスが作ります。
httpd を一度も起動していない状態で `apachectl configtest` を実行すると、この証明書が無いというエラーになるため、先に `httpd-init` サービスを起動しています。

httpd サービスを起動し、OS の再起動時に httpd サービスを自動起動するように設定します。

```bash
# systemctl enable --now httpd
# systemctl is-enabled httpd
enabled
```

## リバースプロキシの疎通確認 \{#local-connection}

httpd の設定完了後、サービスを起動してローカルホストからの HTTPS の疎通確認を行います。

443 番ポートの VirtualHost は `ServerName` に一致するホスト名でアクセスしたときだけ使われるため、`curl` の `--resolve` で `ServerName` のホスト名を `127.0.0.1` に向けて確認します。
疎通確認のための証明書は自己署名なので、`-k` で証明書の検証を省きます。

```bash
$ curl -k --head --resolve ucidm.example.com:443:127.0.0.1 https://ucidm.example.com/sys/
HTTP/1.1 200 OK
$ curl -k --head --resolve ucidm.example.com:443:127.0.0.1 https://ucidm.example.com/ui/
HTTP/1.1 200 OK
```

```bash
$ curl -k --resolve ucidm.example.com:8443:127.0.0.1 https://ucidm.example.com:8443/status/version
{"ucidmVersion":"1.9.0","serverVersion":"814902d","idFederationClientVersion":"91a6c9e","mongoDBVersion":"8.2.4","rabbitMQVersion":"4.2.5"}
```

### リモートホストからの疎通確認 \{#remote-connection}

Web ブラウザで `https://${ホスト名}/sys/` へアクセスしてログイン画面が表示されることを確認します。
疎通確認のための証明書を使っている間は、自己署名の証明書であるという警告が Web ブラウザに表示されます。

疎通できない場合はファイアウォールの設定などを確認してください。

```bash
# systemctl status firewalld
```
