Cockpitをリバースプロキシ（Apache）の配下で使えるようにする

# はじめに

LinuxをWeb上にて各種設定をするための便利なツールとしてcockpitがあります．そのcockpitについてリバースプロキシを踏み台にして活用する方法を示します．ただし，リバースプロキシはApacheを用いるものとして説明します．

それにあたっては，
(1) [Cockpitをリバースプロキシの配下で使えるようにする](https://qiita.com/h-sakuzo/items/bf3a3a80a9eba70e7bab)
(2) [Reverse Proxy setup for Cockpit with Apache (in a sub directory)](https://evermeet.cx/wiki/Reverse_Proxy_setup_for_Cockpit_with_Apache_(in_a_sub_directory))
(3) [Cant proxy from apache. #8647](https://github.com/cockpit-project/cockpit/issues/8647)
を参考にしております．

なお，almalinux 9 である自環境にて動作を確認しましたが，すべての環境での動作は保障いたしませんので，悪しからずご了承ください．

# 前提条件

(1) [cockpitが使える状態とします．](https://higmasan.com/cockpit/install-cockpit-in-almalinux/)
(2) [apacheでSSL通信が可能であるものとします．](https://qiita.com/heimaru1231/items/3786e6a2b0d548bd76f1)
(3) 文中のサーバ名はsrv.hoge.comとします．
(4) URLにおけるドメインもsrv.hoge.comとします．
(5) confファイルの編集にはviとかemacsなどのエディタが使えるものとします．

# 設定方法
## cockpit.conf

管理者権限にて /etc/cockpit/cockpit.conf を編集します．
```
# vi /etc/cockpit/cockpit.conf
```
それによって，アクセス先を
https://srv.hoge.com:9090/
から
https://srv.hoge.com:9090/cp/
に変更する役割を持たせます．

何もないようであれば新規編集となるし，そうでなければ追加になるでしょう．

```/etc/cockpit/cockpit.conf
# 新規編集
[WebService]
Origins = https://srv.hoge.com https://srv.hoge.com:9090
ProtocolHeader = X-Forwarded-Proto
AllowUnencrypted = true
UrlRoot = /cp/
```
:::note info
UrlRoot = /cp/　の部分は各自お好みで変えて下さい．ただし，以下の部分も整合が必要です． 
:::



## リバースプロキシ
管理者権限にて/etc/httpd/conf.d/cockpit.conf を編集します．
```
# vi /etc/httpd/conf.d/cockpit.conf
```
ここでは，
https://srv.hoge.com:9090/cp/
を
https://srv.hoge.com/cp/
としてアクセス可能にするため，apacheによってreverse proxyを立てることとします．

```/etc/httpd/conf.d/cockpit.conf
<IfModule mod_ssl.c>
  <VirtualHost *:443>
     ServerName srv.hoge.com
     SSLEngine On

     # Set the path to SSL certificate
     SSLCertificateKeyFile /etc/letsencrypt/live/srv.hoge.com/srv.key
     SSLCertificateFile /etc/letsencrypt/live/srv.hoge.com/srv.pem
     SSLCertificateChainFile /etc/letsencrypt/live/srv.hoge.com/chain.cert
     # 上記のcertificateに関する3行は各自の環境に合わせてお書き換えください．

     SSLProxyEngine On
     SSLProxyVerify none
     SSLProxyCheckPeerCN Off
     SSLProxyCheckPeerName Off
     SSLProxyCheckPeerExpire Off
     ProxyPreserveHost On
     ProxyRequests Off

     ProxyPass /cockpit/socket wss://srv.hoge.com:9090/cockpit/socket
     ProxyPassReverse /cockpit/socket wss://srv.hoge.com/cockpit/socket

     ProxyPass "/cp/" "https://srv.hoge.com:9090/cp/"
     ProxyPassReverse "/cp/" "https://srv.hoge.com/cp/"

   </VirtualHost>
</IfModule>
```

:::note info
srv.hoge.comと書いている部分は各自の環境で修正してください． 
:::
:::note warn
/etc/cockpit/cockpit.conf において UrlRoot=/cp/ の cp を別名にした場合は /etc/httpd/conf.d/cockpit.conf における /cp/ の部分も同じく修正してください． 
:::

### 追記（2024/01/14）
上記の方法で私の場合ですと不具合が見つかりましたので，記事：[Proxying Cockpit over Apache with LetsEncrypt](https://cockpit-project.org/external/wiki/Proxying-Cockpit-over-Apache-with-LetsEncrypt)のなかほど，「Set up Apache Reverse Proxy in a Subdirectory」の部分を参考にしたところ，以下の書き方が安定しているように感じます．（あくまでも自分のマシンに対してですが）
```
# 新規作成
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule ssl_module modules/mod_ssl.so


<IfModule mod_ssl.c>
	  <VirtualHost *:443>
		SSLProxyEngine          On
                # required module
                RewriteEngine           On
                # required module
                ProxyPreserveHost       On
                # required
                ProxyRequests           Off
                # RECOMMENDED, disables forwarding, see https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxyrequests
                ProxyErrorOverride      Off
                # if possible, present cockpit's error pages instead of apache's
                SSLProxyVerify optional_no_ca
                # cockpit has a self-signed cert by default, therefore no CA
                SSLProxyCheckPeerCN Off
                # SSL error without this
                SSLProxyCheckPeerName Off
                # SSL error without this
                SSLProxyCheckPeerExpire Off
                # recommended since potential SSL error without this
                RequestHeader set "X-Forwarded-Proto" "https"
                # required by cockpit.conf
                # following is adapted from https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html
                RewriteCond %{HTTP:Upgrade} websocket [NC]
                RewriteCond %{HTTP:Connection} upgrade [NC]
                RewriteRule "^/cp/(.*)" "wss://127.0.0.1:9090/cp/$1" [P,L]
                # when websocket in upgrade AND
                # within UrlRoot, rewrite proxy with wss://
                RewriteCond ${HTTP:Upgrade} !=websocket [NC]
                RewriteRule "^/cp/(.*)" "https://127.0.0.1:9090/cp/$1" [P,L]
                # when no websocket upgrade AND
                # within UrlRoot, rewrite proxy with https://
        </VirtualHost>
</IfModule>
```
2024/01/14追記：ここまで


## その後の仕上げ

以下のコマンドを管理者権限にて打ちます．
```
# systemctl restart cockpit
# systemctl restart httpd
```
::: note info
または
```
# systemctl restart cockpit httpd
```
でも良いでしょう．
:::
## 動作確認

ブラウザにてURLを https://srv.hoge.com/cp/ として，cockpitの画面がでるかどうかを確認します．
![スクリーンショット 2023-12-23 185114.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/773471/9471a718-5e72-11eb-09c2-4817df7bb71b.png)
このような画面が表示されれば設定は成功です．

# 注意
この設定を行うと，不特定多数に表示する危険性があるため，アクセス制限を行うなどの工夫が必要ではないかと思われます．
また，リバースプロキシにおいては，apacheよりもnginxやsquidを用いる場合が多いので，この記事はあくまでもapacheを用いる場合を対象としています．

# 参考

(1) [Cockpitをリバースプロキシの配下で使えるようにする](https://qiita.com/h-sakuzo/items/bf3a3a80a9eba70e7bab)
(2) [Reverse Proxy setup for Cockpit with Apache (in a sub directory)](https://evermeet.cx/wiki/Reverse_Proxy_setup_for_Cockpit_with_Apache_(in_a_sub_directory))
(3) [Cant proxy from apache. #8647](https://github.com/cockpit-project/cockpit/issues/8647)