共用サーバにおけるSymlink Attacksによる攻撃とその対策について

  • 投稿日:
  • by
  • Category:

先日、大手レンタルサーバ事業者において、ワードプレスを使用したウェブサイトが大量に書き換えられるという事件が発生しました。
これについては、すでに多くのニュースやブログ記事などにおいてご存知の方も多いと思います。
当初はクラックではなく管理画面への不正ログインであるというリリースが出ていたり、グループの会長が「クラックなどではない」と断言されておられたことなどもあり、よくあるブルートフォースアタックであろうと思われていました。
しかし結果としてワードプレスは無実であり、サーバソフトウェアの設定の問題を突いたクラック行為によるものであることが分かりました。
詳細は発表されていませんが、Optionsを設定できなくしたということやFollowSymLinksを無効にしたという発表から、Symlink Attacksと呼ばれる種類のアタックが行われたと断定しても問題ないと思います。
真似する人が出ると困るので、あえて解説は避けていましたが、既に手口などの情報も出始めてしまったので、手口だけでなく対策法まで解説することにしました。この手口によって他ユーザのファイルを閲覧することは犯罪ですので、くれぐれも悪用などされないようにお願いします。

それでは今回のケースを見ていきますが、端的に言うと他ユーザのディレクトリ内にあるwp-config.php(ワードプレスの設定ファイル)へシンボリックリンクを張って、自分のウェブサイトURL経由でその内容を閲覧したというものです。
多くのレンタルサーバ事業者など共有サーバの管理者は、各ユーザのホームディレクトリの権限を 701や705などに設定し、ユーザを全て同一のグループに所属させて、ユーザ間のファイルの読み書きを抑制しています。そのため、ホームディレクトリ配下にある全てのファイルは、FTPやシェル(コマンドライン)経由で、他ユーザに見られたり、書き換えられたりすることはありません。
しかし、Apacheは別です。Apacheのプロセスは、ユーザとは異なるグループ権限で動作しているので、全てのユーザのファイルを見れます。
20130903-symlink1.png

とはいえ、wp-config.phpにアクセスしても、PHPのコードが実行されるだけで、ファイルの中にあるパスワードなどを見ることはできません。

そのため、攻撃者は自分のディレクトリ内に、wp-config.txtなどPHPと認識されない拡張子のファイル名で、他ユーザのwp-config.phpへのシンボリックリンクを張り、自分のウェブサイト経由でアクセスすれば、テキストファイルとして他ユーザのwp-config.phpの中身をテキストとして閲覧することが可能になります。

20130903-symlink2.png20130903-symlink3.png

対策としては、chrootやjailを使ってパス空間を分離したり、仮想化して完全に別々のインスタンスにしたりというものもありますが、今回の問題に対するもっともスマートな解決法は、他ユーザのファイルへのシンボリックリンクを無効化するというものです。
以下のような設定を行うことにより、シンボリックリンクをたどる際にはリンク元とリンク先のユーザ権限が一致しているかどうかを確認するようになります。

Options MultiViews Indexes SymLinksIfOwnerMatch Includes ExecCGI


既に指定しているOptionsを生かすのであれば、以下のように設定しても構いません。

Options +SymLinksIfOwnerMatch -FollowSymLinks


なお、ユーザが.htaccessにおいてOptionsを自由に設定できないように、AllowOverrideにおいて制限する必要があります。以下のように、AllではなくOptionsを除いた項目を列挙します。

AllowOverride FileInfo AuthConfig Limit Indexes


この設定をしないと、.htaccessのOptionsにおいて +FollowSymLinks -SymLinksIfOwnerMatch という設定を入れられた場合に、異なるユーザ間でのシンボリックリンクが有効化されてしまいます。
さくらのレンタルサーバにおいては上記のような設定をしており、今回のケースにおけるクラック行為は成立しないわけですが、ユーザが.htaccessにおいてOptionsを設定すると 500 Internal Server Errorとなってしまうため、提供にあたってFAQを用意するなど、サポート面での対応策が必要なりました。ですので、変更にあたっては、そのサーバのユーザへの対応が必要なことをご留意ください。

ちなみに、Apache 2.2以降であれば、Optionsでユーザが設定できる項目を指定できるようになり、Indexesなどのよく利用されるOptionsの項目に限定してユーザ側に許可することが可能になりました。これにより、Optionsが指定できないことによる弊害も、かなり抑制できます。

AllowOverride FileInfo AuthConfig Limit Indexes Options=MultiViews,Indexes


さくらのレンタルサーバではApache 1.x系で上記の設定ができなかったため、Optionsの利用を全て不可にしていたのですが、現在サーバを順次アップグレードをしているところであり、いずれはサービスにおいてOptionsを使用できるようにしたいと思っています。

今回の攻撃手法については昔から知られており、多くのレンタルサーバ事業者においては適切な設定がなされていますが、一部に適切でない事例も見られるようです。
レンタルサーバ事業者など不特定多数にサーバをレンタルする管理者の方々においては、Symlink Attacksについて広く知られることとなった現状を勘案し、適切な設定への修正を行って頂きますよう、強く推奨したいと思います。
ちなみに、Symlink Attacksについては以上のとおりですが、suEXECを使っていない環境において、他ユーザのファイルへアクセスできる脆弱性は残っていますので、phpのモジュールモードなど、Apache権限で不特定多数のユーザに自由にスクリプトを実行できる環境を提供しているサーバ管理者の方々も対応をお願いします。
また今回のケースでは、MySQLデータベースサーバがインターネットから自由にアクセスできたこともあり、wp-config.phpの中にあったユーザ名とパスワードで、データベースを直接書き換えられたというのも被害を大きくした理由だったようですので、インターネットへ公開する共用サーバは必要最小限にするということも重要です。

ところで、この騒ぎの中で「共用サーバは危ない」「AWSやさくらのVPSへ移行しよう」という意見を見受けますが、これは多くのケースにおいては間違った対応です。共用サーバを提供する多くの事業者においては、知られた脆弱性に対して迅速に対応されていますし、逆にセキュリティ対策ができない状況でAWSやVPSのような素のサーバを使うことは非常に危険です。しっかりとサーバ管理の出来るケースに限って、AWSやVPSなどを活用すべきだと思います。

最後に、今回のケースでは直接ワードプレスが悪いというより、よく利用されているCMSだからターゲットにされたということがありました。良く利用されているアプリケーションについては狙われやすいということがあるので、ユーザ名やパスワードを他のサイトと異なるものにしたり、複雑なものにしたりと、さまざまな対策をユーザ側でも行うことが重要です。

ウェブ開発者のための、1時間でできるLAMP環境構築術(CentOS編)

  • 投稿日:
  • by
  • Category:

最近、さくらのVPSやServersmanなど格安のVPSサービスや、Amazon Web ServicesやNiftyクラウドに代表されるクラウドサービスなどの台頭により、以前よりもサーバを使うことのハードルが下がりました。
そのためウェブ開発者がサーバの運用に関わる機会が増えていますが、ApacheやMySQL、PHP(Perl)などのいわゆるLAMP環境を作るには、意外と手間がかかることに気づかされます。
そこで、今回は1時間で出来るサーバセットアップを目標に、LAMP環境構築のチュートリアルとまとめました。

この手順においてはCentOSの基本的な設定が完了しているものとします。
参考:CentOSをサーバーとして活用するための基本的な設定(さくらインターネット創業日記)
なお、この記事はCentOS 5 もしくは CentOS 6 の64ビット版をベースに書いていますので、これ以外のOSの場合には適宜読み替えて下さい。

CentOS 最新版へのバージョンアップ

今回の作業を行うにあたって、対象サーバがCentOS 5.5であったため、yum upgradeを実行して CentOS 5.6へバージョンアップしました。
現在(2012/5/7)の最新バージョンは、CentOS 5.7 もしくは CentOS 6.2 です。バージョンアップを行うと、それぞれ最新版のCentOSへとアップデートされます。
すでにCentOS 最新版の場合には以下の作業は行わなくてもかまいません。

[root@ ~]# rpm -qa | grep centos-release
centos-release-notes-5.5-0
centos-release-5-5.el5.centos
[root@ ~]# yum upgrade -y
Loaded plugins: fastestmirror
Determining fastest mirrors
色々出てくる
Total download size: 162 M
Downloading Packages:
色々出てくる
Importing GPG key 0xE8562897 "CentOS-5 Key (CentOS 5 Official Signing Key) " from /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
[root@ ~]# rpm -qa | grep centos-release
centos-release-notes-5.6-0
centos-release-5-6.el5.centos.1 ← CentOS 5.6へとアップグレードされた


yumのリポジトリ追加

yumとは各種ソフトウェアをパッケージという単位にして、簡単にインストール・アンインストールするための仕組みのことです。
リポジトリを追加することによって、パッケージのダウンロード元サイトを増やし、インストールできるソフトウェアのバリエーションを増やすことが可能です。
標準のリポジトリではPHPの最新バージョンなどが用意されていませんので、今回は Fedora EPEL 、remi、RPMForge という3つのリポジトリを追加します。

はじめに、Fedora EPELのダウンロードを行います。

CentOS 5 の場合

[root@ ~]# wget http://dl.fedoraproject.org/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm

CentOS 6 の場合

[root@ ~]# wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-7.noarch.rpm

※download.fedora.redhat.comに繋がらない場合には上記の通りdl.fedoraproject.orgに変更すればダウンロードできます。

上記のファイルが無くなっている場合には、次のURLからepel-release-で始まるファイルを探してダウンロードして下さい。
http://dl.fedoraproject.org/pub/epel/5/x86_64/ (CentOS 5)
http://dl.fedoraproject.org/pub/epel/6/x86_64/ (CentOS 6)

次にremiのダウンロードを行います。

CentOS 5 の場合

[root@ ~]# wget http://rpms.famillecollet.com/enterprise/remi-release-5.rpm

CentOS 6 の場合

[root@ ~]# wget http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

上記と同様に、ファイルが利用できない場合には、以下のURLからダウンロードして下さい。
http://rpms.famillecollet.com/

最後に、RPMForgeのダウンロードを行います。

CentOS 5 の場合

[root@ ~]# wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm

CentOS 6 の場合

[root@ ~]# wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm

上記と同様に、ファイルが利用できない場合には、以下のURLからダウンロードして下さい。
http://dag.wieers.com/rpm/packages/rpmforge-release/

それでは、3つのリポジトリを追加します。

CentOS 5 の場合

[root@ ~]# rpm -Uvh epel-release-5-4.noarch.rpm remi-release-5.rpm rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm

CentOS 6 の場合

[root@ ~]# rpm -Uvh epel-release-6-7.noarch.rpm remi-release-6.rpm rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm


リポジトリが追加できたら、それぞれのリポジトリをいったん無効化します。
具体的に言うと、設定ファイルのenabledという項目を0に変更し、yum実行時に明示的に指定されない限り、新たに追加したリポジトリが利用されないようにします。
ちなみに、remiはもともとenabled=0となっているので、Fedora EPELとRPMForgeのみviコマンドで編集します。
※意図せず、標準外のリポジトリ(今回追加したリポジトリ)が使われないための対策です。

vi /etc/yum.repos.d/epel.repo

[epel]
name=Extra Packages for Enterprise Linux 5 - $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/5/$basearch
mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=epel-5&arch=$basearch
failovermethod=priority
enabled=0 ← 1を0に変更
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL

vi /etc/yum.repos.d/rpmforge.repo

[rpmforge]
name = RHEL $releasever - RPMforge.net - dag
baseurl = http://apt.sw.be/redhat/el5/en/$basearch/rpmforge
mirrorlist = http://apt.sw.be/redhat/el5/en/mirrors-rpmforge
#mirrorlist = file:///etc/yum.repos.d/mirrors-rpmforge
enabled=0 ← 1を0に変更
protect = 0
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rpmforge-dag
gpgcheck = 1

これでリポジトリの追加作業は完了です。

パッケージのインストール

それでは、パッケージのインストールを行います。
次のコマンド一発でインストールが開始され、途中で「y」を2回入力すれば、一気にLAMP環境を作られます。
今回は、追加したリポジトリが利用されるよう、--enablerepo オプションを付けています。

[root@ ~]# yum --enablerepo=remi,epel,rpmforge install httpd-devel php-devel php-pear mysql-server phpmyadmin -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile

・・略・・

Total download size: 42 M
Downloading Packages:

・・略・・

warning: rpmts_HdrFromFdno: Header V3 DSA signature: NOKEY, key ID 00f97f56
remi/gpgkey | 1.3 kB 00:00
Importing GPG key 0x00F97F56 "Remi Collet " from /etc/pki/rpm-gpg/RPM-GPG-KEY-remi

Running rpm_check_debug

今回インストールしたモジュールを一覧にしました。

モジュールアーキテクチャバージョンリポジトリ
apr-develx86_641.2.7-11base
apr-util-develx86_641.2.7-11base
cyrus-sasl-develx86_642.1.22-5base
db4-develx86_644.3.29-10base
expat-develx86_641.95.8-8.3base
httpdx86_642.2.3-45base
httpd-develi3862.2.3-45base
httpd-develx86_642.2.3-45base
libeditx86_6420090923-3.0_1rpmforge
libmcryptx86_642.5.8-4extras
libtool-ltdlx86_641.5.22-7base
mysqlx86_645.5.11-1remi
mysql-libsx86_645.5.11-1remi
mysql-serverx86_645.5.11-1remi
mysqlclient15x86_645.0.67-1remi
openldap-develx86_642.3.43-12base
perl-DBD-MySQLx86_643.0007-2base
perl-DBIx86_641.52-2base
phpx86_645.3.6-3remi
php-clix86_645.3.6-3remi
php-commonx86_645.3.6-3remi
php-develx86_645.3.6-3remi
php-mbstringx86_645.3.6-3remi
php-mcryptx86_645.3.6-3remi
php-mysqlx86_645.3.6-3remi
php-pdox86_645.3.6-3remi
php-pearnoarch1.9.2-3remi
phpmyadmin.noarch2.11.11.3-1rpmforge

これで、インストールは完了です。


Apacheの設定 - モジュール編

それでは、Apacheの設定に移ります。
Apacheの設定は、/etc/httpd/conf/httpd.conf というファイルを編集して行いますが、モジュールの設定と、同時接続数の設定に分けて、順に見ていきましょう。

まずはモジュールの設定です。Apacheの場合、さまざまな機能を「モジュール」という形で用意しています。
モジュールを増やせばたくさんの機能を利用できますが、その反面メモリを大きく消費してしまうという問題があります。
CentOSのデフォルト状態では、ほぼ全てのモジュールが有効になっているため、必要以外のモジュールを除外する必要があります。

例えば、一切モジュールを消さないデフォルトの状態だと、1プロセスあたり5MB程度のメモリを消費していることが分かります。

#  ps aux|grep -v Ss|grep '[h]ttpd'|head -1
apache 22523 0.0 0.4 257548 5036 ? S 12:27 0:00 /usr/sbin/httpd

これを適切に設定しなおすと、4MB程度まで減らせます。
1プロセスあたり1MB省略できれば、200プロセスで200MB削減できることになりますし、実際にリクエストを受け付けているプロセスの場合はさらに消費メモリの差が出ることになります。

#  ps aux|grep -v Ss|grep '[h]ttpd'|head -1
apache 24715 0.0 0.4 161716 4228 ? S 19:46 0:00 /usr/sbin/httpd

とはいえ、どのモジュールが必要なのかが分かりにくいので、モジュールの一覧と、私の勝手な重要度をまとめました。
重要度は、◎、○、△、+、の4種類で分類しており、一覧にある重要度のタイトルをクリックすると、フィルターすることも可能です。
◎=必須
○=あったほうが良い
△=必要ならあればよい
+=必要性なし

モジュール名コメント
mod_auth_basicベーシック認証
mod_auth_digestダイジェスト認証
mod_authn_file認証にテキストファイルを利用する
いわゆる.htpasswdを使う場合は必要
mod_authn_alias
mod_authn_anon匿名ユーザを認証する
mod_authn_dbm認証にDBMファイルを利用する
mod_authn_default
mod_authz_hostホスト/IPアドレスでのアクセス制限
Orderや、Allow from ?? を使う場合は必須
mod_authz_userユーザ名でのアクセス制限
mod_authz_ownerファイル所有者でのアクセス制限
mod_authz_groupfileグループでのアクセス制限を行う(テキストファイル)
mod_authz_dbmグループでのアクセス制限を行う(DBMファイル)
mod_authz_default
mod_ldapLDAP用の基本モジュール
mod_authnz_ldapLDAPでのアクセス制限
mod_includeSSIを提供
SSIを利用する場合は有効にする
mod_log_configログ保存
アクセスログをとるためには必須
mod_logio送受信バイト数のログ保存(このモジュールがなければ保存できない)
mod_envCGIやSSIでの環境変数を設定する
必要なければ無効でかまわない
mod_ext_filterデータ返送時に外部プログラムを経由させる
mod_mime_magicファイルの内容をベースにMIMEタイプ決定
mod_expiresExpireヘッダをセットする
mod_deflateデータ返送時に圧縮する
mod_headersリクエスト、レスポンスヘッダを制御する
必要なければ無効でかまわない
mod_usertrackクッキーでユーザ追跡を行う
mod_setenvif環境変数の制御を行う
無効でもかまわないが、標準の設定ファイルで利用されており、有効にするのが無難
mod_mime拡張子をベースにMIMEタイプを決定
mod_davWebDAVを提供
mod_status/server-statusにてサーバ状態を表示する(URLは変更可能)
mod_autoindexディレクトリへのアクセス時にファイル一覧を作成する
mod_info/server-infoにてサーバ設定を表示する(URLは変更可能)
mod_dav_fsWebDAVを提供
mod_vhost_aliasバーチャルホストを簡単に生成
mod_negotiationクライアントに適したファイルを自動判別する(.jaなど)
mod_dirディレクトリの取り扱いを行う(index.htmlの取り扱いなど)
mod_actions特定の拡張子へのリクエストに応じてCGIを実行する
mod_speling大文字小文字を同じように扱えるようにする
mod_userdirユーザのホームディレクトにアクセスできるようにする(チルダ形式など)
mod_aliasAliasやRedirectを利用できるようにする
mod_rewriteRewrite機能を提供する
mod_proxyProxyを提供する
mod_proxy_balancerProxy時に負荷分散機能を提供
mod_proxy_ftpProxy時にFTP接続機能を提供
mod_proxy_httpProxy時にHTTP接続機能を提供
mod_proxy_connectProxy時にCONNECT機能を提供
mod_cacheキャッシュを提供
mod_suexecsuexecを提供
mod_disk_cachecache_moduleにおいて、ディスクキャッシュを提供
mod_file_cache静的ファイルをメモリにキャッシュさせる
mod_mem_cachecache_moduleにおいて、メモリキャッシュを提供
mod_cgiCGIを提供
mod_versionクライアントへのレスポンスにApacheバージョンを挿入する


※注意点
以下のモジュールを無効にすると、標準の設定ファイル(/etc/httpd/conf/httpd.conf)のまま起動するとエラーとなります。

  • mod_authz_hostを無効にした場合には、OrderやAllowなどの項目(例えば332行目など)をコメントアウトする必要があります
  • mod_proxyを無効にした場合には、以下ようにコマンドを実行し拡張設定ファイルを無効化する必要があります
  • # mv /etc/httpd/conf.d/proxy_ajp.conf /etc/httpd/conf.d/proxy_ajp.conf.stop
  • mod_autoindexを無効にした場合には、IndexOptionsから始まる関連項目(例えば592行目?657行目)を全てコメントアウトする必要があります
    もしくは以下のとおり、<IfModule>で括ってしまう方法もあります
  • vi /etc/httpd/conf/httpd.conf
    <IfModule mod_autoindex.c>
    IndexOptions FancyIndexing VersionSort NameWidth=* HTMLTable
    ・・略・・
    IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t
    </IfModule>

ちなみに、私はいつも以下のモジュールを有効にしています。
なお、mod_autoindex と mod_proxy を無効化していますので、前述のとおり設定を変更しなければエラーとなって起動しません。

LoadModule authz_host_module modules/mod_authz_host.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule mime_module modules/mod_mime.so
LoadModule status_module modules/mod_status.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule dir_module modules/mod_dir.so
LoadModule alias_module modules/mod_alias.so


Apacheの設定 - 同時接続数編

それでは、Apacheの同時接続数の設定を見ていきましょう。
ここで基本を押さえておきたいのですが、Apacheにはpreforkとworkerという大きく分けると2つの方式があります。
preforkはサーバ1つ(1プロセス)で1つのリクエストを処理し、workerはサーバ1つで複数のリクエストを処理できます。
一見、workerのほうが良いように見えますが、workerはマルチスレッドで実装されていることから、ライブラリ全てがマルチスレッドに対応している必要があります。
ただ、PHPを使う場合にはライブラリ全てがマルチスレッド対応か否かを検証することは難しく、余計なトラブルを避けるためにもpreforkを利用するのが賢明であるといえます。
ということで、今回はpreforkを使う前提で説明を行います。

標準のhttpd.confでは、以下のように設定されています。

<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 4000
</IfModule>

これらを順に見てみましょう。

  • StartServers
  • Apache開始時に立ち上げておくべきサーバ数。
    Apache起動直後は、ここで指定した数のサーバが立ち上がる。
  • MinSpareServers
  • アイドル中のサーバ数の下限。アイドル中とは、リクエストに対して即座に対応できる状態(つまり処理していない)のこと。
    ここで指定したサーバより少なくなった場合は、新たなサーバを立ち上げる。
    この数値が小さすぎると、急激にアクセスが増えたときに、リクエストに受けきれなくなる。
  • MaxSpareServers
  • アイドル中のサーバ数の上限。
    ここで指定したサーバより多くなった場合は、余計なサーバを終了させる。
    この数字が大きすぎると、アクセスが落ち着いている状態でもサーバが終了されず、メモリが無駄に消費されることになる。
  • ServerLimit
  • 後述するMaxClientsに指定できる数字の上限を指定する。
    MaxClientsを256より大きな数字にするとき以外は、特に変更の必要はない。
  • MaxClients
  • サーバ数の上限。
    ここで指定した数以上のサーバは立ち上がらない。
  • MaxRequestsPerChild
  • 処理できるリクエストの上限数。
    処理したリクエストがここで指定した数を超えると、該当サーバは終了される。

文字ではなかなかピンと来ない方も多いと思うので、グラフでまとめてみました。
このグラフでは見やすくするため、MaxClients 30、StartServers 10、MinSpareServers 5、MaxSpareServers 20としています。

apache-20110514.png

1起動直後であり、StartServersで指定された10サーバが立ち上がっている
210サーバが接続中でアイドル状態のサーバが0となったため、MinSpareServersに指定された5サーバが追加される
320サーバが接続中で上記と同じくアイドル状態サーバが0となったため、さらに5サーバが追加される
4アイドル状態のサーバが0になったものの、MaxClientsで指定された30サーバになったため、新規サーバは追加されない
5-7MaxClientsを超える数の接続がきたため、30の上限を超えるリクエストは、空きが出るまでまで待たされる
9-10アイドル状態のサーバ数は5以上20以下であり、新たなサーバの起動や、余剰サーバの終了処理は行わない
1130サーバがアイドル状態となったため、MaxSpareServersで指定された20サーバにすべく、10サーバが終了させられた


それでは、実際にどのような数字を設定すればいいか、考えて見ましょう。
一番重要なのはMaxClientsです。これが決まれば、上記の法則を見て他の値も決定してください。
たくさんのリクエストを受け付けるためには、大きな数値にすればよいと考えられがちですが、メモリやCPU能力が十分でなければ、むしろパフォーマンスが低下します。
経験則では、PHPを稼動させるApacheは1サーバあたり10MBから30MB程度のメモリを消費します。
例えば、Apacheで利用するメモリ容量を500MB程度に抑えたければ、20から40程度の数値にしておくのが無難です。

以下の例は、MaxClientsが256のときと、20のときで、どのように挙動が変わるかをabで図ったものです。

# ab -c 100 -n 2000 http://49.212.??.??/phpmyadmin/

MaxClientsが256の場合は、スワップを大きく消費しているほか、ロードアベレージも大きく上がっており、SSHのレスポンスについても非常に悪化していました。
それに対し20の場合は、それほど負荷の上昇は見られず、計測時間、秒間処理数、リクエストにかかる秒数の全てにおいて、改善していることが分かります。
要は、無理に同時に処理する数を増やすより、少々待たされる状態が出たとしてもサーバ能力を超えない範囲にしたほうが、結果としてレスポンスは良くなるということです。
サーバ負荷が高く、レスポンスが悪化した場合は、MaxClientsを増やすのではなく、減らすことをまず考えた方が賢明です。

MaxClientsスワップロードアベレージ計測時間秒間処理数リクエスト
256859MB79.2655.40秒36.10/秒2.73秒
2011MB5.4635.66秒56.08/秒1.74秒


1サーバあたりのメモリ使用量(ps結果のRSS)は10MB程度でしたので、100サーバだと1GB程度消費するのに対し、20サーバだと200MB程度で済みます。結局のところ、Apacheで使用する容量÷10MB?30MB程度で考えるのが良いでしょう。

参考までに、私が1GBメモリ、2コア程度のサーバ(さくらのVPS 1Gプラン相当)でいつも行っている設定は以下のような値です。

<IfModule prefork.c>
StartServers 10
MinSpareServers 5
MaxSpareServers 15
ServerLimit 256
MaxClients 40
MaxRequestsPerChild 1000
</IfModule>


Apacheの起動

Apacheを起動するには、serviceというコマンドを利用します。
以下のように打ち込んで、問題なければ正常に起動します。

# service httpd start
Starting httpd:                                            [ OK ]

なおエラーが出る場合には、モジュールを削ったときの設定ファイル変更を忘れている可能性があります。
設定ファイルの問題の際には、エラーメッセージとともに行番号が書かれていますので、再確認して下さい。


MySQLの設定と起動

それでは、MySQLの設定と起動を見てみましょう。
MySQLの設定については /etc/my.cnf を編集することで可能ですが、あらかじめ最低限の設定はされているので、ひとまず起動をして管理者パスワードの設定を行います。

MySQLを起動するには、serviceコマンドを利用します。

# service mysqld start
Initializing MySQL database:  Installing MySQL system tables...
OK
Filling help tables...
OK

・・中略・・

[ OK ]
Starting mysqld: [ OK ]

無事に起動できれば、[ OK ] と表示されます。

次に設定を移ります。
設定には専用のスクリプトが用意されているので、そちらを利用します。

# /usr/bin/mysql_secure_installation

・・略・・

Enter current password for root (enter for none): ← デフォルトではパスワードが無いので、そのままリターン
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.

Set root password? [Y/n] y ← 「y」と入力してリターン
New password: ← rootパスワードとして設定したい文字列を入力してリターン
Re-enter new password: ← もう一度入力してリターン
Password updated successfully!
Reloading privilege tables..
... Success!


By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them. This is intended only for testing, and to make the installation
go a bit smoother. You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y ← 「y」と入力してリターン
... Success!

Normally, root should only be allowed to connect from 'localhost'. This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] y ← 「y」と入力してリターン
... Success!

By default, MySQL comes with a database named 'test' that anyone can
access. This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] y ← 「y」と入力してリターン
- Dropping test database...
... Success!
- Removing privileges on test database...
... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] y ← 「y」と入力してリターン
... Success!

Cleaning up...

All done! If you've completed all of the above steps, your MySQL
installation should now be secure.

Thanks for using MySQL!

これで、MySQLが利用できるようになりました。


phpmyadminの設定

ここまでで、Apache、PHP、MySQLの全てが利用可能になりました。
最後に、phpmyadminの設定を行いましょう。

まずは、phpmyadminの設定ファイルを変更します。
変更するのは、blowfish_secret という項目だけです。以下のようにご自身で決めたランダムな文字列を入れてください。

vi /usr/share/phpmyadmin/config.inc.php

$cfg['blowfish_secret'] = 'dfj29jwIO1w19jjsdw219Ujdsjlk'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */

次に接続元のIPアドレスを追加します。
以下のように、/etc/httpd/conf.d/phpmyadmin.conf を編集し、Allow from を追加します。

vi /etc/httpd/conf.d/phpmyadmin.conf

<Directory "/usr/share/phpmyadmin">
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
Allow from 59.106.??.??
</Directory>

設定ファイルの編集が終われば、Apacheに設定ファイルを再読み込みさせれば完了です。

# service httpd reload
Starting httpd:                                            [ OK ]

ブラウザからアクセスをすると、無事phpmyadminの画面が表示されました。
ユーザ名に root と入力し、パスワードには先ほどの文字列を入力します。

20110514-phpmyadmin.png


自動起動設定と、再起動

これで、LAMP環境の設定がひとまず完了し、利用可能な状況となりました。
しかし、これで安心してはいけません。
再起動した場合には、ApacheもMySQLも自動で起動せず、アクセスが受け付けられない状況となります。

自動起動するかどうかを確認するためには、chkconfigコマンドを利用します。
3という項目がoffの場合には、再起動時にApacheやMySQLが自動起動されません。

# chkconfig --list|grep -E "httpd|mysql"
httpd           0:off   1:off   2:off   3:off   4:off   5:off   6:off
mysqld          0:off   1:off   2:off   3:off   4:off   5:off   6:off
# chkconfig httpd on
# chkconfig mysqld on
# chkconfig --list|grep -E "httpd|mysql"
httpd           0:off   1:off   2:on    3:on    4:on    5:on    6:off
mysqld          0:off   1:off   2:on    3:on    4:on    5:on    6:off
#

これで再起動をすれば、全ての作業が完了です。
再起動しなくても問題ありませんが、再起動された時に自動で全てのソフトウェアが起動するかどうかを確かめるためにも、再起動を強くお勧めします

時間としては1時間程度で済みましたでしょうか?
最近では、クラウドの機能が増えたことによりこういった作業を必要ないという人もいますが、ウェブ開発者のたしなみとして、これくらいはできるべきだと思います。
慣れれば10分くらいでできますし、数十台程度であれば平行で作業すれば30分もあれば出来ます。

ということで、皆さんもぜひがんばってチャレンジしてみてください。
なお皆さまからも「ここはこの方がいい!」とかあればぜひご指摘頂ければ幸いです。

2012/5/7 CentOS 最新版に対応すべく修正しました。

格安の低価格VPSを比較する

  • 投稿日:
  • by
  • Category:

最近、IaaS型クラウドの流行の裏で、VPSがひそかな人気を集めています。
VPSは、クラウドのような従量課金やAPIアクセス、柔軟なリソース増減はできませんが、その分安価な価格設定が行われることが多く、数ヶ月以上利用するのであればクラウドよりも非常に安価で高いパフォーマンスを得られることが特徴です。
また、コントロールパネルで起動、停止、再起動などの操作や、OS再インストールなど、クラウドで言うところの「セルフサービスによる」という部分は多くのVPSで実現されており、さくらのVPSに限ってはコンソールをホストOS経由で直接アクセスできるなど、物理サーバの置き換え用途としても十分に利用できる内容となってきました。
さらに、申し込みから利用開始まで数分から数十分程度で行えるなど、従量課金ではないことと解約が手動となる点を除けばIaaS型クラウドに決して劣るものではありません。

ただ、たくさんのVPSが各社から提供され、なかなか選べないよという方も多いのが実情です。
今回は、さくらのVPSのほか、話題を呼んでいる日本ラッドさんのSaaSes Osukini Serverと、DTIさんのServersman@VPSを取り上げ、それぞれのVPSについて比較をしてみました。
いちおう公平に書くようにしましたが、色眼鏡で見ていただいても結構です。m(_ _)m

それでははじめに各社の仕様をまとめてみます。

プラン名 さくらのVPS Osukini Server Serversman@VPS
512 1G 1.5G 4G 8G LT ST GT XT Entry Standard Pro
初期費用(円) 0 2,980 4,980 9,980 19,980 6,000 6,000 10,000 14,000 0 0 0
月額(円) 980 1,480 1,980 3,980 7,980 450 980 1,980 4,980 490 980 1,980
年払い割引 1か月分割引 なし なし
試用期間 2週間 2週間 記載なし
(キャンペーン対応)
メモリ容量 512MB 1GB 1.5GB 4GB 8GB 512MB 1GB 2GB 4GB 256MB 512MB 1GB
HDD容量 20GB 30GB 50GB 120GB 240GB 50GB 100GB 200GB 400GB 10GB 30GB 50GB
SWAP設定 ×
リモート
コンソール
× ×
固定IP v4
v6 × ×
追加IP ×
月額500円
×
1個

3個
IP逆引き
制限あり
仮想化プラットフォーム KVM完全仮想化 Xen完全仮想化 OpenVZコンテナ
OS CentOS
Debian
Ubuntu
Fedora × ×
FreeBSD × ×
現在のキャンペーン
今なら初期費用半額 今なら最大2か月分を無料に
その他の制約等 試用期間中は2Mbps制限
試用期間中はOP25Bあり

VPN設定不可
iptablesエントリ数の上限あり
※Serversman@VPSは、ウェブサイト上にて最大メモリの表記がありますが、あくまでも保障メモリで比較しています。


これではわかりにくいので、一番の関心事であろう価格について、それぞれ初年度にいくらかかるかを比較してみましょう。
また、メモリ1MBあたりの単価、HDD 1GBあたりの単価も見てみます。

プラン名 さくらのVPS Osukini Server Serversman@VPS
512 1G 1.5G 4G 8G LT ST GT XT Entry Standard Pro
年間の利用額(円) 10,780 19,260 26,760 53,760 107,760 11,400 17,760 33,760 73,760 5,880 11,760 23,760
メモリ1MBあたり(円) 21.0 18.8 17.4 13.1 13.2 22.3 17.3 16.5 18.0 23.0 23.0 23.2
HDD 1GBあたり(円) 539.0 642.0 535.2 448.0 449.0 228.0 177.6 168.8 184.4 588.0 392.0 475.2


ここで、グラフ化してそれぞれのプランがどのような位置にあるのかを見てみます。
まず、メモリの容量を横軸にした価格帯です。
VPS価格比較
導入費用が絶対価格で最も安いのはServersman@VPSのEntryプランですが、概ね価格帯は似通っているといえます。
低スペック帯では唯一256MBモデルを出しているServersman@VPSが安価であり、512MBあたりでは3社とも同様の価格となり、高スペック帯ではさくらのVPSがもっとも安価ということがわかります。

次に、HDD容量を横軸にした価格帯を見てみましょう。
VPS価格比較
総じていえるのは、Osukini Serverが飛びぬけて大容量であるということでしょう。
例えば、1万円の場合にさくらのVPSは20GB、Serversman@VPSは30GBのところ、Osukini Serverは50GBと大幅に大きいことがわかります。

ちなみに、キャンペーン適用した価格はどうなのか?1年を超えると結果は違うのでは?との質問もあったので、いちおうグラフを作りました。正直なところずっとキャンペーンをしている事業者は不公正だし信用できないので加味する必要性を全く感じませんが、信頼性がないとか言われても嫌なので参考までに。

結果的には大して変わりませんでした。
結局、低スペック帯ではServersman@VPSが価格優位なこと、SaaSesが価格に対してHDDが大容量なこと、高スペック帯ではさくらのVPSが価格優位なこと、それぞれ変わることはありません。
ただ、Serversman@VPSは期間が長くなると価格メリットが薄れてくるようです。

それでは気をとりなおして、最後にベンチマーク比較を見てみましょう。
既にこれらのVPSサービスの利用者の方がunixbenchで計測されていますので、その情報を見てみたいと思います。
それぞれ、「さくらのVPS unixbench」「Saases unixbench」「serversman unixbench」とGoogleで検索して出てきたページから抜粋しています。

VPS性能比較
これを見ると、さくらのVPSが1200から1500程度、Serversman@VPSがEntryで200から400程度、Standardで400?800程度で、Osukini ServerがLTとSTともに600程度です。
unixbenchだけでは結果はわかりませんが、数字を見る限りさくらのVPSが飛びぬけて性能がよいのは間違いなさそうです。

ただ、性能だけを見ても仕方が無いので、価格性能比をマッピングしてみましょう。
VPS性能比較
やはり性能についてはさくらのVPSが良いですが、興味が惹かれるのはServersman@VPSです。Osukini Serverが価格が上がっても性能が変わらないのに対し、Serversman@VPSはプランごとに性能が変わっているうえ、TurboモードをONにすることによる性能の向上が見られます。
完全仮想化の場合はゲスト空間が利用者に全て委ねられるのに対し、OpenVZの場合はCPU性能をコントロール出来るというのが寄与しているものと思われます。

それでは、ここでまとめにしたいと思います。
比較を実際にしてわかったのは、各社各様に特徴があるなというところで、本当はさくらのVPSを推したいところですが、そうは甘くないようです。
ということで各社の特徴をまとめてみました。

  • さくらのVPS
    • 高スペックプランになるほど、コストパフォーマンスがよくなる
    • リモートコンソールが利用できる
    • サーバ性能が飛びぬけて良い
    • 利用できるOSが多い
    • 初期費用が無い(980プランのみ)
  • Osukini Server
    • HDD容量が飛びぬけて大きい
  • Serversman@VPS
    • IPv6が利用できる
    • IPv4が複数利用できる(StandardとProのみ)
    • 低スペックプランがラインナップされ、最も安い
      (過去のキャンペーン適用者で、Entryを月105円で利用できてる人もいるらしい)
    • 運が良ければ保障以上のメモリを使える(但しプロセスがしばしばkillされる)
    • 初期費用が無い

私の結論としては、

  • スペックや性能が低くてもとにかく安くということでは、Serversman@VPS
  • HDD容量が欲しければ、Osukini Server
  • HDD容量はそこそこで良く、月に980円以上出せるのであれば、さくらのVPS
というところでしょうか。

なお上述のとおり、ある程度の値段になると、Osukini Serverか、さくらのVPSという選択肢しかなく、スワップが利用できることも考えると、本格運用の場合には Osukini Server か、さくらのVPSの2択かなと思います。
本当はさくらのVPSだけを推したいところでしたが、さすが岡田さんだけあってOsukini Serverも良くできているという印象です。

また今後、Amazon Web Servicesや、Linodeなども取り上げる予定ですが、皆さんからもご意見などいただければ幸いです。

ウェブアプリで文字コードを簡単かつ確実に判別する方法

  • 投稿日:
  • by
  • Category:

最近、某とあるサイトにて文字化けが起こるという申告が増えてきました。
理由は2つあって、ひとつは携帯(AU)からのアクセスが増えてきたということ、もうひとつは海外からの利用が増えてきたことです。
いちおう明示的にUTF-8と指定しているのですが、AUさんはShift-JISで送ってきたり、中国語のよく分からないクライアントはGB2312で送ってきたりして、文字判別は一筋縄にはいきません。
今回は、文字化けを防ぐ改造に当たってやったことを書きたいと思います。

文字化けの話はGoogleででも検索を

さて文字コードを自動判別するという技術は色々あって、よく利用されるのは特定の文字コードでしか利用されない文字を探し当て、判別するというものです。
言わずと知れた漢字コード変換コマンドである nkf でも、上記の方法で非常に精度の高い自動判別を行ってくれます。
ただ、これには大きな問題があります。それは「短い文字列だと判別できない」ということです。
某とあるサイトでは、単語を入力してロゴを作るというウェブサービスを提供していますが、入力される文字列が短いことからうまく自動判別がうまくいきません。

そのため今回取った対策は、submitされるフォームデータと共に判別用文字列を送るというものです。
例えば「文字」という文字列をUTF-8で送ると%E6%96%87%E5%AD%97となり、Shift-JISで送ると%95%B6%8E%9Aとなります。
ですので、判別用文字列がどのような文字列になって送られてきたかを見ると、他のフォームデータの文字コードを知ることが出来るというわけです。

それでは実際のプログラムです。
detectstrのところが、判別用文字列を埋め込んだところです。
ちなみに「文字」というのを利用した理由ですが、日本語のみならず、中国語簡体字、中国語繁体字においても同じ形だからということです。例えば自動という文字の場合は、簡体字で動という文字が異なるコードになってしまいますので利用できません。
なお最初は「日本」という文字を判別用文字列にしていたのですが、hiddenで日本という文字列が入っていると中国の利用者の方からいらぬ誤解を受けたり都市伝説化するのも嫌なので、途中で変えました。

送信側プログラム

<form action="test.php">
<input type="hidden" name="detectstr" value="文字" />
名前: <input type="text" name="name" />
<input type="submit" value="送信" />
</form>

受信側プログラム

<?php
$charsetList = array(
  "utf-8"  => "%E6%96%87%E5%AD%97",
  "sjis"   => "%95%B6%8E%9A",
  "euc-jp" => "%CA%B8%BB%FA",
  "jis"    => "%1B%24BJ8%3Bz%1B%28B",
  "Big-5"  => "%A4%E5%A6r",
  "HZ"     => "%7E%7BNDWV%7E%7D",
  "EUC-KR" => "%D9%FE%ED%AE",
  "GB2312" => "%CE%C4%D7%D6",
);
$charset = NULL;
foreach( $charsetList as $key => $val ){
  if( @$_GET["detectstr"] == $val ){
    $charset = $key;
    break;
  }
}
if( !$charset ) die("Couldn't detect a character set");
$name = mb_convert_encoding( @$_GET["name"], "UTF-8", $charset );

print htmlspecialchars($name);


なお、「文字」以外を判別用文字列に利用したい方の為に、コードジェネレータを作りました。


以上、いかがでしたでしょうか。
少々セコいですが、簡単かつ確実に行える対策です。
ただ、フォームの送信元と送信先の両方のプログラムに手を入れることになりますので、それが出来ない環境では別の方法をとる必要がありますのでご注意を。

ddコマンド実行途中に、何バイトコピーできたかを見る方法

  • 投稿日:
  • by
  • Category:

知り合いと話していた際に、「ddコマンドでディスクをコピーしているとき、scpのようにプログレスバーが表示できたらいいのに」という話を聞きました。
意外と知られていないのですが、USR1シグナルを送ることで途中経過を表示させることが可能です。

[root@wwwxxxxu ~]# dd if=/dev/zero of=/dev/null &
[1] 31092
[root@wwwxxxxu ~]# kill -USR1 31092
7764899+0 records in
7764898+0 records out
3975627776 bytes (4.0 GB) copied, 6.02001 seconds, 660 MB/s
[root@wwwxxxxu ~]# kill -USR1 31092
25123042+0 records in
25123041+0 records out
12862996992 bytes (13 GB) copied, 17.8137 seconds, 722 MB/s
[root@wwwxxxxu ~]# kill -USR1 31092
43986419+0 records in
43986418+0 records out
22521046016 bytes (23 GB) copied, 31.3739 seconds, 718 MB/s
[root@wwwxxxxu ~]# kill 31092
[1]+ Terminated dd if=/dev/zero of=/dev/null
[root@wwwxxxxu ~]#

ddを利用する際は大きなファイルのことが多いので、途中で経過が見えるだけでもストレスが減るのではないでしょうか。
ちなみに私は、上記の出力を元にプログレスバーを表示するスクリプトを作りました。

CentOSをサーバーとして活用するための基本的な設定

  • 投稿日:
  • by
  • Category:

自宅やホスティングなどにおいてCentOSなどのLinuxを利用する人が増えてきました。
最近では格安VPSも増え、さくらインターネットのVPSなど、個人で利用できる安価でパフォーマンスの高いLinux環境が簡単に手に入るようになりました。
このようにサーバを活用する人が増えることは喜ばしい事ですが、いつの間にか乗っ取られていたり、大量のアクセスが来てダウンしてしまったり、自宅のパソコンとの違いに驚く人も多いようです。

今回は、CentOSをサーバとして利用する際に、最初にやっておきたい基本的な設定について解説をします。

本解説は特にさくらのVPSに限ったものではなく、CentOS全般を対象にしています。
さくらのVPSのデフォルトでは、多くのデーモンを停止済みにしているほか、selinuxもdisabledとなっています。

それではみていきましょう。

  1. まず最初にsshのポート番号を変更します。
  2. ポート番号の変更は必ずしないといけない訳ではないですが、簡単にできる攻撃対策です。
    インターネットでは、全世界の22番ポートをくまなく調べ、セキュリティホールのあるサーバが無いかチェックしているロボットがいます。
    もちろん、どうしてもあなたのサーバを落としたい!というロボットがいたら別ですが、普通のロボットは無差別なIPアドレスへポート22固定で攻撃をしてきますから、22番ポート以外に変更することは非常に効果があります。

    /etc/ssh/sshd_config

    #Port 22
    Port 10022

    今回は10022番ポートに変更しました。
    再起動されれば変更が反映されます。

  3. 次に公開鍵認証でssh接続するように変更します
  4. sshでは公開鍵を利用してパスワードを使わずに接続することが可能です。
    具体的にはクライアントでキーペア(秘密鍵と公開鍵)を生成し、サーバには公開鍵だけを登録することで達成できます。
    キーペアの生成方法はクライアントによって異なりますが、teratermの場合でしたら「設定」→「SSH鍵生成」で生成できます。
    もしクライアントがLinuxやFreeBSDなどでOpenSSHを利用しているのであれば、以下のようにして生成を行います。

    # ssh-keygen
    Generating public/private rsa key pair.
    Enter file in which to save the key (/root/.ssh/id_rsa):
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /root/.ssh/id_rsa.
    Your public key has been saved in /root/.ssh/id_rsa.pub.
    The key fingerprint is:
    ・・・・

    次に生成された公開鍵をサーバにセットします。

    # cat >> ~/.ssh/authorized_keys
    ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArg5hePwQQPJKWvlNFGi4TArKI2kB
    e4pZNGY/KeEYp3JkmRbcFgThliRmaCVUauCYvSddenbuwF5jytP8py5JtYNaUOnEO
    J4JU5298dA1Ul2rrft9B+GcEN1tYL4iJStMi4gkK1234567890/3rD+0bfEv5M6PwgRhy6
    gE3LrYw+hpigyi7EChcgtv0e205fDUFcenArrjgGxz9Vw5edz7pHA9dSHLveLanrxNu0p
    Ry5KYH49IdSp141TcQXm1xL/l/3erH+pnoG4taDjH3LIdC8BglZzVPbuO5jySW62ciRw
    QFguH7hzp/Uily3pbsmy0EtAjIcrZ5SCUe7rXLHlfQ== tanaka@tanaka-PC
    ^D
    #

    これで公開鍵を利用したログインが可能になります。

    ただ、ここで安心してはいけません。
    今の状態は、公開鍵"でも"ログインできる状態なだけで、公開鍵"でしか"ログインできないわけではありません。
    これを変更するには、再度sshの設定を変更します。

    /etc/ssh/sshd_config

    PermitRootLogin without-password

    このあとでsshdを再起動すれば、rootログインは公開鍵認証でのみ行えるようになります。

    なお、root以外のユーザにおいても公開鍵のみのログインにしたい場合には、以下のような設定を行います。

    PasswordAuthentication no

    これで、SSHログインは全てのユーザにおいてパスワード認証が無効化されました。

  5. 次にiptablesを設定します。
  6. 基本は、sshとhttp以外は通さないようにするのが吉ですし、sshについては自宅や会社、レンタルサーバなどのIPアドレスからのみ接続できるように設定したほうが良いでしょう。
    以下の例では、httpのみどこからでも接続できるように設定し、sshは210.224.160.0/19からのみ、それ以外のポートは閉じる設定です。

    /etc/sysconfig/iptables

    *filter
    :INPUT ACCEPT [0:0]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [0:0]
    :RH-Firewall-1-INPUT - [0:0]
    -A INPUT -j RH-Firewall-1-INPUT
    -A FORWARD -j RH-Firewall-1-INPUT
    -A RH-Firewall-1-INPUT -i lo -j ACCEPT
    -A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
    -A RH-Firewall-1-INPUT -p 50 -j ACCEPT
    -A RH-Firewall-1-INPUT -p 51 -j ACCEPT
    -A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
    -A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
    -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
    -A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
    -A RH-Firewall-1-INPUT -s 210.224.160.0.0/19 -m state --state NEW -m tcp -p tcp --dport 10022 -j ACCEPT
    -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
    COMMIT

  7. 次に不要なデーモンをストップします
  8. ここからはパフォーマンスの設定です。
    CentOSデフォルトでは、びっくりするくらいのサービスが動いています。これらのほとんどはサーバに必要ないものですので、ざっくりoffにしましょう。

    chkconfig auditd off
    chkconfig autofs off
    chkconfig avahi-daemon off
    chkconfig bluetooth off
    chkconfig cups off
    chkconfig firstboot off
    chkconfig gpm off
    chkconfig haldaemon off
    chkconfig hidd off
    chkconfig isdn off
    chkconfig kudzu off
    chkconfig lvm2-monitor off
    chkconfig mcstrans off
    chkconfig mdmonitor off
    chkconfig messagebus off
    chkconfig netfs off
    chkconfig nfslock off
    chkconfig pcscd off
    chkconfig portmap off
    chkconfig rawdevices off
    chkconfig restorecond off
    chkconfig rpcgssd off
    chkconfig rpcidmapd off
    chkconfig smartd off
    chkconfig xfs off
    chkconfig yum-updatesd off

  9. 要らないコンソールを無効にします
  10. /etc/inittabを以下のようにコメントアウトしましょう。

    #2:2345:respawn:/sbin/mingetty tty2
    #3:2345:respawn:/sbin/mingetty tty3
    #4:2345:respawn:/sbin/mingetty tty4
    #5:2345:respawn:/sbin/mingetty tty5
    #6:2345:respawn:/sbin/mingetty tty6

  11. selinuxを無効にします
  12. selinuxについても、一般的なウェブサーバでは不要でしょうから、offにします。
    /etc/sysconfig/selinuxのSELINUX=enforceを以下のように書き換えれば完了です。

    SELINUX=disabled

    selinuxがoffにすることで、幾分パフォーマンスが向上するそうです。

これで設定は完了です。
再起動を行うことで、全ての設定変更が反映されます。
sshdのポートが変わっていますから、あせらず新しいポートへ接続してみてください。

さて今回、後半に解説したパフォーマンス改善は意外と見落としがちのことです。
今回は512MB搭載した64ビットの仮想環境(VPSでは無い)で実験しましたが、起動時間、空きメモリ共に大きな改善が見られました。
起動時間はチューンナップ前が61秒だったのに対し、チューンナップ後は41秒と3割以上も短縮されました。
メモリの使用量についても、チューンナップ前が219MBだったのが144MBにやはり3割以上も削減されました。

変更前のfree結果

[root@localhost ~]# free
total used free shared buffers cached
Mem: 510008 219440 290568 0 12284 126340
-/+ buffers/cache: 80816 429192
Swap: 1048568 0 1048568

変更後のfree結果

[root@localhost ~]# free
total used free shared buffers cached
Mem: 510008 144544 365464 0 10220 109736
-/+ buffers/cache: 24588 485420
Swap: 1048568 0 1048568


最近では自宅サーバの搭載メモリも増えましたし、さくらのVPSやSaaSesなどスワップが利用できるVPSも増えてきましたので、以前ほどはメモリ不足に悩まされる機会も減りました。
しかし、古いマシンを活用する場合や、OpenVZ系VPSのServersman@VPSなどスワップが利用できないサービスの場合には、メモリ不足に悩まされる方も多いと聞きます。
このようなときに、上記のようなチューンナップを行うことによって、エラーに悩まされることなく利用できるようになるでしょう。

なお、CentOSの場合にはインストール時にDesktopとかServerとか選択せず、X-Window Systemも入れるべきではありません。
また、64bitのOSは高速ですがメモリを多く消費するので、メモリの少ない環境(2GB以下)の場合には32bit版の活用も検討すると良いと思います。

最後になりますが、改めてパフォーマンスと併せてセキュリティに関心を持ってもらえればと思います。
以前友達のパソコンにLinuxをインストールしていた時のこと、アップデートをしている間に裏でクラックされていたなんて笑えない話もありました。
最近のパッケージはそれなりに初期状態からしっかりしていますが、周りの人に迷惑をかけないためにも、きっちりとサーバ管理を行われることをお願いします。

さくらのVPSにFreeBSDをインストールする

  • 投稿日:
  • by
  • Category:

さくらインターネットでは、先日より「さくらのVPS」を提供開始し、予想を上回る大ヒットサービスとなっています。
特徴を言い始めるとキリがありませんが、国内の格安VPSとしては初めてKVMの完全仮想化を実現し、インストールできるOSの可能性は大きく広がっていることも大きな特徴の一つでしょう。
そのようなことから、近日中にも、Ubuntu、Debian、Fedora、FreeBSDなどの様々なOSを、コンパネ上から自由にインストーラーを起動できるように準備を進めております。

ただ、本日は「正式対応まで待てない!」という人のために、さくらインターネットの1ユーザとしての立場からFreeBSDのインストールを試した際の作業メモを公開します。
なお、完全に無保証ですし、あくまでも1ユーザ(ちゃんと自分で支払ってますよ)としての立ち位置でのメモですので、くれぐれもサポートなどに問い合わせを頂かないよう理解頂ければ幸いです。

それでははじめていきましょう。
手順は、スワップパーティションを削除してFreeBSDのインストールイメージを展開し、GRUBからインストーラーを起動し、インストールを行うというものです。

  1. 設定情報をメモする
  2. インストールを開始するにあたり、まず設定情報をメモします。 必要なのは、ホスト名、デフォルトルーター、IPアドレス、ネットマスク、ネームサーバです。
    ホスト名 www30xxu.sakura.ne.jp
    デフォルトルータ 59.106.176.1
    IPアドレス 59.106.176.xx
    ネットマスク 255.255.254.0
    ネームサーバ 210.188.224.10
    210.188.224.11

    [root@www30xxu ~]# cat /etc/resolv.conf
    nameserver 210.188.224.10 ← ネームサーバ
    nameserver 210.188.224.11
    search sakura.ne.jp
    [root@www30xxu ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
    DEVICE=eth0
    IPADDR=59.106.176.xx ← IPアドレス
    NETMASK=255.255.254.0 ← ネットマスク
    GATEWAY=59.106.176.1 ← デフォルトルーター
    ONBOOT=yes
    [root@www30xxu ~]# hostname
    www30xxu.sakura.ne.jp ← ホスト名
    [root@www30xxu ~]#


  3. OSを初期状態に戻す
  4. コンパネにログイン(会員メニューからの場合はhttps://secure.sakura.ad.jp/menu/service/?mode=S1010より)し、「OS再インストール」よりOSを初期状態に戻します。
    これは必ずしも必要な作業ではありませんが、いろいろと設定変更している場合には実施したほうがよいと思います。

  5. スワップパーティションを削除
  6. /etc/fstabを開いてスワップパーティションをコメントアウトし、再起動します。

    /etc/fstab


    LABEL=/ / ext3 defaults 1 1
    LABEL=/boot /boot ext3 defaults 1 2
    tmpfs /dev/shm tmpfs defaults 0 0
    devpts /dev/pts devpts gid=5,mode=620 0 0
    sysfs /sys sysfs defaults 0 0
    proc /proc proc defaults 0 0
    #LABEL=SWAP-vda3 swap swap defaults 0 0 ← ここをコメントアウト

    再起動せずにswapoff -aを実行するだけでもよいかもしれませんが、再起動したほうがより安全でしょう。

    スワップの削除が完了すれば、fdiskを実行してスワップパーティションをFreeBSDに変更し、もう一度再起動します。

    [root@www30xxu ~]# fdisk /dev/hda
    Command (m for help): t ← パーティションのシステムIDを変更
    Partition number (1-4): 3 ← パーティション3を選択(旧スワップパーティション)
    Hex code (type L to list codes): a5 ← パーティションをFreeBSDに変更
    Changed system type of partition 3 to a5 (FreeBSD)

    Command (m for help): a ← パーティションのBootフラグを設定
    Partition number (1-4): 3 ← パーティション3を選択(旧スワップパーティション)

    Command (m for help): p ← パーティション一覧を表示

    Disk /dev/hda: 21.4 GB, 21474836480 bytes
    255 heads, 63 sectors/track, 2610 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes

    Device Boot Start End Blocks Id System
    /dev/hda1 * 1 13 104391 83 Linux
    /dev/hda2 14 2355 18812115 83 Linux
    /dev/hda3 * 2356 2610 2048287+ a5 FreeBSD ← FreeBSDに変更できたのを確認

    Command (m for help): w
    The partition table has been altered!

    Calling ioctl() to re-read partition table.

    WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
    The kernel still uses the old table.
    The new table will be used at the next reboot.
    Syncing disks.
    [root@www30xxu ~]# reboot ← 再起動

  7. スワップパーティション跡にOSのインストールイメージを展開
  8. まずFreeBSDのインストールイメージをダウンロードします。
    ここでポイントは、memstick.imgというUSBメモリインストール用イメージをダウンロードしてくるということです。
    ISOファイルの場合は、一度展開して自分でディスクイメージを作る必要があります。

    今回は、FreebSD 8.1のi386版をダウンロードしました。
    パフォーマンスだけでいえばamd64版の方が良いかもしれませんが、メモリやハードディスクを食いますので、ケースバイケースで使い分けしてください。

    [root@www30xxu ~]# wget ftp://ftp8.jp.freebsd.org/pub/FreeBSD/ISO-IMAGES-i386/8.1/FreeBSD-8.1-RELEASE-i386-memstick.img
    --2010-09-04 10:17:03-- ftp://ftp8.jp.freebsd.org/pub/FreeBSD/ISO-IMAGES-i386/8.1/FreeBSD-8.1-RELEASE-i386-memstick.img
    => `FreeBSD-8.1-RELEASE-i386-memstick.img'
    Resolving ftp8.jp.freebsd.org... 210.224.179.153
    Connecting to ftp8.jp.freebsd.org|210.224.179.153|:21... connected.
    Logging in as anonymous ... Logged in!
    ==> SYST ... done. ==> PWD ... done.
    ==> TYPE I ... done. ==> CWD /pub/FreeBSD/ISO-IMAGES-i386/8.1 ... done.
    ==> SIZE FreeBSD-8.1-RELEASE-i386-memstick.img ... 948244480
    ==> PASV ... done. ==> RETR FreeBSD-8.1-RELEASE-i386-memstick.img ... done.
    Length: 948244480 (904M)

    100%[================================================>] 948,244,480 9.86M/s in 96s

    2010-09-04 10:18:39 (9.41 MB/s) - `FreeBSD-8.1-RELEASE-i386-memstick.img' saved [948244480]

    次に、先ほどFreeBSDパーティションへ変更したhda3にインストールイメージを展開します。

    [root@www30xxu ~]# dd if=FreeBSD-8.1-RELEASE-i386-memstick.img of=/dev/hda3
    1852040+0 records in
    1852040+0 records out
    948244480 bytes (948 MB) copied, 13.4296 seconds, 70.6 MB/s
    [root@www30xxu ~]#

  9. GRUBを変更
  10. GRUBを変更して、hda3から起動できるように設定します。
    具体的には、/boot/grub/menu.lst に次の項目を追記します。

    title FreeBSD Install
            rootnoverify (hd0,2)
            chainloader +1
    

  11. VNC(リモートデスクトップ)を起動
  12. さくらのVPSには、非公式ながらVNC機能が備わっています。
    コントロールパネルにログインした状態で、以下のURLを開けばVNCウィンドウが立ち上がります。

    VNCのURL: https://secure.sakura.ad.jp/vpscontrol/main/vnc
    20100904-1.jpg

    ※MacBookでUS-Keyboardだと、ブラウザのTightVNC Java Viewerで入力できない文字があるそうなので、その場合はJISキーボードを接続すると回避できるそうです。 by @utaaniさん

  13. 再起動してインストーラーを起動
  14. ここからは、リモートコンソール(シリアルコンソール)ではなく、VNC画面での作業が必須です。
    OSを再起動し、VNC画面内でGRUBメニューを開いてインストーラーを起動します。
    手順は以下の通り。

    Press any key to continue. の画面で、何かキーを押す
    20100904-2.jpg

    Booting CentOSの画面で、何かキーを押す
    20100904-3.jpg

    GRUBのメニューにて、FreeBSD Installを選択する
    20100904-4.jpg


  15. 通常通りにインストールを行う
  16. ブートローダーが起動して、インストーラーが起動すればひとまずは成功です。
    20100904-5.jpg 20100904-6.jpg

    ここからは、通常のインストール手順です。
    私は、Standardを選択して進めました。

    FDISKが起動されると、ext2fsが2つとfreebsdが1つあるはずです。
    20100904-7.jpg

    これらをすべて削除します。
    20100904-8.jpg

    その後、a キーを押しパーティションすべてをFreeBSDで利用します。
    ここで w キーを押してパーティション情報を保存するとインストールに失敗しますので、そのまま q を押してディスクラベルエディターへ進みます。
    20100904-9.jpg

    ディスクラベルを編集します。
    私は a キーを押して、自動でパートわけしました。
    ここでも、w キーは押さずに次へ進みます。
    20100904-10.jpg

    インストールメディア選択では、2番目の「FTP」を選択します。
    20100904-11.jpg

    FTPサイトは、ftp8.jp.freebsd.orgを選択します。
    このサイトはさくらインターネットが運営しているFreeBSD公式サイトですので、大変スムーズにダウンロードできます。
    20100904-12.jpg

    ネットワーク設定画面では、先ほどメモしたネットワーク情報を入力します。
    ここで注意すべきは、ネットマスクです。255.255.255.0ではなく255.255.254.0ですので、くれぐれも間違えないようにしてください。
    20100904-13.jpg

    最終メッセージが出てくれば、インストール実行です。
    これを行うと、CentOSはすべてなくなってしまいますので、十分に注意してください。
    20100904-14.jpg

    無事インストールが開始されました。
    20100904-15.jpg

    ファイルコピー終了後に、私はSSHのみ有効にしました。
    20100904-16.jpg

  17. 無事インストール完了!
  18. 無事インストールが完了しました。
    20100904-17.jpg
    あとは、SSHでリモートログインができるように設定すれば、完了です。

    なお、さくらのVPSのリモートコンソール(シリアルコンソール)機能はFreeBSDで安定しないので、シリアルコンソール設定はせずにVNCで対応頂ければ幸いです。

さくらのVPSと互換の実験環境ではWindows(XP / Vista / Server 2008)のインストールもできましたので、もしかしたら可能かもしれませんね。
※ただしWindowsのデスクトップ向けOSは仮想環境で動かせるライセンスが無いようですので、インストールして利用してしまうとライセンス違反になりますからご注意ください。

以上、FreeBSDのインストールでした。
しつこいようですが、公式にはFreeBSDは使えないことになっていますので、その点はご理解いただければ幸いです。

今後、公式なOSインストール機能も予定しており、IPアドレス逆引きや、IPv6対応、上位プラン(できればCPU占有プラン)などのアナウンスもできるかと思いますので、全ての環境をさくらのVPSでということも可能になります。
これからも、さくらインターネットおよびさくらのVPSを、どうぞよろしくお願いします。

「さくらのVPS」を使ってみる

  • 投稿日:
  • by
  • Category:

先日、「さくらのVPS」のベータテストが開始されました。
私も個人的にさくらのレンタルサーバを利用しているので、7月14日にフライングして申し込みしました。
(最終テスト中だったようで、社員にまじめに怒られてしまいましたが・・。スイマセン)

まず基本仕様


  • CPU 2コア

  • メモリー 512MB

  • HDD 20GB

  • ネットワーク 100Mbps(いちおうの上限)

  • リモートコンソール付き

  • 再起動、再インストールは、セルフサービスでコンパネから可能

ホスト側は、QuadCore Xeonで、1Gbpsにて上位スイッチに接続し、10Gbpsでさくらインターネットの基幹ネットワークに接続しています。
(クローズドベータテスト中に400Mbps位出たという記事もありましたが、さすがに対策する予定です)

ハイパーバイザーは、巷の格安VPSで多く利用される、VirtuaozzoやOpenVZ、Xenの準仮想化と異なり、KVMで完全仮想化になっています。
完全に512MBの実メモリを割当しますから、ホストOS側でスワップされずパフォーマンスが低下しないですし、ゲスト環境側でスワップを用意することも可能です。

実メモリは、ゲストで必要とするメモリ容量の1.5倍?2倍程度を搭載しています。
というのは、ホストOSのメモリの2/3以上をゲストに割り当てると、過負荷時のレスポンスが急激に悪化したり、不安定になったりということが言われており、当社でも再現されているので、余裕を持った設計にしています。
さらに、ホストOSのメモリの余裕を持たすことで、ディスクI/Oも劇的によくなります。
ゲストOSのスワップ時でも、ホストOSのキャッシュに入っていれば、メモリの延長上といえるかもしれません。

このように、100Mbpsインターフェース、20GBのHDD、2 CPU、512MBメモリといっても、同種のVPSサービスとは一線を画します。
その上で、「格安VPS」といえる価格帯で出す予定にしていますので、海外にも増してメリットのあるサービスになるのではと考えています。


と、宣伝はここまでにして、早速利用してみます。


まず、私が行ったのは、sshの公開鍵を設置してrootログインできないようにすることです。
申し込み直後は、ほぼ最新のパッチを当てて出荷されますので、いきなりクラックされることは考えなくてもよいと思いますが、なんとなく不安です。
(対策として、ネットワークをシャットダウンしたまま出荷するオプションを用意するなど、検討の余地があると考えています。)

ということで、ssh-keygenを行い、/etc/ssh/sshd_configにrootでのパスワードログインを禁止します。

[root@www10xxu ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
1b:f0: root@www10xxu.sakura.ne.jp
[root@www10xxu ~]#
/etc/ssh/sshd_config
変更前
PermitRootLogin yes
変更後
PermitRootLogin without-password
[root@www10xxu ~]# service sshd restart


次に無駄なデーモンをoffにします。
さくらのVPSの初期状態において脊髄反射で感じるのは「思いのほか空きメモリが少ない!」ということです。

ps -aux結果

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1  10348   688 ?        Ss   Jul15   0:00 init [3]
root         2  0.0  0.0      0     0 ?        S<   Jul15   0:03 [migration/0]
root         3  0.0  0.0      0     0 ?        SN   Jul15   0:00 [ksoftirqd/0]
root         4  0.0  0.0      0     0 ?        S<   Jul15   0:00 [watchdog/0]
root         5  0.0  0.0      0     0 ?        S<   Jul15   0:01 [migration/1]
root         6  0.0  0.0      0     0 ?        SN   Jul15   0:00 [ksoftirqd/1]
root         7  0.0  0.0      0     0 ?        S<   Jul15   0:00 [watchdog/1]
root         8  0.0  0.0      0     0 ?        S<   Jul15   0:00 [events/0]
root         9  0.0  0.0      0     0 ?        S<   Jul15   0:00 [events/1]
root        10  0.0  0.0      0     0 ?        S<   Jul15   0:00 [khelper]
root        15  0.0  0.0      0     0 ?        S<   Jul15   0:00 [kthread]
root        20  0.0  0.0      0     0 ?        S<   Jul15   0:00 [kblockd/0]
root        21  0.0  0.0      0     0 ?        S<   Jul15   0:00 [kblockd/1]
root        22  0.0  0.0      0     0 ?        S<   Jul15   0:00 [kacpid]
root        90  0.0  0.0      0     0 ?        S<   Jul15   0:00 [cqueue/0]
root        91  0.0  0.0      0     0 ?        S<   Jul15   0:00 [cqueue/1]
root        94  0.0  0.0      0     0 ?        S<   Jul15   0:00 [khubd]
root        96  0.0  0.0      0     0 ?        S<   Jul15   0:00 [kseriod]
root       168  0.0  0.0      0     0 ?        S    Jul15   0:00 [khungtaskd]
root       169  0.0  0.0      0     0 ?        S    Jul15   0:00 [pdflush]
root       170  0.0  0.0      0     0 ?        S    Jul15   0:00 [pdflush]
root       171  0.0  0.0      0     0 ?        S<   Jul15   0:00 [kswapd0]
root       172  0.0  0.0      0     0 ?        S<   Jul15   0:00 [aio/0]
root       173  0.0  0.0      0     0 ?        S<   Jul15   0:00 [aio/1]
root       317  0.0  0.0      0     0 ?        S<   Jul15   0:00 [kpsmoused]
root       361  0.0  0.0      0     0 ?        S<   Jul15   0:00 [ata/0]
root       362  0.0  0.0      0     0 ?        S<   Jul15   0:00 [ata/1]
root       363  0.0  0.0      0     0 ?        S<   Jul15   0:00 [ata_aux]
root       373  0.0  0.0      0     0 ?        S<   Jul15   0:00 [kstriped]
root       386  0.0  0.0      0     0 ?        S<   Jul15   0:04 [kjournald]
root       407  0.0  0.0      0     0 ?        S<   Jul15   0:00 [kauditd]
root       435  0.0  0.1  12672   764 ?        S<s  Jul15   0:00 /sbin/udevd -d
root      1059  0.0  0.0      0     0 ?        S<   Jul15   0:00 [kmpathd/0]
root      1060  0.0  0.0      0     0 ?        S<   Jul15   0:00 [kmpathd/1]
root      1062  0.0  0.0      0     0 ?        S<   Jul15   0:00 [kmpath_handlerd]
root      1112  0.0  0.0      0     0 ?        S<   Jul15   0:00 [kjournald]
root      1429  0.0  0.1   5908   608 ?        Ss   Jul15   0:00 syslogd -m 0
root      1432  0.0  0.0   3804   424 ?        Ss   Jul15   0:00 klogd -x
dbus      1492  0.0  0.1  21256   964 ?        Ss   Jul15   0:00 dbus-daemon --system
root      1501  0.0  0.1   3800   580 ?        Ss   Jul15   0:00 /usr/sbin/acpid
68        1509  0.0  0.7  30604  3660 ?        Ss   Jul15   0:00 hald
root      1510  0.0  0.2  21692  1056 ?        S    Jul15   0:00 hald-runner
68        1518  0.0  0.1  12324   844 ?        S    Jul15   0:00 hald-addon-acpi: listening on acpid socket /var/run/acpid.socket
68        1523  0.0  0.1  12324   848 ?        S    Jul15   0:00 hald-addon-keyboard: listening on /dev/input/event0
root      1532  0.1  0.1  10228   680 ?        S    Jul15   4:09 hald-addon-storage: polling /dev/hdc
root      1547  0.0  0.2  62624  1208 ?        Ss   Jul15   0:00 /usr/sbin/sshd
ntp       1558  0.0  0.9  23388  5028 ?        SLs  Jul15   0:00 ntpd -u ntp:ntp -p /var/run/ntpd.pid -g
root      1576  0.0  0.4  69004  2348 ?        Ss   Jul15   0:00 sendmail: accepting connections
smmsp     1584  0.0  0.3  59764  1800 ?        Ss   Jul15   0:00 sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue
root      1593  0.0  0.2  19708  1144 ?        Ss   Jul15   0:00 crond
root      1601  0.0  0.0  18732   456 ?        Ss   Jul15   0:00 /usr/sbin/atd
root      1615  0.0  0.2  52108  1332 ?        Ss   Jul15   0:00 login -- root
root      1616  0.0  0.0   3792   480 tty2     Ss+  Jul15   0:00 /sbin/mingetty tty2
root      1617  0.0  0.0   3792   484 tty3     Ss+  Jul15   0:00 /sbin/mingetty tty3
root      1628  0.0  0.0   3792   480 tty4     Ss+  Jul15   0:00 /sbin/mingetty tty4
root      1629  0.0  0.0   3792   480 tty5     Ss+  Jul15   0:00 /sbin/mingetty tty5
root      1640  0.0  0.0   3792   480 tty6     Ss+  Jul15   0:00 /sbin/mingetty tty6
root      1641  0.0  0.1   3800   536 ttyS0    Ss+  Jul15   0:00 /sbin/agetty -h 115200 ttyS0 vt100
root      1684  0.0  3.1 201952 15920 ?        SN   Jul15   0:00 /usr/bin/python -tt /usr/sbin/yum-updatesd
root      1686  0.0  0.2  12916  1160 ?        SN   Jul15   0:00 /usr/libexec/gam_server
root      1722  0.0  0.6  90320  3528 ?        Ss   Jul15   0:00 sshd: root@pts/0
root      1724  0.0  0.2  10932  1440 pts/0    Ss+  Jul15   0:00 -bash
root      1758  0.0  0.2  10928  1372 tty1     Ss+  Jul15   0:00 -bash
root     10606  0.0  0.6  91048  3380 ?        Rs   13:17   0:00 sshd: root@pts/1
root     10608  0.0  0.2  10932  1392 pts/1    Ss   13:17   0:00 -bash
root     10643  0.0  0.1  10460   876 pts/1    R+   13:38   0:00 ps -aux

まず、コンソール(mingetty)はこんなに要らないので、減らします。

/etc/inittabを以下のように編集


# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1
#2:2345:respawn:/sbin/mingetty tty2
#3:2345:respawn:/sbin/mingetty tty3
#4:2345:respawn:/sbin/mingetty tty4
#5:2345:respawn:/sbin/mingetty tty5
#6:2345:respawn:/sbin/mingetty tty6

デーモンも減らします。

[root@www10xxu ~]# chkconfig yum-updatesd off
[root@www10xxu ~]# chkconfig haldaemon off
[root@www10xxu ~]# chkconfig yum-updatesd off
[root@www10xxu ~]# chkconfig acpid off
[root@www10xxu ~]# chkconfig messagebus off

これで再起動すれば、ずいぶんとメモリの空きができます。
再起動後に確認すると、使用中は150MBとなっていました。もう少しがんばれば、もっと削減できそうです。


なお、unixbenchも実行してみました。
index scoreは1540.6ですので、そこそこ速いのではないでしょうか。

   #    #  #    #  #  #    #          #####   ######  #    #   ####   #    #
   #    #  ##   #  #   #  #           #    #  #       ##   #  #    #  #    #
   #    #  # #  #  #    ##            #####   #####   # #  #  #       ######
   #    #  #  # #  #    ##            #    #  #       #  # #  #       #    #
   #    #  #   ##  #   #  #           #    #  #       #   ##  #    #  #    #
    ####   #    #  #  #    #          #####   ######  #    #   ####   #    #

Version 5.1.2 Based on the Byte Magazine Unix Benchmark

Multi-CPU version Version 5 revisions by Ian Smith,
Sunnyvale, CA, USA
December 22, 2007 johantheghost at yahoo period com


1 x Dhrystone 2 using register variables 1 2 3 4 5 6 7 8 9 10

1 x Double-Precision Whetstone 1 2 3 4 5 6 7 8 9 10

1 x Execl Throughput 1 2 3

1 x File Copy 1024 bufsize 2000 maxblocks 1 2 3

1 x File Copy 256 bufsize 500 maxblocks 1 2 3

1 x File Copy 4096 bufsize 8000 maxblocks 1 2 3

1 x Pipe Throughput 1 2 3 4 5 6 7 8 9 10

1 x Pipe-based Context Switching 1 2 3 4 5 6 7 8 9 10

1 x Process Creation 1 2 3

1 x System Call Overhead 1 2 3 4 5 6 7 8 9 10

1 x Shell Scripts (1 concurrent) 1 2 3

1 x Shell Scripts (8 concurrent) 1 2 3

2 x Dhrystone 2 using register variables 1 2 3 4 5 6 7 8 9 10

2 x Double-Precision Whetstone 1 2 3 4 5 6 7 8 9 10

2 x Execl Throughput 1 2 3

2 x File Copy 1024 bufsize 2000 maxblocks 1 2 3

2 x File Copy 256 bufsize 500 maxblocks 1 2 3

2 x File Copy 4096 bufsize 8000 maxblocks 1 2 3

2 x Pipe Throughput 1 2 3 4 5 6 7 8 9 10

2 x Pipe-based Context Switching 1 2 3 4 5 6 7 8 9 10

2 x Process Creation 1 2 3

2 x System Call Overhead 1 2 3 4 5 6 7 8 9 10

2 x Shell Scripts (1 concurrent) 1 2 3

2 x Shell Scripts (8 concurrent) 1 2 3

========================================================================
BYTE UNIX Benchmarks (Version 5.1.2)

System: www1010u.sakura.ne.jp: GNU/Linux
OS: GNU/Linux -- 2.6.18-194.8.1.el5 -- #1 SMP Thu Jul 1 19:04:48 EDT 2010
Machine: x86_64 (x86_64)
Language: en_US.utf8 (charmap="UTF-8", collate="UTF-8")
CPU 0: Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz (5319.4 bogomips)
x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET
CPU 1: Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz (5290.9 bogomips)
x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET
10:15:43 up 1 day, 19:18, 2 users, load average: 0.02, 0.02, 0.00; runlevel 3

------------------------------------------------------------------------
Benchmark Run: Sat Jul 17 2010 10:15:43 - 10:43:56
2 CPUs in system; running 1 parallel copy of tests

Dhrystone 2 using register variables 14188657.9 lps (10.0 s, 7 samples)
Double-Precision Whetstone 3011.2 MWIPS (9.8 s, 7 samples)
Execl Throughput 1775.5 lps (29.6 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks 709457.6 KBps (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks 210832.6 KBps (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks 1449865.3 KBps (30.0 s, 2 samples)
Pipe Throughput 1955338.6 lps (10.0 s, 7 samples)
Pipe-based Context Switching 259909.8 lps (10.0 s, 7 samples)
Process Creation 8795.8 lps (30.0 s, 2 samples)
Shell Scripts (1 concurrent) 4125.4 lpm (60.0 s, 2 samples)
Shell Scripts (8 concurrent) 1416.6 lpm (60.0 s, 2 samples)
System Call Overhead 3385128.4 lps (10.0 s, 7 samples)

System Benchmarks Index Values BASELINE RESULT INDEX
Dhrystone 2 using register variables 116700.0 14188657.9 1215.8
Double-Precision Whetstone 55.0 3011.2 547.5
Execl Throughput 43.0 1775.5 412.9
File Copy 1024 bufsize 2000 maxblocks 3960.0 709457.6 1791.6
File Copy 256 bufsize 500 maxblocks 1655.0 210832.6 1273.9
File Copy 4096 bufsize 8000 maxblocks 5800.0 1449865.3 2499.8
Pipe Throughput 12440.0 1955338.6 1571.8
Pipe-based Context Switching 4000.0 259909.8 649.8
Process Creation 126.0 8795.8 698.1
Shell Scripts (1 concurrent) 42.4 4125.4 973.0
Shell Scripts (8 concurrent) 6.0 1416.6 2361.0
System Call Overhead 15000.0 3385128.4 2256.8
========
System Benchmarks Index Score 1157.7

------------------------------------------------------------------------
Benchmark Run: Sat Jul 17 2010 10:43:56 - 11:12:10
2 CPUs in system; running 2 parallel copies of tests

Dhrystone 2 using register variables 27985122.2 lps (10.0 s, 7 samples)
Double-Precision Whetstone 5992.4 MWIPS (9.7 s, 7 samples)
Execl Throughput 7332.5 lps (30.0 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks 218518.6 KBps (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks 63801.8 KBps (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks 502186.1 KBps (30.0 s, 2 samples)
Pipe Throughput 3771938.1 lps (10.0 s, 7 samples)
Pipe-based Context Switching 775819.3 lps (10.0 s, 7 samples)
Process Creation 20049.5 lps (30.0 s, 2 samples)
Shell Scripts (1 concurrent) 9979.2 lpm (60.0 s, 2 samples)
Shell Scripts (8 concurrent) 1579.2 lpm (60.0 s, 2 samples)
System Call Overhead 5635202.3 lps (10.0 s, 7 samples)

System Benchmarks Index Values BASELINE RESULT INDEX
Dhrystone 2 using register variables 116700.0 27985122.2 2398.0
Double-Precision Whetstone 55.0 5992.4 1089.5
Execl Throughput 43.0 7332.5 1705.2
File Copy 1024 bufsize 2000 maxblocks 3960.0 218518.6 551.8
File Copy 256 bufsize 500 maxblocks 1655.0 63801.8 385.5
File Copy 4096 bufsize 8000 maxblocks 5800.0 502186.1 865.8
Pipe Throughput 12440.0 3771938.1 3032.1
Pipe-based Context Switching 4000.0 775819.3 1939.5
Process Creation 126.0 20049.5 1591.2
Shell Scripts (1 concurrent) 42.4 9979.2 2353.6
Shell Scripts (8 concurrent) 6.0 1579.2 2632.1
System Call Overhead 15000.0 5635202.3 3756.8
========
System Benchmarks Index Score 1540.6

と、雑多にまとめてみました。

なお、ただいまベータテスト中で、追加予定機能は山のようにあるので、状況を見ながらアップデートして行きたと思います。
ツイッターでもさまざまな要望を頂いていますが、ぜひ参考にさせていただきたいので、コンパネ上の「ご意見・ご要望」もご活用ください。

kumofsを使う

  • 投稿日:
  • by
  • Category:

最近KVS(Key-Value-Storage)が流行っていますが、うちの研究所においても「えとらぼ」さんと共同でkumofsの研究をしています。
色々とバギーなところも多いのですが、最新パッチを頂きながら、それなりに成果が出てきたようです。
kumofsの詳細については、さくらインターネット研究所に任せることにして、今回は一般にソースが公開されたこともあるので個人的にインストールした際のログを紹介します。


1. まず関連する諸ライブラリのインストール

libtoolのインストール
# yum install libtool

OpenSSLのインストール
# yum install openssl-devel

BZip2ライブラリのインストール(tokyo cabinetインストールのために必要)
# yum install bzip2-devel


2. msgpackのインストール

ダウンロード
http://msgpack.sourceforge.jp/

私は、msgpack-0.4.0.tar.gzをダウンロードしました。

ここで注意!
私の環境で ./configure && make した際、インストールは無事完了したものの、いざライブラリを使おうと思うと、__sync_sub_and_fetch_4が無いとのエラーが出ました。

kumofsの./configureをconfig.logより


configure:19500: checking for main in -lmsgpack
configure:19524: gcc -o conftest -O4 -Wall -O4 -L/usr/local/lib/ -mtune=i386 conftest.c -lmsgpack -lcrypto -lz -lpthread -lstdc++ >&5
/usr/local/lib/libmsgpackc.so.2: undefined reference to `__sync_sub_and_fetch_4'
collect2: ld returned 1 exit status
configure:19530: $? = 1

__sync_sub_and_fetchというのは、マルチスレッド環境下においてアトミックな加算処理を行うためのgcc組み込み関数ですが、なぜか_4が付いてしまっています。
これはgccの仕様で、引数の型を見て、その型のビット長を付けるためだと分かりました。
例えば今回の場合、4バイトなので 「_4」 をつけられています。
まあ、これはいいのですが、-march=i686をつければgccの挙動が変わるとのことなので、msgpackの./configure前には CFLAGSとCPPFLAGSにセットしておくことで回避しました。

# tar xvfz msgpack-0.4.0.tar.gz
# cd msgpack-0.4.0
# export set CFLAGS=-march=i686
# export set CPPFLAGS=-march=i686
# ./configure
# make
# make install

※参考になったサイト
仙石浩明の日記: __sync_bool_compare_and_swap_4 とは何か? ? glibc をビルドする場合は、 gcc の --with-arch=i686 configure オプションを使ってはいけない


3. tokyo cabinet のインストール

http://1978th.net/tokyocabinet/
私は、バージョン1.4.41をダウンロードしました。

# tar xvfz tokyocabinet-1.4.41.tar.gz
# cd tokyocabinet-1.4.41/
# ./configure
# make
# make install


4. kumofsのインストール

ダウンロードは、古橋さんのサイトからできます。
http://d.hatena.ne.jp/viver/20100118/p1

私は、githubよりkumofs-0.3.0 をダウンロードしました。


次に /usr/local/lib がライブラリに含まれるよう、環境変数をセット。
(私の場合、新しい環境だったので、これがないと cannot find -lmsgpack となりました)

# export set LDFLAGS=-L/usr/local/lib

早速ビルドを開始

# ./bootstrap
# ./configure
# make
# make install

とりあえず、インストールは完了したようです。

早速起動と行きたいところですが、また時間を見つけてクラスターを組んでみたいと思います。


なお、うちの研究所では型落ちのサーバを山のように用意して、実験をしているようですので、パフォーマンスなど実際のレポートは、そちらを期待してください。
私のほうでは、とりあえず画像生成サイトなど、個人的にやっているいくつかのサイトのバックエンドを、kumofsにしてみようかと思っています。
Apache用のmod_kumofsとかを作って、kumofsに格納されたバリューを、直接クライアントに返すなんてこともやってみたいところです。

将来的には、mysqlのように、共用サーバやクラウドでのインスタンス貸しをしてみたいものですね。

とある櫻花の画像生成(ジェネレーター)

  • 投稿日:
  • by
  • Category:

いろんな人たちから「何やってんだ(笑)」と言われつつも、とある櫻花の画像生成が完成しました。


http://to-a.ru


元ネタは言わなくてもお分かりいただけるでしょうが、某禁書目録や某超電磁砲のタイトル風画像を作れるだけのサイトです。
ちなみに、「とある画像の自動生成」というサイトが既にあるのですが、Silverlightベースなのでクライアントのインストールが必要ですし、そのほかにも改良したいところが多かったので、自分で作りました。

改良したところ

  • サーバでの生成方式に変えた
  • グラデーションの粒度を細かくした
  • すべての文字にアンチエイリアスをかけた
  • フォントを極太明朝に変えた(HG明朝E)
  • サーバへの保存機能を設けた
  • とある???で、3文字入力を可能にした→ ex. とあるラジオの超電磁砲

今回は、PHP+GDで書いたのですが、文字に斜めの滑らかなグラデーションをかけるのは意外と難しく、文字データとグラデーションを別個で作って、独自のルーチンで合成するということをしました。
ImageMagickのレイヤーを使えば簡単だと言う情報をさまざまな人から寄せられたのですが、「プログラマたるもの制約の中で最高のアウトプットを出さんとあかん」ということで、GDのままです。(といいつつ、「ここまで作ったしGDでいいや」ってのが本音ですww)

まず、グラデーションを生成するコード。