Mazn.net

やってみて 調べてみて 苦労しなけりゃ 箱は動かじ

apache

Wordpress高負荷対策→同一ApacheのIPのアクセス数制限@CentOS 5

一日に数回サーバ高負荷で応答がなくなってしまって困っていました。load average 90超え!!ありえん・・・ 低性能なサーバなのに、大してApacheもMySQLものチューニングしていないからなあ・・・

ということで、最初はWordpressがアクセスしているMySQLが重たいのではと思い、メモリや接続数を少なくしてみたが効果なし。ということで、基本に戻って、まずは現状把握から。

sysstat パッケージでsarによる性能情報収集を開始し、topの結果を数秒おきにログに保存、さらに長い時間がかかるSQLもログに記録するようにしてみてわかったこと。それは、

  • DoSアタックとは言わないが、同一IPからの大量アクセスが発生
  • httpdプロセスが大量に生成
  • 非力なサーバでスワップが発生しまくり
  • 処理しきれずダウン

という典型的な非力サーバの事象でした。

で、httpd.confをよく見ると、ServerLimitやMaxClients がデフォルトで 256 と、非力なサーバでは処理しきれない値になっている・・。とりあえサーバの最大プロセス数を数個に削減。そんなにアクセスがあるサーバではないので問題ないと思う。

次に、同一IPからの連続アクセスは制限をかけました。

具体的には、mod_limitipconn というApacheモジュールを入れました。 これはその目的通り、同一IPからの接続を制限するためのモジュールです。epel のリポジトリに入っているので、リポジトリを設定している人であれば、インストールは

# yum install mod_limitipconn

とするだけです。リポジトリ設定していない人は、この辺りから適当にRPMをダウンロードしてインストールしましょう。 あとは、httpd.conf に

 MaxConnPerIP 5

と追記して、apacheをリロードすれば、どういつIPからは5接続に制限できます。制限に達するとレスポンスコード503が返ります。

ちなみに、同じページに画像などが複数あると、この接続数に達して、画像が一部表示できないことがあります。なので、対象のディレクトリの設定で、

<Directory "/var/www/html">
   ~ 省略 ~
    NoIPLimit image/*
</Directory>

と記述してあげれば、画像はこの制限から除外することができます。

 

参考 : Apache で同一IPからの接続数を制限する mod_limitipconn 設定方法

MaxClients

ApacheのNameVirtualHostのデフォルトサイト設定(含SSL)@CentOS 5

CentOS 5 のApacheで、名前ベースのバーチャルホストを構築してみた。

CentOS 5では、基本設定は /etc/httpd/conf/httpd.conf 、追加設定や追加モジュール設定は /etc/httpd/conf.d/ ディレクトリ配下に ~.conf というファイル名で置くような作りになっているので、新しいバーチャルホストもここに置くようにしたい所です。

しかし、バーチャルホストの設定は、一番最初に定義したものが、デフォルトサイトとして使われるようで、IPアドレスでアクセスした場合はこのバーチャルホストのページが表示されてしまいます。

よって、Include文でconf.d 配下のファイルを読み取る前に、デフォルトのバーチャルホストを以下のように定義してあげればOK。

# vi /etc/httpd/conf/httpd.conf

~ 省略 ~
NameVirtualHost *:80
<virtualhost *:80>
 ServerAdmin root@localhost
 DocumentRoot /var/www/html
 ServerName 192.168.0.10          ← サーバのIP または ドメイン名
</virtualhost>
#
# Load config files from the config directory "/etc/httpd/conf.d".
#
Include conf.d/*.conf            ← この行の前に書く
~ 省略 ~

あとは、conf.d 配下に以下のように、サイト毎のバーチャルホストを定義するだけです。例えば、http://www.hoge.net/ というサイトを作りたいならば、/etc/httpd/conf.d/hoge.conf  ファイルを作って、以下のように記述するだけです。

# vi /etc/httpd/conf.d/hoge.conf

<VirtualHost *:80>
ServerAdmin [email protected]
DocumentRoot /home/www/hoge
ServerName www.hoge.net:80
ErrorLog logs/hoge-error_log
CustomLog logs/hoge-access_log combined

<Directory "/home/www/hoge">
Options FollowSymLinks
Order allow,deny
Allow from all
AllowOverride All
</Directory>
</VirtualHost>

ちなみに、Apache 2.2.12 以降では、SNI(Server Name Indication) が実装され、https (SSL) のサイトでもバーチャルホストを定義できます。SSL のバーチャルホストも、通常のバーチャルホストと同様最初に定義されたサイトがデフォルトになるようです。ただし、CentOS 5 のSSLの設定は、すでに conf.d ディレクトリ配下に ssl.conf として外だしされています。そのため、このssl.conf をデフォルトのサイトにしたい場合、このファイルが最初に読み込まれる必要があります。しかし、他のバーチャルホスト(例えばhoge-ssl.conf )を置いた場合、"h" は "s" よりもアルファベット順が先のため、ssl.conf よりも先にhoge-ssl.conf が読み込まれてしまいます。

よって、解決方法として、 ssl.conf を 00-ssl.conf といった名前に変更してあげれば、大抵のファイルよりも先に読み込んでくれます。なお、80ポートの時と同様、SSLののバーチャルホストを使う場合、NameVirtualHostの定義が必要になるので注意してください。

# vi /etc/httpd/conf/httpd.conf

NameVirtualHost *:80
<virtualhost *:80>
 ServerAdmin root@localhost
 DocumentRoot /var/www/html
 ServerName 192.168.0.10
</virtualhost>
NameVirtualHost *:443
#
# Load config files from the config directory "/etc/httpd/conf.d".
#
Include conf.d/*.conf            ← この行の前に書く

SSLのバーチャルホスト追加。

# vi /etc/httpd/conf/hoge-ssl.conf

<VirtualHost *:443>
ServerAdmin [email protected]
DocumentRoot /home/www/hoge
ServerName www.hoge.net:443
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

SetEnvIf User-Agent ".*MSIE.*" \
 nokeepalive ssl-unclean-shutdown \
 downgrade-1.0 force-response-1.0

CustomLog logs/hoge-ssl_access_log ssl-combined
ErrorLog logs/hoge-ssl_error_log

<Directory "/home/www/hoge">
 Options FollowSymLinks
 Order allow,deny
 Allow from all
 AllowOverride All
</Directory>
</VirtualHost>

上記はあくまでオレオレ証明書なので、ちゃんとした証明書が必要な場合は、別途設定が必要です。 なお、SSLのバーチャルホストは、対応したブラウザで見る必要があるらしいですが、最近のブラウザならほとんど対応しているようです。

 

参考 : http://builder.japan.zdnet.com/etc/20402262/

== 2011/5/7 追記 ==

httpdのRPMをアップデートすると、ssl.confを00-ssl.confにしていた場合、/etc/httpd/conf.d/ssl.conf というファイルが新しく作られてしまい、その影響でhttpdが起動できなくなってしまいますので、こういう時は ssl.conf を削除または .conf 以外のファイル名にリネームしてあげてください。

mod_rewriteを使って、特定のファイルをSSLアクセスにする@Apache with RHEL5

TracやWikiなどのWebアプリケーションを使ってて、普段は通常のhttpアクセスを行い、ログイン部分だけは暗号化のためにhttpsにリダイレクトしたい場合があります。

まず、特定のファイルなどをSSL以外でアクセスさせないようにするには、httpd.confで以下のように設定します。ここでは/home/mazn/public_html/hogeをSSL限定にしてみます。

<Directory "/home/mazn/public_html/hoge">
   SSLRequireSSL
</Directory>

直接httpsでアクセスすれば、もちろんアクセスできるのですが、Webアプリの場合ソースの改変が必要だったりするので、httpでアクセスがきた場合はmod_rewriteでhttpsに書き換えてあげます。ここでは/hoe/login へのアクセスをhttpsにしています。

<IfModule mod_rewrite.c>
   RewriteEngine On
   RewriteRule ^/hoge/login(.*)$  https://%{HTTP_HOST}/hoge/login [R=301,L]
</IfModule>

RewriteRule で書き換えのルールを指定します。"^"と"$"でマッチさせるルールの初めと最後を指定します。(.*)はloginに続く任意の文字列を意味しています。末尾の[]はオプションでRはリダイレクトで、HTTPレスポンスとして301(=Moved Permanently)を返します。Lは条件にマッチした場合そこで次のルールを評価しないという意味です。

リダイレクト後のloginにリダイレクト前の(.*)にマッチした部分を追加するには、\1を使います。

   RewriteRule ^/hoge/login(.*)$  https://%{HTTP_HOST}/hoge/login\\1 [R=301,L]

参考 : mod_rewriteリファレンス

名前ベースのVirtualHost

今までapacheを名前ベース(NameVirtualHost)をエラーが出たまま使ってたので、ちゃんと調べてみた。

例えばport 8080でVirtualHostを使いたい場合以下のようになります。

NameVirtualHost *:8080
<VirtualHost *:8080>
DocumentRoot "/var/www/mazn"
ServerName www.abcd.com
ServerAdmin webmaster@localhost
ErrorLog /var/log/apache2/error.log
TransferLog /var/log/apache2/saccess.log
ServerAlias www.efgh.com
</VirtualHost>

これでwww.abcd.comにアクセスした場合、/var/www/mazn/ のドキュメントが表示されるようになります。またServerAliasでwww.efgh.comが設定されているので、www.efgh.comへアクセスした場合も同じものが表示されます。

複数のVirtualHostを書いた場合、一番上に書いた物が優先され、どれにもマッチしない場合も一番上のVirtualHostが表示されます。

Apacheのプロキシ(proxy)機能

Apacheにはフォワードプロキシやリバースプロキシの機能があります。 フォワードプロキシは、Apache上のあるURLにアクセスした場合、他のサーバへ転送できます。

リバースプロキシは、クライアントから見れば同一サーバにアクセスしているのに、実は他のサーバをアクセスしているようにできます。 ファイアウォール内のサーバに外部からアクセスさせたい場合に有効です。 以下のような設定をします。

      UseCanonicalName on
      ProxyRequests Off
      <Proxy *>
              Order deny,allow
              Allow from all
      </Proxy>
      ProxyPass /hoge/ http://192.168.1.2:8008/abcd/
      ProxyPassReverse /hoge/ http://192.168.1.2:8008/abcd/

上記の場合"http://公開IP/hoge/"にアクセスした場合、実際にはローカルの"http://192.168.1.2:8008/abcd/"がアクセスされます。(ProxyPass機能) またHTTPヘッダ内の"http://192.168.1.2:8008/abcd/iii/"は"http://ServerName/hoge/iii/"に書き換えられます。(ProxyPassReverse機能) なので、ServerNameはきちんと設定しておく必要があります。また

UseCanonicalName on

も指定しておく必要があります。

Apache 2.0 + OpenSSL

OpenSSLは SSLv2/SSLv3/TLSv1 をサポートしているオープンソースの暗号化ライブラリ。もともとNetscape社が開発していたもので、最初のリリースがSSLv2だったため、バージョンは2からとのこと。

世界中のセキュリティ専門家さま達がSSLv2の脆弱性を指摘、それを修正したものがSSLv3となったそうな。

TLSv1はSSLv3をもとに作られたらしく SSLv3≒TLSv1 と考えていいみたい。じゃ、何が違うんだ??って思うのが普通だと思うけど、そこまで調べてないです。

ちなみに、IE6ではデフォルトはTLSがoffになってます。なぜだろ?

Apache 2.0 は標準でこの三つのプロトコルをサポートしてるので、何も考えなくてもデフォルトで使えちゃいます。もし使うプロトコルをSSLv3/TLSv1に限定したいなら apacheのSSL設定ファイル(httpd.confとかssl.conf)に

SSLProtocol  SSLv3 TLSv1

のように書いてあげればOK.

このブログについて
プライバシーポリシー・お問い合わせ等
購読する(RSS)
記事検索
アーカイブ
カテゴリー
  • ライブドアブログ