VirtualBox上のOpenBSDを使う
what
前回のアノニマスCVSで、whatなんて言うコマンドを知った。BSD特有っぽい。一応manしとくと
NAME what - show what versions of object modules were used to construct a file SYNOPSIS what [-s] file ... DESCRIPTION what reads each file and searches for sequences of either the form `$' immediately followed by the system name (sysname) as defined by uname(3), or the form "@(#)" as inserted by the source code control system (SCCS). : HISTORY The what command first appeared in the SCCS package and was rewritten for 4.0BSD for licensing reasons.
どうやら、ファイルの素性を炙り出すやつみたいだ。 ソースが有ったんで眺めている。特殊なサーチコマンドみたい。
ob$ what what.c what.c: $OpenBSD: what.c,v 1.16 2020/04/18 15:10:06 martijn Exp $
ソースファイルの冒頭にある、あれだな。
ob$ head what.c /* $OpenBSD: what.c,v 1.16 2020/04/18 15:10:06 martijn Exp $ */ /* $NetBSD: what.c,v 1.4 1994/12/20 16:01:03 jtc Exp $ */ :
リナスが普及させたgit以前ではバージョン管理ソフトと言ったら、SCCSとかcvsが普通だった。Linuxが肥大化するにつけ、これらのソフトではスピードが遅くて対応出来なくなった。業を煮やしたリナスは、自分に都合がいいバージョン管理システムを作った。それがgitだ。
だから、普通のリナにはインストールされていないんだな。OpenBSDはソースの規模も小さいので、十分昔流の方法でも管理出来る。そんな訳でwhatも健在とな。
ファイル毎に、バージョン番号が付与されている。元になったのはNetBSDのそれって分かる。人間的な管理方法。
gitは、ファイルのsha1だかで取った指紋を元に管理してる。改変検出が容易って利点があるな。セキュリティー重視のOpenBSDは、改変をどうやって検出してるのかな? 親分に聞いてみたいぞ。
VirtualBox
前回、思わぬ事から、VirtualBoxにOpenBSDを入れた。用が済んだんで、バッサリ消してしまってもよかったんだけど、一応恩義が有るんで、少し戯れてみる。日本人ですから、情が有る訳ですよ。浪花節ですよ。まあ、外人には理解出来ないだろうけど。
setup
裸で使うと、色々な難が有るので、眼に付いた所を少し修正。
vbox$ cat /etc/sysctl.conf ddb.console=1 kern.utc_offset=540
ddbしか使えないんで、コンソールからddbが使えるように有効化。インストール時にTZは、アジアの東京を認識して正しい時刻になってた。が、改めて再起動すると、9時間ずれ。VMWareでは、こういう事が無いので、vboxの癖なんだろうね。カーネルに540分(60x9)ズレてるよって教えてあげた。
シリアルポートを使いたいので、下記の設定を施す。
vbox$ grep tty00 /etc/ttys tty00 "/usr/libexec/getty std.9600" vt220 on secure
serial by TCP
vboxの設定からシリアルポートのポート1を選ぶ。ポートモードをTCPに設定。存在するパイプソケットに接続をOFF。パスアドレスに(好みの番号)2323を設定。
WSLなdebianにnetcatをインストールする。そして、OpenBSDを起動後、debianな端末から
sakae@atom:~$ nc localhost 2323 OpenBSD/i386 (vbox.local.jp) (tty00) login: sakae sakae Password:hogefuga Last login: Wed Jun 3 05:28:11 on ttyp0 from 10.0.2.2 OpenBSD 6.7 (GENERIC) #1: Sat May 16 15:49:28 MDT 2020 Welcome to OpenBSD: The proactively secure Unix-like operating system. vbox$ pwd pwd /home/sakae
問題は入力したパスワードが見え見え。そんな事より問題なのは、ncが行指向のインテリジェントな端末って事。一行毎にOpenBSDにコマンドが送られる。OpenBSDは、送られて来た文字をエコーバック。よって、余計な出力が見えちゃう。
lessコマンドやviコマンドみたいな、文字指向を要求するコマンドは正しく動かない。端末は馬鹿なやつでいいんだよって言う、超昔の時代を期待してるんだ。そう言われてもねぇ。
serial by named pipe
そんな訳なんで、vboxのnamed pipeを試す。パイプ名は、\\.\pipe\mypipename とかにする。存在するパイプに接続はOFFにしておく。そうしないと、OpenBSD起動は失敗するので注意。
対向する端末は、Tera Term だあ。これを起動すると、ホスト名を聞いて来るので、そこに、上記と同じパイプ名を設定すればOK。
OpenBSD/i386 (vbox.local.jp) (tty00) login: sakae Password: Last login: Wed Jun 3 05:46:49 on tty00 OpenBSD 6.7 (GENERIC) #1: Sat May 16 15:49:28 MDT 2020 Welcome to OpenBSD: The proactively secure Unix-like operating system. vbox$ pwd /home/sakae
今度はきちんと動作した。能ある鷹は爪を隠すを地で行く端末だな。日本のことわざをちゃんと理解してるよ。
ssh
一応、ネットワーク接続出来るように、ポートフォワーディングの設定をvboxにした。これで、qemuの感覚で使えるな。Host.port: 2022 Guest.port: 22 って具合にqemuの設定と同じにしておいた。これで迷う事は無い。
ソースを取り込め
diskに余裕が有ったので、カーネルのソースだけを入れた。普通はsys.tar.gzを取ってきて展開するんだけど、今回はcvsでやる。
export CVSROOT='anoncvs@anoncvs.jp.openbsd.org:/cvs'
これ、長崎大学の経済学部所属のホストらしいです。好きな人がおられるんですね。
vbox$ cvs export -r OPENBSD_6_7_BASE sys
取ってきた物は220Mぐらいだった。まだ少し余裕が有るので、vi用のtagファイルを作っておく。
vbox$ cd sys/arch/i386 vbox$ make tags TDIR=`mktemp -d /tmp/_tagXXXXXXXXXX` || exit 1; eval "S=/home/sakae/sys/arch/i386/../.." && config -s /home/sakae/sys/arch/i386/../.. -b ${TDIR} /home/sakae/sys/arch/i386/conf/GENERIC.MP && eval "_arch=\"`make -V _arch -f ${TDIR}/Makefile`\"" && eval "_mach=\"`make -V _mach -f ${TDIR}/Makefile`\"" && eval "_machdir=\/home/sakae/sys/arch/i386/../../arch/${_mach}" && eval "_archdir=\/home/sakae/sys/arch/i386/../../arch/${_arch}" && eval "HFILES=\"`find /home/sakae/sys/arch/i386/../.. \( -path /home/sakae/sys/arch/i386/../../'arch' -o -path /home/sakae/sys/arch/i386/../../stand -o -path /home/sakae/sys/arch/i386/../../lib/libsa -o -path /home/sakae/sys/arch/i386/../..'/lib/libkern/arch' \) -prune -o -name '*.h'; find ${_machdir} ${_archdir} /home/sakae/sys/arch/i386/../../lib/libkern/arch/${_mach} \( -name boot -o -name stand \) -prune -o -name '*.h'`\"" && eval "SFILES=\"`make -V SFILES -f ${TDIR}/Makefile`\"" && eval "CFILES=\"`make -V CFILES -f ${TDIR}/Makefile`\"" && eval "AFILES=\"`make -V AFILES -f ${TDIR}/Makefile`\"" && ctags -wd -f /home/sakae/sys/arch/i386/tags ${CFILES} ${HFILES} && egrep "^[_A-Z]*ENTRY[_A-Z]*\(.*\)" ${SFILES} ${AFILES} | sed "s;\\([^:]*\\):\\([^(]*\\)(\\([^, )]*\\)\\(.*\\);\\3 \\1 /^\\2(\\3\\4$/;" >> /home/sakae/sys/arch/i386/tags && sort -o /home/sakae/sys/arch/i386/tags /home/sakae/sys/arch/i386/tags && rm -rf ${TDIR}
とても長くて読む気にもならないスクリプトが走って、123Mと言う巨大なtagファイルが出来上がった。これでvi使いに慣れるかな?
ddb
折角シリアルポートからログインする環境を作ったので、gdbに変わって、ddbを使えるようにしておく。だって、vboxが提供するVGAなコンソールは切り貼り出来ないからね。
vbox# cat /etc/boot.conf set tty com0 set timeout 1
上記の設定をして、シリアルポートの先にぶら下がっているターミナルもコンソールの役目(ddbの起動可)を許す。ついでに、bootプロンプト後1秒で動作を開始するように設定。
ddbのマニュアルには、breakの送出でddbに入ると記されていた。Tera TermではBreak信号を送出出来るみたいだけど、反応しなかったので、苦肉の策で、愛リアスを登録した。
alias inddb='sysctl -w ddb.trigger=1'
ddbに落ちるか、一応確認しとく。
vbox# inddb Stopped at db_enter+0x4: popl %ebp ddb> trace db_enter() at db_enter+0x4 ddb_sysctl(f5791d20,1,cf7bbf98,f5791d18,cf7b9f98,4,d325d184) at ddb_sysctl+0x109 sys_sysctl(d325d184,f5791d90,f5791d88) at sys_sysctl+0x144 syscall(f5791dd0) at syscall+0x28e Xsyscall_untramp() at Xsyscall_untramp+0xa9 end of kernel ddb> c ddb.trigger: 0 -> 1
vi with tags
折角vi用のtagsファイルを作ったので、使い方を調べておく。
key | action |
---|---|
vi -t xx | xxを含むfileを開く |
:tag xx | 同上 |
Ctl-] | push tag reference |
Ctl-T | return tag context |
:tagpo | 同上 |
tagsファイルの有る所で起動する事。Ctl-T は、tmuxのキーに割り当てているので、exコマンドのそれで代替出来る。って、vboxではtmuxを起動しない使い方なんで、問題無いか。
stty
前回やったsttyのソースの中に、 ws_row
なんてのが出て来る。termios.hをざっと見しても出てこないので、真面目に探してみる。
sys/ttycom.h
see66$ grep ws_row /usr/include/{*.h,*/*.h} /usr/include/sys/ttycom.h: unsigned short ws_row; /* rows, in characters */ see66$ grep ttycom.h /usr/include/termios.h #include <sys/ttycom.h>
大体、sys/の中に用が有るってのは、特殊な人なのかな? いや、そんな事は無い。気を利かせて、勝手にincludeしてるんだな。
sys/ttycom.h
/* * Window/terminal size structure. This information is stored by the kernel * in order to provide a consistent interface, but is not used by the kernel. */ struct winsize { unsigned short ws_row; /* rows, in characters */ unsigned short ws_col; /* columns, in characters */ unsigned short ws_xpixel; /* horizontal size, pixels */ unsigned short ws_ypixel; /* vertical size, pixels */ };
カーネルが気を利かせて用意してるけど、使っていないとな。するってえと、アプリが眼明日として利用してるって事かな。
set window size
kern/tty.cの中に、window sizeを設定する部分が収められている。
case TIOCSWINSZ: /* set window size */ if (bcmp((caddr_t)&tp->t_winsize, data, sizeof (struct winsize))) { tp->t_winsize = *(struct winsize *)data; pgsignal(tp->t_pgrp, SIGWINCH, 1); } break;
面白いと思ったのは、pgsignalの部分。プロセスグループに対してSIGWINCHと言うシグナルを送ってる。
signal(3)によれば、
SIGWINCH discard signal window size change
こういう意味。ウィンドウのサイズが変わったから、対処が必要なら遅滞なく処理宜しくって広告だ。
ひょっとして、このあたりが、Windows Terminalを使った時の動的フォント変更に反応して、sttyで出て来る rows サイズを変更してるんではなかろうか?
ssh
sshのソースの所で、上記シグナルを受け取っていないか、確認しる。
see66$ grep SIGWINCH *.c clientloop.c: * Signal handler for the window change signal (SIGWINCH). This just sets a clientloop.c: signal(SIGWINCH, window_change_handler); clientloop.c: signal(SIGWINCH, SIG_DFL); mux.c: signal(SIGWINCH, control_client_sigrelay); mux.c: signal(SIGWINCH, control_client_sigrelay); progressmeter.c: signal(SIGWINCH, sig_winch); progressmeter.c: signal(SIGWINCH, sig_winch);
更に、サイズ変更してないか?
see66$ grep TIOCSWINSZ *.c sshpty.c: (void) ioctl(ptyfd, TIOCSWINSZ, &w);
ここから追って行くと、session.cに行きつきそこで、 session_pty_req()
とかから、サイズ変更の指令を実行してる。
多分こうじゃなかろうか劇場が開幕します。
Windows Terminalアプリが、フォントサイズ変わったぜいってのを、debian上のbash経由でsshに告知。 それがパケットになって、OpenBSD側に飛んで来る。sshは、パケットを受け取って、サイズ更新。長い旅である。
sakae@atom:~$ ssh -vvv xxx.xxx.xxx.xxx : debug2: PTY allocation request accepted on channel 0
Windows側でsshのセッションログを取ってみると、それらしい文字列が見つかった。 その怪しい文字列を頼りにそれっぽい所を探してみると、 clientloop.c で見つかった。
void client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem, const char *term, struct termios *tiop, int in_fd, struct sshbuf *cmd, char **env) : channel_request_start(ssh, id, "pty-req", 1); client_expect_confirm(ssh, id, "PTY allocation", CONFIRM_TTY); if ((r = sshpkt_put_cstring(ssh, term != NULL ? term : "")) != 0 || (r = sshpkt_put_u32(ssh, (u_int)ws.ws_col)) != 0 || (r = sshpkt_put_u32(ssh, (u_int)ws.ws_row)) != 0 || (r = sshpkt_put_u32(ssh, (u_int)ws.ws_xpixel)) != 0 || (r = sshpkt_put_u32(ssh, (u_int)ws.ws_ypixel)) != 0) fatal("%s: build packet: %s", __func__, ssh_err(r));
お馴染みのやつに出会った。本来ならWSL上のdebianのsshソースに当たるのが正統だろうけど、ssh本家のOpenBSD側での確認になりました。
wiresharkで検証
こうじゃないか劇場で考察したように、フォントサイズ変更したら、その旨を知らせるパケットがOpenBSD側に飛んで来るか検証する。
OpenBSD 6.7にwiresharkを入れた。つられて、Python 2.7.18もくっついてきた。見なかった事にしておこう。
port ssh で、キャプチャ開始。Ctl-= とかしてサイズ変更すると、それに同期して確かにWindows側からパケットが飛んできていた。パケットの中身は、残念な事に暗号化されているので、確かめるすべがない。
でも、確かにフォント変更のキーボード操作に同期してるんで、間違い無いだろう。
ネットを調べてみると、httpsな通信をキャプチャして、それを平文に直す方法が散見されるけど、sshにはどう適用したら良いのやら?
VMWareでもシリアル接続
実は上で出て来た Tera Term を昔少し使ってみたんだけど、emacsのstatusラインが上手く表示出来なくて疎遠になってたんだ。今回改めて入れ直した、随分と進化してる風だったんで、emacsの有る環境で確かめてみようって言う気になった。
VMWare上のOpenBSDにしかemacsが入っていない。そこで、VMWareにシリアルを追加した。 vbox接続用のTeraTerm設定をそのまま使いたい。
で、VMWareのシリアル、起動時に接続、パイプ名は上記と同じ、サーバーです、接続先はアプリケーションですって、設定した。
ちゃんとemacsのステータスが表示されてた(違和感無し)、manした時、強調文字が黄色で表示されてた。ちょっとかっこいい。
TeraTermのフォントを、Windows Terminalが連れて来たやつに変更。サイズを大きめに設定した。シリアル接続では、画面サイズが設定されない。よって、黙って使うと24行のターミナルと見做されてしまい、以後それを保持しちゃう。TeraTermのメニューから、端末をリセットすれば、初期状態になる。
ちと鬱陶しいので、 .profileに、下記を追加した。
if [ '/dev/tty00' = `tty` ]; then stty rows 32 fi
シリアルコンソールなら、32行ターミナルになってねって設定だ。この端末では、清く正しく、viだけを使う事にしよう。