2013年12月15日日曜日

mikutter LiveDVD(NEGIX) 13.12のリリースと今後について

(ディストリビューション/パッケージマネージャー Advent Calendar 2013の記事を兼ねての投稿です.)

mikutter LiveDVD 13.12(NEGIX)リリース

ダウンロードしてDVDやUSBメモリに書き込んだらmikutter環境がすぐ使えるmikutter LiveDVD(NEGIX). その新バージョンとなる13.12をリリースしました.

http://yuzuki.hachune.net/negix/
http://repo.hachune.net/Linux/ArchLinux/iso/2013.12.15/

Arch LinuxのLiveCDと同様に毎月更新ということを銘打っていたのですが,今回はいろいろあって10月のOSC東京(秋)以来のリリースとなってしまいました.もうしわけねぇもうしわけねぇ.

mikutter LiveDVDの目標

mikutter LiveDVDの目標としては,以下の点があります.

  • Live環境を起動したら日本語環境でmikutterがすぐ使える状態にする
  • 毎月リリースする
    • Arch LinuxのLiveCDをベースに,可能な限り弄らない
    • Arch Linuxのパッケージをそのまま使う

何故かインストールが難しいと評判のmikutterを簡単に使えるようにすることを第一の目標としています. また,Arch Linuxらしさ(更新の早さ,パッケージの新しさ,簡素さ)も十分に発揮できるよう, 可能な限り毎月リリースすることも目標としています.そこで,最小限の手間でLiveDVDを作れるよう, 基本環境やパッケージには可能な限り手を入れないよう心がけています.

mikutter LiveDVDの今後

debianやubuntuの標準リポジトリにmikutterが入り導入難易度がぐーんと下がったということもあり, 若干存在意義が危ぶまれている感じもしますが, 「最新揃いのArch Linux環境でmikutterが簡単にすぐ使える」という売りもあるので, まだまだ需要は...ある?

Raspberry PiやBeagle Bone Blackとかでパッと使えるmikutter環境イメージがほしい, という意見もあったりするようで,いろいろ作ってみたいところですが,手が足りていない感じです. (今はOpenVPNとかをRPiで簡単に使えるようにする環境のようなモノを作っていたりもするので,それができたら...)

画像はイメージです

2013年8月6日火曜日

Android端末でOpenVPNを使ってみよう

何やらRTX810でVPNを張ってRDP経由でゲームするのが流行っているという噂を 某所で聞きました.しかし,RTX810は高くて買えないという方も多いので はないでしょうか. そこで,RTX810を買えない方でも気軽に試せるオープンソースのVPNソフト, OpenVPNを用いたVPN環境をWindowsとAndroid端末間で作る方法を紹介してみよ うと思います.

ここで例に上げる環境は,以下の通りになるよう構成します.

  • LAN: 10.39.39.0/24
  • VPN: 10.3.9.0/24
  • Windows: LAN - 10.39.39.31, VPN - 10.3.9.1
  • Android: LAN - 10.39.39.33, VPN - 自動割当

OpenVPNのインストール

サーバ(Windows)側

まずはOpenVPNサーバ環境をWindows側に準備します.公式ページでWindows用のイン ストーラが用意されているので,これをダウンロードしインストールしてくだ さい.
http://openvpn.net/index.php/open-source/downloads.html
インストール時に,「OpenVPN RSA Certificate Management Scripts」もイン ストールするようチェックするのを忘れないでください.

クライアント(Android)側

次に,クライアント環境をAndoroid側に準備します.OpenVPNはGoogle Playに て公式に配信されているため,これをインストールします.
https://play.google.com/store/apps/details?id=net.openvpn.openvpn&hl=ja
残念ながら,古いAndroidでは利用できないようです.(私は4.0以降の端末で動作確認しました)

OpenVPNでは,共通鍵暗号と公開鍵暗号の両方をサポートしていますが, Android版では公開鍵暗号のみをサポートしているため,こちらを利用します.

鍵生成の設定

OpenVPNの公開鍵生成の支援ツールは,C:\Program Files\OpenVPN\easy-rsa以 下にインストールされています.まずeasy-rsaディレクトリごとデスクトップ などにコピーし,メモ帳などでeasy-rsa\vars.bat.sampleの 以下の部分を環境に合わせて編集,vars.batとして保存します.

set KEY_COUNTRY="US"
set KEY_PROVINCE="CA"
set KEY_CITY="SanFrancisco"
set KEY_ORG="Fort-Funston"
set KEY_EMAIL="me@myhost.mydomain"
set KEY_OU="MyOrganizationalUnit"

今回の環境では,以下のように定義しなおしました.

set KEY_COUNTRY="JP"
set KEY_PROVINCE="Kanagawa"
set KEY_CITY="Kawasaki"
set KEY_ORG="Hachunet"
set KEY_EMAIL="phenomer@g.hachune.net"
set KEY_OU="Hachunet"

鍵生成

管理者権限でcmd.exeを開き実際に鍵生成スクリプトを実行します. build-*実行時にCommonNameとNameを問い合わせられた際には,それぞれの鍵 に適した名前を入力してください. また,buikd-key-serverとbuild-keyを実行する際に,以下のように問い合わ せがありますが,これは共にyとしてください.

  • Sign the certificate? [y/n]
  • 1 out of 1 certificate requests certified, commit? [y/n]
> cd \Program Files\OpenVPN\easy-rsa
> init-config
> vars
> mkdir keys
> clean-all
> build-ca
> build-key-server server
> build-key android
> build-dh

以上の作業で,それぞれの端末に必要な鍵ファイルの生成ができました. OpenVPNの実行に必要なファイルは以下の表のとおりです.

ファイル名必要とするホスト
ca.crtサーバ,クライアント
dh2048.pemサーバ
server.crtサーバ
server.keyサーバ
android.crtクライアント
android.keyクライアント

鍵生成まわりは,いろいろとハマりどころが多いように感じるので, 失敗した場合はドキュメント やエラーメッセージをよく読んでやり直してみてください.

サーバ(Windows)側の準備

メモ帳等を利用し,設定ファイルserver.ovpnを記述します. サーバ側の設定ファイルは,以下のようになります.

port  1194
proto udp
dev   tun
ca         ca.crt
cert       server.crt
key        server.key
dh         dh2048.pem

server   10.3.9.0 255.255.255.0
ifconfig 10.3.9.1 255.255.255.0

comp-lzo
keepalive 10 60
ping-timer-rem
persist-key
persist-tun
max-clients 5

この設定ファイルを保存したフォルダ内に,先ほど生成した鍵ファイルのうち サーバ側で必要なものをまとめて入れておいてください.

クライアント(Android端末)側の準備

Android用OpenVPNの設定は,以下のように記述します. 通常のOpenVPNの設定ファイルと異なる点として,次のようなタグを用い鍵ファイルの内容を全て 設定ファイル内に記述しなければならない点があります.

  • <ca> - ca.crt
  • <cert> - android.crt
  • <key> - android.key
client
dev tun
proto udp
remote 10.39.39.31 1194
persist-key
persist-tun
ns-cert-type server
comp-lzo

<ca>
-----BEGIN CERTIFICATE-----
MIIE6DCCA9CgAwIBAgIJAI7WSDBm6otGMA0GCSqGSIb3DQEBCwUAMIGoMQswCQYD
VQQGEwJKUDERMA8GA1UECBMIS2FuYWdhd2ExETAPBgNVBAcTCEthd2FzYWtpMREw
DwYDVQQKEwhIYWNodW5ldDERMA8GA1UECxMISGFjaHVuZXQxFDASBgNVBAMTC0hh
Y2h1bmV0IENBMRAwDgYDVQQpEwdFYXN5UlNBMSUwIwYJKoZIhvcNAQkBFhZwaGVu
b21lckBnLmhhY2h1bmUubmV0MB4XDTEzMDgwNjA3MjgyM1oXDTIzMDgwNDA3Mjgy
M1owgagxCzAJBgNVBAYTAkpQMREwDwYDVQQIEwhLYW5hZ2F3YTERMA8GA1UEBxMI
S2F3YXNha2kxETAPBgNVBAoTCEhhY2h1bmV0MREwDwYDVQQLEwhIYWNodW5ldDEU
MBIGA1UEAxMLSGFjaHVuZXQgQ0ExEDAOBgNVBCkTB0Vhc3lSU0ExJTAjBgkqhkiG
9w0BCQEWFnBoZW5vbWVyQGcuaGFjaHVuZS5uZXQwggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQChYUPyhc0vD1OVa3RU1wtbPUYDZXxQuMKTv9wiuIp60Eep
keR7CpolWNDxsksptUNAk0MIpc6t+SuBw80Kx6uLe4MeEulPsZ9ztG92OZ7k28cf
ufoOcxFSbnbJlwyhhHkjRMjxw/XL06gL1b/DakjfW/yW3LBXL4pn2ZFajGBapw48
2Z76mq/O21RiXMYy1LCRcYqhAGsC5TPHeXHRPecwPOFfO/YvnhKquuSxe06/hIvC
4ceJ9/jQ1tK8zFhA2TGgv2ae3VDdurinWiO0I9omzd7JYr/xq9XrGP2Zqujbp45H
KLzn8hCo83e/zj6zyzUOlwqYZu6FhtdV5XP2isVRAgMBAAGjggERMIIBDTAdBgNV
HQ4EFgQUdKavhZG6LzXHLOUrVP2M+bjSYh0wgd0GA1UdIwSB1TCB0oAUdKavhZG6
LzXHLOUrVP2M+bjSYh2hga6kgaswgagxCzAJBgNVBAYTAkpQMREwDwYDVQQIEwhL
YW5hZ2F3YTERMA8GA1UEBxMIS2F3YXNha2kxETAPBgNVBAoTCEhhY2h1bmV0MREw
DwYDVQQLEwhIYWNodW5ldDEUMBIGA1UEAxMLSGFjaHVuZXQgQ0ExEDAOBgNVBCkT
B0Vhc3lSU0ExJTAjBgkqhkiG9w0BCQEWFnBoZW5vbWVyQGcuaGFjaHVuZS5uZXSC
CQCO1kgwZuqLRjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQB1hZnf
UdGllXFPSKp80IT5B0uwV1TGy2ixw9WdVQGPnB/GMgxEHUaoc3ctdKjYcis7fxzf
aDMCgt8/GgxsG1zGwmSYDxpjK+0VOSi6uAb6hzWamPggSIV9Dz237mrPMV+eJMcC
NoTiX4oD07tMkvWMC2FAOTaY7ARBiXBnI4qUrPVT+HxL2AdihmOIn4BrCLfUg1RK
8ptsOP1qNP2WBjouh37wb+TlvfzTwFi2JcyQw8lpdL3qmLdkBtasYzo4IE9o+rDr
9C9tHyLRe/itvGwU/RWUKG0MgQMIWN1gKmhuzxoHiOhT9NmU3F5g6vYSYT0akWRi
qbpxmVm5yJAo9kSL
-----END CERTIFICATE-----
</ca>

<cert>
-----BEGIN CERTIFICATE-----
MIIFKjCCBBKgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBqDELMAkGA1UEBhMCSlAx
ETAPBgNVBAgTCEthbmFnYXdhMREwDwYDVQQHEwhLYXdhc2FraTERMA8GA1UEChMI
SGFjaHVuZXQxETAPBgNVBAsTCEhhY2h1bmV0MRQwEgYDVQQDEwtIYWNodW5ldCBD
QTEQMA4GA1UEKRMHRWFzeVJTQTElMCMGCSqGSIb3DQEJARYWcGhlbm9tZXJAZy5o
YWNodW5lLm5ldDAeFw0xMzA4MDYwNzMwMTNaFw0yMzA4MDQwNzMwMTNaMIGkMQsw
CQYDVQQGEwJKUDERMA8GA1UECBMIS2FuYWdhd2ExETAPBgNVBAcTCEthd2FzYWtp
MREwDwYDVQQKEwhIYWNodW5ldDERMA8GA1UECxMISGFjaHVuZXQxEDAOBgNVBAMT
B2FuZHJvaWQxEDAOBgNVBCkTB2FuZHJvaWQxJTAjBgkqhkiG9w0BCQEWFnBoZW5v
bWVyQGcuaGFjaHVuZS5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDaPA6/FlqlL6gbz/r1AzBF+VazenL6WHV2NkcPd1Fj0HUdowGaQR8E23rzN0dg
wRkcRIp86dTMkPVNhpvp3HE6ECcsW6LaskrIqXLZPkx5n9iVGvM0YPVY8zQkCM5u
UhHQjDPaJry9fo58nVr1YO8jFB7p0AxbZOyqVxKpsaZ49UOzLUTGIgP6QoqBGuR2
YNmd/7OE+pG7A/m912u8G5CZ3XHoDAUUh0nazn4ob6PTGb0csZGjdhNJoOsIIQcV
h0A3slgRlCMiYKLYCKSXpvrvo3vwtJP3Fq3coU0dytriPJKrX6R6NSclVl7/cO4J
nXZCuC3xXJNcADYuaKvawvqbAgMBAAGjggFfMIIBWzAJBgNVHRMEAjAAMC0GCWCG
SAGG+EIBDQQgFh5FYXN5LVJTQSBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
BBYEFCfOnKmBT1kX72NW//8iRzOCA1M+MIHdBgNVHSMEgdUwgdKAFHSmr4WRui81
xyzlK1T9jPm40mIdoYGupIGrMIGoMQswCQYDVQQGEwJKUDERMA8GA1UECBMIS2Fu
YWdhd2ExETAPBgNVBAcTCEthd2FzYWtpMREwDwYDVQQKEwhIYWNodW5ldDERMA8G
A1UECxMISGFjaHVuZXQxFDASBgNVBAMTC0hhY2h1bmV0IENBMRAwDgYDVQQpEwdF
YXN5UlNBMSUwIwYJKoZIhvcNAQkBFhZwaGVub21lckBnLmhhY2h1bmUubmV0ggkA
jtZIMGbqi0YwEwYDVR0lBAwwCgYIKwYBBQUHAwIwCwYDVR0PBAQDAgeAMA0GCSqG
SIb3DQEBCwUAA4IBAQBwbK5ZTfiM6Ce8wbfPeU6RSzswiY9LypvR7LFrbufYwiNt
ptWJVR9zG5JKzPIthgEesjEyhlucaPfReCfox8+2uADDjjTIr8aXO/UgeuPz06X7
os6an6KV/czSBspA3XVn6mrPaixaNVHUluPDKQlfinW8LjZdE1dcHHSsF79NBIeo
x1LLjMl9avGntkAV1WmUdaE+atNgeGYwJzBV9gqmWX01StIb3hsVSCINGu85Woch
2YP8N0UM52LXbgXPy6Jnpy80GfoaXjxNI/+xtmnQfzrm8OisKx+HWdaBjFE6lOtR
DtHKIm3/sL5Dj3nAiiDw4xyuFqTIZ9Di7ZAjQ15E
-----END CERTIFICATE-----
</cert>

<key>
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDaPA6/FlqlL6gb
z/r1AzBF+VazenL6WHV2NkcPd1Fj0HUdowGaQR8E23rzN0dgwRkcRIp86dTMkPVN
hpvp3HE6ECcsW6LaskrIqXLZPkx5n9iVGvM0YPVY8zQkCM5uUhHQjDPaJry9fo58
nVr1YO8jFB7p0AxbZOyqVxKpsaZ49UOzLUTGIgP6QoqBGuR2YNmd/7OE+pG7A/m9
12u8G5CZ3XHoDAUUh0nazn4ob6PTGb0csZGjdhNJoOsIIQcVh0A3slgRlCMiYKLY
CKSXpvrvo3vwtJP3Fq3coU0dytriPJKrX6R6NSclVl7/cO4JnXZCuC3xXJNcADYu
aKvawvqbAgMBAAECggEAGWTnqmClh5c2DpZy81O9qEbNSfEzs+HbOTgzqJ8Pv3eg
SSSQqSxuuZf4hJioG6Acled73fEvq+YqRS0ms13NZx4+ELFRD/WzMgpVrOXM7FIn
V6JdLnkh04npRVApBTlTjVrjJb1gNQSm++UrkmYHLaPHvRlSdsgVqfSb3VcoseZR
Q0RTTm6iAx0+7fFUJg+rPfhtDpKCPdIOSPXksTObts+7ErWDGlr9DglIuJqUSo/Y
crPpkk8gZp1X6bJNS+glxJtwvXP0P2pikQIqKwM2MNgjRxr4fGtoD50LwC6N068o
ZSXKGOR+miw/5u+KJySdbGNlu5AbbIkeJtUEbPC2sQKBgQDz7pLhGCB1dw6Ga+Ox
wwxuAApPIBpywxHesEF06dQFITXs60Xm4LWmUAXdCjFO4NMQ0Fl6I9ozP1S7hQur
Qkds76dx9VJg6NkBwy/Ncma5oADjBi3hRbN6sO6MKBvqlF9nm8guR4dn5ZhoyO1v
uBnmvMOlIZzY88VlUf2PHPSuHwKBgQDlCAYx54vHylP49w/I19v/MzgX9OcTegz1
JxewFmpKvEgehNgvQpYbSIGjZ5UctoSbslDU47B2gb75ocI1JXIfhpNHkNqCZZ5j
zdtaKSp2NurEcop4tJ0f3h2o8zBhwrgsDsegIwP4XJVF7xjF/+ohLj6Vmk/Xhhaa
4hYBWansBQKBgQCbdXVoPT8afZjlNEc1mBAI3r+zM8uHTijKWlwtDYSRDFxYtIyl
GprJ9n/2IjPQiFobgh00STsbpAX1SFJqf+ATXhzB9M3ecycyB1okvf8X2BAYn2yI
ACrlS3OMIVfBRXQUDOUkEXQLU/iw9zTTGWpwcebiC6zxW1J3Qyysk5CgkwKBgGDa
8tu54tf7zWU0/hzehG+49ljTPcFz1PT7sj3KTOsMEqetYEskKpyhHgm/bUS2PwAk
+Z/+JgsHtX6WFK4rBsckPzZ9oJqSZNgqH0BStl1FviSTl9GR9/yZDwv6xBQjp4Ui
PvOOu0gVxx7LDTv2jMm5Z8gWePtY/khDojCx/XUNAoGAHEZ3i2mBT0/PPTbHdrK7
UkBMEZdXgVfwWkN7pDz18hqH2e5c0jX9BREd3DA6PLs9tUkwmw+acvbt9B3/igYl
pGwHdrIntfbDeVz2EoYXp/slEHHE0g6Gws36nIIy+2NKFIh/PfFWG+P/ylMwoek5
TgEVSiKmUDWPP7G8JbTQSp4=
-----END PRIVATE KEY-----
</key>

サーバ側の起動

サーバ側では,コマンドプロンプトを管理者権限で実行し,以下のように openvpnコマンドを実行します.

> openvpn server.ovpn

クライアント側の起動

OpenVPN Connectアプリを起動し,メニューから「Import Profile from SD card」を選択,先ほどコピーした設定ファイルandroid.ovpnを開きます.する と,「Connect」ボタンが出てくるので,これをタップします.

正しく接続が確立できると,以下のような画面になります.

また,サーバ側には以下のようにPeer Connection Initiatedと出るはずです.

Tue Aug  6 16:42:55 2013 10.39.39.32:48589 [android] Peer Connection Initiated with [AF_INET]10.39.39.32:48589

その他の設定

後はインターネット接続に利用しているルータ側で, UDP 1194番ポートへの通信をサーバ側に転送するよう設定し,クライアント側の設定をそのサーバのアドレスに変更すれば,インター ネット経由のVPNを介しWindowsマシンに安全にアクセスすることができるように なるはずです. 合わせて,Dynamic DNSの設定などもおこなうと,より便利になるかもしれま せん.

参考

2013年4月21日日曜日

OpenBlocks AX3でOpenVPN Serverを作る

GbEが4ポートもあるのならばVPNルータにしたいよなぁ、ということでOpenVPN サーバにしてみる。

ネットワーク構成

今回は、二つのサブネット(10.3.93.0/24, 10.39.3.0/24)の上に VPN(10.3.9.0/24)を構築する。

各ホストのハード・ソフトは以下の通りである。
  • server(OpenBlocks AX3)
    • Kernel: 3.0.6 #1 SMP Thu Apr 18 12:26:22 JST 2013 armv7l
    • OpenVPN: 2.1.3-2+squeeze1(Debian squeezeパッケージ)
  • hatsune
    • CPU: AMD Opteron(tm) Processor 3280
    • NIC: Intel Corporation 82574L Gigabit Network Connection
    • Kernel: 3.8.7-1-ARCH #1 SMP PREEMPT Sat Apr 13 09:01:47 CEST 2013 x86_64
    • OpenVPN: 2.3.0-2(Arch Linuxパッケージ)
  • kagamine
    • CPU: AMD E-450 APU with Radeon(tm) HD Graphics
    • NIC: Atheros AR8151 v2.0 Gigabit Ethernet (rev c0)
    • Kernel: 3.8.7-1-ARCH #1 SMP PREEMPT Sat Apr 13 09:01:47 CEST 2013 x86_64
    • OpenVPN: 2.3.0-2(Arch Linuxパッケージ)

鍵ファイルの生成

まず、認証に必要な公開鍵を作成する必要がある。OpenVPN公式にて用意して いる公開鍵基盤を管理するスクリプト群としてeasy-rsaが存在するので、これ を用いる。
easy-esaの各スクリプトを実行する前に、varsファイルを元に有効期限や証明 書の情報を環境変数に設定する。初期化する場合はclean-allスクリプトの実 行が必要である(clean-allを実行するとkeysディレクトリ以下の全ての鍵ファ イルが削除されるので注意)。
その後buildスクリプトを実行しCA鍵、サーバ鍵、クライアント鍵、DHパラメー タの生成を行う。ビルド作業はウィザード形式で行われるが、基本的にvarsファ イルと引数に渡した名前を元にデフォルト値が設定されているため、特に値を 指定し直す必要がある箇所はない。また、今回は秘密鍵にパスフレーズは付与 しない。
% git clone https://github.com/OpenVPN/easy-rsa.git
% cd easy-rsa/easy-esa/2.0
% vi vars
% source ./vars
% ./clean-all
% ./build-ca
...
% ./build-key-server server
...
% ./build-key hatsune
...
% ./build-key kagamine
...
% ./build-dh
...
生成した鍵ファイルはサブディレクトリkeys以下に全て保存される。 easy-rsaの詳細に関してはdoc/README-2.0やスクリプトのソースを参照すると よい。

サーバ設定

サーバのネットワーク設定とOpenVPNの設定ファイルの作成を行う。
miku@obsax3% sudo sysctl net.ipv4.ip_forward=1
miku@obsax3% sudo ip link set eth1 up
miku@obsax3% sudo ip addr add 10.3.93.1/24 dev eth1
miku@obsax3% sudo ip link set eth2 up
miku@obsax3% sudo ip addr add 10.39.3.1/24 dev eth2
OpenVPNサーバの最小限の設定ファイルは以下のようになる。
port  1194
proto udp
dev   tun0

ca         key/ca.crt
cert       key/server.crt
key        key/server.key
dh         key/dh2048.pem

server   10.3.9.0 255.255.255.0
ifconfig 10.3.9.1 255.255.255.0

client-to-client
client-config-dir ccd/
comp-lzo

keepalive 10 60
ping-timer-rem

persist-key
persist-tun

今回はクライアント毎にIPアドレスを固定で割り当てる為、 client-config-dirにて設定したディレクトリ(ccd)にCN毎のファイル (hatsune, kagamine)を置き、それぞれにIPアドレスの割り当てオプションを 記述する。
# hatsune
ifconfig-push 10.3.9.2 10.3.9.1
# kagamine
ifconfig-push 10.3.9.3 10.3.9.1

クライアント設定

hatsune

miku@hatsune% sudo ip link set enp4s0 up
miku@hatsune% sudo ip addr add 10.3.93.2/24 dev enp4s0
miku@hatsune% sudo ip route add 10.39.3.0/24 via 10.3.93.1
クライアントhatsuneの設定ファイルは以下の通りである。
client

dev tun0
proto udp
remote 10.3.93.1 1194

persist-key
persist-tun

ca   key/ca.crt
cert key/hatsune1024.crt
key  key/hatsune1024.key

ns-cert-type server
comp-lzo

kagamine

miku@kagamine% sudo ip link set enp2s0 up
miku@kagamine% sudo ip addr add 10.39.3.2/24 dev enp2s0
miku@kagamine% sudo ip route add 10.3.93.0/24 via 10.39.3.1
クライアントkagamineの設定ファイルは以下の通り。 hatsuneの設定ファイルとの違いは、リモートのIPアドレスと証明書・秘密鍵 のファイル名である。
client

dev tun0
proto udp
remote 10.39.3.1 1194

persist-key
persist-tun

ca   key/ca.crt
cert key/kagamine.crt
key  key/kagamine.key

ns-cert-type server
#comp-lzo
fragment 1472
mssfix 1472

各ホスト毎のファイルのリスト

各ホスト毎に必要なファイルは以下の通りである。
  • hatsune
    • client.conf (クライアント設定ファイル)
    • key/ca.crt (CA証明書)
    • key/hatsune.key (クライアント秘密鍵)
    • key/hatsune.crt (クライアント証明書)
  • kagamine
    • client.conf (クライアント設定ファイル)
    • key/ca.crt (CA証明書)
    • key/kagamine.key (クライアント秘密鍵)
    • key/kagamine.crt (クライアント証明書)
  • server
    • server.conf (サーバ設定ファイル)
    • key/ca.crt (CA証明書)
    • key/server.key (サーバ秘密鍵)
    • key/server.crt (サーバ証明書)
    • key/dh2048.pem (DHパラメータ)
    • ccd/hatsune (クライアントhatsune設定ファイル)
    • ccd/kagamine (クライアントkagamine設定ファイル)

デーモンの起動

各ホスト毎に先ほど準備したファイルを転送し、OpenVPNデーモンを起動する。 それぞれInitialization Sequence Completedとなれば接続が確立できている 筈である。
miku@obsax3% sudo openvpn server.conf
Fri Apr 19 22:19:05 2013 OpenVPN 2.1.3 arm-unknown-linux-gnueabi [SSL] [LZO2] [EPOLL] [PKCS11] [MH] [PF_INET6] [eurephia] built on Feb 21 2012
Fri Apr 19 22:19:05 2013 NOTE: OpenVPN 2.1 requires '--script-security 2' or higher to call user-defined scripts or executables
Fri Apr 19 22:19:05 2013 /usr/bin/openssl-vulnkey -q -b 2048 -m <modulus omitted>
Fri Apr 19 22:19:06 2013 TUN/TAP device tun0 opened
Fri Apr 19 22:19:06 2013 /sbin/ifconfig tun0 10.3.9.1 pointopoint 10.3.9.2 mtu 1500
Fri Apr 19 22:19:06 2013 UDPv4 link local (bound): [undef]
Fri Apr 19 22:19:06 2013 UDPv4 link remote: [undef]
Fri Apr 19 22:19:06 2013 Initialization Sequence Completed
Fri Apr 19 22:19:15 2013 10.3.93.2:1194 Re-using SSL/TLS context
Fri Apr 19 22:19:15 2013 10.3.93.2:1194 LZO compression initialized
Fri Apr 19 22:19:15 2013 10.3.93.2:1194 [hatsune] Peer Connection Initiated with [AF_INET]10.3.93.2:1194
Fri Apr 19 22:19:22 2013 10.39.3.2:1194 Re-using SSL/TLS context
Fri Apr 19 22:19:22 2013 10.39.3.2:1194 LZO compression initialized
Fri Apr 19 22:19:22 2013 10.39.3.2:1194 [kagamine] Peer Connection Initiated with [AF_INET]10.39.3.2:1194

性能測定

VPNクライアント間の通信が確立できていることを確認し、性能を測定する。 クライアントの1つ(hatsune)にて性能測定用のファイルを生成し、tmpfsがマ ウントされたディレクトリに置きHTTPとSCPでダウンロード可能な状態にして おく。(tmpfs上に置くのは、ディスクアクセス速度がボトルネックとならない ようにするため)
測定用ファイルの生成は以下のように行った。
miku@hatsune% dd if=/dev/urandom of=/tmp/dummy.img bs=1M count=1000
miku@hatsune% dd if=/dev/zero of=/tmp/zero.img bs=1M count=1000
今回は、VPNを用いずに通信した場合、VPN上にてLZO圧縮を有効にし通信した 場合、VPN上にてLZO圧縮を無効にし通信した場合について比較を行う。 LZO圧縮を無効にする場合は、サーバとクライアント全ての設定ファイルから comp-lzoオプションを取り除く。
SCPの場合、以下のように/dev/nullを宛先として指定する。
miku@kagamine% scp 10.3.9.2:/tmp/dummy.img /dev/null
dummy.img                               100% 1000MB   5.0MB/s   03:22
HTTPの場合もSCPと同様に、/dev/nullを宛先として指定する。
% wget -O/dev/null http://10.3.9.2:3939/dummy.img
--2013-04-19 23:07:34--  http://10.3.9.2:3939/dummy.img
10.3.9.2:3939 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 1048576000 (1000M) [application/octet-stream]
`/dev/null' に保存中

100%[============================>] 1,048,576,000 5.01MB/s 時間 3m 21s

2013-04-19 23:10:55 (4.98 MB/s) - `/dev/null' へ保存完了 [1048576000/1048576000]
それぞれ10回づつ計測を行った場合の平均は以下のようになった。
テスト内容非VPNVPNVPN(lzo)
転送(1GB, HTTP, ZERO)112MB/s5.0MB/s7.8MB/s
転送(1GB, HTTP, RANDOM)112MB/s5.0MB/s4.9MB/s
転送(1GB, SCP, RANDOM)16.7MB/s5.1MB/s5.0MB/s
ping rtt min/avg/max/mdev0.557/0.699/0.765/0.0801.471/1.520/1.582/0.0581.525/1.558/1.638/0.031
ping(-s 1472 -M do)0.628/0.802/0.846/0.0712.119/2.180/2.276/0.0771.544/1.689/1.737/0.050
予想以上に暗号化処理の負荷が大きいようで、VPN経由だと非VPN経由の1/24ま でスループットが低下した。ファイル転送の際には、OpenBlocks上のopenvpn デーモンのCPU使用率が100%に張り付いていた。
OpenVPNは今のところ単一プロセスでのSMP対応はされていないため、2core以 上を活かしたい場合はサーバ・クライアント双方を–remote-random等で分割 し利用できるよう準備する必要がある。
似た構成のIPSecだとどの程度になるのか気になるところ。

OpenVPNのバージョンを上げてみる

試しにOpenBlocks上にてOpenVPN-2.3.1を野良ビルドし比較してみたが、今回 のテストにおける速度に関してはほとんど同じだった。
野良ビルドの手順は以下の通り。
miku@obsax3$ aptitude install liblzo2-dev libssl-dev libpam0g-dev
miku@obsax3$ wget http://swupdate.openvpn.org/community/releases/openvpn-2.3.1.tar.gz
miku@obsax3$ tar xzf openvpn-2.3.1.tar.gz
miku@obsax3$ cd openvpn-2.3.1
miku@obsax3$ ./configure --prefix=/usr/openvpn && make && sudo make install

beta版ファームウェア(wheezy)を試す

そうこうしているうちにdebian wheezyがOpenBlocks AX3に入ったようなので、 早速アップデートして比較してみる。wheezyでのカーネルのバージョンは3.2.36、OpenVPNのバージョンは2.2.1-8となっ ている。
テスト内容非VPNVPNVPN(lzo)
転送(1GB, HTTP, ZERO)112MB/s4.7MB/s7.6MB/s
転送(1GB, HTTP, RANDOM)112MB/s4.7MB/s4.7MB/s
転送(1GB, SCP, RANDOM)16.4MB/s4.7MB/s4.7MB/s
ping rtt min/avg/max/mdev1.096/1.596/1.767/0.2642.035/2.553/2.693/0.2022.052/2.589/2.863/0.208
ping(-s 1472 -M do)1.203/1.738/1.828/0.1822.694/3.109/3.285/0.2132.805/2.846/3.110/0.107
一気に速くなるのかなぁとわくわくしながら実行したのだが、結果は地味に遅くなってしまった。OpenVPN経由でない場合も遅くなっているようなので、 原因はOpenVPN以外(kernel側?)に存在する可能性が高そうである。

その他

kagamineのAtheros AR8151が、同時に蟹wlanを利用している状態である程度通 信すると突然死する謎の症状に悩まされる事があった。wlanを止めると死なな い。原因は不明。

2013年4月2日火曜日

feel6でIPv6(on Arch Linux)

プロバイダがPPPoEな固定IPv6サービスを始める気配がまったく無いので、久 しぶりにfeel6(http://start.feel6.jp/)を使ってみる。 ホスト環境はいつも通りArch Linux。

dtcpclientのビルド

dtcpclientのソースをダウンロードしてきてビルドする。FreeBSD用に書かれ ておりそのままではビルドできないため、オリジナルのMakefileを参考に直接 gccを叩く。

また、libbsdがインストールされていない場合は先にインストールしておく。

% wget http://www.imasy.or.jp/~ume/ipv6/dtcpclient-20060111.tar.gz
% tar xzf dtcpclient-20060111.tar.gz
% cd dtcpclient-20060111
% gcc -lbsd -lcrypto -Wall -DPREFIX=\"/usr/dtcp\" dtcpclient.c -o dtcpclient
% ./dtcpclient
usage: dtcpclient [-dDhlnU] [-b udpport] [-B naptport] [-e nickname]
[-f pidfile] [-m mtu] [-p port] [-s script] [-t tuntype] [-u username] server

起動

とりあえずfeel6にDTCPでログインできるか試してみる。 今回はNAT下で利用するため、-nオプションを付ける。-lは切断時の自動再接 続、-dはデバッグモードとなる。

% ./dtcpclient -d -l -n -t network -u ユーザ名 dtcp.feel6.jp 
no authinfo file found
password for hachune:
logging in to dtcp.feel6.jp port 20200
>>> +OK xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx FBDC TunnelBroker (version
0.2) Ready. <578926>:4096
<<< tunnel hachune yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy network
>>> +OK 118.1.71.38 43.244.255.37 2001:03e0:0988::/48
sleep(60)
<<< ping
>>> +OK pong
sleep(60)

ネットワーク設定スクリプトを作成

ログインに成功しアドレスが取得できたことが確認できたので、早速ネットワー ク設定スクリプトを書きなおす。dtcpclientの-sオプションに渡すスクリプト は、ログイン完了時と切断時に引数に以下のように渡され起動されるので、そ れに合わせて記述する。

up dtcp.feel6.jp 10.39.39.37 network 118.1.71.38 43.244.255.37 2001:03e0:0988::/48

LinuxにてIPv6 over IPv4なトンネルを利用する場合は、sitインターフェース を利用する。

#!/bin/sh

DEV=sit0
STATUS=${1}
SERVER=${2}
NLOCAL=${3}
MODE=${4}
LOCAL=${5}
REMOTE=${6}
V6PREFIX=${7}

case ${STATUS} in
up)
        ip link add link ${DEV} type sit
        ip link set dev ${DEV} up
        ip address add `echo ${V6PREFIX} | sed -e 's|/48||'`1/64 dev ${DEV}
        ip -6 route add default via ::${REMOTE} dev ${DEV}
        ;;
down)
        ip -6 route delete default
        ip link delete ${DEV}
        ;;
esac

確認

最後に、通信が確立していることを確認する。プロバイダのDNSサーバを利用 している場合、AAAAフィルタが有効になっていてv6アドレスが引けないことが あるので注意する。

% ping6 -c 4 ipv6.google.com
PING ipv6.google.com(2404:6800:4004:802::1012) 56 data bytes
64 bytes from 2404:6800:4004:802::1012: icmp_seq=1 ttl=53 time=17.6 ms
64 bytes from 2404:6800:4004:802::1012: icmp_seq=2 ttl=53 time=29.9 ms
64 bytes from 2404:6800:4004:802::1012: icmp_seq=3 ttl=53 time=15.5 ms
64 bytes from 2404:6800:4004:802::1012: icmp_seq=4 ttl=53 time=15.8 ms

--- ipv6.google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 15.518/19.732/29.904/5.929 ms

(参考)AAAAフィルタ

AAAAフィルタが存在する場合

miku@hachune% dig @10.39.39.1 AAAA www.kame.net

; <<>> DiG 9.9.2-P2 <<>> @10.39.39.1 AAAA www.kame.net
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58213
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;www.kame.net.                  IN      AAAA

;; ANSWER SECTION:
www.kame.net.           71617   IN      CNAME   orange.kame.net.

;; Query time: 16 msec
;; SERVER: 10.39.39.1#53(10.39.39.1)
;; WHEN: Tue Apr  2 11:53:43 2013
;; MSG SIZE  rcvd: 62

AAAAフィルタが存在しない場合

miku@hachune% dig @8.8.8.8 AAAA www.kame.net

; <<>> DiG 9.9.2-P2 <<>> @8.8.8.8 AAAA www.kame.net
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47873
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;www.kame.net.                  IN      AAAA

;; ANSWER SECTION:
www.kame.net.           21599   IN      CNAME   orange.kame.net.
orange.kame.net.        21599   IN      AAAA    2001:200:dff:fff1:216:3eff:feb1:44d7

;; Query time: 275 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Tue Apr  2 11:53:53 2013
;; MSG SIZE  rcvd: 90

2013年3月23日土曜日

NetBSD/RPiで遊ぶ(SDカードへの書き込み回数を気にしつつ)

流行りのRaspberry PiでNetBSDが動くようになったと聞いて、早速遊んでみる。 今回は、SDカードをread onlyにし、USBメモリに動的なファイルを書き出すこ とで、書き込み制限回数超過による不具合が起きにくく(起きても簡単に修復 可能)、かつSDカード側の更新が容易にできるようなシステムを目指す。

用意しておくもの

  • Raspberry Pi
  • Micro-USBケーブル(電源用)
  • キーボード, HDMI対応ディスプレイ, HDMIケーブル(可能ならRS-232C経由 でもOK)
  • SDカード(rootfs用、1GBで十分)
  • USBメモリ(unionfs用)
  • NetBSD環境(VMでも可)
  • はちゅねさん(監視役)

NetBSD/RPiのイメージを入手

NetBSD/rpiのHEADのイメージを入手する。もちろん自分でソースからbuild.sh してもよい。 今回は、てっとり早く済ませる為にNetBSD-dailyミラーから入手。 (NetBSD-daily/HEAD/日付/evbarm/binary/gzimg/rpi.img.gz) ftp://ftp.jaist.ac.jp/pub/NetBSD-daily/HEAD/201303201620Z/evbarm/binary/gzimg/rpi.img.gz

イメージの編集

ダウンロードしたイメージファイルを展開しSDカードに書き込み、NetBSD環境 にて編集する。今回は、SDカードとUSBメモリを直接NetBSDがインストールさ れている仮想マシン(KVM)に接続し編集を行う。それぞれの環境上で各デバイ スは以下のようになっているものとする。
デバイス用途ホストゲスト(NetBSD)RPi(NetBSD)
SDカードroot/dev/mmcblk0/dev/ld1/dev/ld0
USBメモリunion/dev/sdb/dev/ld2/dev/sd0
miku@hachune% gzip -cd rpi.img.gz | sudo dd of=/dev/mmcblk0 bs=1M
miku@hachune% sudo qemu-system-x86_64 -enable-kvm -m 512 \
> -drive file=/dev/mmcblk0,if=virtio \
> -drive file=/dev/sdc,if=virtio \
> -serial pty -nographic
まずはRasberry Pi用イメージ上のルートファイルシステムとなるファイルシ ステムを/mnt以下にマウントする。その中にunionfsの上のレイヤーとなるUSB メモリのマウントポイント/unionを作成しマウントする。また、/union以下に 各ディレクトリとのunionディレクトリを作成する。
nbsd# mount /dev/ld1a /mnt
nbsd# mkdir /mnt/union
nbsd# mount /dev/ld2a /mnt/union
nbsd# mkdir /mnt/union/usr /mnt/union/var \
> /mnt/union/etc /mnt/union/root /mnt/union/home
/mnt/etc/rc.confを編集する。今回ネットワークはdhcpcd任せとするが、もち ろん静的設定を行っても良い。また、swap領域をSDカード上に作成しては書き 込み回数を抑える事ができないためsavecoreと合わせて無効にしておく。
更に、mountcritlocalの時点で/varが書き込み可能な状態でマウントされるよ う、critical_filesystems_localを設定しておく。(これを行なっていないと、 /varに書き込めずsyslog等を正しく実行できない)
if [ -r /etc/defaults/rc.conf ]; then
        . /etc/defaults/rc.conf
fi
rc_configured=YES
hostname=negi.k.hachune.org
sshd=YES
dhcpcd=YES
wscons=YES
no_swap=YES
savecore=NO
critical_filesystems_local="/union /etc /var"
/etc/fstabを編集する。ここでは、swap領域のコメントアウトと/tmpのtmpfs の追加、unionfsの設定を行なう。
/dev/ld0a       /               ffs     rw,log,noatime  1 1
# /dev/ld0b       none            swap    sw      0 0
/dev/ld0e       /boot           msdos   rw      1 1
kernfs          /kern           kernfs  rw
ptyfs           /dev/pts        ptyfs   rw
procfs          /proc           procfs  rw
tmpfs           /tmp            tmpfs   rw,-m=1777,-s=67608576

/dev/sd0e       /union          ffs     rw,log,noatime  1 1
/union/usr      /usr            union   rw
/union/var      /var            union   rw
/union/etc      /etc            union   rw
/union/root     /root           union   rw
/union/home     /home           union   rw
最後に、ssh経由でログインできるようホスト側のパスワードファイル等をコ ピーし、ホームディレクトリを作成しておく。
nbsd# cp /etc/group /etc/passwd /etc/master.passwd /mnt/etc
nbsd# mkdir /mnt/home

カーネルのrebuild

残念ながら現在のRPIのカーネルはunionfsがサポートされていない(コメント アウトされている)ようで、そのままで起動するとunion mountに失敗し悲しい 状態に陥る。仕方ないのでカーネルだけ設定を変えてビルドしてみる。ついで に使いそうな機能も有効に。
通常のRPIカーネルと今回作成するNEGIPIカーネルの設定のdiffは以下の通り。
miku@hatsune% diff sys/arch/evbarm/conf/{RPI,NEGIPI}
43c43
< #file-system  UNION           # union file system
---
> file-system   UNION           # union file system
252c252
< #pseudo-device        carp                    # Common Address Redundancy Protocol
---
> pseudo-device carp                    # Common Address Redundancy
  Protocol
256,257c256,257
< #pseudo-device        ppp                     # Point-to-Point
  Protocol
< #pseudo-device        pppoe                   # PPP over Ethernet
  (RFC 2516)
---
> pseudo-device ppp                     # Point-to-Point Protocol
> pseudo-device pppoe                   # PPP over Ethernet (RFC 2516)
262,263c262,263
< #pseudo-device        tap                     # virtual Ethernet
< #pseudo-device        tun                     # network tunneling over tty
---
> pseudo-device tap                     # virtual Ethernet
> pseudo-device tun                     # network tunneling over tty
後はいつも通りbuild.sh。(クロスコンパイルがLinux上でも簡単にできるのは 非常にうれしい)
miku@hatsune% ./build.sh -O ../objarm -m evbarm -N0 -j9 -U tools kernel=NEGIPI
...
===> Kernels built from NEGIPI:
  /home/miku/netbsd/src/../objarm/sys/arch/evbarm/compile/NEGIPI/netbsd
===> build.sh ended:      Sat Mar 23 04:28:47 JST 2013
===> Summary of results:
         build.sh command:    ./build.sh -O ../objarm -m evbarm -N0 -j5 -U kernel=NEGIPI
         build.sh started:    Sat Mar 23 04:27:45 JST 2013
         NetBSD version:      6.99.17
         MACHINE:             evbarm
         MACHINE_ARCH:        arm
         Build platform:      Linux 3.8.4-1-ARCH-amd64 x86_64
         HOST_SH:             /bin/sh
         MAKECONF file:       /etc/mk.conf (File not found)
         TOOLDIR path:        /home/miku/netbsd/src/../objarm/tooldir.Linux-3.8.4-1-ARCH-amd64-x86_64
         DESTDIR path:        /home/miku/netbsd/src/../objarm/destdir.evbarm
         RELEASEDIR path:     /home/miku/netbsd/src/../objarm/releasedir
         Updated makewrapper: /home/miku/netbsd/src/../objarm/tooldir.Linux-3.8.4-1-ARCH-amd64-x86_64/bin/nbmake-evbarm
         Building kernel without building new tools
         Building kernel:     NEGIPI
         Build directory:     /home/miku/netbsd/src/../objarm/sys/arch/evbarm/compile/NEGIPI
         Kernels built from NEGIPI:
          /home/miku/netbsd/src/../objarm/sys/arch/evbarm/compile/NEGIPI/netbsd
         build.sh ended:      Sat Mar 23 04:28:47 JST 2013
===> .
miku@hatsune% ls -l ../objarm/sys/arch/evbarm/compile/NEGIPI/netbsd.bin
-rwxr-xr-x 1 miku miku 4637568  3月 23 04:28 ../objarm/sys/arch/evbarm/compile/NEGIPI/netbsd.bin
完成したカーネル(netbsdではなくnetbsd.bin)をSDカードのFAT領域に kernel.imgとしてコピーしておく。

起動

後はRaspberry PiにWrite protectスイッチをONにしたSDカードとUSBメモリを 挿し起動するだけ。所々カーネルがWARNINGを吐いているが、とりあえずは動 いているようだ。ssh経由だと結構サクサク動いているように感じる。

ハマりどころ

  • disklabelの扱いがamd64とevbarmで若干異なる
  • postfixが起動できない(unionfsでfcntlがコケる?, 未解決)
postfix/master[1087]: fatal: open lock file
/var/db/postfix/master.lock: cannot create file exclusively: Permission denied
negi# touch /var/db/postfix/master.lock
negi# chown postfix:postfix /var/db/postfix/master.lock
postfix/postfix-script: warning: not owned by postfix: /var/db/postfix
negi# chown postfix:postfix /var/db/postfix
postfix/master[1678]: fatal: fcntl: set non-blocking flag on: Operation not supported

dmesg

Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 6.99.17 (NEGIPI) #2: Sat Mar 23 04:28:45 JST 2013
        miku@hatsune.k.hachune.org:/home/miku/netbsd/objarm/sys/arch/evbarm/compile/NEGIPI
total memory = 192 MB
avail memory = 183 MB
timecounter: Timecounters tick every 10.000 msec
cprng kernel: WARNING insufficient entropy at creation.
mainbus0 (root)
cpu0 at mainbus0 core 0: 700 MHz ARM1176JZ-S r0p7 (ARM11J V6ZK core)
cpu0: DC enabled IC enabled WB enabled LABT
cpu0: isar: [0]=0x140011 [1]=0x12002111 [2]=0x11231121 [3]=0x1102131, [4]=0x1141, [5]=0
cpu0: mmfr: [0]=0x1130003 [1]=0x10030302 [2]=0x1222100 [3]=0
cpu0: pfr: [0]=0x111 [1]=0x11
cpu0: 16KB/32B 4-way L1 Instruction cache
cpu0: 16KB/32B 4-way write-back-locking-C L1 Data cache
vfp0 at cpu0: VFP11
obio0 at mainbus0
bcmicu0 at obio0
bcmmbox0 at obio0: VC mailbox
vcmbox0 at bcmmbox0
bcmtmr0 at obio0 intr 3: VC System Timer
bcmpm0 at obio0: Power management, Reset and Watchdog controller
bcmrng0 at obio0: RNG
plcom0 at obio0 intr 57
plcom0: txfifo disabled
plcom0: console
genfb0 at obio0no data for est. mode 640x480x67
: switching to framebuffer console
genfb0: framebuffer at 0xc006000, size 1920x1200, depth 32, stride 7680
wsdisplay0 at genfb0 kbdmux 1: console (default, vt100 emulation)
wsmux1: connecting to wsdisplay0
wsdisplay0: screen 1-3 added (default, vt100 emulation)
sdhc0 at obio0 intr 62: SDHC controller
sdhc0: interrupting on intr 62
sdhc0: SD Host Specification 3.0, rev.153
sdmmc0 at sdhc0 slot 0
dotg0 at obio0 intr 9: USB controller
bcmspi0 at obio0 intr 54: SPI
spi0 at bcmspi0: SPI bus
bsciic0 at obio0 intr 53: BSC0
iic0 at bsciic0: I2C bus
bsciic1 at obio0 intr 53: BSC1
iic1 at bsciic1: I2C bus
usb0 at dotg0: USB revision 2.0
timecounter: Timecounter "clockinterrupt" frequency 100 Hz quality 0
timecounter: Timecounter "bcmtmr0" frequency 1000000 Hz quality 100
WARNING: module error: vfs load failed for `usbverbose', error 45
uhub0 at usb0WARNING: module error: vfs load failed for `usbverbose', error 45
: vendor 0x0000 DWC OTG root hub, class 9/0, rev 2.00/1.00, addr 1
uhub0: 1 port with 1 removable, self powered
ld0 at sdmmc0: <0x02:0x544d:SD04G:0x38:0xb0f6cf37:0x088>
ld0: 3780 MB, 1920 cyl, 64 head, 63 sec, 512 bytes/sect x 7741440 sectors
ld0: 4-bit width, bus clock 50.000 MHz
WARNING: module error: vfs load failed for `usbverbose', error 45
WARNING: module error: vfs load failed for `usbverbose', error 45
uhub1 at uhub0 port 1WARNING: module error: vfs load failed for `usbverbose', error 45
WARNING: module error: vfs load failed for `usbverbose', error 45
: vendor 0x0424 product 0x9512, class 9/0, rev 2.00/2.00, addr 2
uhub1: multiple transaction translators
uhub1: 3 ports with 2 removable, self powered
WARNING: module error: vfs load failed for `usbverbose', error 45
WARNING: module error: vfs load failed for `usbverbose', error 45
usmsc0 at uhub1 port 1
WARNING: module error: vfs load failed for `usbverbose', error 45
WARNING: module error: vfs load failed for `usbverbose', error 45
usmsc0: vendor 0x0424 product 0xec00, rev 2.00/2.00, addr 3
usmsc0:  Ethernet address b8:27:eb:a1:40:7b
ukphy0 at usmsc0 phy 1WARNING: module error: vfs load failed for `miiverbose', error 45
: OUI 0x00800f, model 0x000c, rev. 3
ukphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
WARNING: module error: vfs load failed for `usbverbose', error 45
uhidev0 at uhub1 port 2 configuration 1 interface 0
WARNING: module error: vfs load failed for `usbverbose', error 45
uhidev0: vendor 0x04d9 USB Keyboard, rev 1.10/3.90, addr 4, iclass 3/1
ukbd0 at uhidev0: 8 modifier keys, 6 key codes
wskbd0 at ukbd0: console keyboard, using wsdisplay0
uhidev1 at uhub1 port 2 configuration 1 interface 1
WARNING: module error: vfs load failed for `usbverbose', error 45
uhidev1: vendor 0x04d9 USB Keyboard, rev 1.10/3.90, addr 4, iclass 3/1
uhidev1: 2 report ids
uhid0 at uhidev1 reportid 1: input=6, output=0, feature=0
uhid1 at uhidev1 reportid 2: input=1, output=0, feature=0
umass0 at uhub1 port 3 configuration 1 interface 0
umass0: JetFlash Mass Storage Device, rev 2.00/1.00, addr 5
umass0: using SCSI over Bulk-Only
scsibus0 at umass0: 2 targets, 1 lun per target
sd0 at scsibus0 target 0 lun 0: <JetFlash, Transcend 4GB, 8.07> disk removable
sd0: fabricating a geometry
sd0: 3830 MB, 3830 cyl, 64 head, 32 sec, 512 bytes/sect x 7843840 sectors
boot device: ld0
root on ld0a dumps on ld0b
mountroot: trying nfs...
mountroot: trying msdos...
mountroot: trying ext2fs...
mountroot: trying ffs...
root file system type: ffs
WARNING: no TOD clock present
WARNING: using filesystem time
WARNING: CHECK AND RESET THE DATE!
warning: no /dev/console
init: copying out path `/sbin/init' 11
sd0: fabricating a geometry
WARNING: module error: vfs load failed for `compat', error 78
WARNING: module error: vfs load failed for `compat', error 78
WARNING: module error: vfs load failed for `compat', error 78
WARNING: module error: vfs load failed for `compat', error 78
WARNING: module error: vfs load failed for `compat', error 78
WARNING: module error: vfs load failed for `compat', error 78
WARNING: module error: vfs load failed for `com', error 78
WARNING: module error: vfs load failed for `com', error 78
nd6_dad_timer: called with non-tentative address 2001:c90:8405:1f9c:ba27:ebff:fea1:407b(usmsc0)
wsdisplay0: screen 4 added (default, vt100 emulation)

2013年3月21日木曜日

OpenBlocks AX3上のLXC用の最小構成Arch Linux rootfsを作る

前回構築したOpenBlocks用Arch Linuxコンテナには 不要なパッケージも多く含まれている。そこで、作成したコンテナを利用し最小構成 (systemdとsshdが上がりログインができる状態)のrootfs tarballを作成する。

基本的な構築方法は x86_64環境のArch LinuxでLXCコンテナ用rootfsを作成した時と同じであるが、 今回はpacstrap時にbaseを丸ごと入れるのではなく、systemdとopensshのみ導入する。

miku@arch% su
root@arch# pacman -S arch-install-scripts
root@arch# mkdir rootfs
root@arch# pacstrap -d rootfs pacman systemd openssh bash
root@arch# chroot rootfs /bin/bash
root@arch(chroot)# ln -s /usr/lib/systemd/system/sshd.service \
> /etc/systemd/system/multi-user.target.wants/sshd.service
root@arch(chroot)# ln -s /usr/lib/systemd/system/sshdgenkeys.service \
> /etc/systemd/system/multi-user.target.wants/sshdgenkeys.service
root@arch(chroot)# pacman -Sc
root@arch(chroot)# rm /var/cache/pacman/pkg/*
root@arch(chroot)# mkdir /dev/pts
root@arch(chroot)# passwd
root@arch(chroot)# groupadd -g 3939 miku
root@arch(chroot)# useradd -g miku -u 3939 -s /bin/bash -m miku
root@arch(chroot)# passwd miku
root@arch(chroot)# exit
root@arch# rm rootfs/root/.bash_history
root@arch# tar cJpf rootfs.tar.gz rootfs

今回作成した最小構成環境が正しく動作するか試したところ、/dev/consoleが 存在しないとのエラーが発生する。

miku@obs$ sudo /usr/miku/bin/lxc-start -n test -- /usr/lib/systemd/systemd
lxc-start: No such file or directory - stat(/proc/26644/root/dev//console)

これも/dev/ptsが存在しない問題と似た問題のようなので、/dev/consoleを作 成しておく。

root@arch(chroot)# mknod -m 600 mini/rootfs/dev/console c 5 1

LXC側で必要としている/dev/tty{1..4}等はLXC側で自動作成しているようなの で、LXC側で必要であるのに/dev/consoleを自動作成できていないのが原因だ と考えられる。

/dev/console作成後は想定通り動作するようになった。

miku@obs% sudo /usr/miku/bin/lxc-start -n test -- /usr/lib/systemd/systemd
<30>systemd[1]: Smack is not enabled in the kernel, not loading access rules.

今回作成したOpenBlocks用の最小構成のrootfs tarballは、以下からダウンロードできるよ うにしておいたので、試してみたい方はどうぞ。
http://repo.hachune.net/Linux/ArchLinux/rootfs/armv7h/2013.03.21/obs_rootfs.tar.xz

OpenBlocks AX3上のLXC内のArch Linuxにmikutter環境を構築

前回作成したOpenBlocks AX3上のLXC内のArch Linux環境にmikutterをインストールし動かしてみる。

Arch Linuxでのmikutterは、Arch User Repository(AUR)にPKGBUILDが存在するため、 環境構築が他ディストリに比べ容易である。 AURのPKGBUILDを利用する場合は、pacmanのフロントエンドyaourtが便利であ るので、それをインストールする。また、一般ユーザでPKGBUILDを元にパッケー ジを作成する場合は、fakerootコマンドが必要であるので、それも合わせてイ ンストールする。
miku@arch% sudo pacman -S yaourt fakeroot
mikutterはアーキテクチャ非依存であるハズなので、サポートアーキテクチャに i686とx86_64と指定されている部分をanyに変更する。
miku@arch% yaourt -S mikutter
PKGBUILDの
arch=('i686' 'x86_64')
を
arch=('any')
に修正しビルド、インストールする。
OpenBlocksには直接ディスプレイを接続することができないため、SSHのX forwarding経由にてmikutterを実行する。 /etc/ssh/sshd_configのX11Forwardingの項を有効にする。
X11Forwarding yes
設定を反映させるため、sshdを再起動する。
miku@arch% sudo systemctl restart sshd.service
また、LXCはIP Masqueradeの内側となるため、SSH Proxyを利用する。 OpenBlocksのIPアドレスは10.39.39.39/24、その中のコンテナのIPアドレスは 10.3.93.11/24であるので、手元の環境の~/.ssh/configに以下のように追記し ておく。
Host obs
HostName 10.39.39.39

Host obs.arch
HostName 10.3.93.11
ProxyCommand ssh -W %h:%p obs
これにより、"ssh obs.arch"だけでobsのsshdを経由しobs.archに接続可能に なる。
miku@hachune% ssh -X obs.arch
X11 forwarding request failed on channel 0
Last login: Wed Mar 20 16:41:43 2013 from 10.3.93.1
どうやら、X11 forwardingに失敗しているようだ。xauthが存在していないの が原因のようなので、xorg-xauthパッケージをインストールする。
miku@arch% yaourt -S xorg-xauth
miku@arch% sudo systemctl restart sshd.service
ようやくX forwardingができたものの、フォントがないため非常に残念なこと になる。
miku@hachune% ssh -X obs.arch
Last login: Wed Mar 20 17:06:50 2013 from 10.3.93.1
miku@arch% mikutter

VL Gothicフォントを入れてやり直し。
miku@arch% yaourt -S ttf-vlgothic
今度は無事mikutterが起動し利用できる状態になった。RUBY_PLATFORMがarmv7l-linux-eabiとなっていることが確認できる。

SSH Proxy経由のX forwardingであるため、かなり残念な表示速度と操作性と なってしまっている。ただ、CPU負荷は500アカウント程度フォローしているホー ムタイムラインのUserStream有効の状態で5%〜30%程度に落ち着いているため、 CPUの性能不足という事は無いようだ。また、Disk I/Oも余裕があるように見 受けられる。
やはりOpenBlocks上でmikutterを利用する場合は、mikutterのデーモンモード を利用するのが無難かと思う。

OpenBlocks AX3上のLXCにArch Linuxを導入

LXCはi386/amd64環境以外でも利用できる。ここでは、ARMv7なマイクロサーバ OpenBlocks AX3にインストールされているDebianにLXCを導入し、その中にArch Linuxをインストールする。ホストとコンテナの論理的な構成(ネットワーク等)は 前回の構成と同じになるよう構築する。 前回とはディストリビューションは異なるものの、設定ファイルの扱い等が少々異なる以外基本はほぼ同じであ る。

ネットワーク設定

ホスト側ブリッジインターフェースとIP Masqueradeは、先に設定したものと 全く同じになるよう設定を行う。当然ながらこの設定は再起動等で消えてしま うため、恒久化する必要があるのであれば/etc/network/interfaces等に記述 しておく。

miku@obs% sudo ip link add br0 type bridge
miku@obs% sudo ip link set br0 up
miku@obs% sudo ip address add 10.3.93.1/24 dev br0
miku@obs% sudo sysctl net.ipv4.ip_forward=1
miku@obs% sudo iptables -t nat -A POSTROUTING \
> -s 10.3.93.0/24 -o eth0 -j MASQUERADE

bootstrap

Arch Linuxのarm版は各armアーキテクチャ毎にrootfsのtarballが用意されて いるが、残念ながらOpenBlocks AX6用のものは用意されていない。そこで、最 も近いと思われるものを http://archlinuxarm.org/platforms/armv7 から選 び試す。ここでは、 http://archlinuxarm.org/os/ArchLinuxARM-cubox-latest.tar.gz を利用する。

まずはlxcパッケージを導入しcgroupをmountする。また、入手したtarballを 展開し、その中にchrootして作業できるようsysfsやproc等をmountする。

miku@obs% sudo aptitude install lxc
miku@obs% sudo mount -t cgroup cgroup /cgroup
miku@obs% sudo mkdir -p /var/lib/lxc/arch/rootfs
miku@obs% sudo tar xpf ArchLinuxARM-cubox-latest.tar.gz \
> -C /var/lib/lxc/arch/rootfs/
miku@obs% sudo mount -t proc proc /var/lib/lxc/arch/rootfs/proc
miku@obs% sudo mount -t sysfs sysfs /var/lib/lxc/arch/rootfs/sys
miku@obs% sudo mount -t devtmpfs devtmpfs /var/lib/lxc/arch/rootfs/dev
miku@obs% sudo mkdir /dev/pts
miku@obs% sudo mount -t devpts devpts /var/lib/lxc/arch/rootfs/dev/pts

コンテナ内の設定

展開したシステムディレクトリにchrootし環境設定を行う。 ここでは、パッケージの更新とssh鍵の作成、LXC環境に必要ないデーモンの無 効化を行なう。

miku@obs% sudo chroot /var/lib/lxc/arch/rootfs /bin/bash
root@obs(chroot)# echo nameserver 10.39.39.1 > /etc/resolv.conf
root@obs(chroot)# pacman -Syu
root@obs(chroot)# find /etc -name "*.pacnew" -exec sh \
> -c 'mv "{}" "`basename {} .pacnew`"' \;
root@obs(chroot)# rm /etc/ssh/ssh_host_*
root@obs(chroot)# ssh-keygen -A
root@obs(chroot)# cd /etc/systemd/system/multi-user.target.wants
root@obs(chroot)# rm {openntpd,netcfg\@ethernet-eth0}.service
root@obs(chroot)# mkdir /dev/pts

最後にユーザアカウントを設定しておく。

root@obs(chroot)# passwd
root@obs(chroot)# groupadd -g 3939 miku
root@obs(chroot)# useradd -g miku -u 3939 -s /bin/bash -m miku
root@obs(chroot)# passwd miku
root@obs(chroot)# exit

コンテナ設定ファイルの作成

今回利用するコンテナ設定ファイルは、 前回Arch Linux上のLXCコンテナ内にArch Linux環境を構築した際に作成したもの と全く同じものを利用する。

コンテナの起動

早速起動してみたところ、カーネルバージョンが3.0.6、lxc-0.7.2-1のホスト 環境ではcgroupディレクトリのrenameに失敗し、コンテナが起動できない問題 が発生した。

miku@obs% uname -a
Linux obsax3 3.0.6 #1 SMP Thu Mar 7 19:14:19 JST 2013 armv7l GNU/Linux
miku@obs% sudo lxc-start -n arch -- /usr/lib/systemd/systemd
lxc-start: No such file or directory - failed to rename cgroup
/cgroup/7787->/cgroup/arch
lxc-start: failed to spawn 'arch'
lxc-start: No such file or directory - failed to remove cgroup '/cgroup/arch'

LXCは既に新しいバージョンが出ているため、最新版を野良ビルドし試す。 今回は、 LXC-0.9.0-RC1(http://lxc.sourceforge.net/download/lxc/lxc-0.9.0.rc1.tar.gz) で試した。このソースのビルドには、gccとmake等の他、libcap-devが必要な ようだ。 設定ファイルが置かれるディレクトリは、システムにインストールされている lxcパッケージと同じところを参照するよう、–with-config-pathオプション を設定しておく。

miku@obs% wget http://lxc.sourceforge.net/download/lxc/lxc-0.9.0.rc1.tar.gz
miku@obs% tar xf lxc-0.9.0.rc1.tar.gz -C /home/miku/src
miku@obs% cd /home/miku/src/lxc-0.9.0.rc1
miku@obs% ./configure --prefix=/usr/miku --with-config-path=/var/lib/lxc
miku@obs% make && sudo make install

今回ビルドしたlxcコマンド群を利用し再度コンテナを起動。

miku@obs% sudo /usr/miku/bin/lxc-start -n arch -- /usr/lib/systemd/systemd
<30>systemd[1]: Smack is not enabled in the kernel, not loading access rules.

カーネルオプションの不足による警告メッセージが現れているが、とりあえず ssh経由でコンテナ内にアクセスすることができた。

miku@obs$ ssh 10.3.93.11                                                                            
miku@10.3.93.11's password: 
Last login: Tue Mar 19 15:41:07 2013 from 10.3.93.1
[miku@alarmcubox ~]$ telnet mikutter.hachune.net 80
Trying 115.177.182.220...
Connected to mikutter.hachune.net.
Escape character is '^]'.

次回は、この環境にてmikutterを動かしてみようと思う。

LXCにArchLinuxを入れる

Arch Linux上のLXCにArch Linuxを入れ、systemdとsshが正しく動作するか試し てみる。 大まかな流れは、
  1. ネットワーク設定
    • ブリッジインターフェースの作成
    • IP Masqueradeの設定
  2. コンテナの作成
    • コンテナ内システムのbootstrap
    • コンテナ内の設定
    • コンテナ設定ファイルの作成
  3. コンテナの起動と終了
となる。
完成時のネットワーク構成は、以下の図のようになる。

ホスト側ブリッジインターフェースの設定

LXCのvethネットワークを束ねるブリッジインターフェース(br0)を作成する。 ブリッジインターフェースの作成とアドレスの割当にはipコマンドを用いる。
miku@host% sudo ip link add br0 type bridge
miku@host% sudo ip link set br0 up
miku@host% sudo ip address add 10.3.93.1/24 dev br0
毎度手動でインターフェース設定を行うのは面倒なので、netcfgの設定を行っ ておく。まずは、/etc/network.d/examples/bridgeを参考に /etc/network.d/bridge0を記述する。
INTERFACE="br0"
CONNECTION="bridge"
DESCRIPTION="Hatsune Bridge connection"
BRIDGE_INTERFACES=""
IP="static"
ADDR="10.3.93.1"
NETMASK="24"
最後に、systemctlでnetcfg@bridge0がシステム起動時に実行されるよう設定 する。
miku@host% sudo systemctl enable netcfg@bridge0.service
一時的に手動でnetcfgを起動することもできる。
miku@host% sudo systemctl start netcfg@bridge0.service

IP Masqueradeの設定

LXCコンテナ側から外部ネットワークにアクセスできるよう、IP Masqueradeを 設定する。まず、IP Forwardingを有効である必要があるため、 /etc/sysctl.confのnet.ipv4.ip_forwardを1に設定する。
net.ipv4.ip_forward = 1
手動で一時的に有効にするには、"sudo sysctl net.ipv4.ip_forward=1"でよ い。
次に、iptablesにて10.3.93.0/24から外部ネットワークに接続されたネットワー クインターフェース(enp2s0)へのIP Masqueradeを設定する。
miku@host% sudo iptables -t nat -A POSTROUTING \
> -s 10.3.93.0/24 -o enp2s0 -j MASQUERADE
この時点のiptablesの状態をiptables-saveコマンドでdumpし、それをそのま まiptablesの恒久的なルールとして利用する。 このルールファイルを置くべきパスは、/etc/conf.d/iptablesに "IPTABLES_CONF=/etc/iptables/iptables.rules"として定義されている。
miku@host% sudo sh -c 'iptables-save > /etc/iptables/iptables.rules'
最後に、システム起動時にこのルールが適用されるようにsystemdを設定する。
miku@host% sudo systemctl enable iptables.service

bootstrap

Arch Linuxのrootfsの構築は、Arch LinuxのLiveCDからインストールする際と 同様にarch-install-scriptsのpacstrapコマンドを用いる。合わせて、lxcパッ ケージとiproute2パッケージを導入しておく。
miku@host% sudo pacman -S lxc arch-install-scripts iproute2
/lxc/arch/rootfs以下に環境を作成する場合の操作は以下のようになる。 Arch LinuxのLXCテンプレートも存在するのだが、Arch Linux側の仕様がよく 変わり使い物にならない(すぐ使い物にならなくなる)ため、pacstrapを直接利 用する。
miku@host% sudo mkdir -m 0755 /var/lib/lxc/arch/rootfs
miku@host% sudo pacstrap -i -d /var/lib/lxc/arch/rootfs base openssh
baseパッケージグループを導入する際には、カーネルパッケージ等LXCコンテ ナ内に必要ないパッケージも多数含まれるので、必要に応じて除外する。
:: There are 52 members in group base:
:: Repository core
   1) bash  2) bzip2  3) coreutils  4) cronie  5) cryptsetup  6) device-mapper  7) dhcpcd  8) diffutils
   9) e2fsprogs  10) file  11) filesystem  12) findutils  13) gawk  14) gcc-libs  15) gettext  16) glibc
   17) grep  18) gzip  19) heirloom-mailx  20) inetutils  21) iproute2  22) iputils  23) jfsutils  24) less
   25) licenses  26) linux  27) logrotate  28) lvm2  29) man-db  30) man-pages  31) mdadm  32) nano  33) netcfg
   34) pacman  35) pciutils  36) pcmciautils  37) perl  38) ppp  39) procps-ng  40) psmisc  41) reiserfsprogs
   42) sed  43) shadow  44) sysfsutils  45) systemd-sysvcompat  46) tar  47) texinfo  48) usbutils
   49) util-linux  50) vi  51) which  52) xfsprogs
LXCパッケージのデフォルトでは各コンテナは/var/lib/lxc以下に置かれるの だが、パスが長くて面倒だという場合は以下のようにシンボリックリンクを張っ ておく。(LXC側で設定を変更することもできるが、lxcパッケージ側で /var/lib/lxcにハードコートされているものが存在するようでエラーとなるた め)
miku@host% sudo ln -s /var/lib/lxc /lxc

コンテナ内の設定

コンテナを起動しssh経由にてログインする際に必要な設定を行う。 sshdの有効化とユーザアカウントの設定が必須で、必要に応じてロケール等の 設定を行う。
miku@host% sudo chroot /var/lib/lxc/arch/rootfs /bin/bash
root@host(chroot)# ln -s /usr/lib/systemd/system/sshd.service \
> /etc/systemd/system/multi-user.target.wants/sshd.service 
root@host(chroot)# passwd
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
root@host(chroot)# groupadd -g 3939 miku
root@host(chroot)# useradd -g miku -u 3939 -s /bin/bash -m miku
root@host(chroot)# passwd miku
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
root@host(chroot)# exit
デバイスノードの管理はsystemd-udevdが行うため、後述するLXCのconfigでの 許可ルール設定のみ注意すればよい。また、/tmpのtmpfsや/devのdevtmpfs、 /sysのsysfs、/procのprocfs等もsystemdが自動でマウントを行うため、LXCの configやfstabへの記述は特に必要ない。

コンテナ設定ファイルの作成

今回設定するコンテナの設定ファイルは、"/var/lib/lxc/arch/config"である。 ここでは、コンテナに割り当てられるネットワークとファイルシステム、デバ イスのルールについて定義を行う。 設定ファイルの詳細については、lxc.conf(5)や/usr/share/doc/lxc/examples 以下のファイル、デバイス番号の一覧は以下のドキュメントを参照。 http://www.kernel.org/pub/linux/docs/device-list/devices.txt
# ホスト名とネットワークの設定
lxc.utsname                     = arch
lxc.network.type                = veth
lxc.network.name                = eth0
lxc.network.flags               = up
lxc.network.link                = br0
lxc.network.ipv4                = 10.3.93.11/24
lxc.network.ipv4.gateway        = 10.3.93.1


# ファイルシステムの設定
lxc.rootfs      = /var/lib/lxc/arch/rootfs


# デバイスの設定
lxc.pts                         = 1024
lxc.tty                         = 4

# deny all devices
lxc.cgroup.devices.deny         = a

# /dev/tty0..3
lxc.cgroup.devices.allow        = c 4:0 rwm
lxc.cgroup.devices.allow        = c 4:1 rwm
lxc.cgroup.devices.allow        = c 4:2 rwm
lxc.cgroup.devices.allow        = c 4:3 rwm

# /dev/tty
lxc.cgroup.devices.allow        = c 5:0 rwm
# /dev/console
lxc.cgroup.devices.allow        = c 5:1 rwm
# /dev/ptmx
lxc.cgroup.devices.allow        = c 5:2 rwm

# /dev/null
lxc.cgroup.devices.allow        = c 1:3 rwm
# /dev/zero
lxc.cgroup.devices.allow        = c 1:5 rwm
# /dev/random
lxc.cgroup.devices.allow        = c 1:8 rwm
# /dev/urandom
lxc.cgroup.devices.allow        = c 1:9 rwm

# /dev/pts/*
lxc.cgroup.devices.allow        = c 136:* rwm
# /dev/rtc
lxc.cgroup.devices.allow        = c 254:0 rwm
最終的に許可されたデバイスの一覧は "/sys/fs/cgroup/devices/lxc/コンテナ名/devices.list" から参照できる。

コンテナ内のArch Linuxの起動と終了

コンテナ内のinitの起動にはlxc-startを用いる。このシステムの場合はコン テナ名がarch、コマンドは/usr/lib/systemd/systemdとなる。
早速起動した所、pivot_root(2)が失敗する問題に遭遇した。
miku@host% sudo lxc-start -n arch -- /usr/lib/systemd/systemd
lxc-start: Invalid argument - pivot_root syscall failed
lxc-start: failed to setup pivot root
lxc-start: failed to set rootfs for 'arch'
lxc-start: failed to setup the container
lxc-start: invalid sequence number 1. expected 2
lxc-start: failed to spawn 'arch'
これはsystemdとLXCの組み合わせで発生する問題で、/以下をprivate mountす ることで解決できるようだ。
miku@host% sudo mount --make-rprivate /
このprivate mountの詳細については、以下のページが詳しい。
再度起動した所、今度は/dev/ptsが存在しないとのエラーが発生。どうや らLXC側で/dev/ptsにdevptsをマウントしようとして失敗しているようなので、 /lxc/arch/dev/ptsを作成しておく。
miku@host% sudo lxc-start -n arch -- /usr/lib/systemd/systemd
lxc-start: No such file or directory - failed to mount a new instance of '/dev/pts'
lxc-start: failed to setup the new pts instance
lxc-start: failed to setup the container
lxc-start: invalid sequence number 1. expected 2
lxc-start: failed to spawn 'arch'
miku@host% sudo mkdir -m 755 /var/lib/lxc/arch/dev/pts
以上2つの問題を解決し、ようやくsystemdとsshdが起動した。
miku@host% sudo lxc-start -n arch -- /usr/lib/systemd/systemd
miku@host% lxc-ps -n arch
CONTAINER   PID TTY          TIME CMD
arch       1113 ?        00:00:00 systemd
arch       1124 ?        00:00:00 systemd-udevd
arch       1132 ?        00:00:00 systemd-journal
arch       1243 ?        00:00:00 sshd
arch       1245 ?        00:00:00 dbus-daemon
arch       1246 ?        00:00:00 systemd-logind
arch       1253 ?        00:00:00 agetty
arch       1254 tty1     00:00:00 agetty
デーモンとして動作させる場合は、以下のように-dオプションとログ出力オプ ションを設定し起動する。
miku@host% sudo lxc-start -n arch  -d \
> --logfile=/var/lib/lxc/arch/lxc.log \
> --console=/var/lib/lxc/arch/console.log  -- /usr/lib/systemd/systemd
LXCコンテナを終了する場合は、lxc-stopコマンドを利用する。
miku@host% sudo lxc-stop -n arch
Arch Linux上のLXCコンテナ内でArch Linuxを動かし、基本的な操作(起動と終了)が 行えることが確認できた。

その他の問題

今回作成した環境には、lxc-consoleにてコンソールにアクセスできない問題 がある。LXCが想定する/dev以下の扱いとsystemd-udevdの挙動の問題なように 見受けられるので、そのあたりを探っておこうと思う。 (LXC側で掴んだデバイスノードと別に/devにmountされたdevtmpfs上のデバイ スノードをsystemd側でgettyしているのが原因?)

2013年1月14日月曜日

DragonflyBSDでvirtioを利用する

DragonflyBSDのGENERICにvirtioが入ったと聞いて早速ビルドして試してみたのだが、 残念ながらネットワークのvirtioサポートはまだらしい(そもそもソースがツ リーに含まれていない感じ)。 virtio_blk.koは存在して利用できるようなので、とりあえず書き込み性能だ け簡単に比較してみた。

ホスト

  • Linux hachune.local 3.6.11-1-ARCH #1 SMP PREEMPT Tue Dec 18 08:57:15 CET 2012 x86_64 GNU/Linux
  • QEMU emulator version 1.2.1, Copyright (c) 2003-2008 Fabrice Bellard

Virtioあり

QEMUの構成

qemu-system-x86_64 -enable-kvm -smp 2 -m 2048 \
  -drive file=/dev/vg0/Dragonfly,if=virtio \
  -net nic,model=virtio,macaddr=52:54:00:43:23:11 \
  -net tap,ifname=tap0,script=/home/miku/kvm/ifup_br0.sh \
  -serial pty \
  -cdrom /home/miku/Image/dfly-x86_64-3.3-current.iso -boot d

HAMMER

29895208.6 bytes/sec

# newfs_hammer -L TEST /dev/vbd0s1b
Volume 0 DEVICE /dev/vbd0s1b    size  11.25GB
initialize freemap volume 0
initializing the undo map (504 MB)
---------------------------------------------
1 volume total size  11.25GB version 6
boot-area-size:       32.00MB
memory-log-size:      32.00MB
undo-buffer-size:    504.00MB
total-pre-allocated:   0.51GB
fsid:                95359a72-5dc9-11e2-a6d0-e915af5f7f28

NOTE: Please remember that you may have to manually set up a
cron(8) job to prune and reblock the filesystem regularly.
By default, the system automatically runs 'hammer cleanup'
on a nightly basis.  The periodic.conf(5) variable
'daily_clean_hammer_enable' can be unset to disable this.
Also see 'man hammer' and 'man HAMMER' for more information.

WARNING: HAMMER filesystems less than 50GB are not recommended!
You may have to run 'hammer prune-everything' and 'hammer reblock'
quite often, even if using a nohistory mount.
# mount_hammer /dev/vbd0s1b /mnt
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 37.101394 secs (28262442 bytes/sec)
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 32.183600 secs (32581066 bytes/sec)
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 38.717169 secs (27082972 bytes/sec)
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 34.504874 secs (30389214 bytes/sec)
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 33.650971 secs (31160349 bytes/sec)

UFS

51055029.6 bytes/sec

# newfs /dev/vbd0s1b
/dev/vbd0s1b: media size 11515.96MB
Warning: Block size and bytes per inode restrict cylinders per group to 89.
Warning: 80 sector(s) in last cylinder unallocated
/dev/vbd0s1b:   23584688 sectors in 5758 cylinders of 1 tracks, 4096 sectors
        11516.0MB in 65 cyl groups (89 c/g, 178.00MB/g, 22400 i/g)
super-block backups (for fsck -b #) at:
 32, 364576, 729120, 1093664, 1458208, 1822752, 2187296, 2551840, 2916384,
 3280928, 3645472, 4010016, 4374560, 4739104, 5103648, 5468192, 5832736,
 6197280, 6561824, 6926368, 7290912, 7655456, 8020000, 8384544, 8749088,
 9113632, 9478176, 9842720, 10207264, 10571808, 10936352, 11300896, 11665440,
 12029984, 12394528, 12759072, 13123616, 13488160, 13852704, 14217248,
 14581792, 14946336, 15310880, 15675424, 16039968, 16404512, 16769056,
 17133600, 17498144, 17862688, 18227232, 18591776, 18956320, 19320864,
 19685408, 20049952, 20414496, 20779040, 21143584, 21508128, 21872672,
 22237216, 22601760, 22966304, 23330848
# mount_ufs /dev/vbd0s1b /mnt
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 19.852371 secs (52818678 bytes/sec)
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 19.631861 secs (53411951 bytes/sec)
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 21.491887 secs (48789388 bytes/sec)
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 22.926797 secs (45735826 bytes/sec)
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 19.233114 secs (54519305 bytes/sec)

Virtioなし

QEMUの構成

qemu-system-x86_64 -enable-kvm -smp 2 -m 2048 \
  -hda /dev/vg0/Dragonfly \
  -net nic,model=e1000,macaddr=52:54:00:43:23:11 \
  -net tap,ifname=tap0,script=/home/miku/kvm/ifup_br0.sh \
  -serial pty \
  -cdrom /home/miku/Image/dfly-x86_64-3.3-current.iso -boot d

HAMMER

17620950.4 bytes/sec

# newfs_hammer -L TEST /dev/ad1s1b
Volume 0 DEVICE /dev/ad1s1b     size  11.25GB
initialize freemap volume 0
initializing the undo map (504 MB)
---------------------------------------------
1 volume total size  11.25GB version 6
boot-area-size:       32.00MB
memory-log-size:      32.00MB
undo-buffer-size:    504.00MB
total-pre-allocated:   0.51GB
fsid:                ff28dca3-5dcb-11e2-b2ce-535400432311

NOTE: Please remember that you may have to manually set up a
cron(8) job to prune and reblock the filesystem regularly.
By default, the system automatically runs 'hammer cleanup'
on a nightly basis.  The periodic.conf(5) variable
'daily_clean_hammer_enable' can be unset to disable this.
Also see 'man hammer' and 'man HAMMER' for more information.

WARNING: HAMMER filesystems less than 50GB are not recommended!
You may have to run 'hammer prune-everything' and 'hammer reblock'
quite often, even if using a nohistory mount.
# mount_hammer /dev/ad1s1b /mnt
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 59.103703 secs (17741291 bytes/sec)
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 57.336238 secs (18288190 bytes/sec)
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 57.117314 secs (18358286 bytes/sec)
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 62.101431 secs (16884893 bytes/sec)
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 62.296237 secs (16832092 bytes/sec)

UFS

28662327.0 bytes/sec

# newfs /dev/ad1s1b
/dev/ad1s1b: media size 11515.96MB
Warning: Block size and bytes per inode restrict cylinders per group to 89.
Warning: 80 sector(s) in last cylinder unallocated
/dev/ad1s1b:    23584688 sectors in 5758 cylinders of 1 tracks, 4096 sectors
        11516.0MB in 65 cyl groups (89 c/g, 178.00MB/g, 22400 i/g)
super-block backups (for fsck -b #) at:
 32, 364576, 729120, 1093664, 1458208, 1822752, 2187296, 2551840, 2916384,
 3280928, 3645472, 4010016, 4374560, 4739104, 5103648, 5468192, 5832736,
 6197280, 6561824, 6926368, 7290912, 7655456, 8020000, 8384544, 8749088,
 9113632, 9478176, 9842720, 10207264, 10571808, 10936352, 11300896, 11665440,
 12029984, 12394528, 12759072, 13123616, 13488160, 13852704, 14217248,
 14581792, 14946336, 15310880, 15675424, 16039968, 16404512, 16769056,
 17133600, 17498144, 17862688, 18227232, 18591776, 18956320, 19320864,
 19685408, 20049952, 20414496, 20779040, 21143584, 21508128, 21872672,
 22237216, 22601760, 22966304, 23330848
# mount_ufs /dev/ad1s1b /mnt
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 37.872868 secs (27686733 bytes/sec)
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 38.206654 secs (27444853 bytes/sec)
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 32.039132 secs (32727978 bytes/sec)
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 40.281541 secs (26031179 bytes/sec)
# dd if=/dev/zero of=/mnt/test.img bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes transferred in 35.640524 secs (29420892 bytes/sec)

結果

virtioを利用した場合のほうが書き込み性能は2倍近く高くなることが分かっ た。読み込みは測るのをうっかり忘れてて途中で気が付いた。

HAMMER(virtio)HAMMERUFS(virtio)UFS
128262442177412915281867827686733
232581066182881905341195127444853
327082972183582864878938832727978
430389214168848934573582626031179
531160349168320925451930529420892
平均29895209176209505105503028662327

おまけのdmesg

# dmesg
Copyright (c) 2003-2013 The DragonFly Project.
Copyright (c) 1992-2003 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
        The Regents of the University of California. All rights reserved.
DragonFly v3.3.0.942.gfa75bf-DEVELOPMENT #0: Mon Jan 14 04:04:37 JST 2013
    root@vy1.hachune.local:/usr/obj/usr/src/sys/X86_64_GENERIC
TSC clock: 1646507109 Hz, i8254 clock: 1193192 Hz
CPU: QEMU Virtual CPU version 1.2.1 (1646.52-MHz K8-class CPU)
  Origin = "AuthenticAMD"  Id = 0x623  Stepping = 3
  Features=0x783fbfd<FPU,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2>
  Features2=0x80802001<SSE3,CX16,POPCNT,VMM>
  AMD Features=0x20100800<SYSCALL,NX,LM>
  AMD Features2=0x65<LAHF,SVM,ABM,SSE4A>
real memory  = 2147081216 (2047 MB)
avail memory = 1964879872 (1873 MB)
lapic: divisor index 0, frequency 500010320 Hz
Initialize MI interrupts
FQ scheduler policy version 1.1 loaded
wdog: In-kernel automatic watchdog reset enabled
kbd1 at kbdmux0
disk scheduler: set policy of md0 to noop
md0: Malloc disk
ACPI: RSDP 0xfd950 00014 (v00 BOCHS )
ACPI: RSDT 0x7fffe3d0 00038 (v01 BOCHS  BXPCRSDT 00000001 BXPC 00000001)
ACPI: FACP 0x7fffff80 00074 (v01 BOCHS  BXPCFACP 00000001 BXPC 00000001)
ACPI: DSDT 0x7fffe410 0124A (v01   BXPC   BXDSDT 00000001 INTL 20121018)
ACPI: FACS 0x7fffff40 00040
ACPI: SSDT 0x7ffffe30 00110 (v01 BOCHS  BXPCSSDT 00000001 BXPC 00000001)
ACPI: APIC 0x7ffffd10 00080 (v01 BOCHS  BXPCAPIC 00000001 BXPC 00000001)
ACPI: HPET 0x7ffffcd0 00038 (v01 BOCHS  BXPCHPET 00000001 BXPC 00000001)
ACPI: SSDT 0x7ffff660 0066E (v01   BXPC BXSSDTPC 00000001 INTL 20121018)
cryptosoft0: <software crypto> on motherboard
acpi0: <BOCHS BXPCRSDT> on motherboard
ACPI FADT: SCI testing interrupt mode ...
ACPI FADT: SCI select level/low
objcache_reclaimlist
objcache_reclaimlist
objcache_reclaimlist
objcache_reclaimlist
acpi0: Power Button (fixed)
Warning: ACPI is disabling APM's device.  You can't run both
acpi_timer0: <24-bit timer at 3.579545MHz> port 0xb008-0xb00b on acpi0
acpi_hpet0: <High Precision Event Timer> iomem 0xfed00000-0xfed003ff on acpi0
acpi_hpet0: frequency 100000000
pcib0: <ACPI Host-PCI bridge> port 0xcf8-0xcff on acpi0
pci0: <ACPI PCI bus> on pcib0
pci_link4: Unable to route IRQs: AE_NOT_FOUND
isab0: <PCI-ISA bridge> at device 1.0 on pci0
isa0: <ISA bus> on isab0
atapci0: <Intel PIIX3 WDMA2 controller> port 0xc060-0xc06f,0x376,0x170-0x177,0x3f6,0x1f0-0x1f7 at device 1.1 on pci0
ata0: <ATA channel 0> on atapci0
ata1: <ATA channel 1> on atapci0
disk scheduler: set policy of acd0 to noop
acd0: DVDROM <QEMU DVD-ROM/1.2.1> at ata1-master WDMA2
pci0: <bridge> (vendor 0x8086, dev 0x7113) at device 1.3 irq 9
vgapci0: <VGA-compatible display> mem 0xfebf0000-0xfebf0fff,0xfc000000-0xfdffffff at device 2.0 on pci0
virtio_pci0: <VirtIO PCI Network adapter> port 0xc040-0xc05f mem 0xfebf1000-0xfebf1fff irq 11 at device 3.0 on pci0
virtio_pci1: <VirtIO PCI Block adapter> port 0xc000-0xc03f mem 0xfebf2000-0xfebf2fff irq 11 at device 4.0 on pci0
virtio_pci1: host features: 0x710006d4 <EventIdx,0x10000000,NotifyOnEmpty,Topology,FlushCmd,SCSICmds,BlockSize,DiskGeometry,MaxNumSegs>
virtio_pci1: negotiated features: 0x254 <FlushCmd,BlockSize,DiskGeometry,MaxNumSegs>
disk scheduler: set policy of vbd0 to noop
atkbdc0: <Keyboard controller (i8042)> port 0x64,0x60 irq 1 on acpi0
atkbd0: <AT Keyboard> flags 0x1 irq 1 on atkbdc0
kbd0 at atkbd0
psm0: <PS/2 Mouse> irq 12 on atkbdc0
psm0: model IntelliMouse Explorer, device ID 4
cpu0: <ACPI CPU> on acpi0
cpu_cst0: <ACPI CPU C-State> on cpu0
cpu1: <ACPI CPU> on acpi0
cpu_cst1: <ACPI CPU C-State> on cpu1
orm0: <Option ROM> at iomem 0xed000-0xeffff on isa0
pmtimer0 on isa0
vga0: <Generic ISA VGA> at port 0x3c0-0x3df iomem 0xa0000-0xbffff on isa0
sc0: <System console> at flags 0x100 on isa0
sc0: VGA <16 virtual consoles, flags=0x300>
sio0 at port 0x3f8-0x3ff irq 4 flags 0x10 on isa0
sio0: type 16550A
sio1: can't drain, serial port might not exist, disabling
ppc0: cannot reserve I/O port range
hpt27xx: no controller detected.
CAM: Configuring 2 busses
CAM: finished configuring all busses
disk scheduler: set policy of cd0 to noop
no B_DEVMAGIC (bootdev=0)
Device Mapper version 4.16.0 loaded
dm_target_error: Successfully initialized
dm_target_zero: Successfully initialized
cd0 at ata1 bus 0 target 0 lun 0
cd0: <QEMU QEMU DVD-ROM 1.2.> Removable CD-ROM SCSI-0 device
cd0: 16.000MB/s transfers
cd0: cd present [347187 x 2048 byte records]
Mounting root from cd9660:cd0
DMA space used: 152k, remaining available: 16384k
Mounting devfs