Android端末にTermux + Dropbearでssh login

TermuxはAndroid上でLinux環境が構築できる独自パッケージシステムなアプリケーションです.端末ソフトも同梱されています.Termux-apiを使うとshellでAndroidの操作が出来てちょっと面白いのですが,Androidのタッチパネルで文字を打つのが面倒.リモート操作したいのでsshdが動かないか試してみました.

パッケージを検索してみます.定番のOpenSSHとDropbearが使えそうです.

$ pkg search ssh
Hit:1 https://termux.net stable InRelease
Reading package lists... Done
Building dependency tree       
Reading state information... Done
All packages are up to date.
Sorting... Done
Full Text Search... Done
autossh/stable 1.4f arm
  Automatically restart SSH sessions and tunnels

corkscrew/stable 2.0-1 arm
  A tool for tunneling SSH through HTTP proxies

dropbear/stable,now 2018.76-1 arm [installed]
  Small SSH server and client

libssh/stable 0.7.5-1 arm
  Tiny C SSH library

libssh-dev/stable 0.7.5-1 arm
  Development files for libssh

openssh/stable 7.7p1-2 arm
  Secure shell for logging into a remote machine

sshpass/stable 1.06 arm
  Noninteractive ssh password provider

今回は操作ができればいいので消費リソースの少ないDropbearを選択しました.

$ pkg install dropbear
$ dropbear -h
Dropbear server v2018.76 https://matt.ucc.asn.au/dropbear/dropbear.html
Usage: dropbear [options]
-b bannerfile   Display the contents of bannerfile before user login
                (default: none)
-r keyfile  Specify hostkeys (repeatable)
                defaults: 
                dss /data/data/com.termux/files/usr/etc/dropbear/dropbear_dss_host_key
                rsa /data/data/com.termux/files/usr/etc/dropbear/dropbear_rsa_host_key
                ecdsa /data/data/com.termux/files/usr/etc/dropbear/dropbear_ecdsa_host_key
-R              Create hostkeys as required
-F              Don't fork into background
(Syslog support not compiled in, using stderr)
-w              Disallow root logins
-G              Restrict logins to members of specified group
-T              Maximum authentication tries (default 10)
-j              Disable local port forwarding
-k              Disable remote port forwarding
-a              Allow connections to forwarded ports from any host
-c command      Force executed command
-p [address:]port
                Listen on specified tcp port (and optionally address),
                up to 10 can be specified
                (default port is 8022 if none specified)
-P PidFile      Create pid file PidFile
                (default /data/data/com.termux/files/usr/var/run/dropbear.pid)
-i              Start for inetd
-W <receive_window_buffer> (default 24576, larger may be faster, max 1MB)
-K <keepalive>  (0 is never, default 0, in seconds)
-I <idle_timeout>  (0 is never, default 0, in seconds)
-V    Version

鍵を用意します.普通に~/.ssh/authorized_keysに公開鍵を登録すれば良いようです.PCで作成した鍵ペアの公開鍵を登録しました.

$ cd && pwd
/data/data/com.termux/files/home
$ ls -lA ~/.ssh
total 4
-rw-------    1 u0_a235  u0_a235        170 Jun 20 03:58 authorized_keys

sshデーモンを起動します.オプションは適当でポート番号を2222番にしています.

$ dropbear -w -T 2 -j -k -p 2222 -I 600

Androidのipアドレスを確認して,

$ ip r
default via 192.168.2.1 dev wlan0  metric 322 
100.93.0.128/26 dev rmnet0  proto kernel  scope link  src 100.93.0.160 
192.168.2.0/24 dev wlan0  proto kernel  scope link  src 192.168.2.211  metric 322

PCからこんな感じで接続してみると繋がりました!

$ ssh u0_a235@192.168.2.211 -p 2222 -i ~/.ssh/id_ed25519_termux

これで操作が楽に&端末の結果を保存しやすくなりました.

追記)
Dropbearを止める

$ pgrep dropbear
10925
10958
$ pkill dropbear

GNU Coreutils 8.25でlsの出力が変わったのを試してみる

DebuanのMLで知ったのですが,Coreutils 8.25lsの出力結果が変わっています.

この変更はlsコマンドを使ったscriptなどが影響を受けそうと思ったのですが端末でのみの変更のようで一安心.
Debian stretch testingでちょっと試しに動かしてみました.
Debian jessie/Ubuntu 14.04以降も同じ手順で行けると思います.

開発環境の導入

$ sudo apt install build-essential
$ sudo apt build-dep coreutils

Coreutils 8.25の入手と署名確認

$ wget ftp://ftp.gnu.org/gnu/coreutils/coreutils-8.25.tar.xz ftp://ftp.gnu.org/gnu/coreutils/coreutils-8.25.tar.xz.sig
$ gpg --verify coreutils-8.25.tar.xz.sig
gpg: 署名されたデータが'coreutils-8.25.tar.xz'にあると想定します
gpg: 2016年01月20日 20時17分46秒 JSTにRSA鍵ID 306037D9で施された署名
gpg: "Pádraig Brady <P@draigBrady.com>"からの正しい署名
gpg:                 別名"Pádraig Brady <pixelbeat@gnu.org>"
gpg: *警告*: この鍵は信用できる署名で証明されていません!
gpg:       この署名が所有者のものかどうかの検証手段がありません。
主鍵フィンガー・プリント: 6C37 DC12 121A 5006 BC1D  B804 DF6F D971 3060 37D9

展開とビルド

$ tar xf coreutils-8.25.tar.xz
$ cd coreutils-8.25
$ ./configure --prefix=$HOME/usr/local
$ make

端末でのlsの動作比較

今パスの通っているのは8.24で,src/ls8.25

$ ls --version
ls (GNU coreutils) 8.24
Copyright (C) 2015 Free Software Foundation, Inc.
ライセンス GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
 
作者 Richard M. Stallman および David MacKenzie。
$ src/ls --version
ls (GNU coreutils) 8.25
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
 
Written by Richard M. Stallman and David MacKenzie.

スペースの含まれたファイルを作成してlsを実行すると8.25のlsでは'で括られる.

$ touch /tmp/hoge\ fuga
$ ls /tmp/hoge\ fuga
/tmp/hoge fuga
$ src/ls /tmp/hoge\ fuga
'/tmp/hoge fuga'

日本語は大丈夫だが,エスケープの必要な文字も括られる.

$ touch /tmp/日本語 /tmp/エスケープの必要な記号\?
$ src/ls /tmp/日本語 /tmp/他の記号\?
'/tmp/他の記号?'  /tmp/日本語

パイプでの動作確認

パイプを通るとこれまでどおりの動作

$ src/ls /tmp/hoge\ fuga | cat
/tmp/hoge fuga

なので,xargsなどで処理したい場合はこれまでどおり

$ src/ls /tmp/hoge\ fuga | xargs cat
cat: /tmp/hoge: そのようなファイルやディレクトリはありません
cat: fuga: そのようなファイルやディレクトリはありません
$ src/ls /tmp/hoge\ fuga | xargs -I{} cat "{}"

回避方法x3

$ src/ls --quoting-style=literal /tmp/hoge\ fuga /tmp/エスケープの必要な記号\?
/tmp/hoge fuga  /tmp/エスケープの必要な記号?
$ src/ls -N /tmp/hoge\ fuga /tmp/エスケープの必要な記号\?
/tmp/hoge fuga  /tmp/エスケープの必要な記号?
$ QUOTING_STYLE=literal src/ls /tmp/hoge\ fuga /tmp/エスケープの必要な記号\?
/tmp/hoge fuga  /tmp/エスケープの必要な記号?

ということでとりあえずこれまでと同じ動作をさせたい場合はQUOTING_STYLE=literalを設定したりls -Naliasを設定しておくといいみたいです.

$ echo 'export QUOTING_STYLE=literal' >> ~/.bashrc

or

$ echo "alias ls='ls -N'" >> ~/.bashrc~/.bashrc

#ところでCoreutils 8.25でまたコマンドが一つ増えていました.今回は覚えやすいけど

** New commands

base32 is added to complement the existing base64 command,
and encodes and decodes printable text as per RFC 4648.

<追記>

DebianではSeverity: serious(重要度:深刻)となってsidの8.25-2no_ls_quoting.patchが入ってrevertされたようです.

$ bin/ls --version|head -1
ls (GNU coreutils) 8.25
$ bin/ls /tmp/hoge\ fuga 
/tmp/hoge fuga
$ cat patches/no_ls_quoting.patch
Description: revert inconsistent ls quoting
 This is a revert of upstream commit 109b9220cead6e979d22d16327c4d9f8350431cc.
 Info changed to reflect current upstream intentions.
 
Bug-Debian: https://bugs.debian.org/813164
 
--- coreutils-8.25.orig/NEWS
+++ coreutils-8.25/NEWS
@@ -71,9 +71,6 @@ GNU coreutils NEWS
   df now prefers sources towards the root of a device when
   eliding duplicate bind mounted entries.
 
-  ls now quotes file names unambiguously and appropriate for use in a shell,
-  when outputting to a terminal.
-
   join, sort, uniq with --zero-terminated, now treat '\n' as a field delimiter.
 
 ** Improvements
--- coreutils-8.25.orig/doc/coreutils.texi
+++ coreutils-8.25/doc/coreutils.texi
@@ -7750,8 +7750,8 @@ this"} in the default C locale.  This lo
 
 You can specify the default value of the @option{--quoting-style} option
 with the environment variable @env{QUOTING_STYLE}@.  If that environment
-variable is not set, the default value is @samp{shell-escape} when the
-output is a terminal, and @samp{literal} otherwise.
+variable is not set, the default value is @samp{literal}, but this
+default may change to @samp{shell-escape} in a future version of this package.
 
 @item --show-control-chars
 @opindex --show-control-chars
--- coreutils-8.25.orig/src/ls.c
+++ coreutils-8.25/src/ls.c
@@ -1581,7 +1581,6 @@ decode_switches (int argc, char **argv)
       if (isatty (STDOUT_FILENO))
         {
           format = many_per_line;
-          set_quoting_style (NULL, shell_escape_quoting_style);
           /* See description of qmark_funny_chars, above.  */
           qmark_funny_chars = true;
         }

</追記>

GNU coreutilsのmktempを試す

あるscriptを見ていたらmktempというコマンドを見かけました.GNU coreutilsの中の1つのようです.ユニークなテンポラリファイルやディレクトリが作成できるようです.

同じようなことをやるのにこれまではこんな感じで年月日やエポックにPIDを付けたりしてました><

$ TMP_FILE=`date +hoge-%F_%T-$$`
$ touch $TMP_FILE
$ ls -l $TMP_FILE
-rw-r--r-- 1 mk mk 0  2月 14 18:37 hoge-2016-02-14_18:36:59-13299
$ TMP_FILE=`date +hoge-%s-$$`
$ touch $TMP_FILE
$ ls -l $TMP_FILE
-rw-r--r-- 1 mk mk 0  2月 14 18:50 hoge-1455443448-13299

mktempの場合は規定値で10桁のランダムな文字が付くようです.更にファイル存在チェックもしているので衝突も起こらないという感じみたいです.

$ mktemp
/tmp/tmp.E66dzdpxMa
$ ls -l /tmp/tmp.E66dzdpxMa
-rw------- 1 mk mk 0  2月 14 18:25 /tmp/tmp.E66dzdpxMa

-dオプションでディレクトリが作成できます.

$ mktemp -d
/tmp/tmp.EFmqt7L0nY
$ ls -la /tmp/tmp.EFmqt7L0nY
合計 0
drwx------ 1 mk   mk      0  2月 14 18:27 .
drwxrwxrwt 1 root root 2920  2月 14 18:27 ..

ファイル名のテンプレートもカスタマイズできます.Xがランダム部になります.3文字以上無いと怒られます.
ランダム部のX部分が複数あると最後尾がランダムになるようです

$ mktemp XXX
zfG
$ mktemp XX
mktemp: テンプレート `hoge-XX' に含まれている X の数が少なすぎます
$ mktemp hoge-XXX
hoge-60h
$ mktemp hoge-XXXXXXXXXXXXXXXXXXXXXXXXXXXX
hoge-26CXkffROkyzwuUhej3Lza4KcdbC
$ mktemp XXX-XXX
XXX-m01
$ mktemp XXX-XXX-XXX
XXX-XXX-wqd

拡張子の指定は--suffixかテンプレートで指定できます.

$ mktemp --suffix=.log hoge-XXXX
hoge-LqWm.log
$ mktemp hoge-XXXX.log
hoge-lxtg.log

-uオプションでドライランです.でも存在チェックのタイミングがずれるのでこのファイル名を使うのは安全ではありません.

$ mktemp -u
/tmp/tmp.hdiPeJef1s
$ ls -l /tmp/tmp.hdiPeJef1s
ls: /tmp/tmp.hdiPeJef1s にアクセスできません: そのようなファイルやディレクトリはありません

-pオプションで作成されるディレクトリの変更が出来ます.(規定値は/tmp)
存在しないディレクトリを指定すると怒られるようです.

$ mktemp -p $HOME/tmp
/home/mk/tmp/tmp.dlx75Z6Wyn
$ mktemp -p `mktemp -u -d -p $HOME/tmp`
mktemp: テンプレート `/home/mk/tmp/tmp.jhGdkmp5SG/tmp.XXXXXXXXXX' からファイルを作成できません: そのようなファイルやディレクトリはありません

mktemp(3)もあるよう.

詳細はman mktemp, info mktempを.

しかしGNU coreutilsみたいな基本的なコマンドでさえ知らない使い方のわからないコマンドが結構あるのでダメですねorz
調べなければ……

$ dpkg -L coreutils | grep bin/
/usr/sbin/chroot
/usr/bin/hostid
/usr/bin/link
/usr/bin/printf
/usr/bin/truncate
/usr/bin/pr
/usr/bin/sha1sum
/usr/bin/nice
/usr/bin/tee
/usr/bin/realpath
/usr/bin/tac
/usr/bin/printenv
/usr/bin/arch
/usr/bin/logname
/usr/bin/sha384sum
/usr/bin/fold
/usr/bin/users
/usr/bin/yes
/usr/bin/paste
/usr/bin/factor
/usr/bin/pathchk
/usr/bin/basename
/usr/bin/dircolors
/usr/bin/du
/usr/bin/shuf
/usr/bin/sha224sum
/usr/bin/head
/usr/bin/tty
/usr/bin/join
/usr/bin/test
/usr/bin/runcon
/usr/bin/base64
/usr/bin/sha512sum
/usr/bin/id
/usr/bin/dirname
/usr/bin/numfmt
/usr/bin/nl
/usr/bin/install
/usr/bin/split
/usr/bin/od
/usr/bin/groups
/usr/bin/env
/usr/bin/tr
/usr/bin/comm
/usr/bin/md5sum
/usr/bin/nproc
/usr/bin/pinky
/usr/bin/uniq
/usr/bin/ptx
/usr/bin/sha256sum
/usr/bin/cksum
/usr/bin/who
/usr/bin/cut
/usr/bin/[
/usr/bin/csplit
/usr/bin/expand
/usr/bin/unexpand
/usr/bin/seq
/usr/bin/stdbuf
/usr/bin/unlink
/usr/bin/chcon
/usr/bin/timeout
/usr/bin/tsort
/usr/bin/expr
/usr/bin/stat
/usr/bin/tail
/usr/bin/mkfifo
/usr/bin/sort
/usr/bin/nohup
/usr/bin/fmt
/usr/bin/whoami
/usr/bin/sum
/usr/bin/wc
/usr/bin/shred
/bin/cp
/bin/dd
/bin/false
/bin/readlink
/bin/echo
/bin/vdir
/bin/mknod
/bin/rm
/bin/df
/bin/rmdir
/bin/sleep
/bin/true
/bin/date
/bin/stty
/bin/ln
/bin/mktemp
/bin/cat
/bin/ls
/bin/uname
/bin/chmod
/bin/touch
/bin/mv
/bin/sync
/bin/mkdir
/bin/dir
/bin/chgrp
/bin/chown
/bin/pwd
/usr/bin/md5sum.textutils

cd(change directory)コマンドの-(hyphen)オプションを今頃知る

以下の記事を読んで知ったのですが,

「さっきいた場所に戻る」の呪文を覚えておきたい。それは「cd -」だ。
画面のように、cdコマンドに引数として「-」のみを指定すると、直前にいたディレクトリに戻ることができる。

毎日何十回も叩いているであろうコマンドなのに知らなかったですorz

mk@x220:~$ cd usr/local/bin
mk@x220:~/usr/local/bin$ cd
mk@x220:~$ cd -
/home/mk/usr/local/bin
mk@x220:~/usr/local/bin$

なるほど確かに.
これは便利ですね.ちなみに同じようなことをするのにpushd/popdを使っていました.組み合わせて使っても大丈夫みたいですね.

mk@x220:~/usr/local/bin$ pushd /tmp
/tmp ~/usr/local/bin
mk@x220:/tmp$ cd
mk@x220:~$ cd -
/tmp
mk@x220:/tmp$ cd /
mk@x220:/$ popd
~/usr/local/bin
mk@x220:~/usr/local/bin$ cd

手元の環境でGNU bash 4.3.42, Zsh 5.2, DASH 0.5.8, BusyBox v1.22.1built-in shell (ash)で動作するのを確認しました.
#そしてpushd/popdDASH, ashに無いのを確認orz

しかしこういうの未だいっぱいあるんだろうなーorz