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だけを使う事にしよう。


This year's Index

Home