カテゴリー別アーカイブ: Debian

Debian Jessie i386をamd64に無理やり移行させる

i386環境から再インストールをしないでamd64に移行させる作業をやってみました。なんとか実現できたものの、今のところは無理やり感が否めません。実際にやってみた感触を記録しておきます。

背景

Debianはメジャーリリース間のアップグレードが行えることを重要視しているディストリビューションであり、実際自分もbo(1.3)からwheezy(7.x)まで更新し続けているインスタンスを持っています。

しかしながら、当然そのような古くからのシステムはアーキテクチャがi386のままです。amd64が公式にサポートされたのはetch(4.0.x, 2007~)からです。途中でmultiarchという複数のアーキテクチャのパッケージを一つのシステムに導入する仕組みもできましたが、それはi386→amd64への移行に直接利用できるようなものではありません。

手法

i386→amd64化を試みた人はこれまでにもあり、いくつかはネット上の私的なドキュメントとして残されています。今回はDebian Wikiに書かれている方法をとってみました。

作業の流れ

大まかに実施する作業の流れを以下に示します。

  • amd64 kernelパッケージのインストール
    • i386アーキテクチャでもlinux-image-*-amd64パッケージがあり、kernelだけ64bit化することはできる
  • debootstrapで/chroot64 以下にamd64の最小環境を構築
    • あとで必要になるパッケージ群を追加で入れる(libc6-i386 file bzip2 openssh-client lftp)
  • Live CD/USB等を使って起動し、/chroot64以下の実行ファイルを/にコピー
    • /chroot64/etc/ld.so.cache も忘れずコピーする
    • /chroo64/lib64は/lib64にコピーを行う
      • Wikiではsymlinkを張る、と記述されているがコピーでないと正常に動作しなかった
      • 動作するかどうかは実際にchroot /chroot64 /bin/sh 等を実行してみれば判断できる
  • amd64 kernelでブートする
    • この段階でパニックを起こした場合、/lib64等が適切に処理されておらずdll不足でinitが実行できなかった可能性が高い
  • インストールされているパッケージをi386からamd64に入れ替える
    • apt-get updateを実行
    • 依存関係と戦いながらi386パッケージをamd64に置き換える
      • インストールパッケージ数が多いほどここの作業は大変
      • 何かあったら以下の手段を試す
        • dpkg –remove –force-all [パッケージ名]:i386; apt-get install [パッケージ名]
        • apt-get -f install
        • cd /var/cache/apt/archives; dpkg -i –force-all [パッケージ名]*.deb ; apt-get -f install

簡単な解説

やっていることは、最低限のバイナリをamd64に置き換えて、あとはapt/dpkgに任せてパッケージを入れ替えます。dpkgがamd64 binaryに変わった時点でシステムの認識はi386からamd64に変わります。しかしaptのDBはi386のままなので、まず一度apt-get updateを行う必要があります。

i386なバイナリもdllさえそろっていれば動作します(/chroot64にlibc6-i386を入れるのはこのため)。再起動した時点で一応システム全体は動くようです。

しかしi386が混在しているのでパッケージの衝突は発生します。dpkg –force-allとapt-get -f installを駆使してなんとか乗り切りましょう。

個人的なハマリポイント

ネットワークの設定はnetwork-manager任せにしていたので、ssh越しに作業をしていたらnetwork-managerの更新がかかったタイミングで通信できなくなり、コンソールからの作業を余儀なくされました。GNU screen/tmuxを活用すべきだったと反省しています。

壊れた仮想ディスクを扱う

立ち上げっぱなしのWindowsマシンが、気が付くとBSoDで落ちてしまいました。原因は追加したHDDにあるようで、Linuxで観測してみると不定期にSATAのエラーを吐きます。

再起動したら、HDD自体が認識されず困ったので、testdiskでパーティションテーブルの復元を試みました。幸いなことに、これでNTFSパーティションの復旧はできました。このtestdiskはSystemRescueCD辺りも含まれているので、普段から起動ディスクとして用意しておくと安心です。

しかしこれだけでは不完全で、NTFSパーティション自体がdirtyになっていたので、回復コンソールからchkdsk /fを実施することでファイルシステムレベルの修正できました。

しかし不幸はこれだけでは終わりませんでした。対象HDD内においていた仮想マシンが起動しなくなり、grubのプロンプトに落ちるという状況になりました。Debianのインストーラーrescueモードで見ると、そもそもext2/3としてのsignatureまで壊れてしまっているようでした。

使っていた仮想マシンのディスク形式はVMware Playerからimportしてきたvmdk形式だったので、いったんqemu-imgでraw形式に変換し、kpartxでパーティションを認識、fsckを実施しました。

# qemu-img convert -f vmdk -O raw /path/to/disk.vmdk /output/disk.img
# kpartx -av /output/disk.img
# fsck.ext3 -y /dev/mapper/loop1p1

大量のエラーが発生し、lost+foundにかなりのデータがおいやられたものの、なんとかfsckは完走しました。/homeごとなくなってしまいましたが…

幸い、以前変換したときの元のイメージも残っていたので、現在はそちらをraw形式に変換してデータの復元を試みています。重要なデータはlost+foundの方を参照することにします。

CVE-2008-0166の爪痕

偶然にも500万個のSSH公開鍵を手に入れた俺たちはという資料が公開されました。GitHubから公開鍵を大量に集めて調査してみたという内容なのですが、なかなか衝撃的だったので英語blogで内容をかいつまんで紹介してみました。

500万個のssh公開鍵のうち、Debian/Ubuntuで作成されたブラックリスト入りの鍵が208件あったそうです。割合として考えてみればそれほど多くはないのですが、まだ爪痕が残っていることを実感します。

cgroupsのnamespace手動削除

自宅のPCルーターは10年以上前に構築したDebian環境をもとに、HDDだけ移しながらupgradeを長年重ねて積み上げたもので、.emacsが結構な腐臭を放っているとか自作init scriptをmake styleにいい加減に修正したものがあったりとか、いろいろガタはあるものの今でも元気に動いています。

時代が時代なので当然アーキテクチャはi386なのですが、いまどきはDebian側でi386向けのamd64 kernelパッケージを提供しているので、現在はそれを使っています。メインメモリも8GB積んでいます。

kernelがamd64なので、debootstrapでamd64のuserlandを構築することも可能です(–arch amd64)。最近、これをベースにLXCコンテナ化しました。やることは単純で/var/lib/lxc/$name/rootfsにシンボリックリンクを張って、設定ファイルを適当にコピペででっちあげるだけです。

ただ、この作業の過程の中で、lxc-startを-KILLシグナルで殺してしまい、cgroupsのnamespaceが残ってしまうという問題が発生しました。これをどうやったら削除できるか調べてみた結果、rmdir /sys/fs/cgroups/lxc/$name で削除できることを覚えました(kernel documentのcgroups.txt)。最初 rm -rfで消そうとして消せない、と苦労していたのですが、ディレクトリだけを削除すれば良いようです。逆にmkdirするとblkioとかcpusetとか必要なものがごそっと生えてきます。

というわけで、何かしらの不手際でcgroupsのnamespaceが残ってしまった場合には、ディレクトリだけをrmdirしましょう。

ついでにわかったこととして、LXC 1.0.6ではこういった「同じ名前のnamespaceが既にある」状況では$name-1といった名前で重複しないように作るような動きをするようです。

DebianパッケージでBuild.PLをポリシーに合うように扱う

ちょっと手間取ったので記録に残しておきます。

かつてのPerlはExtUtils::MakeMakerという標準モジュールを使い、Makefile.PLを用意しておくというのが一般的でしたが、最近はそれ以外にもModule::Build, Module::Build::Tinyというパッケージを使い、Build.PLというファイルを用意して処理することもあるようです。dh-make-perlはModule::Buildにも対応しているような感じでしたが、Module::Build::Tinyには対応していないようです(dh-make-perl 0.84-1で確認)。

dhのoverrideを使って、以下のようなコードをdebian/rulesに追加することで望みどおりの動作をするようになりました。

override_dh_auto_install:
        ./Build install --destdir=$$(pwd)/debian/$pkgname --installdirs=vendor

追記

同じ内容の記事を英語blogの方にも書いたところ、debhelperの問題という指摘を受けました。この問題が発生するのはwheezyのdebhelperに限定されます。sidではこのような対応は不要です。

第120回東京エリアDebian勉強会、2014年11月勉強会参加

先日「第120回東京エリアDebian勉強会、2014年11月勉強会」に参加してきました。

rroonga関連のパッケージをどうにかしようと考えていたのですが、Jornada 720にDebianを入れようとしていた人が来ていたので、そのお手伝いをしました。私自身はJornada 680を持っていて、過去にDebianを入れて使った経験があったので、それが多少役に立ちました。

Jornadaは、今は亡き「ハンドヘルドPC」と呼ばれるカテゴリのデバイスで、キーボードとディスプレイのついた小型PC的なものです。680はsh3が、780はStrongARMが搭載されています。標準OSとしてWindows CEが入っています。

基本的には「Lenny on j720」にあるカーネル、ブートローダー(CE用実行バイナリ)をCFに入れて、適切なカーネルパラメータを設定して起動するだけです。

任意のアプリケーションをインストールできるようにしたかったのですが、その場にあったPCMCIAネットワークカード(Corega PCC-TD)の認識がうまくゆかず、そこまではたどり着けませんでした。

一応、最近のkernelにもjornada 780向けのコード自体は入っていますが、パッケージとして用意されているarm用カーネルでその設定を有効にしたものは現状ありませんでした。コンパイルして動くかどうかもあやしい気がします。

この時代のunstableはLennyだったようで、userlandはLennyのものでした。このころはhotplug周りの仕組みが変化していた時期でしたが、Lennyは既にudevで動いていたようです。/etc/pcmcia/config*にCorega PCC-TDの設定を追加してやればNICも動いたかもしれません。

しかしLennyの頃はアーキテクチャarmとarmelが用意されていたのに対して、それ以降ではarmel/armhfに変わっています。ABIも変わってしまっているので、直接的なアップグレードはおそらくうまくいかなかったことでしょう。

Jornada 780は探せば1万円を切る程度の価格で入手できるようですが、さすがに今から使おうという気にはちょっとなれませんでした。

SSLv3の脆弱性(POODLE)対応

SSL 3.0に、プロトコル自体の脆弱性がGoogleによって発見されました。”Paddning Oracle On Downgrade Legacy Encryption”略してPOODLEと呼ばれています。

検証サイト https://www.poodletest.com/ が立ち上がっており、脆弱性の詳細に関する元ソースへのリンクもあります。

今回の脆弱性はサーバー、クライアントともに対策が必要になります。とり急ぎ自分の周りにあるSSL/TLSを使うサービスに対策を施しました。

Apache+mod_ssl

SSL_Engine onとしているセクション内で、以下の設定をしました。

SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"

SSL 2.0, 3.0を無効にし、利用可能な暗号からMD5,  3DES等を外しています(参考: httpsだからというだけで安全?調べたら怖くなってきたSSLの話!?)。

Postfix

smtpd_use_tls=yes
smtpd_tls_mandatory_protocols = !SSLv3, !SSLv2
smtpd_tls_mandatory_exclude_ciphers = aNULL, MD5, RC4

参考: Postfix TLS Support

Courier-imapd

##NAME: TLS_PROTOCOL:0
#
# TLS_PROTOCOL sets the protocol version.  The possible versions are:
#
# OpenSSL:
#
# SSL3 - SSLv3
# SSL23 - either SSLv2 or SSLv3 (also TLS1, it seems)
# TLS1 - TLS1
#
# Note that this setting, with OpenSSL, is modified by the TLS_CIPHER_LIST
# setting, below.
#
# GnuTLS:
#
# SSL3   - SSLv3
# TLS1   - TLS 1.0
# TLS1_1 - TLS 1.1
#
# When compiled against GnuTLS, multiple protocols can be selected as follows:
#
# TLS_PROTOCOL="TLS1_1:TLS1:SSL3"
#
# DEFAULT VALUES:
#
# SSL23 (OpenSSL), or "TLS_1:TLS1:SSL3" (GnuTLS)
TLS_PROTOCOL="TLS1"

Debianのcourier-imapdはOpenSSLをリンクしているのでTLS1のみ設定しています。

確認方法

OpenSSLのs_clientを利用することで、任意のバージョンのSSL/TLSを使った接続を試すことができます。

$ openssl s_client -connect target.server.example.jp:443 -ssl3
(略)
SSL handshake has read 2844 bytes and written 289 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : SSLv3
    Cipher    : ECDHE-RSA-AES256-SHA
(略)
$ openssl s_client -connect example.jp:443 -ssl3 -cipher `openssl ciphers RC4`
(略)
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-RC4-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : SSLv3
    Cipher    : ECDHE-RSA-RC4-SHA

上記サンプルでは、1回目はSSLv3, AESでの接続、2回目はSSLv3, RC4での接続ができています(参考: 私が愛した openssl (SSL/TLS 編))。設定が正しくできれば、以下のような結果となりネゴシエーションに失敗します。

SSL handshake has read 7 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : SSLv3
    Cipher    : 0000

STARTTLSを使う場合は-starttlsオプションが利用できます。

$ openssl s_client -connect example.jp:587 -ssl3 -cipher `openssl ciphers RC4` -starttls smtp
(略)
SSL handshake has read 2128 bytes and written 264 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-RC4-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: zlib compression
Expansion: zlib compression
SSL-Session:
    Protocol  : SSLv3
    Cipher    : ECDHE-RSA-RC4-SHA

Debianでの対応状況(2014/10/16朝頃)

ownCloudのDBマイグレーション失敗とリカバー

ふとしたことから、手元のsid環境を更新したのですが、その時にownCloudが5.0.25から7.0.2へと大きく変わってしまいました。ownCloudはアップブレード機能を持っている(web, occコマンド)のですが、それが途中でこけてしまったので、対処方法をblogに残しておきます。

5.0.25から7.0.2へ移行

自分はsid環境を、lxcコンテナの一つに持っています。その中でownCloudも運用しています。最初に導入したときのバージョンは5.0.25だったのですが、この記事を書いている辞典では7.0.2が最新です。5->6のメジャーアップグレードをはさめばうまくいったのかもしれませんが、自分のケースではデータベースの移行がうまくゆきませんでした。バックエンドにはSQLite3を使っています。

oc_lucene_statusでのエラー

アップグレード時に発生したエラーログの一部を以下に示します。

{"app":"core","message":"Simulated database structure update failed (exception OC\\DB\\MigrationException' with message 'An exception occurred while executing
'INSERT INTO oc_lucene_status (fileid, status) SELECT fileid, status FROM __temp;
__oc_lucene_status':\n\nSQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: oc_lucene_status.fileid'

oc_lucene_statusというテーブルの移行に失敗しています。このテーブルはLuceneによる全文検索用のものと思われますが、自分自身が全文検索を使ったことがこれまでなかったので、単純にテーブルの削除と再作成をすればよいだろうと推測し、まずはバックアップを取ったうえでdropしてみました。

単純にdropをしただけでは、当然テーブルがなくなるだけなので、やはりアップグレードに失敗します。その時のエラーは以下の通りです。

$ sudo occ upgrade
Turned on maintenance mode
Checked database schema update
Updated database
An exception occurred while executing 'DELETE FROM "oc_lucene_status" WHERE "fileid" IN (
                                        SELECT "fileid"
                                        FROM "oc_lucene_status"
                                        GROUP BY "fileid"
                                        HAVING count("status")  1
                                )
                      ':
SQLSTATE[HY000]: General error: 1 no such table: oc_lucene_status
Turned off maintenance mode
Update successful

データベースのテーブルの定義はXMLで書かれています。ソースコードのapps/search_lucene/appinfo/database.xmlが該当するファイルです。これを見て適当に見よう見まねでテーブルを作ってみたところ、うまくゆきませんでした。

$ sudo occ upgrade
Turned on maintenance mode
Unknown database type integerv requested, Doctrine\DBAL\Platforms\SqlitePlatform may not support it.
Turned off maintenance mode
Update successful

これはまずいと思い、バックアップしておいた方のデータベース上でのテーブル構造を参照してみました。

sqlite> .schema oc_lucene_status
CREATE TABLE "oc_lucene_status" ("fileid" INTEGER DEFAULT 0 NOT NULL, "status" VARCHAR(1))
CREATE INDEX status_index ON "oc_lucene_status" (status ASC)

この結果を参考に、新しい方のデータベースで同じテーブルを作成し(表示されているSQLをそのまま実行する)、再度アップグレードを試みたところ成功しました。

$ sudo occ upgrade
Turned on maintenance mode
Checked database schema update
Updated database
Turned off maintenance mode
Update successful

無事アップグレードに成功し、今では普通に利用できています。

第116回東京エリアDebian勉強会参加、そしてJessieインストーラBeta1

先の8/23に、第116回東京エリアDebian勉強会に参加してきました。

今回のお題

東京エリアDebian勉強会は、参加に際してなんらかの「お題」が出ます。ここ最近は「もくもく会」と呼ばれる「みんなでその場で集まって、各自が抱えている課題に黙々と取り組む」スタイルが多く、お題の内容は「もくもく会での目標」となることがほぼ常態になっています。

私の目標は

といったあたりを考えていたのですが、当日の午前中にイレギュラーが発生したので、急きょそちらをもくもく会のターゲットにしました。

DELL Latitude E6520購入

日経トレンディネットでDELL Latitude E6520が約4万円で販売という記事をみかけ、急きょ開店直後のPCボンバーへ赴きました。あらかじめスペックはある程度把握していたのですが、店頭で現物も見せてもらえたので、以下の点を評価してその場で購入を決意しました。

  • 1080p フルHDディスプレイ
  • SandyBridge世代だけどCore i7-4200M
  • 今となっては貴重なIEEE1394端子搭載
  • メモリは最大8GB(もしかしたら16GBいけるかもしれない)
  • eSATA端子搭載
  • ビデオにNVIDIA GF119内蔵

特に1394はいまだDVビデオカメラを持っている身としては貴重です。今まで使っていた動画配信用のノートPCは液晶を壊してしまったので、これでdvswitch+icecast2でのOgg Theora/Vorbisによる自由ソフトウェアでの動画中継も可能です。

Debianのセットアップ

wheezy 7.6

まずは普通に現状の安定板、7.6のインストーラーを試しました。使用したメディアはUSBメモリです。

無線LANで躓く

E6520の無線LANデバイスはIntel Corporation Centrino Advanced-N 6205、iwlwifiドライバで動作します。このドライバはnon-free firmware blobが必要なのでhttp://cdimage.debian.org/cdimage/unofficial/non-free/firmware/から取得しておき、インストールメディアにudebファイルを置いておく必要があります。デバイスの認識自体はこれだけでいけました。

問題は接続勉強会の会場はWPA2-PSKな無線LANが来ていたのですが、SSIDとパスワードを入力してもうまくネットワークに接続できませんでした。きちんとログを見ていなかったので、原因はまだわかっていません。再度インストールにトライすれば確認できるだろう、ということでとりあえずこの問題はさておいて、ちょっと前にリリースされたJessie Installer Beta 1を使ってみることにしました。

Jessie Installer Beta 1

次の安定板になるJessieは来年初頭には出るだろうと思われます。まずはbeta 1インストーラーをためし、何か不具合がないかを調べようと試してみました。

無線LANが認識しない

いきなりこれです。有線(82579LM e1000e)は普通に認識できました。幸い会場には有線の口とケーブルもあったので、そちらを使ってインストールを続けました。

インストール完了後であれば、firmwre-iwlwifiをインストールすることで無線LANを使えるようになりますが、インストール時にうまく検出できていないのは問題です。

再起動できない

wheezy, jessieどちらにも共通していますが、再起動がうまくゆきません。ただしシャットダウンはうまく動きます。それぞれでインストールされるカーネルのバージョンは3.2.0, 3.14.0です。

世代的に枯れたハードウェアだと思うので、BIOSあたりが怪しいのではないかと思っています。バージョンを確認してみると、A00 (2011-05-11)と出ました。現在のBIOSはA19が最新のようなので、一度更新して確認したいところです。

今後の予定

幸い購入したばかりなので、今の段階であればいくらでもインストーラーのテストが可能な状態です。いろいろと試行錯誤をして、可能であればJessieのインストーラのバグなどをつぶしてゆきたいところです。

インストール状況が落ち着くまでは、USBメモリをルートメディアにしてしのごうと思います。今のところ16GBの2000円程度のメディアを使っていますが、速度的には思ったほど不満はありません。

Intel Celeron N2806のeMMC(RPMB)

ECS LivaというBay-Trail MベースのPCがあります。秋葉原の複数の店舗やAmazonで扱っています。2万円しない小型PCで、メモリ(2GB)とストレージ(eMMC 32GB)を搭載しているので、OSさえ用意すれば他には何もなくても使えるマシンです。

公式でUbuntu 14.04が動作すると書かれているのですが、やはりDebianを使いたいのでなんとかしてインストールしてみました。

しかし、wheezyのインストーラではストレージを認識できません。Linux kernel 3.8から入ったsdhc_acpiというホストドライバが必要なのですが、Debian wheezyの標準kernelは3.2と古いのが原因です。

結局、自分は一度Ubuntu Live USBイメージから起動して、debootstrapで頑張ってDebianをインストールするという手段で実現しました。Debianさえ入ってしまえば、backportsにある3.14 kernelがwheezyでも使えます。

最初はwheezy用のインストーラを作るべく頑張ってみたのですが、3.14 debian udebにsdhc-acpi.koが含まれていないというバグがあるため(kernel debにはある)、kernelパッケージを作り直す必要がありました。しかし作り直しても、eMMCデバイスは見えるけれどもアクセスすると固まるという問題があったため、挫折しました。

今のbackports kernelでは一応動いていますが、Replay Protected Memory Block(RPMB)と呼ばれる領域にアクセスできないという不具合があります。この警告はUbuntu kernelだと出ません。

[    3.202626] mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900
[    3.205033] mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900
[    3.207399] mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900
[    3.209806] mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900
[    3.212209] mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900
[    3.214579] mmcblk0rpmb: timed out sending r/w cmd command, card status 0x400900
[    3.214861] end_request: I/O error, dev mmcblk0rpmb, sector 8190

Ubuntu kernelからこの対応をやっている箇所をどうやって特定しようか、と考えていたら、対応している人の記事がみつかりました。

/dev/nell – RPMB eMMC errors under Linux

この記事ではASUS T100Aを対象としているようですが、おそらくLivaでも使えることでしょう。