basE91で少し効率よくバイナリをテキストに変換

バイナリを利用できない環境でのデータ転送時にUNIX環境では古くは uudecode, uuencode が,日本のパソコン通信では ish などが使われていました.近頃は base64 がよく使われているように感じます.

これらのツールではバイナリをASCIIで表現するためサイズが大きくなってしまいます.でも全てのASCIIを使っていません.

今回見つけたbasE91はASCIIの0x21-0x7Eのうち -, \, ' を除いた91文字を使ってデコードすることで効率よくするもののようです.

早速試してみます.Debianパッケージがないかなと探しましたがありませんでした.

sourceを貰ってきてmakeします.
※hashは「 basE91 – Browse /basE91/0.6.0 at SourceForge.net 」で確認できる.

$ wget http://downloads.sourceforge.net/base91/base91-0.6.0.tar.gz
$ md5sum base91-0.6.0.tar.gz
e227841d900cc463a162bd79775aeb54  base91-0.6.0.tar.gz
$ sha1sum base91-0.6.0.tar.gz
00cfd573ec8b3d0160dbf53e2c7a49b99a1aa720  base91-0.6.0.tar.gz
$ tar tvf base91-0.6.0.tar.gz
-rw-r--r-- 0/0             575 2005-06-25 00:00 base91-0.6.0/AWK/README
-rwxr-xr-x 0/0             727 2006-11-02 05:13 base91-0.6.0/AWK/b91dec.awk
-rw-r--r-- 0/0             932 2006-09-04 03:00 base91-0.6.0/PHP4/README
-rw-r--r-- 0/0            1513 2006-11-02 05:13 base91-0.6.0/PHP4/base91.php
-rw-r--r-- 0/0             149 2006-09-04 03:00 base91-0.6.0/test/Makefile
-rw-r--r-- 0/0            4265 2006-11-02 05:13 base91-0.6.0/test/test.sh
-rw-r--r-- 0/0             332 2006-08-25 17:00 base91-0.6.0/DOS-asm/readme.txt
-rw-r--r-- 0/0            3487 2006-11-02 05:13 base91-0.6.0/DOS-asm/b91enc.asm
-rw-r--r-- 0/0            5034 2006-11-02 05:13 base91-0.6.0/Java/b91cli.java
-rw-r--r-- 0/0            3297 2006-11-02 05:13 base91-0.6.0/Java/basE91.java
-rw-r--r-- 0/0            1526 2006-11-02 05:13 base91-0.6.0/Java/license.txt
-rw-r--r-- 0/0             793 2006-11-02 05:13 base91-0.6.0/Java/readme.txt
-rw-r--r-- 0/0             112 2006-09-04 03:00 base91-0.6.0/Java/manifest.mf
-rwxr-xr-x 0/0             178 2006-11-02 05:13 base91-0.6.0/Java/build_jar.sh
-rw-r--r-- 0/0            7502 2006-11-02 05:13 base91-0.6.0/cli.c
-rw-r--r-- 0/0            5066 2006-11-02 05:13 base91-0.6.0/base91.c
-rw-r--r-- 0/0            1501 2006-11-02 05:13 base91-0.6.0/LICENSE
-rw-r--r-- 0/0             561 2006-11-02 05:13 base91-0.6.0/base91.h
-rw-r--r-- 0/0            2360 2006-11-02 05:13 base91-0.6.0/README
-rw-r--r-- 0/0            1762 2006-11-02 05:13 base91-0.6.0/base91.1
-rw-r--r-- 0/0             903 2006-09-04 03:00 base91-0.6.0/Makefile
-rw-r--r-- 0/0            2330 2006-11-02 05:13 base91-0.6.0/NEWS
$ tar xf base91-0.6.0.tar.gz
$ cd base91-0.6.0
$ make
$ ./base91 -h
Usage: base91 [OPTION]... [FILE]
basE91 encode or decode FILE, or standard input, to standard output.

  -d, --decode          decode data
  -m SIZE               use SIZE bytes of memory for buffers (suffixes b, K, M)
  -o, --output=FILE     write to FILE instead of standard output
  -v, --verbose         verbose mode
  -w, --wrap=COLS       wrap encoded lines after COLS characters (default 76)
  --help                display this help and exit
  --version             output version information and exit

With no FILE, or when FILE is -, read standard input.

encodeしてdecodeしてみます.
当たり前ですが,encode, decodeしてもdiffもhashも同じです.

$ ./base91 ./base91 -o ./base91.base91
$ ./base91 -d ./base91.base91 -o ./base91.tmp
$ diff ./base91 ./base91.tmp
$ sha512sum ./base91
bc903be7c5b694841a9d0303351846f80f4798ad8848e8f298cf2c4818c68a2270b065db495b969503b25cdf672632e1cced18094f935fed47b75718c3c3e976  ./base91
$ ./base91 ./base91 | ./base91 -d | sha512sum
bc903be7c5b694841a9d0303351846f80f4798ad8848e8f298cf2c4818c68a2270b065db495b969503b25cdf672632e1cced18094f935fed47b75718c3c3e976  -

basE91, base64, base32, uudecode で変換してみます.
basE91 が一番小さいですね

$ ls --block-size=1 -s ./base91
16384 ./base91
$ ./base91 ./base91 | wc -c
17340
$ base64 ./base91 | wc -c
19615
$ uuencode ./base91 - | wc -c
20024
$ base32 ./base91 | wc -c
23538

圧縮すると大分小さくなります.圧縮のほうがずっと効きますね.

$ xz -c ./base91 | wc -c
4528
$ xz -c ./base91 | ./base91 | wc -c
5640
$ xz -c ./base91 | base64 | wc -c
6120
$ xz -c ./base91 | uuencode - | wc -c
6260
$ xz -c ./base91 | base32 | wc -c
7344

他のファイルも試してみます./usr/bin 以下のファイルを適当に見繕って比較x5です.

#!/bin/bash

XZ=`mktemp`
for i in `seq 1 5`
do
  CMD=`find /usr/bin -type f | shuf -n 1`
  echo $CMD
  echo -n "raw  "
  stat -c %s $CMD
  xz -9 -c $CMD > $XZ
  echo -n "xz "
  stat -c %s $XZ
  echo -n "xz.uu  "
  uuencode $XZ - | wc -c
  echo -n "xz.base64  "
  base64 $XZ | wc -c
  echo -n "xz.base91  "
  base91 $XZ | wc -c
done
rm $XZ
$ bash ./bin2ascii.bash | column -t
/usr/bin/lxc-snapshot
raw                          27632
xz                           6756
xz.uu                        9328
xz.base64                    9127
xz.base91                    8418
/usr/bin/dh_installtmpfiles
raw                          3263
xz                           1540
xz.uu                        2144
xz.base64                    2084
xz.base91                    1917
/usr/bin/pbmtogo
raw                          10384
xz                           3164
xz.uu                        4380
xz.base64                    4276
xz.base91                    3942
/usr/bin/chartread
raw                          3966528
xz                           772956
xz.uu                        1064980
xz.base64                    1044169
xz.base91                    963047
/usr/bin/spamassassin
raw                          29898
xz                           9608
xz.uu                        13258
xz.base64                    12981
xz.base91                    11971

おまけ?armelでstatic linkなバイナリを作ってみました.Sipeed Lichee Nano で動かないかな?と.

$ git diff HEAD~~ Makefile
diff --git a/Makefile b/Makefile
index 246aede..129acff 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
-CFLAGS = -Wall -W -O2
-LDFLAGS = -s
+CFLAGS = -static -Wall -W -O2
+LDFLAGS = -static -s

-CC = gcc
+CC = arm-linux-gnueabi-gcc
 INSTALL = install
 INSTALL_DATA = $(INSTALL) -m 444
 INSTALL_PROGRAM = $(INSTALL) -m 555

qemu-arm-static では動くのを確認したけど実機では未確認です.

$ file ./base91
./base91: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, BuildID[sha1]=88ec4ccbf69c4bb41640b5de63b6b5373b7e5365, for GNU/Linux 3.2.0, stripped
$ ldd ./base91
        not a dynamic executable
$ echo 😺 | qemu-arm-static ./base91 | pee cat "qemu-arm-static ./base91 -d"
=~m6xHA
😺

以下にバイナリとuuencodeしたものが置いてあります.

blog元のmemo

環境
$ dpkg-query -W gcc-10-arm-linux-gnueabi qemu-user-static gcc coreutils sharutils
coreutils       8.32-3
gcc     4:10.1.0-1
gcc-10-arm-linux-gnueabi        10.2.0-3cross2
qemu-user-static        1:5.0-13
sharutils       1:4.15.2-5
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64

鹿児島Linux User Groupの鹿児島Linux勉強会 2020.07(オンライン)に参加

  • 「鹿児島Linux勉強会 2020.07」
    日時
    2020-07-26(sun) 14:00〜17:00
    会場
    Discord
    テキストチャンネル「meetup-202007」,ボイスチャンネル「General」.
    前回まではボイスチャンネルを分けていたけど今の所勉強会のとき以外はボイスチャンネルが使われていない&間違える人が居たのでGeneralのみに.テキストチャンネルは毎回分けて終了後しばらくしたらアーカイブする感じにしています.

参加人数は申込者9人で実際の参加者は7人でした.地域は鹿児島県が3人,その他4人(東京都,静岡県,岐阜県,愛知県x2)オンラインになってからの鹿児島の参加人数が一番多かった気がします.

以下のような話題で盛り上がりました.

  • 「Photon OSを使ってみた話」
  • 「ssh login時の通知を簡単に設定できないか?の相談」
  • 「ArchiveBoxで自分用WebArchive(django版)」
  • 「5月のYoctoLTSの続報」
  • 「ArchLinuxのインストールがうまく行かない相談」
  • 「m3u8のプレイリストからダウンロード」
  • 「Free RADIUSサーバーの構築についての相談」

この中で私の発表は,「ArchiveBoxで自分用WebArchive(django版)」でした.鹿児島Linux勉強会2019.08(オンライン)での発表の続報でした.不具合が減っていろいろと機能も増えていい感じです.リモートで試せるようデモサーバをRaspberry Piで起動して触って貰ったりしました.

次回は08/23(日)の開催予定です.

Raspberry Pi OS/Debian/Ubuntuでの既定のPython切り替え

最近使うPythonアプリはPython3が多くなっています.Python2のEoLが迫っているので正しいのですが,手元の環境では python コマンドは python2 に向いています.python3 コマンドを叩けばいいのですが,これを python3 に向けられないかなと試してみました.

Raspberry Pi OS arm64(busterベース)でのPython確認してみます.python コマンドは python2.7 を呼ぶようになっています.

$ python --version
Python 2.7.16
$ ls -l `which python`
lrwxrwxrwx 1 root root 7  3月  5  2019 /usr/bin/python -> python2
$ ls -l `which python2`
lrwxrwxrwx 1 root root 9  3月  5  2019 /usr/bin/python2 -> python2.7
$ ls -l `which python3`
lrwxrwxrwx 1 root root 9  3月 26  2019 /usr/bin/python3 -> python3.7

update-alternatives で管理されてるのかな?と思いましたが設定がなさそうです.

$ update-alternatives --get-selections|grep -i ^python

update-alternatives を手動で設定してみます.
これで python コマンドが python3.7 を呼ぶようになりました.

$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
update-alternatives: /usr/bin/python (python) を提供するために自動モードで /usr/bin/python2.7 を使います
$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.7 2
update-alternatives: /usr/bin/python (python) を提供するために自動モードで /usr/bin/python3.7 を使います
$ ls -l `which python`
lrwxrwxrwx 1 root root 24  7月 28 08:47 /usr/bin/python -> /etc/alternatives/python
$ python --version
Python 3.7.3
$ update-alternatives --query python
Name: python
Link: /usr/bin/python
Status: auto
Best: /usr/bin/python3.7
Value: /usr/bin/python3.7

Alternative: /usr/bin/python2.7
Priority: 1

Alternative: /usr/bin/python3.7
Priority: 2

切り替えたいときはこんな感じで選択肢なおせばok.

$ sudo update-alternatives --config python
alternative python (/usr/bin/python を提供) には 2 個の選択肢があります。

  選択肢    パス              優先度  状態
------------------------------------------------------------
* 0            /usr/bin/python3.7   2         自動モード
  1            /usr/bin/python2.7   1         手動モード
  2            /usr/bin/python3.7   2         手動モード

現在の選択 [*] を保持するには <Enter>、さもなければ選択肢の番号のキーを押してください:

Debian asid amd64, Ubuntu 20.04 LTS amd64 でも設定してみました.

Debian sid amd64
$ update-alternatives --query python
Name: python
Link: /usr/bin/python
Status: auto
Best: /usr/bin/python3.8
Value: /usr/bin/python3.8

Alternative: /usr/bin/python2.7
Priority: 1

Alternative: /usr/bin/python3.7
Priority: 2

Alternative: /usr/bin/python3.8
Priority: 3
Ubuntu 20,04 LTS amd64
$ update-alternatives --query python
Name: python
Link: /usr/bin/python
Status: auto
Best: /usr/bin/python3.8
Value: /usr/bin/python3.8

Alternative: /usr/bin/python2.7
Priority: 1

Alternative: /usr/bin/python3.5
Priority: 2

Alternative: /usr/bin/python3.8
Priority: 3

てことで python コマンドが python3 になりました.しかしシステムワイドな設定なのでシステムのプログラムなどで問題が出るかもしれないですね.
問題が起こったらpython2に戻しましょう.

Rasoberry Pi OS amd64
$ dpkg-query -W python python3
python  2.7.16-1
python3 3.7.3-1
$ lsb_release -dr
Description:    Debian GNU/Linux 10 (buster)
Release:        10
$ uname -m
aarch64
$ cat /proc/device-tree/model&&echo
Raspberry Pi 3 Model B Rev 1.2
Debian sid amd64
$ dpkg-query -W python python3 python3.7
python  2.7.17-2
python3 3.8.2-3
python3.7       3.7.7-1+b1
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64
Ubuntu 20.04 LTS amd64
$ dpkg-query -W python python3 python3.7
python  2.7.17-1
python3 3.8.2-0ubuntu2
python3.7
$ lsb_release -dr
Description:    Ubuntu 20.04.1 LTS
Release:        20.04
$ uname -m
x86_64

Sipeed Lichee Nanoでhello world

2020-07-23低レベル勉強会に参加しました.Zoom.usでの開催でした.

内容はLinux名刺的なものを開発しようという内容で,リファレンスとしてSDカードサイズの小さなLinuxの動作するarmコンピュータのSipeed Lichee Nanoを使いました.

欲しい場合は1000円ちょいくらいからで入手できそうです.

Lichee Nanoを持っていない人はリモートで触れるようにしてあったので持っていない私も楽しめました.

このリモート開発の仕組みはLichee NanoとRaspberry PiをUSB経由のUARTで接続し,Raspberry PiでGNU screenを起動,ssh経由でGNU screenに繋いで操作という感じです.
GNU screenをGotty等にするとウェブブラウザで参加できてちょっと便利かもと思ったりも.(GoTTYは開発止まってるように見えるから別のもののほうがいいかもしれない)

Lichee Nanoで何かを動かしたい.armだけどarmhf動くのかな?とりあえずなにか転送して動かしてみようと.

とりあえずDebianのarmhfバイナリをuuencodeしてコピペで転送してみます.これが動けばDebianのパッケージ群が利用できるかもだけど…….

まずは簡単そうなfortuneを試します.

Debian sidでfortune-modパッケージのarmhfバイナリパッケージをダウンロードして展開(add archtecture armhfしてある環境)
$ apt download -t armhf fortune-mod
$ unar fortune-mod_1.99.1-7+b1_armhf.deb
$ cd fortune-mod_1.99.1-7+b1_armhf
$ tar xf data.tar.xz
$ cd usr/games

Lichee Nanoはserialで接続されていて,Internetには繋がっていないのでバイナリファイルの転送にはuudecode/uuencodeを使いました.久々です.
手元のGNU sharutils 4.15.2のuudecodeにはbase64を使う -m, --base64 があるので良さそう.と思ったけどLichee Nanoの方はbusyboxのもので非対応でした.

ローカル端末で圧縮してuuencodeしてクリップボードへ
$ gzip -c fortune | uuencode fortune.gz > fortune.gz.uu
$ cat fortune.gz.uu | xclip
リモートで伸張して解凍
# cat | uudecode    #ここでクリップボードから貼り付け
# zcat fortune.gz > fortune
# rm fortune.gz

そして…​…​

# ./fortune
-sh: ./fortune: not found
# ldd ./fortune
checking sub-depends for 'not found'
checking sub-depends for '/lib/libc.so.6'
/lib/ld-linux.so.3 (0xb6fa0000)
librecode.so.0 => not found (0x00000000)
libc.so.6 => /lib/libc.so.6 (0x00000000)
/lib/ld-linux.so.3 => /lib/ld-linux.so.3 (0x00000000)

これを動かすのはダイナミックリンクされているものを用意してあげないといけないのでストレージの容量的に難しいですね.

ここではgzipで圧縮しましたが,Lichee Nanoのbusyboxにxzがありました.gzipよりxzにしたほうが小さくなりますね.試してみるとこんな感じでした.$ xz -c fortune | uuencode fortune.xz > fortune.xz.uu

サイズ比較
-rw-r--r-- 1 matoken matoken 22368 Jul 23 15:11 fortune #元ファイル
-rw-r--r-- 1 matoken matoken 30844 Jul 23 14:58 fortune.uu 
-rw-r--r-- 1 matoken matoken 14975 Jul 23 15:08 fortune.gz.uu  + uudecode
-rw-r--r-- 1 matoken matoken 13047 Jul 23 15:47 fortune.xz.uu  + uudecode

そういえばあまり有名ではないですがbasE91なんてものもあります.base64よりサイズが小さくなりますが導入からやらないといけないのでちょっと面倒.

Hello worldを試してみます.適当にプログラムを用意してスタティックリンクでコンパイルしてみます.

$ cat hello.c
 <stdio.h>
int
main(void)
{
    printf("Hello, world!\n");
    return 0;
}
$ gcc -static ./hello.c
$ ./a.out
Hello, world!
$ ls -l a.out
-rwxr-xr-x 1 pi pi 571120 7月 23 16:18 a.out

でかい…​…​

とりあえずでかいのはおいといてこれだとarm64なので動くはずがない.ということでクロスコンパイル環境を用意します.

今回試したホストはDebian sid amd64/Ubuntu 20.04 LTS arm64/Raspberry Pi OS arm64です.いずれも同じ手順でOKでした.

crossbuild-essential-<arch> パッケージで各種アーキテクチャの環境が導入できるようです.

$ apt-cache search crossbuild-essential-
crossbuild-essential-amd64 - Informational list of cross-build-essential packages
crossbuild-essential-arm64 - Informational list of cross-build-essential packages
crossbuild-essential-armel - Informational list of cross-build-essential packages
crossbuild-essential-armhf - Informational list of cross-build-essential packages
crossbuild-essential-i386 - Informational list of cross-build-essential packages
crossbuild-essential-powerpc - Informational list of cross-build-essential packages
crossbuild-essential-ppc64el - Informational list of cross-build-essential packages
crossbuild-essential-s390x - Informational list of cross-build-essential packages
crossbuild-essential-mips - Informational list of cross-build-essential packages
crossbuild-essential-mips64 - Informational list of cross-build-essential packages
crossbuild-essential-mips64el - Informational list of cross-build-essential packages
crossbuild-essential-mips64r6 - Informational list of cross-build-essential packages
crossbuild-essential-mips64r6el - Informational list of cross-build-essential packages
crossbuild-essential-mipsel - Informational list of cross-build-essential packages
crossbuild-essential-mipsr6 - Informational list of cross-build-essential packages
crossbuild-essential-mipsr6el - Informational list of cross-build-essential packages

沢山あります.今回はarmlf/armhfの crossbuild-essential-armel, crossbuild-essential-armhf を導入しました.

$ sudo apt install crossbuild-essential-armel crossbuild-essential-armhf

gccだけでいい場合はarmlfは gcc-arm-linux-gnueabi,armhfは gcc-arm-linux-gnueabihf だけでOKです.

まずは arm-linux-gnueabihf-gcc を使ってarmhfのバイナリを作ります.

$ /usr/bin/arm-linux-gnueabihf-gcc -static ./hello.c
$ strip a.out
$ xz -c a.out | uuencode a.out.xz > a.out.xz.uu

armhfは駄目そうです.

# cat | uudecode
^d
# xzcat ./a.out.xz > ./a.out
# chmod +x ./a.out
# ./a.out
Segmentation fault

次は gcc-arm-linux-gnueabi でarmlfのバイナリを作って試すと動きました.

$ /usr/bin/arm-linux-gnueabi-gcc -static ./hello.c
$ strip a.out
$ xz -c a.out | uuencode a.out.xz > a.out.xz.uu
# cat | uudecode
^d
# xzcat ./a.out.xz > ./a.out
# chmod +x ./a.out
# ./a.out
Hello, world!
# /usr/bin/time -f "%M KB" ./a.out
Hello, world!
2144 KB

この辺りで今回は時間切れ.次回の同じような感じになりそうです.興味のある方は以下のページから.

とりあえずarmelのバイナリが動くようなのがわかったので面白そうな小さなプログラムを試そうかなと思っています.cowsayとか好きなんだけどこれはPerlなので容量的に難しそう.とりあえずfortuneあたりかな?

以前PQI Air PenでやったようにSD cardを用意してそこにDebian armlf環境を展開してchrootとかもできそうです.

rsync 3.2.0の新機能を少し試す

ファイル同期にとても便利なrsyncの3.2.0がリリースされました.

バグフィクスや,いくつかの新機能が入ったようなので少し試してみました.

※1. この記事投稿時には 3.2.2 が出ています.
※2. 鹿児島Linux勉強会 2020.06で発表したものと同じ内容です.

導入例

Debian sid amd64 & Ubuntu 20.04 LTS amd64

$ sudo apt build-dep rsync
$ sudo apt install libxxhash-dev libzstd-dev liblz4-dev
$ wget -c \
https://download.samba.org/pub/rsync/rsync-3.2.0.tar.gz \
https://download.samba.org/pub/rsync/rsync-3.2.0.tar.gz.asc \
https://opencoder.net/WayneDavison.key
$ gpg2 --import ./WayneDavison.key
$ gpg2 --verify ./rsync-3.2.0.tar.gz.asc
$ tar tvzf ./rsync-3.2.0.tar.gz
$ tar xzf ./rsync-3.2.0.tar.gz
$ cd rsync-3.2.0
$ ./configure --help
$ ./configure
$ make
$ ./rsync --version
rsync  version 3.2.0  protocol version 31
Copyright (C) 1996-2020 by Andrew Tridgell, Wayne Davison, and others.
Web site: http://rsync.samba.org/
Capabilities:
    64-bit files, 64-bit inums, 64-bit timestamps, 64-bit long ints,
    socketpairs, hardlinks, symlinks, IPv6, batchfiles, inplace, append,
    ACLs, xattrs, iconv, symtimes, prealloc, SIMD
Checksum list:
    xxh64 (xxhash) md5 md4 none
Compress list:
    zstd lz4 zlibx zlib none

rsync comes with ABSOLUTELY NO WARRANTY.  This is free software, and you
are welcome to redistribute it under certain conditions.  See the GNU
General Public Licence for details.
Note
gpg鍵は次から入手できます.rsync download

Raspberri Pi OS amd64

Raspberry Pi OS arm64の場合 libzstd-dev のバージョンが 1.3.8+dfsg-3 と少し古くbuildに失敗します. ./configure --disable-zstd としてzstdを無効にするか,sourceから zstd 1.4.5 を導入することでbuild出来ました.

$ make
  :
token.c: In function ‘init_compression_level’:
token.c:73:40: warning: implicit declaration of function ‘ZSTD_minCLevel’; did you mean ‘ZSTD_maxCLevel’? [-Wimplicit-function-declaration]
   min_level = skip_compression_level = ZSTD_minCLevel();
                                        ^~~~~~~~~~~~~~
                                        ZSTD_maxCLevel
token.c: In function ‘send_zstd_token’:
token.c:685:2: error: unknown type name ‘ZSTD_EndDirective’; did you mean ‘ZSTD_DDict’?
  ZSTD_EndDirective flush = ZSTD_e_continue;
  ^~~~~~~~~~~~~~~~~
  ZSTD_DDict
token.c:685:28: error: ‘ZSTD_e_continue’ undeclared (first use in this function)
  ZSTD_EndDirective flush = ZSTD_e_continue;
                            ^~~~~~~~~~~~~~~
token.c:685:28: note: each undeclared identifier is reported only once for each function it appears in
token.c:701:3: warning: implicit declaration of function ‘ZSTD_CCtx_setParameter’ [-Wimplicit-function-declaration]
   ZSTD_CCtx_setParameter(zstd_cctx, ZSTD_c_compressionLevel, do_compression_level);
   ^~~~~~~~~~~~~~~~~~~~~~
token.c:701:37: error: ‘ZSTD_c_compressionLevel’ undeclared (first use in this function); did you mean ‘skip_compression_level’?
   ZSTD_CCtx_setParameter(zstd_cctx, ZSTD_c_compressionLevel, do_compression_level);
                                     ^~~~~~~~~~~~~~~~~~~~~~~
                                     skip_compression_level
token.c:751:13: error: ‘ZSTD_e_flush’ undeclared (first use in this function); did you mean ‘ZSTD_DCtx_s’?
     flush = ZSTD_e_flush;
             ^~~~~~~~~~~~
             ZSTD_DCtx_s
token.c:753:8: warning: implicit declaration of function ‘ZSTD_compressStream2’; did you mean ‘ZSTD_compressStream’? [-Wimplicit-function-declaration]
    r = ZSTD_compressStream2(zstd_cctx, &zstd_out_buff, &zstd_in_buff, flush);
        ^~~~~~~~~~~~~~~~~~~~
        ZSTD_compressStream
$ cd ..
$ sudo apt remove libzstd-dev
$ wget https://github.com/facebook/zstd/releases/download/v1.4.5/zstd-1.4.5.tar.gz \
https://github.com/facebook/zstd/releases/download/v1.4.5/zstd-1.4.5.tar.gz.sha256
$ sha256sum -c ./zstd-1.4.5.tar.gz.sha256
$ tar tvf ./zstd-1.4.5.tar.gz | lv
$ tar xf ./zstd-1.4.5.tar.gz
$ cd zstd-1.4.5
$ make
$ sudo make install
$ cd ../rsync-3.2.0
$ ./configure && make

Debian sid amd64

Debian sid amd64 環境にはすでに降ってきているのでパッケージから導入するだけでOKです.

$ sudo apt install rsync
$ rsync --version
rsync  version 3.2.0  protocol version 31
Copyright (C) 1996-2020 by Andrew Tridgell, Wayne Davison, and others.
Web site: http://rsync.samba.org/
Capabilities:
    64-bit files, 64-bit inums, 64-bit timestamps, 64-bit long ints,
    socketpairs, hardlinks, symlinks, IPv6, batchfiles, inplace, append,
    ACLs, xattrs, iconv, symtimes, prealloc, SIMD
Checksum list:
    xxh64 (xxhash) md5 md4 none
Compress list:
    zstd lz4 zlibx zlib none

rsync comes with ABSOLUTELY NO WARRANTY.  This is free software, and you
are welcome to redistribute it under certain conditions.  See the GNU
General Public Licence for details.
$ dpkg-query -W rsync
rsync   3.2.0-1

ってことで試せるようになりました.NEWSを見てみます.

BUG FIX

Avoid a hang when an overabundance of messages clogs up all the I/O buffers.

このバグ修正がちょっと気になります.fat32の制限に引っかかったときに帰ってこない問題もこれで解決してるかも?未確認.

ENHANCEMENTS

–checksum-choice=STR, –cc=STR

チェックサム形式を選べるようになったようです.現在選択できるのは xxh64/md5/md4 の3種類 or none or auto(既定値)

man(1)より
              o      auto (the default)
              o      xxh64 (aka xxhash)
              o      md5
              o      md4
              o      none

--version にも出力されます.

$ rsync --version | grep Checksum -A1
Checksum list:
    xxh64 (xxhash) md5 md4 none

configure option に --disable-xxhash がありました.

  --disable-xxhash        disable xxhash checksums

環境変数 RSYNC_CHECKSUM_LIST でも指定できます.オプション --checksum-choice がある場合はオプションのほうが優先なようです.

ちなみに --checksum-choice オプションに対応していない 3.1.3 に対して xxh64 を向けて叩いてみると以下のようなエラーになりました.(md4, md5 はok)

$ rsync --checksum-choice=xxh64 -avc ./* user@remote:/tmp/
unknown checksum name: xxh64
rsync error: requested action not supported (code 4) at checksum.c(73) [server=3.1.3]
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(235) [sender=3.2.0]

時間がどのくらい変わるかちょうど転がっていたkernel source(小さいファイルが沢山)で試してみました.はじめ普通に同期した後,キャッシュクリアして md4, md5, xxh64 で試してみました.思ったより差が出ない感じ?

md4
$ find ./linux-5.6 | wc -l
82114
$ du -ms ./linux-5.6
1310    ./linux-5.6
$ rsync --checksum-choice=auto -ac ./linux-5.6 /tmp/
$ sync ; echo 3 | sudo tee /proc/sys/vm/drop_caches ; time rsync --checksum-choice=md4 -ac ./linux-5.6 /tmp/
3

real    0m52.393s
user    0m5.051s
sys     0m12.246s
md5
$ sync ; echo 3 | sudo tee /proc/sys/vm/drop_caches ; time rsync --checksum-choice=md5 -ac ./linux-5.6 /tmp/
3

real    0m57.716s
user    0m6.976s
sys     0m13.486s
xxh64
$ sync ; echo 3 | sudo tee /proc/sys/vm/drop_caches ; time rsync --checksum-choice=xxh64 -ac ./linux-5.6 /tmp/
3

real    1m5.520s
user    0m2.507s
sys     0m13.625s

大きめのファイルでも試してみました.4GB程のisoファイル1つです.md4, md5 はあまり代わりませんが,xxh64 はかなり高速ですね.

md4
$ ls -s ./Parrot-security-4.9.1_x64.iso*
3909164 ./Parrot-security-4.9.1_x64.iso  3909164 ./Parrot-security-4.9.1_x64.iso2
$ sync ; echo 3 | sudo tee /proc/sys/vm/drop_caches ; time rsync --checksum-choice=md4 -ac ./Parrot-security-4.9.1_x64.iso ./Parrot-security-4.9.1_x
64.iso2
3

real    0m23.276s
user    0m10.601s
sys     0m4.387s
md5
$ sync ; echo 3 | sudo tee /proc/sys/vm/drop_caches ; time rsync --checksum-choice=md5 -ac ./Parrot-security-4.9.1_x64.iso ./Parrot-security-4.9.1_x64.iso2
3

real    0m28.150s
user    0m16.945s
sys     0m4.399s
xxh64
$ sync ; echo 3 | sudo tee /proc/sys/vm/drop_caches ; time rsync --checksum-choice=xxh64 -ac ./Parrot-security-4.9.1_x64.iso ./Parrot-security-4.9.1_x64.iso2
3

real    0m12.767s
user    0m1.375s
sys     0m4.060s

この辺の速度は環境により大分変わると思うので参考程度に.

–compress-choice=STR, –zc=STR

--compress オプション利用時の圧縮形式を指定できるようです.

圧縮形式はrsync 3.2.0 同士では zlibx 形式が zlib 形式よりも優先されるようです.
選択できるオプションは zstd, lz4, zlibx, zlib, none のようです.

man(1)より
              o      zstd
              o      lz4
              o      zlibx
              o      zlib
              o      none

rsync --version でも確認できます.

$ rsync --version | grep Compress -A1
Compress list:
    zstd lz4 zlibx zlib none

configure oprion に --disable-zstd, --disable-lz4 があります.

  --disable-zstd          disable zstd compression
  --disable-lz4           disable LZ4 compression

環境変数 RSYNC_COMPRESS_LIST でも指定できるようです.

未対応の 3.1.3 に対して指定すると unknown option と言われます.

$ time rsync --compress-choice=zstd --compress -a ./hoge mk@x201i.local:/tmp/
rsync: on remote machine: --compress-choice=zstd: unknown option
rsync error: syntax or usage error (code 1) at main.c(1596) [server=3.1.3]
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(235) [sender=3.2.0]

こちらも簡単にベンチを.でもWi-Fi環境だし参考程度に.

zstd
$ ssh user@remote rm -rf ~/tmp/linux-5.6; echo 3 | sudo tee /proc/sys/vm/drop_caches; time rsync --compress-choice=zstd --compress -a --rsync-path=~/src/rsync-3.2.0/rsync ~/src/linux-5.6 user@remote:~/tmp/
3

real    4m38.921s
user    0m24.463s
sys     0m7.182s
lz4
$ ssh user@remote rm -rf ~user/tmp/linux-5.6; echo 3 | sudo tee /proc/sys/vm/drop_caches; time rsync --compress-choice=lz4 --compress -a --rsync-path=~/src/rsync-3.2.0/rsync ~/src/linux-5.6 user@remote:~/tmp/
3

real    9m28.829s
user    0m4.878s
sys     0m6.177s
zlibx
$ ssh user@remote rm -rf ~user/tmp/linux-5.6; echo 3 | sudo tee /proc/sys/vm/drop_caches; time rsync --compress-choice=zlibx --compress -a --rsync-path=~/src/rsync-3.2.0/rsync ~/src/linux-5.6 user@remote:~/tmp/
3

real    5m21.702s
user    0m46.740s
sys     0m6.541s
zlib
$ ssh user@remote rm -rf ~user/tmp/linux-5.6; echo 3 | sudo tee /proc/sys/vm/drop_caches; time rsync --compress-choice=zlib --compress -a --rsync-path=~/src/rsync-3.2.0/rsync ~/src/linux-5.6 user@remote:~/tmp/
3

real    5m28.722s
user    0m45.861s
sys     0m6.381s
none
$ ssh user@remote rm -rf ~user/tmp/linux-5.6; echo 3 | sudo tee /proc/sys/vm/drop_caches; time rsync --compress-choice=none -a --rsync-path=~/src/rsync-3.2.0/rsync ~/src/linux-5.6 user@remote:~/tmp/
3

real    22m56.712s
user    0m1.848s
sys     0m7.323s

–debug=NSTR

チェックサムと圧縮の詳細を表示するオプションのようです.どのアルゴリズムを利用しているのかが確認できます.

–debug=NSTR を付けたときのの実行結果例
Client negotiated checksum: xxh64
Client compress: zstd (level 3)

–debug=OPTS, -M—​debug=OPTS

--debug=OPTS を使うとリモートのrsyncにデバッグオプションを送らなくなるようです.これによりクライアント側とサーバ側で異なるデバッグレベルを指定できるようになったそうです.
リモート側にオプションを送る場合には -M—​debug=OPTS

SIGINFO & SIGVTALRM

rsyncプロセスに SIGINFO & SIGVTALRM シグナルを送信することでステータスを表示できるようになったようです.Linuxは SIGINFO に対応していないので, SIGVTALRM を試しました.

rsyncを実行している状態で SIGVTALRM を送信
$ pkill -SIGVTALRM rsync
rsyncがステータスを表示
linux-5.6/arch/sparc/lib/lshrdi3.S
    114,384,392  81%  931.12kB/s    0:01:59 (xfr#21058, ir-chk=1030/23451)

–copy-as=USER[:GROUP]

指定ユーザ/グループ権限でファイルをコピーするようです.

コピー元に3ユーザのファイル
$ ls -Al /tmp/rsync-test/
total 0
-rw-r--r-- 1 matoken  matoken  0 Jun 25 18:50 matokenfile
-rw-r--r-- 1 root     root     0 Jun 25 18:51 root
-rw-r--r-- 1 www-data www-data 0 Jun 25 18:51 www-data
普通にコピーするとユーザが引き継がれる
$ sudo ./rsync -a /tmp/rsync-test/ /tmp/rsync-test2
$ ls -lA /tmp/rsync-test2
total 0
-rw-r--r-- 1 matoken  matoken  0 Jun 25 18:50 matokenfile
-rw-r--r-- 1 root     root     0 Jun 25 18:51 root
-rw-r--r-- 1 www-data www-data 0 Jun 25 18:51 www-data
--copy-as=matoken を指定するとすべてmatokenになる
$ sudo \rm -rf /tmp/rsync-test2
$ sudo ./rsync --copy-as=matoken -a /tmp/rsync-test/ /tmp/rsync-test2
$ ls -lA /tmp/rsync-test2
total 0
-rw-r--r-- 1 matoken matoken 0 Jun 25 18:50 matokenfile
-rw-r--r-- 1 matoken matoken 0 Jun 25 18:51 root
-rw-r--r-- 1 matoken matoken 0 Jun 25 18:51 www-data

-V

--version の短いオプションとして -V が入りました.

$ ./rsync --help|grep -- -V
--version, -V            print the version + other info and exit
$ ./rsync --help|grep \-V
grep (GNU grep) 3.4
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://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 Mike Haertel and others; see
<https://git.sv.gnu.org/cgit/grep.git/tree/AUTHORS>.

–ipv4, -4 / –ipv6, -6

ipv4, ipv6 を指定したいときに rsh='ssh -4' とするより便利な --ipv4, -4, --ipv6, -6 オプションが入りました.

ipv4しかない環境で -6 を指定して失敗する
$ rsync -avc6 ./ user@remote:/tmp/
ssh: Could not resolve hostname remote: Name or service not known
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(235) [sender=3.2.1]

awesome wmでの壁紙変更設定を変更(crontabからDISPLAY番号取得)

awesome wm環境での壁紙自動変更にcrontab経由で feh コマンドを利用しています.

30分ごとに~/Pictures/wp/以下のファイルをダンダムに設定
*/30 * * * *    DISPLAY=:0 feh --bg-scale "$(find ~/Pictures/wp/ -type f | shuf -n 1)"

このときXのディスプレイ番号を固定で書いているのですがディスプレイ番号が変わることもあってその時エラーになってしまいます.
ウィンドウマネージャを変更したときもよくなさそう.

ということでcronからユーザのawesome wmのディスプレイ番号を探すようにしてみました.

まずは対象ユーザのawesome wmのプロセス番号を調べます.

$ pgrep -u $(id -u) awesome
2932

/proc/$PID/environ からDISPLAYを探します.

$ cat /proc/2932/environ 2> /dev/null | tr '\0' '\n' | grep ^DISPLAY=:
DISPLAY=:1

カレントユーザのawesome wmのディスプレイ番号が :1 なのが解りました :)

これを組み合わせてこのようにしてみました.これでディスプレイ番号が変わっても大丈夫で,awesome以外のウィンドウマネージャを使ったときには何もしないはず( xargs --no-run-if-empty )です.
同じユーザでawesomeを複数起動した場合は先に起動した方しか反映されないはずですが,あまりそういったことはしないと思うので大丈夫かなと.

*/30 * * * *    cat /proc/$(pgrep -u $(id -u) awesome)/environ 2> /dev/null | tr '\0' '\n' | grep ^DISPLAY=: | xargs --no-run-if-empty -I{} sh -c '{} feh --bg-scale "$(find ~/Pictures/wp/ -type f | shuf -n 1)"'

2020-07-17 ADD
fehに -z, --randomize と言うオプションがありました.これを使うとコマンドが2つ減って少しわかりやすく……あまり変わらないか.

*/30 * * * *    cat /proc/$(pgrep -u $(id -u) awesome)/environ 2> /dev/null | tr '\0' '\n' | grep ^DISPLAY=: | xargs --no-run-if-empty -I{} {} feh --bg-scale -z ~/Pictures/wp/
環境
$ dpkg-query -W awesome feh procps findutils grep
awesome 4.3-4
feh     3.4.1-1
findutils       4.7.0-1
grep    3.4-1
procps  2:3.3.16-5
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64

Speaker Deckのスライドが全て非公開になって困る

Speaker Deckというスライド共有サービスがあります.日本ではSlideShareの次くらいによく使われていそうなサービスです.ここでトラブルがあったので健忘録としてメモしておきます.

このサービスにスライドを登録しようとアップロードしたところ変換に失敗してしまいます.スライドのデータが悪いのかな?と他のものも試すとやはり駄目です.
よく見ると5月以降に登録したスライドはアクセスが0です.なにかおかしい.

ログアウトした状態で見るとスライドが1つも見えなくなってしまっています.

speakerdeck 20200625 07:06:04 766282.resized

既存のスライドを公開(publish)し直しても公開されません.

全てのスライドが非公開になっている,ログインしたら見えるけど公開できない,新しいスライドの登録は失敗する……という状態です.

DMCAとか著作権違反とかが報告されてロックされていそうな感じがします(心当たりはないけど他のサービスもそれでBANされた前科あり).メールを探しますが特にそれらしいものは見当たりません.

ちょっと自分ではどうしようもなさそうだとSpeaker Deckの「Feedback」リンクからメールで問い合わせてみました.しかし反応がありません.
ダメ元でTwitterのSpeaker Deckアカウントである@speakerdeckにmentionを投げてみると数時間で復旧していました.

スライドはちゃんと公開され,新しいスライドのアップロードも出来ました.ということでよくわかりませんがシステムの不具合だったのかな?

やっぱり人任せにするのは怖いですね.自分でコントロールできるところでもまとめておこうと思います.

鹿児島らぐの「鹿児島Linux勉強会 2020.06」に参加

2020-06-28(sun)に開催された「鹿児島Linux勉強会 2020.06」に参加しました.

今回もDiscordで開催.主に音声チャットでやり取りで発表は画面共有で行う感じです.参加者は6名(申し込み7人欠席2人飛び入り1人)でした.

以下のような話がありました.

私は先月の「YoutubeLiveを細い回線で「聴く」」の続きをと思ったのですが,スライドのアクセスがとても少なく(たぶん自分を除くと一桁)反応良くなさそうだったのと,Twitterでrsyncの新機能への反応が良かったように見えたので「rsync 3.2.0の新機能を試してみた」と,参加者少なさそうだったので急遽「cowsayのcowを増やそう」を用意しました.
まあどちらもいまいち刺さらなかったかな…….

次回は07/26(日)でオンライン開催の予定です.

小江戸らぐ 6月のオフな集まり(第215回) オンライン開催に参加

06/13(Sat) 14:00〜20:00

カンファレンスツールにはZoom.us を利用して,14:00〜18:00 が勉強会.その後は懇親会な感じです.実際は00:00過ぎまでやっていました.

参加者はだいたい20人前後な感じでした.

以下のような発表がありました.

私の発表は「Linux環境で(低解像度の)画面共有を行うTips」でした.
しかし,今発表腕紹介したXephyrを使って発表しようとしたら今回のツールのZoom.us Linux版 clientでは画面共有の一覧に出てこず利用できませんでした(あとでChromiumでZoom.usを利用したら共有できるのを確認).スライドのまま共有してもほとんどアクセスはないのでそのうちblogにでもまとめなおそうと思います.

次回は恐らく07/11(Sat)にオンライン開催です.

torのhidden serviceで使うアドレスを計算する(Vanity Addresses)

最近このような記事を読みました.

今のインターネットはドメイン頼りな割に単一障害点となってしまってあまりよろしくない.でも逃げ道があまりないのですよね…….
とりあえず以前からそのうちやろうと思って放置していたtorのhidden serviceでミラーを立てるのをやってみようかなと思い立ちました.

とりあえず /etc/tor/torrc で以下のあたりを有効にしてtorを再起動してhttpdの設定をするだけで動きます.

HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 80 127.0.0.1:80

このときのアドレスはtor再起動後に HiddenServiceDir 以下に作られる hostname ファイルの中の名前になります.

$ sudo cat /var/lib/tor/hidden_service/hostname
tbiettfnprnqpoccrz3ll7hioprbyjoam2n6okihpadf5ukaa4hwrwad.onion

このアドレスは[a-z|3-7]の32文字(BASE32)からなる16文字の onion v2 アドレスと,56文字の onion v3 アドレスがあって,最近は後者のv3アドレスが規定値になっているようです.鍵は RSA から ed25519 になっています.

Onion v2 はホストネームから秘密鍵を求めるのに現実的な時間で済むのが近づいてきているようなのでとても長くて使いづらいですがこれからはOnion v3 アドレスにしたほうが良さそうです.
今はv2,v3 を併用しているところも多いようです.

Onion v2 Onion v3

hostname文字長

16

56

鍵形式

RSA

ed25519

鍵ファイル名

private_key

hs_ed25519_secret_key hs_ed25519_public_key

(無駄に)アドレスを計算して好みの単語にマッチしたものを探す(例えばmatokenから始まるアドレスを探すとか)ことが可能です.
こういったアドレスはVanity Addresses というようです.

他にもアドレスを売っているところもありますが,相手は秘密鍵を持っているわけであまりよくないと思います.

Onion v2 アドレスを eschalot で探す

add 2020-07-28)

Onion v2 アドレスは2021年11月あたりで使えなくなるようです.

Onion v2 アドレスを eschalot というツールを使ってみます.

導入
$ sudo apt install libssl-dev
$ git clone https://github.com/ReclaimYourPrivacy/eschalot
$ cd eschalot
$ make
$ ./eschalot
Version: 1.2.0

usage:
eschalot [-c] [-v] [-t count] ([-n] [-l min-max] -f filename) | (-r regex) | (-p prefix)
  -v         : verbose mode - print extra information to STDERR
  -c         : continue searching after the hash is found
  -t count   : number of threads to spawn default is one)
  -l min-max : look for prefixes that are from 'min' to 'max' characters long
  -n         : Allow digits to be part of the prefix (affects wordlist mode only)
  -f filename: name of the text file with a list of prefixes
  -p prefix  : single prefix to look for (1-16 characters long)
  -r regex   : search for a POSIX-style regular expression

Examples:
  eschalot -cvt4 -l8-12 -f wordlist.txt >> results.txt
  eschalot -v -r '^test|^exam'
  eschalot -ct5 -p test

  base32 alphabet allows letters [a-z] and digits [2-7]
  Regex pattern examples:
    xxx           must contain 'xxx'
    ^foo          must begin with 'foo'
    bar$          must end with 'bar'
    b[aoeiu]r     must have a vowel between 'b' and 'r'
    '^ab|^cd'     must begin with 'ab' or 'cd'
    [a-z]{16}     must contain letters only, no digits
    ^dusk.*dawn$  must begin with 'dusk' and end with 'dawn'
    [a-z2-7]{16}  any name - will succeed after one iteration

以下は -t でスレッド数を指定,-v で冗長出力,-pabc 方始まるホスト名を探しています.
見つかると標準出力にホスト名と秘密鍵が出力されます.

$ time ./eschalot -t`nproc` -v -p abc
Verbose, single result, no digits, 4 threads, prefixes 3-3 characters long.
Thread #1 started.
Thread #2 started.
Thread #3 started.
Thread #4 started.
Running, collecting performance data...
Found a key for abc (3) - abcamzmribeujuzw.onion
----------------------------------------------------------------
abcamzmribeujuzw.onion
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDIHD5uCynAW/Y1Vmyef8KrKuyFMzavij5Gl6aHYoiaGWNkJOZ7
P/Xc1Z78YTZ7LtzpWCAWLax4PmIhQiwPhldsD/kVWKAi0fODxaP/Z0XoJjqIfx8f
CmVWIQ1L9TVp9kfp8nLtXm9CnawCT98g0VE/jvZEddBV2oaVCuq88BTsoQIEAQBz
4QKBgBHzMeQAOOkyB3yCc51oYOh92jYLyXJuc511HR9yki7b/CxIhjL7miA+GVmJ
n4DD9nKubE5/xE6KrNnm3YZ1kmar2Yl/8fLJxBUrVoDUeGAc7i77i+tqM4d1LCr3
X1Ead8S7WpnnTVSmRHiLjuebaF78BWiMII4+3v9d1e6PQXbRAkEA9IJknhUNSO5b
1bzEIOmybg94r3fvBdWsc9xiwm6ONMBI2WyAVwmxDZ63Spwb/AyKCEblwekcaw6h
NMmhBQeUmQJBANGDs597RqBQUsFqtb5BoBkQgELIVeS4xKgZXrDI9SKfnnpTxv8Z
ypah+g335EN3/bBgfbqy8C7zFZhjHclzFUkCQQDcoP4aDG1zPO4TFcnguwvnGv/j
kOBS3h0CJOVY+rLTlUaekvjD6ugVLQ0olFItL1wyyZ3IifKcDHoDWJo/OOZZAkAQ
82dcvUGLOUpZObyFTdyUkU/eytiXaQZM0UdTDPnGYmrH/CBEaoSSjgRG7MEdFf2k
r+VVLqSnp+g6tFwp9It5AkBI4fJxCrrANt3E/CCrFW4iZXIqP3aPXHHZK5SqtQzJ
gBKUN8HSRxo/dURQPOLKKX0ynVJaMhg5UO4tQ3rHiJwa
-----END RSA PRIVATE KEY-----

Segmentation fault

real    0m0.126s
user    0m0.399s
sys     0m0.015s

-r オプションで正規表現が利用できます.以下の例は abc から始まり bca で終わるホスト名か,deadbeef で始まるアドレスを探しています.

$ ./eschalot -t`nproc` -v -r "^abc.*bca^|^deadbeef"

-c オプションで1つ見つかっても中断するまで探し続けます.
ファイルにリダイレクトしておくと便利です.

$ ./eschalot -cvt`nproc` -r "^abc.bca^|^deadbeef" >> result.log

探したいワードが多い場合は1ワード1行の辞書ファイルを作成して -f オプションで指定すると便利です.ただし,辞書ファイル指定時は7文字以下のワードは無視されるようです.-l オプションで 7-16 のように最小文字数を7以下にすればと思ったのですが,このオプションは7以下だとエラーで終了してしまいます.

$ ./eschalot -cvt`nproc` -f ./wordlist.dic >> result.log

GPUを使うツールも複数あります.例えば Scallion こっちのほうがずっと速いでしょう.(ASICとかもあるのかな?)

Onion v3 アドレスを mkp224o で探す

Onion v3 アドレスは mkp224o というツールを使ってみました.

configure optionに --enable-amd64-51-30k , --enable-amd64-64-24k というものがあるので試してみましたが,なし,--enable-amd64-51-30k , --enable-amd64-64-24k のいずれでも有意な速度差は見られませんでした.(Intel® Core™ i5-3320M)

導入
$ sudo apt install libsodium-dev autoconf
$ git clone https://github.com/cathugger/mkp224o
$ cd mkp224o
$ ./autogen.sh
$ ./configure
$ make
$ ./mkp224o
Usage: ./mkp224o filter [filter...] [options]
       ./mkp224o -f filterfile [options]
Options:
        -h  - print help to stdout and quit
        -f  - specify filter file which contains filters separated by newlines
        -D  - deduplicate filters
        -q  - do not print diagnostic output to stderr
        -x  - do not print onion names
        -v  - print more diagnostic data
        -o filename  - output onion names to specified file (append)
        -O filename  - output onion names to specified file (overwrite)
        -F  - include directory names in onion names output
        -d dirname  - output directory
        -t numthreads  - specify number of threads to utilise (default - CPU core count or 1)
        -j numthreads  - same as -t
        -n numkeys  - specify number of keys (default - 0 - unlimited)
        -N numwords  - specify number of words per key (default - 1)
        -z  - use faster key generation method; this is now default
        -Z  - use slower key generation method
        -B  - use batching key generation method (>10x faster than -z, experimental)
        -s  - print statistics each 10 seconds
        -S t  - print statistics every specified ammount of seconds
        -T  - do not reset statistics counters when printing
        -y  - output generated keys in YAML format instead of dumping them to filesystem
        -Y [filename [host.onion]]  - parse YAML encoded input and extract key(s) to filesystem
        --rawyaml  - raw (unprefixed) public/secret keys for -y/-Y (may be useful for tor controller API)
        -p passphrase  - use passphrase to initialize the random seed with
        -P  - same as -p, but takes passphrase from PASSPHRASE environment variable

探したいワードを引数に与えて実行するだけで利用できます.結果はホスト名のディレクトリ以下にファイルとして出力されます.

$ time ./mkp224o abcd
sorting filters... done.
filters:
        abcd
in total, 1 filter
using 4 threads
abcdpr2quwoxranttf2ywckm7g5giysscy62kmhyqmnq2ycvooxbtryd.onion
^Cwaiting for threads to finish... done.

real    0m8.982s
user    0m21.740s
sys     0m0.167s
$ ls -A abcdpr2quwoxranttf2ywckm7g5giysscy62kmhyqmnq2ycvooxbtryd.onion
hostname  hs_ed25519_public_key  hs_ed25519_secret_key

結果を onion ディレクトリに格納するようにしました.

$ time ./mkp224o -d ./onion abcd

フィルタは複数書けます.

$ time ./mkp224o -d ./onion abcd efgh ijkl

-S オプションで指定した秒数ごとに統計上を鵜を出力します.フィルタに辞書ファイルを使います.

$ ./mkp224o -S 300 -d ./onion -f ./wordlist.dic

以下は手元のNotePCとRaspberry Pi 3 model Bでの速度です.PCの方は熱でスロットリングが効いているのもありますが,案外Raspberry Pi が悪くない数字に見えます.自分の環境の場合電気代等を考えるとRaspberry Pi を並列で動かしておくほうが良さそうです.

Intel® Core™ i5-3320M
>calc/sec:202602.624226, succ/sec:0.000000, rest/sec:0.000000, elapsed:300.129147sec
>calc/sec:177378.183948, succ/sec:0.006667, rest/sec:0.006667, elapsed:600.131277sec
>calc/sec:155232.657607, succ/sec:0.006667, rest/sec:0.006667, elapsed:900.106274sec
>calc/sec:111928.180486, succ/sec:0.000000, rest/sec:0.000000, elapsed:1200.166338sec
Raspberry Pi 3 model B(aarch64 kernel)
>calc/sec:103867.893552, succ/sec:0.003333, rest/sec:0.003333, elapsed:300.130969sec
>calc/sec:100761.039921, succ/sec:0.003333, rest/sec:0.003333, elapsed:600.155046sec
>calc/sec:94511.877034, succ/sec:0.009999, rest/sec:0.009999, elapsed:900.194934sec
>calc/sec:91854.274354, succ/sec:0.003334, rest/sec:0.003334, elapsed:1200.130938sec

Vanity Addresses の設定

Onion v2

torrc の HiddenServiceDir 以下の hostname, hs_ed25519_public_key, hs_ed25519_secret_key を退避します.
次に private_key ファイルをtorの権限で作成し,見つけたRSA鍵を保存します.

その後torのサービスを再起動すると反映されて hostname ファイルも作成されます.

$ grep ^HiddenServiceDir /etc/tor/torrc
HiddenServiceDir /var/lib/tor/other_hidden_service/
$ sudo ls -A /var/lib/tor/other_hidden_service/
authorized_clients  hostname  hs_ed25519_public_key  hs_ed25519_secret_key  private_key
$ sudo rm /var/lib/tor/other_hidden_service/hostname /var/lib/tor/other_hidden_service/hs_ed25519_public_key /var/lib/tor/other_hidden_service/hs_ed25519_secret_key
$ sudo install -o debian-tor -g debian-tor -m 400 /dev/null /var/lib/tor/other_hidden_service/private_key
$ echo '-----BEGIN RSA PRIVATE KEY-----
> MIICXQIBAAKBgQDIHD5uCynAW/Y1Vmyef8KrKuyFMzavij5Gl6aHYoiaGWNkJOZ7
> P/Xc1Z78YTZ7LtzpWCAWLax4PmIhQiwPhldsD/kVWKAi0fODxaP/Z0XoJjqIfx8f
> CmVWIQ1L9TVp9kfp8nLtXm9CnawCT98g0VE/jvZEddBV2oaVCuq88BTsoQIEAQBz
> 4QKBgBHzMeQAOOkyB3yCc51oYOh92jYLyXJuc511HR9yki7b/CxIhjL7miA+GVmJ
> n4DD9nKubE5/xE6KrNnm3YZ1kmar2Yl/8fLJxBUrVoDUeGAc7i77i+tqM4d1LCr3
> X1Ead8S7WpnnTVSmRHiLjuebaF78BWiMII4+3v9d1e6PQXbRAkEA9IJknhUNSO5b
> 1bzEIOmybg94r3fvBdWsc9xiwm6ONMBI2WyAVwmxDZ63Spwb/AyKCEblwekcaw6h
> NMmhBQeUmQJBANGDs597RqBQUsFqtb5BoBkQgELIVeS4xKgZXrDI9SKfnnpTxv8Z
> ypah+g335EN3/bBgfbqy8C7zFZhjHclzFUkCQQDcoP4aDG1zPO4TFcnguwvnGv/j
> kOBS3h0CJOVY+rLTlUaekvjD6ugVLQ0olFItL1wyyZ3IifKcDHoDWJo/OOZZAkAQ
> 82dcvUGLOUpZObyFTdyUkU/eytiXaQZM0UdTDPnGYmrH/CBEaoSSjgRG7MEdFf2k
> r+VVLqSnp+g6tFwp9It5AkBI4fJxCrrANt3E/CCrFW4iZXIqP3aPXHHZK5SqtQzJ
> gBKUN8HSRxo/dURQPOLKKX0ynVJaMhg5UO4tQ3rHiJwa
> -----END RSA PRIVATE KEY-----' | sudo -u debian-tor tee /var/lib/tor/other_hidden_service/private_key
$ sudo service tor restart
$ torsocks w3m `sudo -u debian-tor cat /var/lib/tor/other_hidden_service/hostname`

Onion v3

torrc の HiddenServiceDir 以下の hostname, hs_ed25519_public_key, hs_ed25519_secret_key を退避します.
次に hs_ed25519_secret_key ファイルをtorの権限でコピーします.

その後torのサービスを再起動すると反映されて hostname, hs_ed25519_public_key ファイルも作成されます.

$ grep ^HiddenServiceDir /etc/tor/torrc
HiddenServiceDir /var/lib/tor/other_hidden_service/
$ sudo ls -A /var/lib/tor/other_hidden_service/
authorized_clients  hostname  hs_ed25519_public_key  hs_ed25519_secret_key  private_key
$ sudo rm /var/lib/tor/other_hidden_service/hostname /var/lib/tor/other_hidden_service/hs_ed25519_public_key /var/lib/tor/other_hidden_service/hs_ed25519_secret_key
$ sudo install -o debian-tor -g debian-tor -m 400 ./onion/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.onion/hs_ed25519_secret_key /var/lib/tor/other_hidden_service/hs_ed25519_secret_key
$ sudo service tor restart
$ torsocks w3m `sudo -u debian-tor cat /var/lib/tor/other_hidden_service/hostname`

まとめ

という感じで3日ほど動かしてみましたが matoken から始まるホスト名を3つほど掘り当てました.近いうちにミラーを設定してみようと思います.(v2, v3のアドレスを1つのtorサービスでホストする方法ってあるのかな?)
しかし設定してもアクセスはほぼ無いような気も…….

ちなみにtorはNAT越えもしてしまうのでsshdなどを許可する場合は注意しましょう.

$ torsocks w3m -dump http://matoken3inrzd4ks.onion/
 _     _   _             ____               _        _              _____
| |__ | |_| |_ _ __ _   / / / __ ___   __ _| |_ ___ | | _____ _ __ |___ /
| '_ \| __| __| '_ (_) / / / '_ ` _ \ / _` | __/ _ \| |/ / _ \ '_ \  |_ \
| | | | |_| |_| |_) | / / /| | | | | | (_| | || (_) |   <  __/ | | |___) |
|_| |_|\__|\__| .__(_)_/_/ |_| |_| |_|\__,_|\__\___/|_|\_\___|_| |_|____/
              |_|
 _                   _ _  _   _                     _                __
(_)_ __  _ __ ______| | || | | | _____   ___  _ __ (_) ___  _ __    / /
| | '_ \| '__|_  / _` | || |_| |/ / __| / _ \| '_ \| |/ _ \| '_ \  / /
| | | | | |   / / (_| |__   _|   <\__ \| (_) | | | | | (_) | | | |/ /
|_|_| |_|_|  /___\__,_|  |_| |_|\_\___(_)___/|_| |_|_|\___/|_| |_/_/
環境
$ dpkg-query -W tor
tor     0.3.5.10-1
$ lsb_release -dr
Description:    Debian GNU/Linux 10 (buster)
Release:        10
$ uname -m
aarch64
$ cat /proc/device-tree/model ;echo
Raspberry Pi 3 Model B Rev 1.2