Ubuntu 19.10 Eoan Ermine に Apache 2.4 をインストールして CGI を動かす

## 概要

- Ubuntu に apache2 パッケージをインストール
- a2enmod コマンドで mod_cgid を有効化
- CGI スクリプトを設置
- a2ensite コマンドで設定を有効化

## Apache 2 のインストール

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

```
$ sudo apt install apache2
```

バージョンを確認。

```
$ /usr/sbin/apachectl -V
Server version: Apache/2.4.41 (Ubuntu)
Server built:   2019-08-14T14:36:32
Server's Module Magic Number: 20120211:88
Server loaded:  APR 1.6.5, APR-UTIL 1.6.1
Compiled using: APR 1.6.5, APR-UTIL 1.6.1
Architecture:   64-bit
Server MPM:     event
  threaded:     yes (fixed thread count)
    forked:     yes (variable process count)
Server compiled with....
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=256
 -D HTTPD_ROOT="/etc/apache2"
 -D SUEXEC_BIN="/usr/lib/apache2/suexec"
 -D DEFAULT_PIDLOG="/var/run/apache2.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="mime.types"
 -D SERVER_CONFIG_FILE="apache2.conf"
```

起動しているのを curl 等でアクセスして確認。

```
$ curl -I http://localhost/
HTTP/1.1 200 OK
Date: Tue, 21 Jan 2020 10:47:37 GMT
Server: Apache/2.4.41 (Ubuntu)
Last-Modified: Tue, 21 Jan 2020 10:28:46 GMT
ETag: "2aa6-59ca3df7ac2c0"
Accept-Ranges: bytes
Content-Length: 10918
Vary: Accept-Encoding
Content-Type: text/html
```

## mod_cgid の有効化

a2enmod cgi または a2enmod cgid で cgid モジュールを有効化する。

```
$ sudo a2enmod cgi
Your MPM seems to be threaded. Selecting cgid instead of cgi.
Enabling module cgid.
To activate the new configuration, you need to run:
  systemctl restart apache2
```

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

> Unix オペレーティングシステムの中には、マルチスレッドのサーバから プロセスを fork するのが非常にコストの高い動作になっているものがあります。 理由は、新しいプロセスが親プロセスのスレッドすべてを複製するからです。 各 CGI 起動時にこのコストがかかるのを防ぐために、mod_cgid は子プロセスを fork して CGI スクリプトを実行するための 外部デーモンを実行します。 主サーバは unix ドメインソケットを使ってこのデーモンと通信します。
> 
> コンパイル時にマルチスレッド MPM が選ばれたときは mod_cgi の代わりに必ずこのモジュールが使用されます。 ユーザのレベルではこのモジュールの設定と動作は mod_cgi とまったく同じです。唯一の例外は ScriptSock ディレクティブの 追加で、このディレクティブは CGI デーモンとの通信用のソケットの名前を 指定します。

## CGI スクリプトを設置

/var/www/hello ディレクトリを作成。

```
$ sudo mkdir /var/www/hello
```

CGI スクリプトファイルを編集するユーザーに権限を与える。

```
$ sudo chown hoge:hoge /var/www/hello
```

index.cgi ファイルを設置する。

```
$ vim /var/www/hello/index.cgi
```

index.cgi の中身。今回はシェルスクリプトによる CGI とする。

```sh
#!/usr/bin/sh
echo 'Status: 200 OK'
echo 'Content-Type: text/html;charset=utf-8'
echo ''
echo '<html><body>Hello, world.</body></html>'
```

index.cgi に実行権限を付与する。

```
$ chmod 755 /var/www/hello/index.cgi
```

## 設定ファイルを設置

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

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

hello.conf ファイルの中身を修正する。

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

hello.conf ファイルは以下の内容に置き換える。

```hello.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

  # CGI を動かす設定
  ScriptAlias /hello/ /var/www/hello/
  <Directory "/var/www/hello/">
    Options ExecCGI
    AddHandler cgi-script .cgi
    DirectoryIndex index.cgi
    AllowOverride None
    Require all granted
  </Directory>

</VirtualHost>
```

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

現時点では 000-default が有効になっている。

```
$ ls -l /etc/apache2/sites-enabled/ | grep conf
lrwxrwxrwx 1 root root 35  1月 21 19:28 000-default.conf -> ../sites-available/000-default.conf
```

a2ensite コマンドで hello.conf を有効にする。

```
$ sudo a2ensite hello
Enabling site hello.
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
```

hello.conf が有効になっているのを確認できる。

```
$ ls -l /etc/apache2/sites-enabled/ | grep conf
lrwxrwxrwx 1 root root 29  1月 21 20:03 hello.conf -> ../sites-available/hello.conf
```

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

```
$ sudo systemctl restart apache2
```

CGI が動作しているのを curl コマンド等で確認できる。

```
$ curl -i http://localhost/hello/
HTTP/1.1 200 OK
Date: Tue, 21 Jan 2020 11:09:41 GMT
Server: Apache/2.4.41 (Ubuntu)
Content-Length: 40
Content-Type: text/html;charset=utf-8

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

## 参考資料

- [Install and Configure Apache | Ubuntu tutorials](https://tutorials.ubuntu.com/tutorial/install-and-configure-apache)
- [Ubuntu 18.04 » Ubuntu Server Guide » Web Servers » HTTPD \- Apache2 Web Server](https://help.ubuntu.com/lts/serverguide/httpd.html)
- [File: apache2\.README\.Debian \| Debian Sources](https://sources.debian.org/src/apache2/2.4.41-2/debian/apache2.README.Debian/)
- [Ubuntu – eoan の apache2 パッケージに関する詳細](https://packages.ubuntu.com/ja/eoan/apache2)
- [Ubuntu Manpage: a2enmod, a2dismod \- enable or disable an apache2 module](http://manpages.ubuntu.com/manpages/eoan/en/man8/a2enmod.8.html)
- [Ubuntu Manpage: a2ensite, a2dissite \- enable or disable an apache2 site / virtual host](http://manpages.ubuntu.com/manpages/eoan/en/man8/a2ensite.8.html)
- [Apache Tutorial: CGI による動的コンテンツ \- Apache HTTP サーバ バージョン 2\.4](https://httpd.apache.org/docs/2.4/ja/howto/cgi.html)
- [RFC 3875 \- The Common Gateway Interface \(CGI\) Version 1\.1](https://tools.ietf.org/html/rfc3875)