SuperMicro社のBMC/IPMI搭載製品では、その初期設定の状態に問題があるため、特定の条件下で外部からコンソール等にアクセス可能となる可能性があります。
本問題については、該当製品で稼働しているOSのroot権限を取得できる可能性があるため、発見後すぐにIPAに脆弱性関連情報の届出を行いましたが、1年以上に渡り返信が無い状態が継続しているという事であり、また適切に設定する事により回避することができるため、広く公開して注意喚起したほうが公益に資すると判断し、公開するものです。
[flat] ;2012/03/19;:IPAに届け出 ;2012/04/04;:IPAより届け出受理の連絡 ;2013/07/17;:IPAより2012/05/16(起算日)以降、製品開発者へ連絡をとっているが、返信がない旨の連絡 ;2013/07/18;:IPAに情報非開示依頼の取下げを依頼 ;2013/08/02;:IPAより情報非開示依頼の取下げの連絡 ;2013/08/10;:本エントリ公開
本問題の対象となる製品は以下の通りです。
[border]
Intel UP Motherboards supported | Intel DP Motherboards supported | AMD Motherboards supported |
---|---|---|
X7SB3-F | X7DCT-3F | H8DMT-F |
X8ST3-F | X7DCT-3IBXF | H8DMT-IBXF |
X8STi-F | X7DCT-LF | |
X8STi-3F | X8DAH+-F | |
X8DT3-F | ||
X8DT3-LN4F | ||
X8DTH-6F | ||
X8DTH-iF | ||
X8DTi-F | ||
X8DTi-LN4F | ||
X8DTT-F | ||
X8DTT-IBQF | ||
X8DTT-IBXF | ||
X8DTU-F |
[border]
Intel Dual-Processor Motherboards supported (-F models only) | Intel Single-Processor Motherboards supported (-F models only) | AMD Motherboards supported (for -F models only) |
---|---|---|
X8DTL-3F/-6F/iF | X7SPA/E-HF/-D525 | H8DGG-QF |
X8DTN+-F | X7SPT-DF-D525 | H8DGT-HF/-HIBQF/-HLF/-HLIBQF |
X8DTU-6F+/6TF+/LN4F+/TF | X8SI6-F | H8DGU-F/-LN4F+ |
X9DBU-6F/iF | X8SIA-F | H8SGL-F |
X9DR6/i-F | X8SIE-F/LN4F | H8SCM-F |
X9DRT-H6F | X8SIL-F | H8DCL-6F/-iF |
X9DRG-QF+ | X8SIT-F/-HF | H8DCT-F/-HIBQF/-HLN4F/-IBQF |
X8SIU-F | H8DG6-F | |
X9SCA-F | H8DGi-F | |
X9SCD-F | ||
X9SCi-LN4F | ||
X9SCL-F | ||
X9SCM-F | ||
X9SRE-F | ||
X9SRW-F |
上記のマザーボードには、Nuvoton WPCM450というBaseboard Management Controller(BMC)が搭載されています。このコントローラにより、専用ポートまたはオンボードのLAN1ポート経由で遠隔地からのコンソールの操作やCDイメージのマウント、電源の制御などが行えます。
このコントローラの標準の設定は以下のような組み合わせになっています。
[flat] ;LANポート:;:Failover ;IPアドレス:;:DHCPで取得
LANポートの"Failover"という設定では、BMCの専用ポートがネットワークに接続されていなければ、オンボードのLAN1ポートで接続を試みます。このため、初期設定の状態で、
といった条件を満たしていると、OSで利用している通信とLAN1ポートをシェアする形でBMCにも独立したIPアドレスが割り当てられ、BMCが提供する各機能にアクセスできるようになります。この時さらに、
という条件が重なった場合は、インターネットからBMCへのアクセスが可能となってしまいます。
このBMCはWeb UIも提供しており、その初期アカウント名とパスワードの情報はマニュアルに記載され、SuperMicro社のサポートページからダウンロード可能な状態で公開されているため、誰でも容易に入手可能な状態となっています。前述の通り、このWeb UIからはコンソールの操作が可能となり、また多くのUNIX系のOSではコンソールからの操作に関してはやや楽観的な初期設定が行われているため、
などといった操作で、簡単にroot権限を奪う事ができてしまいます。また、コンソールに表示されているカーネルからのメッセージを確認する事も可能となります。
BMCポートを外部から遮断されたネットワークに接続することで、ひとまずこの問題は回避できますが、接続先の機器の電源が落ちるなどしてネットワークが不通になると、すぐにオンボードのLAN1ポートに切り替わってしまいます。
さらに悪い事に、いったんBMCがLAN1ポートに切り替わってしまうと、BMC専用ポートの接続が復旧しても自動的に戻らないため、迅速に元に戻すためにはOSをシャットダウンして電源ケーブルを抜き、しばらく待ってから再起動する必要があります。
これらの問題も含めて回避するためのいくつかの方法を説明します。
Web UIにログインしてパスワードを変更します。一番基本的かつ有効な対策です。
BMC専用ポートを保護されたネットワークに接続してこちらのみ使用するようにします。
OS側でCtrl+Alt+Deleteによる再起動を無効にする
直接的な解決方法ではありませんが、インストールしているOS側でCtrl+Alt+Deleteキーによる再起動を無効化することもできます。
;Linux(CentOS)の場合:
/etc/init/control-alt-delete.confを編集して次の行をコメントアウトする
exec /sbin/shutdown -r now "Control-Alt-Delete pressed"
または/etc/inittabを編集して以下の行をコメントアウトする
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
))) ;FreeBSDの場合:
以下のコマンドを実行する
sysctl hw.syscons.kbd_reboot=0
さらに以下の行を/etc/sysctl.confに追加して再起動する
hw.syscons.kbd_reboot=0
))) )))
BMCの機能を使うつもりが無いのであれば、マザーボード上のJPBジャンパーの設定を変更してBMCを無効化してしまいましょう。
[免責事項]
以上
だいぶ手を入れていたせいでなかなか踏ん切りがつかなかったtDiaryの環境を一念発起して最新の4.0.0に上げる事に。ruby18+2.2.3(EUC)からruby19+4.0.0(UTF-8)への移行ということで、なかなか厳しいかなと思っていたのですが、結果的には1日で終わりました。tDiary開発陣の継続性への配慮には感服するばかりです。とはいえ多少手こずったのでメモを残しておきます。
最初に手順をまとめておくと、
という順にやるのが確実なようです。
まず試したのは4.0.0のインストール。最初gem版を入れてみたのですが、プラグインやテーマ、BlogKitなどの入れ方がよく分からなかったので、すぐに挫折してダウンロード版を使う事に。ダウンロードページからフルセットとBlogKitをダウンロードして展開、コピー。この辺の手順は2.2.3の頃とほとんど変わりません。
データをコピーしてアクセスしてみると、以下のエラー
There was a Errno::ENOENT while loading tdiary.gemspec: No such file or directory - git ls-files from /home/socodanet/local/tdiary/core/tdiary.gemspec:16:in ``' (Bundler::GemspecError)
検索するとgitが必要そうな記述を発見。ここはsandbox上で動かしていて開発用ツールを入れるつもりは無いので、4.0.1あたりで直るだろうということで4.0.0化もあっさり挫折。結果論ですがこの判断は正しかったです。
で、3.2.2を入れようとしたのですが、tDiaryのダウンロードページにリンクが無い。ここは慌てず騒がず、4.0.0のパスから類推してフルセットとBlogKitを無事ダウンロード。展開してインストール。
日記のデータをコピーして、テスト用のパスで表示すると文字化け。キャッシュを消してみても変わらず。原因が分からずいろいろと情報を探すと、3.0.0のリリースノートに「tDiary 3.0とruby 1.9.2を同時にアップデートしない」とちゃんと書いてありました。今頃アップデートしようとしてるから自業自得です。ということで、ruby18を使うようにindex.cgiのshebangを書き換え、
#!/usr/local/bin/ruby18 require '/usr/local/tdiary-3.2.2/index'
キャッシュをクリアしてからアクセスするとUTF-8に正しく変換されて文字化けは解消しました。すばらしい。
ただ、テーマがうまく反映されず、調べているうちに、複数のtDiaryを運用している事を思い出し、[[同一サーバで複数のtDiaryを運営する方法|http://www.tdiary.org/20021205.html]]を参考にpluginsの下にうちの環境に合わせたchange_url.rbを設置して解決。
# change_url.rb def theme_url '/tdiary/theme' end def js_url '/tdiary/js' end
思い出したついでに他のページでも以下を繰り返して3.2.2にアップデート。
これでほぼ作業完了ですが、hikidoc.rbとファイルアップロードのプラグインは改造したものを使っているので置き換え。こちらは幸いにもファイルの漢字コードをEUC-JPからUTF-8に変換するだけで問題無く動きました。
当初予定していた4.0.0化は出来なかったけどUTF-8化とruby19対応は出来たので良いかと思い一区切りつけたものの、ちょっともやもやが残っていたのでTwitterで愚痴ったら、30分もしないうちに@machuさんからお返事がきて、インストールしたtDiaryのトップディレクトリにあるGemfileの5行目の"gemspec"という行を削除すれば動くとの助言をいただきました。
source 'https://rubygems.org' if File.exist?(File.expand_path('../tdiary.gemspec', __FILE__)) # directly installed (e.g. git clone, archive file) # gemspec <-この行をコメントアウト else :
さっそく試してみると、なぜか手元の環境ではfastimageが見つからないとのエラー
[clear] ダウンロードしてきたtar ballを展開した状態では.bundle/ruby/1.9.1/gems/fastimage-1.5.0に入っていて、このパスが見つけられない模様。rubyは1.9.3p448なのでバージョン番号と思われる"1.9.1"を"1.9.3"に変えてみても駄目。試しに"1.9"にしたところ、こんどはGemfile.lockへの書き込みエラーになったので、Gemfile.lockのownerをwwwにしてapacheに書き込み権限を与えたら無事動きました。
@machuさんに報告すると、先方の環境ではruby 1.9.3でもパスは1.9.1のままで動くとのことなので、rubyやgemのコンパイルやインストール時のオプションが原因かもしれないと思いちょっと調べてみましたが、よく分かりませんでした。rubyもgemもbundlerもFreeBSDのportsを使ってインストールしているので、そんなに変な環境ではないはずなんですが…{{fn '1.8と1.9を共存させるためにちょっといじってはいます'}}
以下、雑感です。
[green]
前回のサーチパスの問題がどうにも気持ち悪いので調べてみました。先に結論を書いておくと、Ruby本体のコンパイル時のオプションによってライブラリのサーチパスが変わり、その影響でbundlerがgemを見つけられなくなるという不具合のようです。
まずは問題のおさらいですが、tDiaryのtarボールを展開するとgemのファイルが".bundle/ruby/1.9.1/"以下に置かれます。ところが、私の環境ではこのパスを見つけられずエラーになってしまいました。調べてみると、
という状況でした。また、@machuさんの環境では1.9.3でもそのままで問題無く動くということでした。とここまでが昨日の時点での話で、ライブラリのサーチパスがかなり怪しいです。
さて昨日も書いたのですが、Ruby関連はFreeBSDのportsを利用しているので、調べてみると、/usr/ports/Mk/bsd.ruby.mk に
: RUBY_DEFAULT_VER?= 1.9 RUBY_VER?= ${RUBY_DEFAULT_VER} : # Directories RUBY_LIBDIR?= ${_RUBY_SYSLIBDIR}/ruby/${RUBY_VER} RUBY_ARCHLIBDIR?= ${RUBY_LIBDIR}/${RUBY_ARCH} RUBY_SITELIBDIR?= ${_RUBY_SITEDIR}/${RUBY_VER} RUBY_SITEARCHLIBDIR?= ${RUBY_SITELIBDIR}/${RUBY_ARCH} RUBY_VENDORLIBDIR?= ${_RUBY_VENDORDIR}/${RUBY_VER} RUBY_VENDORARCHLIBDIR?= ${RUBY_VENDORLIBDIR}/${RUBY_ARCH} : GEMS_BASE_DIR= lib/ruby/gems/${RUBY_VER} GEMS_DIR= ${GEMS_BASE_DIR}/gems DOC_DIR= ${GEMS_BASE_DIR}/doc CACHE_DIR= ${GEMS_BASE_DIR}/cache SPEC_DIR= ${GEMS_BASE_DIR}/specifications GEM_NAME?= ${PORTNAME}-${PORTVERSION} GEM_LIB_DIR?= ${GEMS_DIR}/${GEM_NAME} :
/usr/ports/lang/ruby19/Makefileに
post-patch: @${REINPLACE_CMD} -E \ -e 's,-l$$pthread_lib,${PTHREAD_LIBS},g' \ -e '/^RUBY_LIB_PATH/s,\.\$$\{TEENY\},,' \ -e '/^RUBY_SITE_LIB_PATH2/s,\.\$$\{TEENY\},,' \ -e '/^RUBY_VENDOR_LIB_PATH2/s,\.\$$\{TEENY\},,' \ ${WRKSRC}/configure
という記述がありました。ところが、これが原因かと思ってさらに追ってみてもどうにもおかしい。前者はパッケージを作るためのパスの設定でコンパイル時には使用されておらず、後者はTEENYを削除していてそれっぽいのですが、ソースを展開してできるconfigureスクリプトには該当する行が無く、さらに探すと展開されたソースツリーのdoc/ChangeLog-1.9.3に
Thu Feb 5 11:21:35 2009 Nobuyoshi Nakada <nobu@ruby-lang.org> * configure.in (RUBY_LIB_VERSION): added for library version, to split from core version. [ruby-dev:37748] * configure.in (RUBY_LIB_PATH, etc): moved actual version dependent stuff to version.c.
と2009年の2月にはconfigureから消されているようで、今現在は意味の無いコードのようでした。よく分からないのでsandboxを作ってRubyをportsを使わずにソースからインストールしてみると、ちゃんと(?)/usr/local/lib/ruby/1.9.1/以下にインストールされるので、ますます謎です。
ここでいったんRubyの追跡をあきらめ、gemのサーチパスが変わってしまう原因を追ってみますが、こちらのportsはソースには全く手を入れておらずにsetup.rbを実行しているだけでした。いよいよ深みにはまってきたなぁと思いつつgemのソースを追います。ここでかなり時間がかかりましたが、なんとか探し出したところ、gemのサーチパスはdefaults.rbというファイルの中のdefault_dirで定義されているようでした。
def self.default_dir path = if defined? RUBY_FRAMEWORK_VERSION then : elsif ConfigMap[:rubylibprefix] then [ {~orange:ConfigMap[:rubylibprefix],~} {~orange:'gems',~} {~orange:ConfigMap[:ruby_version]~} ] else : end @default_dir ||= File.join(*path) end
このConfigMapはrubygems.rbの中で、
unless defined?(ConfigMap) ## # Configuration settings from ::RbConfig ConfigMap = Hash.new do |cm, key| cm[key] = RbConfig::CONFIG[key.to_s] end else :
のように初期化されています。RbConfig::CONFIGってなんぞやとぐぐってみると、「RbConfigというのがあってビルド時の情報とかが取れる」というブログの記事が見つかりました。こちらに習って確認すると、
% ruby19 -rpp -e"pp RbConfig::CONFIG" {"DESTDIR"=>"", "MAJOR"=>"1", "MINOR"=>"9", "TEENY"=>"1", : "ruby_version"=>"1.9", : "rubylibprefix"=>"/usr/local/lib/ruby",
おぉ、ruby_versionが"1.9"だ。同じくソースを直接コンパイルした環境で試すと、
% ruby -rpp -e"pp RbConfig::CONFIG" : "ruby_version"=>"1.9.1", :
と、ちゃんと"1.9.1"になっています。いよいよ核心に迫ってきています。
そうすると、このruby_versionをどこかで変更しているはずだと思ってさがしてみると、/usr/ports/lang/ruby19/Makefileに、
CONFIGURE_ARGS= ${RUBY_CONFIGURE_ARGS} \ --enable-shared \ --enable-pthread \ {~orange:--with-ruby-version=minor~} \ --with-sitedir="${PREFIX}/lib/ruby/site_ruby" \ --with-vendordir="${PREFIX}/lib/ruby/vendor_ruby"
という記述を発見。configure --helpで確認すると、
--with-ruby-version=STR ruby version string for version specific directories [[full]] (full|minor|STR)
とあったのでビンゴ。FreeBSDのportsではこの"--with-ruby-version=minor"指定でライブラリのインストールパスを"1.9"にしておいて、最初のbsd.ruby.mkでパッケージ化する際のパスを調整しているようでした。
残る疑問は、Rubyのバージョンが"1.9.3"でもライブラリのパスがデフォルトでは"1.9.1"になっている点ですが、こちらは、1.9.2のリリースノートのFAQに答えがありました。
{''標準ライブラリが/usr/local/lib/ruby/1.9.1にインストールされる''} このバージョン番号は「ライブラリ互換バージョン」です。Ruby 1.9.2は1.9.1とおおよそ互換なので、ライブラリはこのディレクトリにインストールされます。
まとめると、
ということのようです。たいへん恐縮ながら、
`center large red` ライブラリの互換性を保証するために(も)使われる名前がコンパイルオプションで自由に変更できるようになってちゃ駄目なんじゃないでしょうか?
途中まではFreeBSD固有の問題かなと思っていたんですが…。
`green`
- まちゅ [レンタルサーバでもこれまで通り簡単に動かせるようにしつつ、新しい環境(RackやBundler)にも対応していこうと..]
- hs [まちゅさん せっかくコメントいただいたのにSPAMフィルタの調子が悪かったようで非表示になっていました。 おかげ..]