ここでは、Apache HTTP Serverを利用したWebサーバの設定方法について記述する。
FC4、FC5、FC6、FC7ではyumで、openSUSE 10.0ではyastでインストールすることができる。
Apacheにはバージョン1系統と2系統があるが、すでに2が主流となっているので、以下の記述は2についてである。なおFC5では2.2が標準になっている。
Apacheのソースファイルなどは、各ミラーサイトから入手できる。
主要な設定は
/etc/httpd/conf/httpd.conf
で行う。httpd.confの日本語訳はここ。openSUSE 10.0の場合は、ファイルが細かく分かれており、httpd.confはそれらのファイルをincludeで読み込んでいるので注意。以下特に注釈がない場合は、httpd.confもしくはそこでincludeされるファイルに記述する。
なお、ubuntuなどdebian系のOSでは、
/etc/apache2/apache2.conf
および、そのサブディレクトリとなっている。
正常にインストールされていれば、Apacheは何も設定しないで起動しても、デフォルトのページが表示されるはずである。
http://www.example.com/でアクセスしたときに表示されるディレクトリはDocumentRootで設定する。設定ファイルで特に設定を行わない限り、このディレクトリを起点として、アクセスされる。例えば、下記のような設定で、http://www.example.com/foo/とアクセスした場合、/srv/www/htdocs/foo/内のファイルが参照される。ServerNameで、サーバ名をServerAdminで連絡先をメールアドレス指定する。
DocumentRoot "/srv/www/htdocs" ServerName www.example.com ServerAdmin info@example.com
サーバサイドインクルード(SSI)を有効にするには、下記のように設定を行う。
AddType text/html .shtml AddOutputFilter INCLUDES .shtml
この場合、shtmlで終わるファイルでのみSSIを使用することができる。htmlで終わるファイルでもSSIを使えるようにするには、htmlも追加する。しかしながら、あまり多くの拡張子を追加すると、サーバのパフォーマンスに影響する。
また、標準の設定では、SSIを使用したファイルには、最終更新日時が付加されず、ブラウザ側のキャッシュの動作にもよろしくないので、必要最小限にすることを推奨する。SSIで最終更新日時を付加する方法は下記を参照。
そしてOptionsで、Includesを指定する。
#SSIを許可する Options Includes
もしくは、他の設定を引き継いで、SSIの設定のみ許可に変更するには、
#SSIの実行を許可する Options +Includes
逆に、SSIの実行を禁止するには
#CGIの実行を禁止する Options -Includes
とする。
下記の設定を追加すると、拡張子がcgiおよびplのファイルでCGIが使えるようになる。
AddHandler cgi-script .cgi .pl
そしてOptionsで、ExecCGIを指定する。
#CGIの実行を許可する Options ExecCGI
もしくは、他の設定を引き継いで、CGIの設定のみ許可に変更するには、
#CGIの実行を許可する Options +ExecCGI
逆に、CGIの実行を禁止するには
#CGIの実行を禁止する Options -ExecCGI
とする。
AddDefaultCharsetは有害なので、必ずコメントアウトしておく。
Apacheではファイル名を指定せずにアクセスすると、まず、デフォルトのファイルを探そうとする。このデフォルトのファイルは、DirectoryIndexに記述されている。
DirectoryIndex index.html index.html.var
例えば、index.shtmlとindex.phpもデフォルトファイルに加えたい場合は、
DirectoryIndex index.html index.html.var index.shtml index.php index.cgi
のようにする。なお、先頭に書いたファイルほど優先される。
このデフォルトファイルがどれも見つからない場合、Apacheはディレクトリ一覧を表示しようとする。これを制御するのが
Options Indexes
これを記述すると、一覧が表示されるようになる。OptionsにIndexesが存在しないと、エラーを返すようになる。
また、
#ディレクトリ一覧を表示する Options +Indexes
このように書いた場合は、他の設定はそのままで、ファイル一覧の表示がオンになる。逆に、
#ディレクトリ一覧を表示しない Options -Indexes
とすると、他の設定はそのままで、ファイル一覧の表示を禁止するようになる。
数分ごとにページ更新をチェックしたり、一度に大量のダウンロードを行うようなアプリケーションを遮断したい場合がある。それには、SetEnvIf User-Agentで場合分けをして、denyで拒否する。
SetEnvIf User-Agent "hugahuga" noua Deny from env=noua
<VirtualHost *:80> ServerName example.net ServerAlias *.example.net DocumentRoot /home/example.net/public_html ErrorLog /home/example.net/log/error.log CustomLog /home/example.net/log/access.log combined </VirtualHost> <Directory "/home/example.net/public_html"> Options FollowSymLinks ExecCGI Includes AllowOverride All Order allow,deny Allow from all </Directory>
SSIを使用した場合、最終更新日時は付加されなくなります。理由は、SSIを使っている場合、内容が毎回変化する可能性があり、ファイルの最終更新日時が同じだからといって、内容まで同じとは限らないからである。
SSIを使用するファイルにも最終更新日時を付加するようにするにはhttpd.confもしくは.htaccessに下記の一行を加え、SSIを含むファイルには実行属性を許可にする。
XBitHack full
参考:http://httpd.apache.org/docs/2.2/ja/mod/mod_include.html
有効期限を設定することにより、クライアントのブラウザはキャッシュをより有効に利用するようになりトラフィックの軽減につながる。また、逆に更新されたコンテンツをキャッシュから読み込まずにすむようになる。
文書の場合はmetaタグでも指定できるが、通常有効期限の長い画像ファイルの場合、ここにある方法を使う。
まず、httpd.confの中でmod_expiresが読み込まれているか確認する。具体的には
LoadModule expires_module modules/mod_expires.so
という行があるかどうか確認する。次にこのモジュールを使用したいところでExpiresActiveをOnにする。例えば、/var/www/example/ディレクトリでこのモジュールを有効にするには、下記のようにする。
<Directory "/var/www/example"> #有効期限モジュールを有効にする ExpiresActive On </Directory>
実際の有効期限は、下記のように記述する。
<Directory "/var/www/example"> ExpiresByType image/gif A7200 ExpiresByType image/gif "access plus 2 hours" ExpiresByType image/jpeg M7200 ExpiresByType image/jpge "modification plus 2 hours" ExpiresByType text/html A600 ExpiresByType text/html "access plus 10 minutes" ExpiresDefault A86400 ExpiresDefault "access plus 1 day" </Directory>
各2行はまったく同じ意味をA or Mプラス秒と文字列で記述したものである。Aはクライアントのアクセス時刻を基準にし、Mはサーバのファイルの更新日時を基準にする。
はじめの2行は、gifファイルの有効期限をアクセス時刻から2時間後に指定している。
次の2行は、jpegファイルの有効期限をファイルの更新時刻から2時間後に指定している。
次の2行は、htmlファイルの有効期限をファイルのアクセス時刻から10分後に指定している。
最後の2行は、ExpiresByTypeで指定されていないそれ以外のファイルのデフォルトの有効期限をアクセス時刻から1日後に指定している。
チューニング項目の一覧
項目 | 内容 | |
---|---|---|
KeepAlive | On|Off | これをOnにすると、ひとつのコネクションで複数のリクエストを出せるようになるため、パフォーマンスが向上する。 |
MaxKeepAliveRequests | 数値 | KeepAliveをOnにした場合、ひとつのコネクションで出せるリクエストの最大数。 |
StartServers | 数値 | |
MinSpareServers | 数値 | |
MaxSpareServers | 数値 | |
MaxClients | 数値 | |
MaxRequestsPerChild | 数値 | |
MinSpareThreads | 数値 | |
MaxSpareThreads | 数値 | |
ThreadsPerChild | 数値 |
まずは、
$ httpd -V
Server version: Apache/2.2.0
Server built: Feb 11 2006 17:41:05
Server's Module Magic Number: 20051115:0
Architecture: 64-bit
Server MPM: Prefork
threaded: no
forked: yes (variable process count)
Server compiled with....
-D APACHE_MPM_DIR="server/mpm/prefork"
-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=128
-D HTTPD_ROOT="/etc/httpd"
-D SUEXEC_BIN="/usr/sbin/suexec"
-D DEFAULT_PIDLOG="logs/httpd.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_LOCKFILE="logs/accept.lock"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="conf/mime.types"
-D SERVER_CONFIG_FILE="conf/httpd.conf"
で、preforkかworkerかを調べる。上記の例ではpreforkである。preforkの場合は、
<IfModule prefork.c> ~ </IfModule>
workerの場合は
<IfModule worker.c> ~ </IfModule>
を変更する。
指定されたドキュメントが存在しないなど、エラーが起きたときに、表示されるファイルはデフォルトで設定されているが、これを自分で作成したページを使って、カスタマイズすることもできる。
カスタマイズするには、ErrorDocumentディレクティブにエラー番号とファイル名を指定する。具体的には下記のようにする。
#404番のエラーが起きたときにカレントディレクトリの404.htmlファイルを表示する ErrorDocument 404 /404.html
この場合、404番のエラーが起きたときに、404.htmlを表示するように指定している。なお、ここでは/で始まっているが、これはLinuxファイルシステムのルートではなくDocumentRootのルートである。
たとえば、ここをクリックすると、このサイトのカスタマイズされたエラーページが出る。
Apacheサーバのバージョンを表示することは、それだけ攻撃者に情報を与えることになる。
これを表示しないようにするには以下のようにする。
ServerSignature Off
参考:http://httpd.apache.org/docs/2.2/ja/mod/mod_rewrite.html
以前から、Apacheにはキャッシュモジュールが付属していたものの、あまり実用になるものではなかった。Apache2.2からは、キャッシュモジュールがかなり改善されていて、これを使うと比較的簡単にパフォーマンスを上げることができる。
キャッシュ場所の違いで、メモリキャッシュとディスクキャッシュを選ぶことがでるが、ここでは、効果の高いメモリキャッシュを使ってみる。
まず、httpd.confの中の下記の2行でモジュールを読み込む。
LoadModule cache_module modules/mod_cache.so LoadModule mem_cache_module modules/mod_mem_cache.so
そして下記のように記述する
<IfModule mod_cache.c> <IfModule mod_mem_cache.c> CacheEnable mem / MCacheSize 4096 MCacheMaxObjectCount 100 MCacheMinObjectSize 1 MCacheMaxObjectSize 2048 CacheDefaultExpire 7200 CacheLastModifiedFactor 0.2 </IfModule> </IfModule>
CacheEnableは最初の引数にmemを指定してメモリキャッシュを行うようにしている。次の引数/は対象となるURLでこの場合は/以下すべてを対象としている。
MCacheMaxObjectCountはキャッシュに入る最大ファイル数。この場合、100個のドキュメントがキャッシュされる。
MCacheMinObjectSizeは1バイト以上のファイルをキャッシュするようにしている。
MCacheMaxObjectSizeは逆に2kB以上のファイルはキャッシュしないようにしている。
CacheDefaultExpireはデフォルトのキャッシュの有効期限で、有効期限や最終更新時刻が指定されていないファイルに関しては、この値が用いられる。デフォルト値は1時間。
CacheLastModifiedFactorは有効期限は設定されていないが、最終更新時刻は設定されているファイルに対して、有効期限を設定する際の重みを指定する。0.2とした場合、最終更新時刻から現時刻までの時間に0.2をかけた時間が過ぎると有効期限を迎えるように設定される。デフォルト値は0.1。
起動
apachectl start FC4、FC5の場合
apache2ctl start openSUSE 10.0、ubuntuの場合
停止
apachectl stop
再起動(gracefulは、現在つながっている接続がすべて、切れるのを待って再起動をかける)
apachectl restart
apachectl graceful
その他、設定ファイルの確認を以下のオプションですることができる。
apachectl configtest
パソコン起動時に自動起動するようにするには
FC4、FC5では、
# chkconfig httpd on
# chkconfig httpd off
openSUSE 10.0では
# chkconfig apache2 on
# chkconfig apache2 off
標準では、アクセスログ、エラーログは、FC4では/var/log/httpd以下に、openSUSE 10.0に場合は/var/log/apache2以下に記録されます。ログファイルは、単にどこからアクセスしてきたかというアクセス情報以外に、起動失敗時や、phpなどがうまく動かないときの、解決の手がかりとなります。
既知のウォームのログは取るとログが非常に長くなってしまい、ほかの肝心のログが埋もれてしまう。下記の設定をすると、いくつかのウォームのログは記録されなくなる。
SetEnvIf Request_URI "^/_mem_bin/" nolog SetEnvIf Request_URI "^/_vti_bin/" nolog SetEnvIf Request_URI "^/c/" nolog SetEnvIf Request_URI "^/d/" nolog SetEnvIf Request_URI "^/msadc/" nolog SetEnvIf Request_URI "^/MSADC/" nolog SetEnvIf Request_URI "^/scripts/" nolog SetEnvIf Request_URI "^/default.ida" nolog
と
CustomLog logs/access_log combined env=!nolog
をhttpd.confに追加
LAN内からのアクセスは、通常他人からのアクセスではないうえ、ホームページの状態を確認したりしてアクセス数もたいてい多いので、通常のログには記録したくない場合がある。
そんな場合はSetEnvIf Remote_Addrを使って、場合分けをする。
例えば、LAN内のIPアドレスが192.168.xxx.xxxの場合は次のように設定する。
SetEnvIf Remote_Addr 192.168. lanaccess CustomLog logs/access.log combined env=!lanaccess CustomLog logs/access_lan.log combined env=lanaccess
これで、通常のアクセスはaccess.logに、LAN内からのアクセスはaccess_lan.logに記録される。
もし、LAN内からのアクセスのログが不要であれば、最後の行は不要である。
サイトの情報を収集にくるロボットなどの情報を、通常のログと同じところに記録すると、webalizerなどでログを分析した際に、これらのアクセスが上位にきてしまうなどといった問題が出てくる。
このような問題を解決するには、ロボットからのアクセスは別に記録してやればよい。
一般的にはUser-Agentで分けてやるのが簡単である。
SetEnvIf User-Agent "Googlebot" botlog CustomLog logs/access.log combined env=!botlog CustomLog logs/access_bot.log combined env=botlog
ワームの場合と同じようにSetEnvIf Request_URIを使う。正規表現を使って、
SetEnvIf Request_URI "\.(gif)|(jpg)|(png)$" nolog CustomLog logs/access_log combined env=!nolog
とする。()内に拡張子を書いていけば他のファイルも記録しないようにすることが出来る。例えばcssファイルを記録しないようにするには、
SetEnvIf Request_URI "\.(gif)|(jpg)|(png)|(css)$" nolog
とする。
ここでは、apacheのWebDAVを使ってファイルを共有することを考える。
apache2系であれば、WebDAVを機能させるのはそれほど難しいことではない。しかしながら、WindowsのエクスプローラからapacheのWebDAVにアクセスすると、大きなファイルの転送時に、システムが固まったようになり、使い勝手それほど良いわけでない。LAN内で使うのであればsambaを、外から、あるいはより安全なファイル転送を求めるならsftpをお薦めする。
まず、FC4の場合、mod_davとmod_dav_fsが組み込まれているかを確認する。具体的には下記の行があるかどうかを確認する
LoadModule dav_module modules/mod_dav.so LoadModule dav_fs_module modules/mod_dav_fs.so
openSUSE 10.0の場合は/etc/apache2/sysconfig.d/loadmodule.confというファイルに書かれているが、これを直接書き換えても、システムが上書きしてしまいうまくいかない。yastを立ち上げ、system、/etc/sysconfig editorを開き、Network、WWW、APACHE_MODULESとすすみ、そこへ最後のところに、dav dav_fsとスペースで区切って追加する。
そして下記の行でWebDAV機能を有効にする。DAVLockDBは必ずすべての外側に書いてください。また、/var/lib/dav/ディレクトリのアクセス権を755にしておく。
DAVLockDB /var/lib/dav/lockdb <Location /testdir/> #WebDAV機能を有効にする DAV On </Location>
これで、\\example.com\testdirでアクセスできるようになります。ただし、
AuthTypeでBasicを指定すると、基本認証が可能になります。
AuthType Basic AuthName "Example" AuthUserFile "/etc/apache2/.davpasswd" Require valid-user
パスワードファイルは、htpasswdもしくはhtpasswd2を使って生成します。
openSUSE 10.0の場合は、htpasswd2を使います。
/etc/apache2ディレクトリへ行き、
# htpasswd2 -c ./.davpasswd hoge
New password:
Re-type new password:
Adding password for user hoge
Digest認証を使うには、mod_auth_digestが必要です。
Digest認証を行うディレクトリが記述されたセクションで、そして下記のように設定します。
AuthType Digest AuthName "Restricted Zone" AuthDigestDomain /foo/ AuthDigestFile /usr/local/apache/passwd/htdigest Require user hoge
AuthTypeでは、Digest認証を使うという指示を与えます。
AuthNameはユーザーがパスワードを入力する際に、表示されます。
AuthDigestDomainでは、どの領域で有効かを設定します。最低限自分のディレクトリは含めること。
AuthDigestFileでは、パスワードファイルを指定します。パスワードファイルは、必ずウェブからアクセスできない場所に作成します。
Requireでは、ここでは。hogeというユーザー名が必要であることを示しています。
パスワードファイルは、
# htdigest [-c] パスワードファイル レルム ユーザー名
の様な構文になります。-cは初めて作成するときのみ指定してください。具体的には、
# htdigest -c /usr/local/apache/passwd/htdigest 'Restricted Zone' hoge
の様に打ちます。
Webalizerはログを解析するソフトウェアである。
設定ファイルは(FC4の場合)/etc/webalizer.conf
複数のサイトがある場合はこのファイルをコピーして、例えば、
/etc/webalizer.example.com.conf /etc/webalizer.example.org.conf
のように複数作成する。
このファイルの中で主に変更すべき箇所は、
解析すべきログファイルの場所(ログファイルの場所は、apacheの設定ファイルhttpd.confの中に書かれている)
LogFile /var/log/httpd/access_log
ログの解析結果を出力する場所。ここにはhtmlファイルが作成され、このディレクトリにブラウザでアクセスすると、グラフィカルに表示される。
OutputDir /var/www/usage
下記は作業ファイルの位置
HistoryName /var/lib/webalizer.ckme.co.jp.hist IncrementalName /var/lib/webalizer/webalizer.current
.htaccessを使うと、httpd.confで設定するようなことを、httpd.confを書き換えなくても.htaccessというファイルを書き換えることによってユーザーが自分で設定することができる。
httpd.confを書き換えるには、通常root権限が必要ですが、この方法であれば、.htaccessを作成することさえできればよいという利点があります。その一方で、サーバの動作はhttpd.confを使うのに比べて遅くなるので注意すること。
なお、.htaccessを使うためには、httpd.confでAllowOverrideを許可する必要がある。
すべてを許可するには、
AllowOverride All
逆にすべて不許可にするには
AllowOverride None
一部機能だけを許可するには、Indexes、Options、FileInfo、AuthConfig、Limitがある。詳しくは書きのページを参照。
参考:http://httpd.apache.org/docs/2.2/ja/mod/core.html#options
ここでは、Basic認証を使用した、パスワード付きのページを作成する方法について記述する。
ExpiresActive On ExpiresByType image/gif A7200 ExpiresByType image/gif "access plus 2 hours" ExpiresByType image/jpeg M7200 ExpiresByType image/jpge "modification plus 2 hours" ExpiresByType text/html A600 ExpiresByType text/html "access plus 10 minutes" ExpiresDefault A86400 ExpiresDefault "access plus 1 day"
ErrorDocument 404 /404.html
httpd.conf内の下記の行を変更すれば、.htaccessの代わりにほかの名前を使うこともできる。
AccessFileName .htaccess
本文中のFC4はFedora ProjectのFedora Core 4を、FC5はFedora Core 5を、FC6はFedora Core 6、FC7はFedora Core 7をopenSUSEはNovellのSUSE Linux OSSを表します。
ここに登場するドメイン名やIPアドレスなどはフィクションです。実在の人物・団体等とは一切関係がありません。