サイトアイコン 上尾市のWEBプログラマーによるブログ

「初めてのWebサーバ「Apache」CentOS 7編」の感想・備忘録2

「初めてのWebサーバ「Apache」CentOS 7編」の感想・備忘録1の続き

CGI, PHP

CGIの設定

デフォルトでは/var/www/cgi-binをCGI置き場とし「http://xxx.xx/cgi-bin/プログラム名」でアクセスされることが想定されている。
ただし、Options Noneが設定さており、Options ExecCGIに変更しないと有効にはならない。
ScriptAlias /cgi-bin/ "/var/www/cgi-bin"
<Directory"/var/www/cgibin">
AllowOverride None
Options None
Require all granted
</Directory>

CGIの実行にはmod_cgiまたはmod_cgidモジュールが使われている。
設定ファイル/etc/httpd/conf.modules.d/01-cgi.confでMPMによってロードするモジュールが切り分けられている。
(preforkはmod_cgi、workerまたはeventはmod_cgid)

※ SELinuxが有効になっている場合、httpd_enable_cgiをオンにしないとCGIが動作しない。
getsebool -a | grep httpd_enable_cgiで確認
getsebool -P httpd_enable_cgi onで有効化

PHPの設定

yum install phpでインストールすると、デフォルトではモジュールとして動作し、モジュールの設定ファイル/etc/httpd/conf.modules.d/10-php.confが生成される。

<IfModule prefork.c>
LoadModule php5_module modules/libphp5.so
</IfModule>
となっているため、デフォルトではprefork MPMでしかPHPは動作しない。

また、ApacheのためのPHP設定ファイル/etc/httpd/conf.d/php.confも生成される。

event MPMでPHPを動作させる

/etc/httpd/conf.modules.d/00-mpm.confを編集してevent MPMにした場合、そのままではPHPは動作しない。
動作させる方法はいくつかあるが、php-fpmを使うのが定番である。

  1. yum install php-fpm
  2. systemctl enable php-fpm
  3. /etc/httpd/conf/httpd.confを修正
    <FilesMatch \.php$>
    SetHandler application/x-httpd-php
    </FilesMatch>
    を以下に変更
    <FilesMatch \.php$>
    SetHandler "proxy:fcgi://127.0.0.1:9000"
    </FilesMatch>

以下をコメントアウト
#php_value session.save_handler "files"
#php_value session.save_path "/var/lib/php/session"

アクセス制御

特定のIPのみ許可

Apache2.4以降ではRequireディレクティブを使用する。

Apache2.4より前のバージョンではOrder, Allow, Denyの3つのディレクティブを使用していた。

アクセス制御を担当するのはauthz_host_moduleモジュール(旧mod_accessモジュール)である。
/etc/httpd/conf.modules.d/00-base.confでLoadModuleディレクティブによってロードされている。
LoadModule authz_host_module modules/mod_authz_host.so

Require AllとRequireAny

Require not ip 192.168.1.2
で特定のIPを拒否できる。
ただし、デフォルトでは/var/wwwと/var/www/htmlにRequire all grantedが設定されているため、「全て許可」または「192.168.1.2を拒否」という矛盾した条件なりエラーとなってしまう。
(Require ipは親のRequire all grantedを上書きするが、Require not ipは上書きしない)
このような場合は、<RequireAll>セクションディレクティブで全ての条件を囲む。
<RequireAll>
Require all granted
Require not ip 192.168.1.2
</RequireAll>

<RequireAny>セクションディレクティブで囲むと「いずれかのRequireディレクティブの条件を満たせば許可」という指定になる。
ただし、デフォルトで<RequireAny>とみなされるので、通常は<RequireAny>を記述せずに省略する。

認証

ベーシック認証

<Directory/var/www/html/hoge>
AuthType Basic
AuthName "Restricted Pages"
AuthUserFile "/etc/httpd/.htpasswd"
Require valid-user
</Directory>
※ 特定のユーザーのみ許可する場合はRequire user taroのようにする

ベーシック認証にはmod_auth_basicモジュール(旧mod_auth)が使用される。
/etc/httpd/conf.modules.d/00-base.confでLoadModuleディレクティブによってロードされている。
LoadModule auth_basic_module modules/mod_auth_basic.so

ダイジェスト認証

<Directory/var/www/html/hoge>
AuthType Digest
AuthName "Digest test"
AuthUserFile "/etc/httpd/.digest"
Require valid-user
</Directory>
※ ダイジェスト認証用のパスワードファイルはhtpasswdではなくhtdigestコマンドで生成する。

ダイジェスト認証は暗号化されるので、Basic認証よりも安全である。
ダイジェスト認証にはmod_auth_digestモジュールが使用される。
/etc/httpd/conf.modules.d/00-base.confでLoadModuleディレクティブによってロードされている。
LoadModule auth_digest_module modules/mod_auth_digest.so

SSL

テスト用証明書の作成

mod_sslをインストールする。
yum install mod24_ssl
(書籍ではyum install mod_sslとなっているが、Apache2.4の場合はmod24_sslでないとconflictエラーになる)
/etc/httpd/conf.modules.d/00-ssl.confが作成され、mod_sslモジュールがロードされる。
LoadModule ssl_module modules/mod_ssl.so

/etc/httpd/conf.d/ssl.confが作成される。
SSLCertificateFileディレクティブで証明書のパス、SSLCertificateKeyFileディレクティブでサーバ鍵(秘密鍵)のパスが指定されている。
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

mod_sslパッケージには、テスト用の仮の証明書が/etc/pki/tls/certs/localhost.crtとして用意されている。

SSLの概要

公開鍵と秘密鍵のペアを使用した公開鍵暗号方式を採用している。
ブラウザはあらかじめサーバの公開鍵を受け取る必要があるが、WEBの場合は見ず知らずのサーバなので正当性を判断することが難しい。
そのため、第三者が発行したデジタル証明書(公開鍵が正しいものであることを証明)によって、サーバの正当性を確かめている。

デジタル証明書を発行できるのは信頼できる機関を認証局(CA)と呼ぶ。
認証局はルート認証局を頂点とする階層構造で構成され、上位の認証局が下位の認証局を認証していく。

独自証明書のサイトをChromeで開く場合、エラー画面でthisisunsafeとキー入力するとアクセスできる。

ログ

ログファイルの設定

/var/log/httpdにログが出力される。
/etc/httpd/logsは/var/log/httpdへのシンボリックリンクになっている。

アクセスログ

アクセスログの出力はCustomLogディレクティブで指定する。
CustomLog パス 使用するフォーマット

フォーマットはcombinedとcommoonの2つがあらかじめ定義されていて、デフォルトはcombinedになっている。
パスはServerRootディレクティブからの相対パスで指定する。
<IfModule log_config_module>
〜省略〜
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{UserAgent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
〜省略〜
CustomLog "logs/access_log" combined
</IfModule>

エラーログ

エラーログはErrorLogディレクティブとLogLevelディレクティブで指定する。
ErrorLog パス
LogLevel レベル

デフォルトでは以下の設定になっている。
ErrorLog logs/error_log
LogLevel warn

バーチャルホスト

IPベース

IPアドレスによってDocumentRootディレクティブを振り分ける。
そのため、サーバに複数のIPが割り当てられている必要がある。
使い道は、WAN側とLAN側で別のWebサイトを公開したい場合などに限られる。
httpd -Sでバーチャルホストの設定を確認することができる。

設定例

www1 IN A 192.168.1.12
www2 IN A 192.168.1.13
というDNSレコードの場合

<VirtualHost 192.16.1.12:80>
ServerName www1.example.com
DocumentRoot /var/www/html
</VirtualHost>

<VirtualHost 192.16.1.13:80>
ServerName www2.example.com
DocumentRoot /var/www/html2
ErrorLog logs/www2-error_log
CustomLog logs/www2-access_log
</VirtualHost>

名前ベース

リクエストのHostヘッダを使ってDocumentRootディレクティブを振り分ける。
DNSで1つのIPアドレスに複数の名前を割り当てる必要がある。

設定ファイルの記述は、<VirtualHost>セクションディレクティブのIPアドレスが同じになる点以外はIPベースの場合と同じになる。
また、IPベースの場合と同様に、httpd -Sでバーチャルホストの設定を確認することができる。

設定例

www1 IN A 192.168.1.12
www2 IN CNAME www1
というDNSレコードの場合

<VirtualHost 192.16.1.12:80>
ServerName www1.example.com
DocumentRoot /var/www/html
</VirtualHost>

<VirtualHost 192.16.1.12:80>
ServerName www2.example.com
DocumentRoot /var/www/html2
ErrorLog logs/www2-error_log
CustomLog logs/www2-access_log
</VirtualHost>

モバイルバージョンを終了