GnukのEmulation mode

2021/3/10 FSIJセミナーで解説されたのでメモ これでできること: 実物のGnukを使わない動作テスト 鍵生成などは失敗すると最悪なにもできなくなるので練習ができる 事前に必要なもの scdaemon usbip python3-cffi, python3-pytest ソースコードの準備とビルド手順、起動まで 別のターミナルを開き、vhci, usbipを用いてUSBデバイスとして扱えるようにする テストの動作 gpgでカードとして扱う PINはadmin: 12345678, 通常 123456 初期化 (factory-reset) 新規鍵生成 (generate) 内容は ~/.gnuk-flash-image に保存される 作成した鍵で暗号化 (gpg -e) 追記(2020-03-12) Facebookでg新部さんよりいくつかご指摘いただきました encryptでは秘密鍵を使わない(のでここはテストになっていない) Debian 10 (Buster)のGnuPG 2.2.12では復号化に失敗する。2.2.27では問題ないとのこと Gnuk 1.2.17時点で鍵生成にバグがある。今は修正がpushされている

Orange PI PCで動画のハードウェアエンコードはできるのか

これはLinux Advent Calendar 2015 18日目の記事です。 ARMベースの小型PCとしてRaspberry PIシリーズが人気です。ハードウェアによる動画(H.264)エンコード支援がついていて、それが目的で使っている人もいるようです。 しかし私はRaspberry PI 2の代わりにOrange PI PCを購入しました。機能的には持っているようなので、できればなんとか使いたいところです。 参考にするため、そもそもRasPiではどうやっているのかをちょっと調べてみました。Googleで検索すると、gstreamerでomxh264encを使うという方法が紹介されています。 これはgst-omxというコンポーネントのようで、OpenMaxというコーデックの取り扱いを抽象化したAPIのようです。さらに調べてみると、RasPiではlibopenmaxil.soという共有ライブラリが呼び出されているようです。 ではこいつのソースコードはどこだと探してみましたが、ファームウェアの一部という扱いでバイナリーのみが配布されているという残念な状況でした。RasPi側からの調査はここが限界です。 ではOrange PIではどうか。Orange PIとAllwinnerのチップの情報に関しては、linux-sunxi.orgが総本山のようです。ここにいろいろと情報がありました。 Orange PI PC用カーネルにはcedar-veというモジュールが追加されており、これがハードウェアコーデック用のデバイスドライバとなっています。/dev/cedar_devというスペシャルデバイスを介してioctlで直接ハードウェアを操作する機能を提供しています。残念ながらメインラインにはマージされていないようです。 そしてそれを使うよう改造されたffmpegが公開されています。これを動かすことを目標としていろいろ試してみました。リポジトリにはdeb化されたバイナリーもありますが、どうもwheezy向けのようです。しかもパッケージングの作法もよろしくなく、既存のdebianパッケージとファイル単位でいろいろ衝突を起こすので、これを利用するのはお勧めしません。 そこで手動でのビルドを行いましたが、ライブラリ周りで苦労しました。最終的には以下のような手順でビルドできると思います。 ビルドしたバイナリを実行してみます。/dev/cedar_devへのrwアクセスができる状態でffmpegを実行します。 残念ながらうまく動きませんでした。gdbで追いかけてみると、ve_open()で/dev/cedar_devをオープンしてioctl IOCTL_GET_ENV_INFOで構造体ve_infoの値を取得していますが、これ自体は失敗しないものの、各種メンバの値reserved_mem, reserved_mem_size, registersがすべて0になっています。これによりve_mallocが失敗して6行目のエラーメッセージが表示されます。ドライバ側のコードを読むと、「このインターフェースは使うな」というコメントがあり、実際に0を返していました。きっと古いcedar_devで動くコードだったのでしょう… http://linux-sunxi.org/CedarX/Encoderの記述によると、現在あるコード以外にもsunxi_memドライバという物理メモリにアクセスするドライバ(/dev/sunxi_mem)と併用して動くCedarXというライブラリが別にあるようです。ハードウェアエンコーダのサンプルコードもあるのですが、やはりバイナリでしか存在しないライブラリ群に依存しています。 それでもいいからなんとか動かせないかと、sunxi_memドライバを追加した勝手カーネルをビルドしようとしたのですが、mach/includes.hという存在しないヘッダファイルを必要としてビルドできませんでした。ここはまだ調査不足です。 現状の結論として、Orange PI PCでH.264のハードウェアエンコードは「できそうな雰囲気」という煮え切れない結論となってしまいました。linux-sunxi MLの購読を始めたので、今後はこのあたりどうなっているかを尋ねてみたいと思っています。

VMware PlayerからVirtualBoxへの移行

最近のスラッシュドットの記事から、VMware Playerのライセンスにおける「非商用の解釈がかわった」という記事(ライセンス解釈が変わったようです。)を目にし、この機会にVirtualBoxへの移行を実施しました。 移行対象は違いますが、既にやってみた人の記事(VMware Fusion 5からVirtualBox 4.3への移行)があったので、作業自体はそれほど難しくはありませんでした。ただ、この記事にもあるようにストレージをSCSIからIDEに変更する、という作業はVMware Playerでも同様に必要でした。 自分の場合、もう一点「ホストオンリーネットワークもそのまま移行したい」という希望があったので、そのために若干の作業が発生しました。参考にしたのは「VirtualBoxのネットワーク設定とCentOS6.5のインストール」です。こちらの記事はMacOSXのようですが、Windowsでも行うことはあまり変わりません。 VirtualBox マネージャーからメニューの「ファイル」「環境設定」を選択し、ダイアログを開きます。さらに「ネットワーク」「ホストオンリーネットワーク」を選択し、ネットワークを追加します。ネットワークレンジやネットマスクを、これまでVMware Playerで使っていたものと同じになるよう設定します。 ここで一点注意があります。VMware Playerが入ったままだと、VMwareの仮想ネットワークインターフェースが設定として保持されたままになるので、vmnetcfg.exeで設定を変更するか、VMware Playerをアンインストールする必要があります。そうしないと、同一のネットワーク設定が存在しているとWindows側に認識され、リンクローカルなネットワークが強制的に割り当てられてしまいます。 あとはOVF化した仮想マシンをVirtualBoxからインポートし、ネットワーク設定を先ほど作成したホストオンリーネットワークに指定して、実際に通信ができれば完了です。 NATネットワークの移行も、ほぼ同様の手順で実行し、Window側のネットワーク共有を使えばできると思います。

ELECOM UCAM-C0220Fを使う

ふと思うところがあって、安価なUSBカメラを購入しました。エレコムの200万画素で安価(1000円程度)なモデルです。 最終的な目的の用途とは異なるのですが、とりあえず自宅の様子をストリーミングさせてみました。かつてはgstreamerを使っていろいろと余計な苦労をする羽目になったのですが(Google Slideの資料9ページ目参照)、いまどきはffmpeg/libavを使ってVorbis/TheoraやWebMにエンコードし、icecastに配送させるのが簡単だと思います。 このデバイスは映像入力をUVCクラス、音声(マイク)入力をAudioクラスとした複合デバイスに見えます。 ffmpegでalsaデバイスとしてこのオーディオデバイスを使うと、定期的に”[alsa @ 0x15fcc00] ALSA buffer xrun.”というエラーが出ます。どうもUSB audioとしての動作が何かおかしいようです。この状態でoggfwdを続けていると、icecast側から接続を切られてしまいます。まあ自分の主目的は映像をとることなのでその用途には十分使えそうです。

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といった名前で重複しないように作るような動きをするようです。

Linuxで扱う乱数に関する話

これはLinux Advent Calendar4日目の記事です。 Unix系OSには、カーネルに乱数生成器を持つ実装が多くあります。乱数は暗号分野でも利用され、非常に重要な位置を占めています。Linuxにおける乱数に関する話題を取りあげてみます。 エントロピープール 一般的に、特別なハードウェアを持たない限り、真の乱数を計算機が生成することは困難です。Linuxでは、質の良い乱数を生成するためにエントロピープールと呼ばれる領域を持っています。エントロピープールには、キーボードの入力タイミングやストレージ、ネットワークなどで発生するハードウェア割り込みなどをもとにした推測の困難な情報(環境ノイズ)が蓄積されます。乱数の生成時には、このエントロピープールの内容を消費、加工します。 エントロピープールにどの程度情報がたまっているかを調べるには、/proc/sys/kernel/random/entropy_availを見ます。エントロピープールの上限値は/proc/sys/kernel/random/poolsizeをcatした出力値です(デフォルト値は4096) 。OpenPGPやSSLの鍵などを生成する際には、この値を確認した方がよいかもしれません。 スペシャルデバイス 乱数を生成する特別なデバイスファイルには、/dev/randomと/dev/urandomの2種類があります。 /dev/randomは全ての乱数をエントロピープールから生成します。エントロピーが不足した場合は新たにたまるまでブロッキングされるため、あまり速度が出ません。乱数の質よりも速度に重点を置く場合には、/dev/urandomを使います。urandomを使う場合、エントロピープールを再利用して乱数を生成します。 havege havegedを動かすことで、より多くの環境ノイズ(主にCPUの情報)をもとにしてエントロピープールを常に多い状態へと保つことができます。エントロピープールへの情報の追加は/dev/randomのioctrlインターフェースを用いています。また、havagedは単独の乱数生成アプリケーションとしても利用できます。 NeuG g新部さんによるハードウェア乱数生成実装として、NeuGがあります。NeuGはSTM32F103上で動作し、チップに搭載されているA/Dコンバーターからの入力の量子化誤差を乱数生成に利用します。NueGの動作するハードウェアとしてFST-01があります。この記事を書いている2014年12月初頭では品切れ中ですが、今後追加生産・販売を予定しているそうです。 仮想化の問題 エントロピープールの情報は、予測が困難であるハードウェアからの情報に大きく依存しています。仮想マシンの場合、多くのハードウェアは仮想化されており、ハイパーバイザ等の配下にあります。したがって、物理マシンと比較すると質の良い乱数を生成させることがより困難となっています。セキュリティに十分な注意を払う必要がある場合には、信頼できない仮想マシン上での暗号鍵の生成などは控えた方が良いでしょう。 訂正 コメントでg新部さんからいくつかご指摘を頂きましたので修正・追記しました。FST-01はhttp://www.seeedstudio.com/より購入可能とのことです。詳細はコメントをご覧ください。 宣伝 この記事はFSIJ勉強会での解説をもとに得た知見を自分なりに記録したものです。FSIJでは定期的に勉強会を開催しています。GnuPGの開発者の一人であるg新部さんもいらっしゃるので、興味のある方はぜひお越しください。  

Published
Categorized as Linux

動作中のプロセスのptyをつなぎかえられる、reptyrを使ってみる

UNIX板のGNU screenスレッドで紹介されていたreptyrを使ってみました。 screen外のプロセスにattachさせる 既にscreenを実行している状況で、screenのセッション外のプロセスを起動してみます。適当なterminalを起動するなり、外からsshでつなげるなりしてみます。あとでプロセスを探しやすいようにttyコマンドで現在使っているptyデバイスが何かを確認しておきます。 次にscreen内の任意のウインドウのshellから、当該プロセスにつなげてみます。 この時点で、元のターミナルは無反応になり、bashの制御がscreen下に移りました。shellを終了すればreptyrに制御が戻ります。 gdbと組み合わせる reptyrのもう一つの機能、ptyを外部から使わせるために確保する-lオプションを使ってみます。 別のshellからgdbでこのptyを使ってみます。set inferior-ttyで/dev/pts/7を指定することで、gdbが動かすプロセスの出力をreptyr側の端末に変更できます。 reptyrを実行していたshell上に、lsの出力が表示されます。標準入出力をデバッガの画面と切り離すことができて便利です。 実装方法 以前「起動済みプロセスのリダイレクト先を設定したい」という記事を見かけた記憶があったので、基本的には同じようなやりかただろうと思いつつソースを見てみたら、その通りでした。 起動しているプロセスに対してptrace(2)でattachし、ptyをdup2でfile descripter 0, 1, 2に複製しています。ただし、単なるリダイレクトと違い仮想端末が相手なのでresize等に対応するためのコードも含まれているようです。 前述の記事や本プログラムのドキュメントにもありますが、Ubuntuのカーネルはデフォルトで一般ユーザーのptraceを禁止しています。procfsを見てそのあたりをチェックするコードも入っています。Ubuntuユーザーが利用する場合、rootで実行するか、sysctlの設定を変更する必要があります。

Published
Categorized as Linux

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としているセクション内で、以下の設定をしました。 SSL 2.0, 3.0を無効にし、利用可能な暗号からMD5,  3DES等を外しています(参考: httpsだからというだけで安全?調べたら怖くなってきたSSLの話!?)。 Postfix 参考: Postfix TLS Support Courier-imapd Debianのcourier-imapdはOpenSSLをリンクしているのでTLS1のみ設定しています。 確認方法 OpenSSLのs_clientを利用することで、任意のバージョンのSSL/TLSを使った接続を試すことができます。 上記サンプルでは、1回目はSSLv3, AESでの接続、2回目はSSLv3, RC4での接続ができています(参考: 私が愛した openssl (SSL/TLS 編))。設定が正しくできれば、以下のような結果となりネゴシエーションに失敗します。 STARTTLSを使う場合は-starttlsオプションが利用できます。 Debianでの対応状況(2014/10/16朝頃) w3mはSSLv3を無効化するパッチの当たったバージョンがsidにアップロードされています SSLv3が無効にされたOpenSSL 1.0.1jがリリースされており、sidにもアップロードされています。

不安定なマシンを無理やり動かす(watchdog, memtest)

実家に設置してあるサーバがここのところ妙に挙動があやしく、いろいろ調べてみた結果どうもメモリがあやしい、という結論に至りました。しかしそのためだけに新幹線で名古屋まで帰ることも出来ず、しかも今ちょっと入院中なので、リモートで出来る限りのことをしてみました。 まずはsoftware watchdogの導入です。これは/dev/watchdogというデバイスをつくり、定期的に書き込みがあるかチェックして、一定時間(デフォルトは60秒)書き込みがなかったら再起動するというものです。チェックをするためのソフトウェアがDebianにはwatchdogという名前のパッケージであります。インストール時にdebconfでいくつか質問されます。私の設定は以下になります。 moduleは利用するwatchdogドライバのモジュール名で、software watchdogはsoftdogを指定します。watchdogデーモンが起動するときにこれがinsmodされます。runは自動起動するかどうかの設定、restartはアップグレード時に再起動をさせるかさせないかを指定します。下手に再起動させると、kernelがwatchdogがとまったと誤認識することがあるので、falseのほうが安全です。 次に/etc/watchdog.confを編集します。デフォルトではコメントアウトされているwatchdog-deviceの行を有効にします。 これで何かあってシステムがハングすると、再起動するようになります。ただし、ソフトウェア実装なので確実ではありません。 しかしそもそも不安定な原因がメモリにあるので、そこをなんとかしたいところです。昔はbadramというパッチがあって、問題のあるメモリ領域を手動で指定して使わないようにさせる、という方法があったのですが、今はもっといい方法があります。 Linux 2.6.26から導入されたkernel組み込みmemtestです。起動パラメータにmemtest=試行回数を指定することで、メモリのエラーをチェックしエラー領域を使わないよう動作します。 残念ながら、Debianデフォルトのカーネルでは有効になっていないので、 CONFIG_MEMTEST=yを.configに追加して自分でカーネルの再構築をする必要があります(make-kpkgを利用) 自作したカーネルパッケージをインストールしたら、カーネルパラメータを追加してやる必要があります。/etc/default/grubを編集します。 GRUB_CMDLINE_LINUXにmemtest=数値を指定して、テスト回数を指定してやります。この例では32回テストします。テストを増やせばエラーを発見する確立が高まりますが、当然起動には時間がかかります。手持ちのノートPCで試しに255を指定したところ、数分待っても終わる様子がないので完走させる前に止めてしまいました。 最後にupdate-grubを実行して、このパラメータをgrub.cfgに反映させてから再起動します。カーネルがエラーを発見すれば、dmesgに以下のような出力が出ます。 これで今のところ問題は起きていません。しかしこんな状態で利用し続けるのも問題なので、可能であればECCメモリーにでも乗せかえたいところです。