Hatena::ブログ(Diary)

adsaria mood このページをアンテナに追加 RSSフィード

2011-03-09 z4rootで携帯がtelnetサーバにもなる

z4rootで携帯がtelnetサーバにもなる

Android携帯にz4rootというroot化のアプリを入れた。z4rootをインストールするとbusyboxというLinuxの標準コマンドが使えるようになるツールも一緒にインストールされる(busyboxについては“こちら”)。

で、busyboxの中身をもう一度よく見たら「おや、telnetd がある」と気が付いた。これはTelnetサーバプログラム。つまりこのbusyboxの中のtelnetdの機能を使えばネットワーク経由でアンドロイド端末にアクセスできる様になる。極端に言えばAndroid端末をTelnetサーバにできることになる。Telnetsshに比べセキュリティは低いが、まさか携帯電話インターネット上でサーバとして運用するわけでもなく、LANに接続してアクセスする程度の話なので十分だろう。Android版のsshdもあるようだが、少ないメモリに色々なアプリも入れたくないし。

こんな感じでさっそくroot化してtelnetdを起動してみた。

# busybox telnetd

ps”コマンドで確認すると、ちゃんと動いているようだが、PCからアクセスできない。telnetdのヘルプを見ていて気付いたのだが、telnetdはクライアントからのアクセスがあると標準では/bin/loginというコマンドを起動してユーザがログインするようになっている。しかしAndroidにはログインなんて概念はなく/bin/loginもある筈もない。動かないわけだ。

そこでクライアントからのアクセスがあった場合に/bin/loginではなく、/system/bin/sh を起動するようにしたら、すんなり動いた。つまり、PCからtelnetを掛けるとログイン画面ではなく、いきなりrootのプロンプトが現れる(telnetdがroot権限で動いているため)。

セキュリティ的にはちょっと危険だが、別にIS04サーバにするわけでもなく、ちょっとrootでファイルをいじくりたい時に使うのだから逆に便利とも言える。(suしないで(rootにならないで)telentdの起動を試みたがソケットがバインドできなくてtelnetd自身が起動しない。)

さて、起動の方法だが、次のようにadbで入ってtelnetdを起動するだけ。何の設定も要らない。

android@android:~$ adb shell
$ su
# busybox telnetd -l /system/bin/sh
# 

端末をUSBデバッグモードにして(もっともz4rootを動かすためにはデバッグモードにしておかないとならないが)、adbで端末に入ってsuしてtelnetdを起動するだけ。これでPCからtelnetでアクセスできるようになる。(勿論、携帯が無線LAN等でIPネットワークに接続されていなければならない。)

試しにPCからアクセスしてみる。その前に携帯のIPアドレスが分からないとアクセスできないので、busyboxのifconfigを使って確かめる。

# busybox ifconfig
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:1784 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1784 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:89200 (87.1 KiB)  TX bytes:89200 (87.1 KiB)

wlan0     Link encap:Ethernet  HWaddr 5C:DA:D4:12:34:56  
          inet addr:192.168.1.3  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::abcd:ffff:ff12:3456/64 Scope:Link
          UP BROADCAST RUNNING  MTU:1500  Metric:1
          RX packets:564 errors:0 dropped:0 overruns:0 frame:0
          TX packets:459 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:89681 (87.5 KiB)  TX bytes:9488 (9.2 KiB)

この例では、端末のIPアドレスは“192.168.1.3”となっていることがわかる。早速、接続。Windowsでもtelnetは使えるのでここでは敢えてDOS窓のサンプルを載せておく。(勿論、TeraTermで使った方がより便利だが。)PCのDOS窓から“telnet 192.168.1.3”と打ち込む。

f:id:adsaria:20110309114303p:image

なんか拍子抜けする画面だが、確かにAndroidシェルが動いている。

最初にUSBを使てadbで入らないければならないが、あとはネットワーク経由でアクセスできるので楽になる。私は ConnectBot という仮想端末ソフト(sshクライアントになる)を入れているが、このアプリはlocalに接続してAndroidシェル端末として使うこともできる。これを入れておけば、USB経由のadbを使うことなしに端末でtelnetdを起動することができる。

f:id:adsaria:20110309114429p:image

なお、以上の方法でtelnetdを起動するとシェルbusybox内蔵のB-Shellもどきではなく、Androidshなのでちょっと不便だ。telnetで入って改めて

# busybox sh

と実行する必要がある。いきなりbusyboxshを起動するにはtelnetdを次のように起動する。

# busybox telnetd -l /sdcard/lbin/sh

ただし、“/sdcard/lbin/sh”はbusyboxへのシンボリックリンクになっている必要があり、予め設定しておかなければならない。

# ls -l /sdcard/lbin/sh
lrwxrwxrwx root     root              2011-03-01 09:30 sh -> /system/bin/busybox

シンボリックリンクの設定についても“こちら”を参照のこと。(私の携帯ではbusyboxへのリンクを作ってあるので、イチイチ busyboxを打ち込む必要はない。)

あと、busyboxの中にはloginも含まれているが、こちらはとか色々と環境を設定しないと動きそうもないので使っていない。

2011-03-05 syslinuxの設定ファイルに関する工夫

syslinuxの設定ファイルに関する工夫

Linuxを使ったネットワークブートで一般的に使うのはsyslinuxによる2次ローダとそれに続くOS本体のダウンロードだろう。syslinuxを呼び出すまでにはDHCPとtftpという仕組み(総括してPXEと呼んでいるが)を使っているが、これについての工夫は別に紹介するとして、まずはPXEで呼び出されたsyslinuxの設定ファイルの構成に関する工夫についてメモっておく。

ここではsyslinuxの中でもPXEブートに関する設定に絞っている。つまり標準で、/tftpboot/syslinux/pxelinux.cfgディレクトリの下のファイル構成が中心となる。

PXEブートにより各クライアントからの要求に対して、“その”クライアントに対する設定ファイルを用意することで、クライアント毎に違うブート設定を実現できる。クライアントの区別は、クライアントMACアドレス、もしくはIPアドレスで行う。“01-xx-xx-xx-xx-xx-xx”というファイル名を用意することで“xx:xx:xx:xx:xx:xx”というMACアドレスクライアントに対するブート設定を記述する(IPアドレスを使った方法もあるが説明を簡単にするためにここではMACアドレスによる指定だけに限定する)。等と言うことはマニュアルなどに書いてあるので(ここ)、一般には/tftpboot/syslinux/pxelinux.cfgディレクトリの下は、クライアントMACアドレスに対応するファイル名が多数できる。これを管理するのは結構手間がかかる。もっとも、クライアント個々で全く異なるカーネルパラメータを使うことは無いので、雛形になるファイルを作り、そのファイルに個々のMACアドレスのファイルをシンボリックリンクすることになる。例えば、

root@ubuntu# cd /tftpboot/syslinux/pxelinux.cfg
root@ubuntu# ls -l
total 8
lrwxrwxrwx 1 root root 23 2011-02-27 18:44 01-aa-bb-cc-dd-ee-00 -> default.ubuntu1004xd32e
lrwxrwxrwx 1 root root 23 2011-02-27 18:44 01-aa-bb-cc-dd-ee-ff -> default.ubuntu1004xd32e
lrwxrwxrwx 1 root root 23 2011-02-27 18:44 01-ff-ee-dd-cc-bb-00 -> default.ubuntu1004xd64e
lrwxrwxrwx 1 root root 23 2011-02-27 18:44 01-ff-ee-dd-cc-bb-aa -> default.ubuntu1004xd64e
-rw-r--r-- 1 root root 53 2011-02-27 18:42 default.ubuntu1004xd32e
-rw-r--r-- 1 root root 53 2011-02-27 18:42 default.ubuntu1004xd64e

root@ubuntu# cat default.ubuntu1004xd32e
DEFAULT ubuntu1004xd32e

LABEL ubuntu1004xd32e
        KERNEL  /diskless/root/ubuntu1004xd32e/vmlinuz
        APPEND  initrd=/diskless/root/ubuntu1004xd32e/initrd.img boot=casper nfsroot=192.168.1.1:/diskless/root/ubuntu1004xd32e netboot=nfs quiet --

という感じでリンクを張ることで、クライアントによってブートするUbuntuを32bit版(i386)か64bit版(amd64)の指定できるようになる。(なお、以下のサンプルではsyslinuxの設定ファイル中で、syslinuxの予約語となっている単語(DEFUALT、LABEL、KERNEL等)は大文字にしてある。これらの予約語は大文字でも小文字でも関係ないので、私は予約語として認識し易くするために大文字を使っている。)

ただ、シンボリックリンクを使ってまとめたとしても雛形のファイル(シンボリック先のファイル、この例では“default.xxxxxx”)も種類がだんだん増えてきて管理が面倒になる。そこで、雛形ファイルを1つにまとめてしまうことを考えた。例えば次のうに“labels”というファイルを作り、そこに設定をまとめてしまう。

root@ubuntu# ls -l
total 12
lrwxrwxrwx 1 root root  23 2011-02-27 18:44 01-aa-bb-cc-dd-ee-00 -> default.ubuntu1004xd32e
lrwxrwxrwx 1 root root  23 2011-02-27 18:44 01-aa-bb-cc-dd-ee-ff -> default.ubuntu1004xd32e
lrwxrwxrwx 1 root root  23 2011-02-27 18:44 01-ff-ee-dd-cc-bb-00 -> default.ubuntu1004xd64e
lrwxrwxrwx 1 root root  23 2011-02-27 18:44 01-ff-ee-dd-cc-bb-aa -> default.ubuntu1004xd64e
-rw-r--r-- 1 root root  53 2011-02-27 19:01 default.ubuntu1004xd32e
-rw-r--r-- 1 root root  53 2011-02-27 19:02 default.ubuntu1004xd64e
-rw-r--r-- 1 root root 503 2011-02-27 18:59 labels

root@ubuntu# cat labels
LABEL ubuntu1004xd32e
	KERNEL  /diskless/root/ubuntu1004xd32e/vmlinuz
	APPEND  initrd=/diskless/root/ubuntu1004xd32e/initrd.img boot=casper nfsroot=192.168.1.1:/diskless/root/ubuntu1004xd32e netboot=nfs quiet --

################################################################################

LABEL ubuntu1004xd64e
	KERNEL  /diskless/root/ubuntu1004xd64e/vmlinuz
	APPEND  initrd=/diskless/root/ubuntu1004xd64e/initrd.img boot=casper nfsroot=192.168.1.1:/diskless/root/ubuntu1004xd64e netboot=nfs quiet --

と、しておく。このlabelsファイルにはLABELの項目だけが含まれ、DEFAULTの行はない。DEFAULTの指定は雛形ファイル(defaul.xxxxxx)で記述する。例えば次のようになる:

root@ubuntu# cat default.ubuntu1004xd32e
INCLUDE pxelinux.cfg/labels
DEFAULT ubuntu1004xd32e

雛形ファイルはlabelsファイルを読み込み、デフォルトを指定しているだけである。(この2行の順番は逆でも構わないが、誤ってlabelsファイルの方にDEFAULTの記述があっても、それを上書きするようにDEFAULT行はINCLUDE行の後にしている。)

この例では2つのエントリーしかないので、このように分けるメリットが余り感じられないが、もっと多様なブート設定が増えてきてもlabelsファイルだけを管理すれば良いので管理が楽になる。

私の環境で更に、クライアントのブート時にどのOSをブートするか指定できるようにメニューも出せるようにしているが、その場合は次の様に default.menuという雛形を作っている。

root@ubuntu# ls -l
total 16
lrwxrwxrwx 1 root root  23 2011-02-27 18:44 01-aa-bb-cc-dd-ee-00 -> default.ubuntu1004xd32e
lrwxrwxrwx 1 root root  23 2011-02-27 18:44 01-aa-bb-cc-dd-ee-ff -> default.ubuntu1004xd32e
lrwxrwxrwx 1 root root  12 2011-02-27 19:24 01-ab-cd-ef-12-34-56 -> default.menu
lrwxrwxrwx 1 root root  23 2011-02-27 18:44 01-ff-ee-dd-cc-bb-00 -> default.ubuntu1004xd64e
lrwxrwxrwx 1 root root  23 2011-02-27 18:44 01-ff-ee-dd-cc-bb-aa -> default.ubuntu1004xd64e
-rw-r--r-- 1 root root  45 2011-02-27 19:23 default.menu
-rw-r--r-- 1 root root  53 2011-02-27 19:01 default.ubuntu1004xd32e
-rw-r--r-- 1 root root  53 2011-02-27 19:02 default.ubuntu1004xd64e
-rw-r--r-- 1 root root 580 2011-02-27 19:33 labels

root@ubuntu# cat default.menu
INCLUDE pxelinux.cfg/labels
DEFAULT menu.c32

この様に設定しておくと“ab:cd:ef:12:34:56”というMACアドレスを持ったPCをPXEブートすると、画面に32bit版のUbuntuを起動するのかか64bit版のUbuntuを起動するのかメニューが表示される。その際に、“ubuntu1004xd32e”といった管理用のファイル名ではなく“Ubuntu 10.04 Desktop i386”というメッセージを出力するようにlabelsファイルでメニューラベルも指定しておく。

root@ubuntu# cat labels
LABEL ubuntu1004xd32e
        MENU LABEL Ubuntu 10.04 Desktop i386
        KERNEL  /diskless/root/ubuntu1004xd32e/vmlinuz
        APPEND  initrd=/diskless/root/ubuntu1004xd32e/initrd.img boot=casper nfsroot=192.168.1.1:/diskless/root/ubuntu1004xd32e netboot=nfs quiet --

################################################################################

LABEL ubuntu1004xd64e
        MENU LABEL Ubuntu 10.04 Desktop amd64
        KERNEL  /diskless/root/ubuntu1004xd64e/vmlinuz
        APPEND  initrd=/diskless/root/ubuntu1004xd64e/initrd.img boot=casper nfsroot=192.168.1.1:/diskless/root/ubuntu1004xd64e netboot=nfs quiet --

この様にLABEL記述だけを別ファイルに独立させることで、メニューを出す雛形も作れるし、(メニューを出さずに)特定のOSを即ブートする雛形も作れる。

以下は、実際に私の環境で使っている例である:

root@ubuntu# cat labels
LABEL mt86plus
        MENU LABEL Memory Test
        KERNEL mt86plus

################################################################################

LABEL gpxe
        MENU LABEL gPXE Boot
        KERNEL gpxe.0

################################################################################

LABEL ubuntu08044s32e-vmrc
        MENU LABEL VMware Remote Console
        KERNEL  /diskless/root/ubuntu08044s32e-vmrc/vmlinuz
        APPEND  initrd=/diskless/root/ubuntu08044s32e-vmrc/initrd.img boot=casper nfsroot=192.168.1.1:/diskless/root/ubuntu08044s32e-vmrc netboot=nfs quiet --

################################################################################

LABEL ubuntu1004xd32e
        MENU LABEL Ubuntu 10.04 Desktop i386
        KERNEL  /diskless/root/ubuntu1004xd32e/vmlinuz
        APPEND  initrd=/diskless/root/ubuntu1004xd32e/initrd.img boot=casper nfsroot=192.168.1.1:/diskless/root/ubuntu1004xd32e netboot=nfs quiet --

################################################################################

LABEL ubuntu1004xd64e
        MENU LABEL Ubuntu 10.04 Desktop amd64
        KERNEL  /diskless/root/ubuntu1004xd64e/vmlinuz
        APPEND  initrd=/diskless/root/ubuntu1004xd64e/initrd.img boot=casper nfsroot=192.168.1.1:/diskless/root/ubuntu1004xd64e netboot=nfs quiet --

################################################################################

LABEL ubuntu_32_-installer
        MENU LABEL Install Ubuntu i386
        KERNEL ubuntu-installer/i386/boot-screens/vesamenu.c32
        APPEND ubuntu-installer/i386/boot-screens/menu.cfg

################################################################################

LABEL ubuntu_64_-installer
        MENU LABEL Install Ubuntu amd64
        KERNEL ubuntu-installer/amd64/boot-screens/vesamenu.c32
        APPEND ubuntu-installer/amd64/boot-screens/menu.cfg

この様にlabelファイルを記述しておけば、先ほどのdefault.menuの雛形を使ったPCからPXEブートすると次のようなメニュー画面が表示される:

f:id:adsaria:20110227231828p:image

“Memory Test”はOSをブートするのではなくMemory Testプログラムを起動実行する。syslinuxに付属するmt86plus(旧memtest86+)を起動しているだけ。

“gPXE”を選択すると、gPXEを使って再ブートに入りiSCSIでのブートが可能となる。ここで、どのiSCSIディスクを使ってブートするのかメニュー化したかったのだが、現バージョン(1.0.1)のgPXEに対してパラメータを渡すことができないようなので、ここだけはマシン依存になってしまう(詳細はgPXEの設定の所で)。今のところはAndroidの開発環境をブートするのに使っている。

VMware Remote Desktop”はシンクライアントとしてPCを立ち上げて、サーバ上で動いている仮想マシンのリモートコンソールとして使う。捨てられずに置いてある昔のPCのための設定である。

Ubuntu 10.04 Desktop i386”、“Ubuntu 10.04 Desktop amd64”は(iSCSIを使わず)ディスクレス形態でUbuntuをブートする。ちょうどUbuntuのライブCDを起動したのと同じ状態をPXEでネットブートする形になる。この設定があると普段はWindowsを動かしているPCでも気軽にUbuntuを起動することができ、マシンの保守などのために利用する。Windowsマシンのバックアップ取る場合はLinuxをブートしてHDD(もしくはシステム・パーティション)を丸ごとイメージとしてバックアップするのに使う。また、HDDからブートできない!とかいう場合にも使う。

“Install Ubuntu i386”、“Install Ubuntu amd64”はUbuntuインストールに使う。この様に設定しておけば、いちいちインストール用のDVDを焼かずにBIOSからPXEブートを選ぶだけでUbuntuインストールが可能となる(ただGUI画面ではくCUI画面でのインストールになるが)。