火曜日, 12月 19, 2006

Debian GNU/Linux で heartbeat を使う

ldirectord を使って高い可用性と拡張性をもつシステムを作りました。
あれ、でもまだひとつ足りません。
そう、LVS自体がSPOF(Single Point Of Failure、故障すると取替えがきかない部分)になってしまったんですね。
なので、これを冗長化します。

これには heartbeat を使います。
まず、aptitude install heartbeat でインストール。
次に、/usr/share/doc/heartbeat/ にある authkeys、ha.cf.gz、haresources.gz を /etc/ha.d/ にコピーします。
authkeys はパーミッションを0600に変更、残りの2つのファイルは gunzip で解凍します。

ここの設定は、それぞれがローカルネットワーク用のeth0、外部向けのeth1を持っている場合です。ひとつしかなければもっと簡単です。

ha.cf
-------------------------------------------------------------------------------------
keepalive 2
deadtime 10
warntime 10
initdead 10
mcast eth0 225.0.0.1 694 1 0
node xvm249
node xvm250
-------------------------------------------------------------------------------------
↑に書いた行のコメントを外して、値を変更します。
最初の辺りの数字は時間です。デフォルトは長すぎるので。
mcastはマルチキャストの意味。
ブロードキャストでもいいのですが、他にもheartbeatを利用した共有を行うつもりなのでマルチキャストにしました。
node はuname -nで出力される名前。参加するホスト分書きます。

haresources
-------------------------------------------------------------------------------------
xvm249 59.106.42.202/28/eth1
-------------------------------------------------------------------------------------
共有するリソースを書きます。
それぞれ、マスターのホスト名とIP、イーサネットの名前を書きます。

authkeys
-------------------------------------------------------------------------------------
auth 2
2 sha1 KYif6FQMB5XmeQT1I7CuYEEQrbQNGCsF
-------------------------------------------------------------------------------------
上のふたつの行を有効にして、パスワードは適当に決めます。
makepasswd -c 32 なんかで作れます。

IPsecを使えばここはなんでもいいです。
認証や暗号化はIPsecに統一したほうが、全体のコストは安上がりでしょう。

これでheartbeatの設定は終わりです。
でも、共有するリソースをheartbeatに開放しないといけません。
/etc/network/interfaces から59.106.42.202を削除します。
でもそうすると、割り当てるIPがなくなるので、boot時にeth1が起動しません。
iface eth1 ...
の代わりに、
up ifconfig eth1 up
を書いて、起動だけするようにしておきます。
結局IPv6のリンクローカルアドレスが割り当てられます。

さらにLVSの設定が必要です。
というのも、テーブルの内容は静的なので同期を取って置けますが、厳密にはTCPのコネクションの情報なども共有しなければいけないからです。
これには、dpkg-reconfigure ipvsadm を実行して、一方のホストをmaster、もう一方をbackupに設定すればできます。

こうすれば同期を取ることができますが、名前からわかるように双方向ではありません。
双方向のパッチもあります。でも、かなり細かい部分なので、僕は本家にマージされるのをのんびり待ちます。

ここまでやると、夜中にシステムダウンで起こされることもなくなります。

金曜日, 12月 15, 2006

Debian GNU/Linux で ldirectord を使う

ldirectord はバックエンドのサーバー群を監視して、自律的にテーブルを書き換えるLVSの拡張です。
もうちょっと具体的に言うと、バックエンドのサーバーに不具合が起きて停止すると、それを発見してリクエストをそちらに送らなくしたりします。
逆に、それまで停止していたサーバーが復帰するとまたリクエストを送るようにしたりするわけですね。

これって、高可用性の要件を満たすのに、めちゃくちゃ有効です。
しかも、ipvsadmと大して手間は変わりません。

まず、aptitude install ldirectord でインストール。
cp /usr/share/doc/ldirectord/ldirectord.cf.gz /etc/ha.d/
gunzip ldirectord.cf.gz
で設定ファイルをコピーします。

設定はこのファイルのサンプルを参考にすればマニュアル見なくても大体わかります。
とりあえずHTTPの設定はこんな感じです。
-------------------------------------------------------------------------------------
# Global Directives
checktimeout=3
checkinterval=1
fallback=127.0.0.1:80
autoreload=yes
#logfile="/var/log/ldirectord.log"
#logfile="local0"
quiescent=yes

# A sample virual with a fallback that will override the gobal setting
virtual=59.106.42.202:80
real=192.168.0.1:80 gate
real=192.168.0.2:80 gate
fallback=127.0.0.1:80 gate
service=http
#request="index.html"
#receive="Test Page"
#virtualhost=some.domain.com.au
scheduler=rr
#persistent=600
#netmask=255.255.255.255
protocol=tcp
-------------------------------------------------------------------------------------

設定が終わったら、/etc/init.d/ldirectord start で起動します。

これで192.168.0.1と192.168.0.2のサーバーを監視して、動いているサーバーにHTTPリクエストを割り振ることができます。
もちろん、重みをつけたり、分散アルゴリズムを指定することもできます。

最後に dpkg-reconfigure ipvsadm を実行してOSの起動時にipvsadmが実行されないようにします。これはもういりません。

木曜日, 12月 14, 2006

LDAP の複製

LDAPの複製です。
slapd のバージョン2.2までは、slurpdを使ってデータをコピーします。
バージョン2.3からは syncrepl を使います。これが便利!

2つの方法の違いは、データの複製を行うサーバーです。
slurpdはマスターがスレーブに対してデータの送信を行います。
sycreplはスレーブからマスターのデータを取得します。
なので、slurpdの場合はマスターの設定変更が必要になるわけですね。
これは、すでに運用中の場合には結構大きな問題です。
それに対して、syncreplの場合はマスターの設定が必要ないので、すでに運用しているLDAPを拡張するのがとても簡単です。

スレーブ側の設定ファイルに、以下を追加します。

syncrepl rid=123
provider=ldap://ldap0.kumicho.net
type=refreshOnly
interval=00:00:10:00
searchbase="dc=kumicho,dc=net"
scope=sub
attrs="*"
schemachecking=off
bindmethod=simple
binddn="uid=kumicho,dc=kumicho,dc=net"
credentials=password

これだけで複製が行えます。
上の設定を見たら想像つきますが、これは普通の検索です。
なので、データの一部だけを複製することも可能です。
また、データを取得するためのユーザーでバインドする必要があります。

認証の方法は"simple"を利用しているので、IPsecを利用しましょう。
もうTLSなんて時代遅れ。

水曜日, 12月 06, 2006

証明書で認証する IPsec

前回作成したIPsecの設定を、証明書(公開鍵)認証を使うものに変更します。

まず秘密鍵を公開鍵のペアを作成します。詳しく知りたい方はSSLをどうぞ。
秘密鍵は、/etc/ssl/private、公開鍵は、/etc/ssl/certs にあるものとします。

psk.txtを書き換えます。
192.168.172.1 EKVq0c5NzjAY3mfMSN3Y4pw0utefVj7i

xm001.kumicho.net
にします。
もう事前秘密鍵は必要ありません。

次に、racoon.confのremoteセクションに、
my_identifier asn1dn;
certificate_type x509 "xm002.crt.pem" "/etc/ssl/private/xm002.key.pem";
peers_identifier asn1dn;
verify_identifier on;
verify_cert on;
を追加します。
互いの認証を証明書で行うように指示します。

さらに、proposalセクションの
authentication_method pre_shared_key;

authentication_method rsasig;
に変更します。

これで証明書による認証が行われます。

Debian GNU/Linux で IPsec を使う

IPパケットのレベルで暗号化します。
これって、結構劇的に便利な気がします。

IPsecの機能自体はカーネルに組み込まれているので、鍵交換サーバーのracoonをインストールします。
aptitude install racoon

次に、/etc/ipsec-tools.conf の編集
コメントを外して、以下のようにします。
-----------------------------------------------------
## Flush the SAD and SPD

flush;
spdflush;

## Some sample SPDs for use racoon

spdadd 192.168.172.2 192.168.172.1 any -P out ipsec
esp/transport//require;

spdadd 192.168.172.1 192.168.172.2 any -P in ipsec
esp/transport//require;
------------------------------------------------------
IPsecをどの通信に適用するかのルールを設定します。

今度は、/etc/racoon/racoon.conf を編集します。
---------------------------------------------------------------------
remote anonymous {
exchange_mode main,aggressive;
proposal {
encryption_algorithm 3des;
hash_algorithm sha1;
authentication_method pre_shared_key;
dh_group modp1024;
}
generate_policy off;
}

sainfo anonymous {
pfs_group modp768;
encryption_algorithm 3des;
authentication_algorithm hmac_md5;
compression_algorithm deflate;
}
-----------------------------------------------------------------------
ここではIPsec通信の内容を設定しています。
すべての通信に同じ強度の暗号化を使うなら、上のようにanonymousにすると楽です。

上の設定ファイルにしたがって、ルート証明書へのパスを設定します。
ln -s /etc/ssl/certs/ /etc/racoon/

最後に、/etc/racoon/psk.txt を編集します。
192.168.172.1 EKVq0c5NzjAY3mfMSN3Y4pw0utefVj7i
てな感じに共通秘密鍵を追加します。

この鍵は、
makepasswd --chars 32
なんて風につくれます。ただし、makepasswdのインストールが必要です。

setkey と racoon を再起動すれば、ホスト間での通信がすべて暗号化されます。
プロトコル毎に暗号化したい場合には、racoon.confをもう少し丁寧に書けばいいです。

IPsecを使うと、これまでサービスごとにSSLを使って暗号化していたやりとりがすさまじく簡単になります。
ここでは使ってないですが、サーバー証明書を使った認証もできます。さらに、個人証明書も使えます。
外部向けのHTTPSなんかは無理ですが、内部で使う分にはものすごくシンプルかつ強力です。