2013/05/05

RaspberryPiでLVS+keepalivedを使ってHA構成にしてみた

RaspberryPiは手軽なLinux実行環境ですが、定格で5V/700mAが必要です。 古いPCやUSBハブに接続した場合には、うまく動かない可能性があります。

iPadやタブレットで充電に1000mA(==1A)が必要な状況なので、それほどUSBの電源周りも余裕のある設計になっているものも多くあるはずです。

とはいえ、USB2の定格は5V/500mAなので古めのPCや電源付きUSBハブにいろいろな機器を接続した場合には動作が不安定になる可能性があります。

またカーネルに3.6-trunk-rpiを選択した時には、2013年5月5日時点では、ファイルシステムに負荷をかけるようなタイミングでBUG: scheduling while atomic: swapper/...のエラーが出てまともに動きませんでした。

対応linuxカーネルの有効化

基本的な環境はarmelhfアーキテクチャのRaspbian "wheezy" をインストールした状態です。

Raspbianのカーネルは3.6.11#371版ですが、ip_vsモジュールなどは導入されていません。

このためパッケージからip_vsモジュールの含まれているイメージを導入します。

$ sudo apt-get install linux-image-3.2.0-4-rpi
起動時のカーネルイメージの変更

linux-image-*パッケージを導入しただけでは、再起動をしても引き続きRaspbianの付属カーネルが使われます。 ポイントは次のとおりです。

  • zImageを/boot/kernel.imgのファイル名でコピーする
  • initrdイメージがある場合は/boot/config.txtに記入する
/boot/kernel.imgファイルの置き換え

既存のkernel.imgファイルは退避して、vmlinuz-3.6-trunk-rpiファイルをコピーします。

$ cd /boot
$ sudo mv kernel.img kernel.3.6.11#371.img
$ sudo cp vmlinuz-3.2.0-4-rpi kernel.img

ちなみに/bootはvfatなので、ハードリンクなどを使う事はできません。 基本的にはcopyで対応することになります。

/boot/config.txtファイルの書き換え

initrdを使用している場合には、対象のファイル名をconfig.txtに書き換えます。

...
ramfsfile=initrd.img-3.2.0-4-rpi
ramfsaddr=0x00a00000
initramfs initrd.img-3.2.0-4-rpi 0x00a00000
...

ちゃんと確認していませんが、/bootにあるものとしてファイル名だけを記述しています。

再起動でカーネルの確認

とりあえず再起動して動作を確認します。

うまく行かない場合には別のPCに接続して編集内容を確認します。 /boot以下はVFAT領域なので、問題なく扱えるはずです。

ramfsaddrなどを指定しないと、initrdのイメージが展開されない事になります。 うまくいけばdmesgに次のようなメッセージが表示されます。

$ dmesg | grep init
...
[    1.049760] Unpacking initramfs...
[    1.710015] Freeing initrd memory: 4476K
...

パッケージの導入

ipvsadmとkeepalivedを使いますが、ipvsadmはkeepalivedの導入時に自動的にインストールされます。

keepalivedの導入

パッケージを導入します。

$ sudo apt-get install keepalived

設定

パッケージを導入しても設定ファイルは一切導入されないので、過去のログをみながら設定ファイルを構成します。

/etc/keepalived/keepalived.confの編集

今回はWebサーバではなくて、ESXi上に構成しているLDAPサーバに対してHA構成を取っています。

振り先の設定

LDAPサーバ側にいくつか設定が必要です。

/etc/sysctl.confの編集

対象サーバが1台しかない場合には、問題になりませんが、複数のslave LDAPサーバに処理を分散させるような場合にはサービス(仮想)IPとMACアドレスが強力に結びついてしまうと、ルータからダウンしたLDAPサーバに常に処理が振られてしまうのでARPリクエストに反応しないように変更する必要があります。

/etc/sysctl.confへの追加内容

net.ipv4.conf.eth0.arp_ignore=1
net.ipv4.conf.eth0.arp_announce=2

設定を反映させます。

$ sudo sysctl -p

sysctlコマンド実行後の画面出力

net.ipv4.conf.eth0.arp_ignore = 1
net.ipv4.conf.eth0.arp_announce = 2
サービス(仮想)IPの設定

IPレベルではリクエストは2台のRaspberryPiで共有されるサービス用の(仮想)IP宛てのパケットがLDAPサーバに到着します。

自分宛てのパケットだと認識しないといけないので、loopback(lo)にIPを設定します。 まだ未使用のlo:0デバイスを使います。他に使用している場合には、lo:1,lo:2など適当な番号に変更してください。

/etc/network/interfacesファイルへの追加内容

auto lo:0
iface lo:0 inet static
  address 192.168.1.182
  netmask 255.255.255.255

さいごに

RaspberryPiを入手して、いろいろ試していますが、電源の品質とカーネルの安定性が一番の問題でした。

電源はUSBハブから取っていますが、マウス、キーボードなどは本体に直接つないで他の機器はつないでいません。

PCなどに接続する場合には、2つ口の片側に接続する事で500mA 2つ分の1000mAまで電流が取れるものが多いようです。 最近ではiPadやタブレットに対応した急速充電可能なタイプであれば、1000mAまで取れるので問題ないでしょう。

SDカードはTranscendのClass10 UHS-I対応16GBと、PanasonicのClass 10 SDHC 8GBのカードを使っています。 他のARM系ボードでも使っていますが、これまでのところ問題は起きていません。

この他にも$ sudo raspi-configで変更できるパラメータは少し変更していて、安定して動くようになってから900MHzへのオーバークロックやVRAMを16Mに変更したり、

tail -5 /boot/config.txtの実行結果

# for more options see http://elinux.org/RPi_config.txt
gpu_mem=16
core_freq=250
sdram_freq=450
over_voltage=2

この記事で取り上げた品々

2013/05/04

namecheapで購入したWildcardSSL証明書をOpenLDAPにインストールしてみた

これまで389ポートで運用してきたESXi 5.1上のOpenLDAPサーバにSSL証明書を適用してみました。

実際のところnamecheapは関係なくて、SSL証明書をどこで購入したのかは問題ではなくて、root CAや中間CA証明書の有無などが問題だったりします。

今回利用する証明書の構成や、対象サーバの環境は以下の通りです。

  • OS: Ubuntu 12.04 LTS 64bit版
  • SSL root CA Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root
  • SSL Issuer: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=PositiveSSL CA 2

最近は4階層のSSL証明書も普通にありますが、PositiveSSLの中間CA証明書は1つだけの3階層です。 4階層はテストしていませんが、c_rehashコマンドでハッシュファイルへのシンボリックリンクを作成するところを外さなければ、問題なく扱えるはずです。

ファイルの準備

SSL関連の操作ではファイル名は任意なのですが、扱うファイルの数は多い傾向があります。

まぎらわしいので参考のためにリストにしておきます。

  • WildcardSSL.crt: CN=*.example.com(Subject: OU=Domain Control Validated, OU=PositiveSSL Wildcard, CN=*.example.com)
  • PositiveSSLCA2.crt: 証明書 (Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=PositiveSSL CA 2)
  • AddTrustExternalCARoot.crt: CA証明書 (Subject: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root)
  • newkey.nopass.pem: パスワードで保護されていないWildcardSSL.crtに対応する鍵ファイル
  • rootca.crt: PositiveSSLCA2.crt + AddTrustExternalCARoot.crtの2つのファイルが連結された単一CA証明書ファイル

*.crtファイルの内容は全て-----BEGIN CERTIFICATE-----で始まるので紛らわしいかと思います。 以下のコマンドで-inオプションの引数にファイルを指定すると中身を確認することができるので便利です。

$ openssl x509 -text -noout -in <cert filename>
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            6f:c7:b2:c6:af:e4:cc:a6:d3:61:4b:1f:6d:56:be:fd
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=PositiveSSL CA 2
        Validity
            Not Before: Dec 13 00:00:00 2012 GMT
            Not After : Dec 13 23:59:59 2014 GMT
...

newkey.nopass.pemファイルは-----BEGIN RSA PRIVATE KEY-----で始まるファイルで、パスワードで保護されていない形式です。

パスワードを外す方法はnewkey.pemがパスワードで保護された鍵ファイルだとして、$ openssl rsa < newkey.pem > newkey.nopass.pemのような要領で作成する事ができます。

ファイルの配置

準備したファイルをOpenLDAPサーバ上に配置していきます。

今回はUbuntuなのでシステムで準備している/etc/ssl/certs, /etc/ssl/privateがありますが、クライアント認証をするわけでもなくシステムデフォルトと一線を引いて管理するためにファイルの配置場所は別に準備します。

$ sudo mkdir -p /opt/openldap/ssl
$ sudo cp WildcardSSL.crt /opt/openldap/ssl
$ cat PositiveSSLCA2.crt AddTrustExternalCARoot.crt | sudo tee /opt/openldap/ssl/rootca.crt
$ sudo c_rehash /opt/openldap/ssl/
$ sudo chgrp openldap /opt/openldap/
$ sudo chmod 750 /opt/openldap/

ESXiサーバのシェルの場合などはc_rehashコマンドが準備されていない事もありますが、手動でのリンク管理は面倒なので利用しています。

うまくいくと、次のような内容の/etc/openldap/sslディレクトリが作成できてるはずです。

sudo $ sudo ls -l /opt/openldap/ssl
lrwxrwxrwx 1 root root   22 May  4 18:35 459f9267.0 -> WildcardSSL.crt
lrwxrwxrwx 1 root root   10 May  4 18:35 5f852f3e.0 -> rootca.crt
lrwxrwxrwx 1 root root   10 May  4 18:35 ed207a3e.0 -> rootca.crt
lrwxrwxrwx 1 root root   22 May  4 18:35 f8a2c70e.0 -> WildcardSSL.crt
-rw-r--r-- 1 root root 1679 May  4 18:27 newkey.nopass.pem
-rw-r--r-- 1 root root 3278 May  4 18:34 rootca.crt
-rw-r--r-- 1 root root 1801 May  4 18:09 WildcardSSL.crt

設定ファイルの変更

必要なファイルを配置したら、Openldapの設定ファイルの変更です。

Ubuntu 12.04 LTSでのopenldapの設定ファイルは/etc/ldap/slapd.d以下でLDAP管理となっています。 そのためファイルを編集するという分けにはいきません。

設定方法は、help.ubuntu.comのOpenLDAP TLS設定方法のページに詳しく掲載されています。

このページに書かれているように、LDIFファイル(/tmp/modify.tls.ldif)を作成してldapmodifyコマンドで実行していきます。

/tmp/modify.tls.ldifファイルの内容

dn: cn=config
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /opt/openldap/ssl/rootca.crt
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /opt/openldap/ssl/WildcardSSL.crt
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /opt/openldap/ssl/newkey.nopass.pem
$ sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /tmp/modify.tls.ldif
/etc/default/slapdの編集

slapdがサポートするプロトコルを指定する行に、ldaps:///を追加します。

/etc/default/slapdの変更個所抜粋

...
SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///"
...
APPARMOR対応

標準となっている/etc/ssl/ディレクトリ以下にアクセスする事がapparmorによって拒否されるため、今回はディレクトリを/etc/apparmor.d/local/usr.sbin.slapdに追加しました。

/etc/apparmor.d/local/usr.sbin.slapdファイルの内容

# Site-specific additions and overrides for usr.sbin.slapd.
# For more details, please see /etc/apparmor.d/local/README.

/opt/openldap/ r,
/opt/openldap/** r,

dh_apparmorパッケージをインストールしたのですが、うまく動かないのでシステム全体を再起動します。

$ sudo /sbin/shutdown -r now

稼働確認

ポートの確認

netstatで636ポートが開いている事を確認します。

$ netstat -nl | egrep '389|636' 
tcp        0      0 0.0.0.0:636             0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:389             0.0.0.0:*               LISTEN     
tcp6       0      0 :::636                  :::*                    LISTEN     
tcp6       0      0 :::389                  :::*                    LISTEN
ldapsによるクエリの実行

実際のクエリはDNなどを含むので、slapdumpなどでディレクトリの構造を把握しておく事が必要です。

$ openldap -x -H ldaps://openldap.example.com:636/ -b uid=user01,ou=People,dc=example,dc=com

もしホスト名をopenldap.example.comではなくlocalhostのように指定した場合には、SSLのCommonName(CN)に指定されているホスト名(*.example.com)との対応が取れずにエラーとなります。

$ ldapsearch -x -H ldaps://localhost:636/ -b uid=user01,ou=People,dc=example,dc=com
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)

localhostの部分をlocalhost.example.comのようにCNと対応するFQDNにすれば、正常に稼働します。

$ ldapsearch -x -H ldaps://localhost.example.com:636/ -b uid=user01,ou=People,dc=example,dc=com
# extended LDIF
#
# LDAPv3
...

まとめ

WildcardSSL証明書はけっこう便利です。 PDFファイルの署名にも論理的には使えますが、CA情報が登録されていないので適切な署名とはみてもらえません。

SSL接続時に警告が出るのはマルウェアなどでサイト誘導されているという認識を持たないと、まったく意味がないのですが、残念ながら世間では、この悪い常識が闊歩しているところもあります。

仕事など、責任を伴なう場面では、積極的にSSL化を勧めて環境を整備しましょう。

2013/03/03

VMWare ESXi 5.1のSSLキーを購入したものに入れ替えてみる

自宅で使用しているVMWare ESXi 5.1のアドレスにWebブラウザでアクセスすると、あたかも乗っ取られたサイトであるかのように表示されるので、以前購入したワイルドカードSSLサーバーキーなファイルに入れ替えてみました。

[2013/05/04 追記]
追加した鍵はnamecheapで購入したCOMODOのWildcardSSLなのですが、rootCAの証明書が入っていませんでした。 そのためFirefox (release 20.0.1)ではhttpsでESXiサーバにアクセスした時に警告画面が表示されてしまいます。
ESXiにsshでログインして、以下の手順(;は改行で読み替え)でrui.rootca.crtという名前のファイルにAddTrust External CA Rootの証明書を作成しています。
$ cd /etc/vmware/ssl; $ vi rui.rootca.crt
rui.crtファイルに複数の証明書を保存する事はできません。 ESXiサーバ上にはc_rehashコマンドがないので手動でopensslが証明書を探せるように、ハッシュ名のファイルにシンボリックリンクを張ります。
ln -s rui.rootca.crt $(openssl x509 -noout -hash -in rui.rootca.crt)
ちなみにcrtファイルはPEM形式なので、openssl x509 -in rui.rootca.crt -noout -textのようなコマンドで中身をチェックする事ができます。 rhttpproxyをリスタートして確認してください。

基本的な操作手順はVMWare公式サイトのthe configuration of Certificate Authority (CA) certificates for a ESXi 5.x host.にあります

手順はsshを有効にするところからあるので長いのですが、実際のステップは次のようなところだけです。

  • Log in to the host and then navigate to /etc/vmware/ssl.
  • Copy the files to a backup location, such as a VMFS volume.
  • Log in to the host with WinSCP and navigate to the /etc/vmware/ssl directory.
  • Delete the existing rui.crt and rui.key from the directory.
  • Copy the newly created rui.crt and rui.key to the directory using Text Mode or ASCII mode to avoid the issue of special characters ( ^M) appearing in the certificate file.
  • Type less rui.crt to validate that there are no extra characters.
  • Switch back to the DCUI of the host and select Troubleshooting Options > Restart Management Agents.

コマンドベースで書くと次のようになるんでしょうか

  • ESXiホストにsshでログイン
  • # cd /etc/vmware/ssl/
  • rui.crtとrui.keyを、入手した証明書とパスワードなし鍵ファイルに置き換える
    • scpやWinSCPを使う事もできるが、証明書はテキストファイルになっている。sshログインしているのであれば、catなどとCopy&Pasteの方がいいかもしれない
    • 例: # cat > rui.crt、コピーした後でControl+c(C-c)
    • # cat > rui.key、同様にコピーした後でC-c
  • # /etc/init.d/rhttpproxy restart

自前CA局が悪いかどうかは状況によるのですが、サイトのポリシーなどでWebサイトに導入するSSL証明書は正規に購入すること、などとなっている場合には必要な作業かと思います。

ただお金を出せば証明してあげる、という構造は理解しやすいのですが、一歩引いてみると、CA局はお金を集めるインセンティブを上から下まで持っているので、ルールが曲げられちゃう可能性もありそうで、それでちゃんとtrust-chainが構成できるのか、少し不安に感じる部分がないでもありません。

最上位CA局は技術・倫理ポリシーを持った非営利的機関にして、それは複数あっていいのだけれど、一般に販売されるブラウザにデフォルトで加えるCA局のスタンダードとかも必要な気がします。

2013/02/06

OpenLDAPを導入したので、各OSでの設定方法をまとめてみる

UbuntuにOpenLDAPを導入して、ldap-account-manager (LAM)で管理しています。

VirtualBOXを使った時のOSへのログインユーザーの管理や、ミドルウェアを稼働させるユーザーの管理をOpenLDAPに一元化したいと思ったので、VMとして使っている主なOSでのldap設定をまとめました。

前提知識

LDAPの設定は様々なミドルウェアで行なえますが、微妙に設定できる名称や設定方法が異なります。

共通部分としてはサーバー名、ポート番号の他にバインドDN(とそのパスワード)、BaseDNなどがあります。

製品によってはユーザー名を構成するサブディレクトリ(ou=People等)の指定ができるものがあります。

また階層を辿るために、base,one,subなどのスコープを設定できるものもあります。 何も設定されていないOpenLDAPは自由に階層を辿る事ができるため、全部のディレクトリ情報を表示する事も可能な事が多く、サンプルもそのように構成されている場合があります。

しかし実際には、ディレクトリ全体を辿られてしまうと社員名とID,e-Mailアドレスとの紐付けなどをごっそり持っていかれる可能性があるため、自分自身のディレクトリ情報以外は編集ができず、それ以外の情報はDNで直に指定しないと閲覧できないように設定されている場合もあるでしょう。

LDAPについての設定方法は標準的な部分と、非標準的な暗黙知によって構成されています。 ActiveDirectoryを前提にしていると、Netscapeに由来するようなDirectory構成

ldapserverldapbasednに指定するサーバー名やBaseDN名は適宜変更してください。

CentOSなど(RedHat系)でのldapログイン設定

以前のブログでも書いていますが、コマンドラインから設定する事が可能です。

 $ sudo authconfig --enableldap --enableldapauth --ldapserver=openldap.example.org --ldapbasedn="ou=accounts,dc=example,dc=org" --updateall

これはCentOS 5.4で試した設定方法ですが、CentOS 6.3でも同様に使えます。

Ubuntuでのldapログイン設定

UbuntuではガイドのLDAPClientAuthenticationにあるように2つのコマンドを実行することでLDAPを設定する事になっています。

 $ sudo apt-get install ldap-auth-client nscd
$ sudo auth-client-config -t nss -p lac_ldap

Ubuntu 12.04 LTSで確認したところ次のようなログインできない問題が発生しました。

  • ログインできず、/var/log/auth.logに次のようなメッセージが表示される pam_ldap: could not open secret file /etc/ldap.secret (No such file or directory)
  • $ getent passwdではUserが表示されるのに、ログインできない
存在しない/etc/ldap.secretの問題

前者の/etc/ldap.secretを要求するのは、/etc/ldap.confでrootbinddnを有効にしているからです。

auth-client-configの設定画面で、クライアントからのパスワード変更を許していないので適当なrootbinddnと空のパスワードを入力したのが原因でした。

/etc/ldap.confからrootbinddn行の先頭に#をつけてコメントにする事で解決しました。

user名は認識されるのにログインできない

単純にnscdがリスタートされていないだけでした。

プロセスを再起動:$ sudo /etc/init.d/nscd restart して、無事にログイン($ ssh user1@example.org)する事ができました。

Debian 6.0.3でのldapログイン設定

DebianにはUbuntuにあったldap-auth-clientパッケージが存在しません。 そのためlibpam-ldap, libnss-ldapを手動で導入します。

$ sudo apt-get install libpam-ldap libnss-ldap
/etc/libnss-ldap.conf, /etc/pam_ldap.confファイルの確認

それぞれアンダースコア'_'やハイフン'-'が入っていてまぎらわしですが、この2つのファイルの内容を念のため確認します。

Ubuntuでの経験を活かして、rootbinddnやパスワードへは空文字列を入力してみましたが、libnss-ldap.confではrootbinddnが何も指定されないまま有効になっていました。

パスワード変更にはOSの機能を使わない事にしているので、今回もrootbinddn行はコメントアウトします。

面倒であれば、apt-getの実行時にadminのDNとパスワードを入力する事で、編集なしで良くなるはずです。

最後に/etc/nsswitch.confを有効にする

nsswitch.confなんて昔のBSD系やLinux OSにはなかったんですけどね…。Solaris 2.2か2.4ぐらいを触った時の衝撃といったらありませんでした…。

他のOSと同様にnsswitch.confのpasswd, group行のcompatfiles ldapに変更すれば完了です。

nscdのリスタート

ここまでで、LDAPに登録したIDにsu -の実行やログインができない場合には、nscdをリスタートしてみてください。

$ sudo /etc/init.d/nscd restart

基本的にはこれで完了するはずです。

FreeBSD 9.1でのldapログイン設定

基本的な流れはガイドのLDAP Authenticationの中にあります。 導入が必要なPortsは以下の通りです。

  • net/nss_ldap
  • security/pam_ldap

自動的に両方のPortsが依存しているnet/openldap24-clientも導入されます。

Portsのインストール(# make install)が完了したら、以下のように3つのファイルを編集するとLDAP認証が有効になります。

/usr/local/etc/nss_ldap.confの設定

基本的にはurlかhost,それにbaseを設定すれば動きますが、使っているLDAPサーバーのディレクトリ構成やサーバー自体の設定によっては必要な追加設定があるかもしれません。

/etc/pam.d/loginの編集

sshd経由でのログインも行なうのであれば、/etc/pam.d/sshdの設定も変更する必要があるはずです。

サンプルはガイドにあるので詳細は省きますが、auth sufficient /usr/local/lib/pam_ldap.so no_warnの設定を入れれば完了です。

/etc/nsswitch.confの編集

ここまでの設定が完了していて、/etc/nsswitch.confファイルのgroup行とpasswd行をcompatからfiles ldapに変更すればログインにldapが使われるようになります。

さいごに

LDAP認証ではBindDNやらAdminDNやらRootBindDNやら、似たようなものや、実質同じものが名前をかえて登場します。

LDAPサーバーの動きをちゃんと捉えるのは面倒ですが、いまならLPI-Japanが無償で配布している高信頼システム構築標準教科書やLPIC Level 3の教本なんかが、良いとっかかりになるはずです。

動きから抑えるのが良いのですが、普段はシステムの裏側にいて、簡単にldapsearchが試せる本番環境というのもあまりありません。

ネットワーク屋さんがルーター管理にRADIUSを動かしても特権用の共有IDなんかをファイルベースで作って終りだったり、本来はLDAPを使うべき場面なのに、他の方法で代用されている場合もあるかもしれないですね。

会社や学校でLDAPサーバーがあっても、それがLDAPサーバーだと気がつかない場合があるかもしれませんし、アクセス制御が厳密でなかなか挙動をリバースエンジニアリングするのは難しい場合もあるかもしれません。

なんにしてもLDAPサーバーを試す環境はいまのところ自分で動かすしかないので、単純にサーバーと管理ツールを入れて終りにしないで、高可用性を保つために何が必要か、よりセキュアな環境にするためには何ができるのか、考えてみると良いでしょう。