OpenBSD

『いちばんやさしいPHPの教本』(インプレス)なんて本が有ったので、懐かしくなって読んでみた。

内容は、素人にapache+PHP+MySQL を使って、Webアプリの作り方を指南する講義形式。 著者は人気講師らしいです。題材は、CookPadに対抗すべく、料理のレシピ作成、閲覧、修正、削除だ。 さりげなくCRUDになってるのがいいね。一言もCRUDなんて言葉は出てこないけど。

WindowsとMACのユーザーに対応するように、Winの場合は、さくらeditorにXAMPP。Macの場合は、 CotEditorとか言うのとMAMPとかの組み合わせ。文字化けを防ぐには、道具を全てutfに 統一するんですよとか、サーバーが上がらなかったら、Skipeが悪さしてるかも知れないので、 回避しましょなんてHowToが書いてあった。

なぜ懐かしくなったかと言うと、昔、会社の掲示板と言うか(社内用2chですな)、Wikiと言うのを、 apacheとrubyとMySQLで作っていたからだ。みんな自前でコンパイルしたもの。隔世の感が しますなあ。

じゃ、PHPなんて出てこないじゃん。そこはそれ、phpMyadminですよ。あの頃、MySQLの動作を 簡単に確認しようと思ったら、黒い画面(とこの本では言ってた)を使うしか無かったからねぇ。 そんな訳で、使いたく無いPHPをおまけで使わされたって訳。

やたら設定ファイルが長くて、苦労したよ。資料も余り無かったしね。爺の戯言ですな。

PHPを使う上で、セキュリティに気を配っているのは、良い傾向。外部から受け取ったデータは、 使う前に必ず検査しろってのは大事な事ですよ。

最後に、IPAの安全なウェブサイトの作り方 を紹介してのるはGood。

果たして、個人がそこまで気を使うかは疑問だけど、最初が肝心。

install OpenBSD

前々回だったか、Fedoraでarm用のカーネルと言うライブラリィーを全く使わない、寂しい アプリを作った。その時、stack領域に実行属性が付いてた事に気がついた。全くLinuxって やつは、行け々ドンドンだなと思った。

セキュリティに厳しいOpenBSDあたりではどうよと、ふと頭を過ぎったんだ。んでもって、 どうなってるかOpenBSDを(わざわざ)入れて、確かめてみる事にする。

何てったって、 30分でできる OpenBSD 日本語デスクトップ環境 とか、 フグも愛せよ! OpenBSD 5.4 をデスクトップ PC として使っちゃおう! こういう OpenBSD/Install53 wikiがあるぐらいですから。結構、人気あるみたいですよ。

本山は、こちら。マスコットのふぐが出迎えてくれるはず なんだけど、ちと模様が違うね。OpnBSDは、淡々と年2回、バージョンが上がって行く。 最新は、3月に出たOpenBSD5.7なんだけど、スナップショットも提供されてるんで、 毒を喰らいたかった、スナップショットをどうぞ。

入れてみたら、いろんなものが動いてた。

$ ps awx
  PID TT  STAT       TIME COMMAND
    1 ??  Is      0:01.13 /sbin/init
23914 ??  Is      0:00.02 dhclient: vic0 [priv] (dhclient)
 8681 ??  Is      0:00.01 dhclient: vic0 (dhclient)
26637 ??  Is      0:00.01 syslogd: [priv] (syslogd)
 3384 ??  S       0:00.09 /usr/sbin/syslogd
15475 ??  Is      0:00.01 pflogd: [priv] (pflogd)
31431 ??  S       0:00.09 pflogd: [running] -s 160 -i pflog0 -f /var/log/pflog (pflogd)
14456 ??  I<s     0:00.01 ntpd: [priv] (ntpd)
 9620 ??  S<      0:00.48 ntpd: ntp engine (ntpd)
25964 ??  I       0:00.02 ntpd: dns engine (ntpd)
  367 ??  Ss      0:00.02 /usr/sbin/sshd
29732 ??  Is      0:00.02 smtpd: [priv] (smtpd)
 8433 ??  I       0:00.01 smtpd: lookup (smtpd)
27125 ??  I       0:00.02 smtpd: control (smtpd)
16492 ??  I       0:00.01 smtpd: queue (smtpd)
28380 ??  I       0:00.01 smtpd: scheduler (smtpd)
30545 ??  I       0:00.01 smtpd: klondike (smtpd)
17054 ??  I       0:00.01 smtpd: pony express (smtpd)
18082 ??  I<s     0:00.00 /usr/bin/sndiod
 4738 ??  Is      0:00.02 /usr/sbin/cron
10917 ??  Ss      0:00.13 sshd: sakae [priv] (sshd)
23486 ??  S       0:00.03 sshd: sakae@ttyp0 (sshd)
 2052 p0  Ss      0:00.02 -ksh (ksh)
  928 p0  R+      0:00.01 ps -awx
10612 C0  Is+     0:00.17 /usr/libexec/getty std.9600 ttyC0
29025 C1  Is+     0:00.01 /usr/libexec/getty std.9600 ttyC1
 7228 C2  Is+     0:00.02 /usr/libexec/getty std.9600 ttyC2
 6453 C3  Is+     0:00.01 /usr/libexec/getty std.9600 ttyC3
21193 C5  Is+     0:00.01 /usr/libexec/getty std.9600 ttyC5

pflogd,ntpd,smtpd,sndiodとか要らないでねぇ。どうやって止めるんだ。/etc/rc.confでしょ。 そこに設定がみんな書いてあるよ。みたら、それは手本で、外れるものを、rc.conf.localに 書き出せとの事。

$ cat /etc/rc.conf.local
pflogd_flags=NO
ntpd_flags=NO
smtpd_flags=NO
sndiod_flags=NO

こんな風に、はっきりと意思表示のNOを書いておくと、起動してこないよ。運用中に、思いついて テンポラリィーに起動したい時は、

$ sudo sh /etc/rc.d/sndiod start
/etc/rc.d/sndiod: need -f to force start since sndiod_flags=NO
$ sudo sh /etc/rc.d/sndiod -f start
sndiod(ok)

こんな風にやるのね。-f なんてのを付けろって事で、間違い防止を謀ってるんだな。

それから、sudoはデフォで入ってた。後、いらない端末が沢山動いていたので、/etc/ttysを 編集し、止めてやった。

DISKがどれぐらい消費してるか? 予想では、600M前後。ドンピシャリでした。

$ df -h
Filesystem     Size    Used   Avail Capacity  Mounted on
/dev/wd0a      509M   46.7M    437M    10%    /
/dev/wd0e      808M   26.0K    767M     0%    /home
/dev/wd0d      2.4G    480M    1.8G    21%    /usr

startxすると、xauthに随分と時間が取られる。回避は /etc/mynameに、フルパスでホスト名を 設定、/etc/hostsにそれを書いておけばOK。懐かしいfvwmが立ち上がってきた。

やれ、xfceだとか見た目に走らず、頑固一徹があの人らしい。manをちゃんと保守してるんで、 インストール後に必要な事は、man afterbootしてねって、手回しよくメールが送られて きていた。

その他に良くある質問は、 Frequently Asked Questionsを読め。 つられて読んでみたら、 8.3 - Can I use programming language 'L' on OpenBSD? なんて、案内も有った。

OpenBSD pkg

OpenBSDを実用的に使うなら、pkgを入れるしかない。debian様は3万個、FreeBSDは2万4千個、 それに対して、OpenBSDは9000個を切っている。このあたりの差は、人気度に比例してるのだろうか? まあ、9000個ぐらいあれば、大抵は用が足りると思うけど。

http://ftp.jaist.ac.jp/pub/OpenBSD/5.7/packages/i386/ に、一覧が有るから好きなの持ってけとばかりの野ざらし状態。Fedoraみたいに綺麗に分類 してくれる訳では無いよ。だから、お取り寄せ用のカタログを作るのさ。

[ob: z]$ w3m -dump http://ftp.jaist.ac.jp/pub/OpenBSD/5.7/packages/i386/ > CAT
[ob: z]$ vi CAT
  :
[ ]   0ad-0.0.17.tgz                                              09-Mar-2015  83M
                                                                        19:49
[ ]   0ad-data-0.0.17.tgz                                         09-Mar-2015 687M
                                                                        19:49
  :

ちょっと醜いので、下記のように加工しました。最初の%sで、カッコの部分を削り、次の命令で、 時間の表示されてる行を削除しました。vi便利。

:%s/......//
:g/^      /d

後は、このカタログを検索するだけです。

[ob: z]$ grep arm CAT
arm-1.4.5.0p1.tgz                                           09-Mar-2015 666K
arm-elf-binutils-2.20p1.tgz                                 09-Mar-2015 4.7M
arm-elf-gdb-7.1p2.tgz                                       09-Mar-2015 3.8M
armagetronad-0.2.8.3.2p0.tgz                                09-Mar-2015 1.7M
barman-1.2.2p0.tgz                                          09-Mar-2015  91K
charm-1.7.0p7.tgz                                           09-Mar-2015 114K
garmin-utils-2.4p1.tgz                                      09-Mar-2015  19K
garmindev-0.3.4p1.tgz                                       09-Mar-2015 249K
gucharmap-3.14.2.tgz                                        09-Mar-2015 3.5M
lua52alarm-20061011p3.tgz                                   09-Mar-2015 3.5K
luaalarm-20061011p3.tgz                                     09-Mar-2015 3.5K
p5-Starman-0.4011.tgz                                       09-Mar-2015  18K
warmux-11.04.1p3.tgz                                        09-Mar-2015 101M
xantfarm-1.16p2.tgz                                         09-Mar-2015  16K

うーん、arm用のgccは作られていないのか。armやるならアセンブラーでごりごりするのが、 OpenBSDな人達なのね。

カタログから欲しい物をピンポイントで指定しても良いし、お勧めを提示して貰って、 そこから選んでもよい。、

# export PKG_PATH=http://ftp.jaist.ac.jp/pub/OpenBSD/5.7/packages/i386/
# pkg_add emacs
quirks-2.54 signed on 2015-03-09T11:04:08Z
quirks-2.54: ok
Ambiguous: choose package for emacs
a       0: <None>
        1: emacs-24.4p0-gtk2
        2: emacs-24.4p0-gtk3
        3: emacs-24.4p0-no_x11
Your choice:

なお、OpenBSDのスナップショット版を入れると、release版のpkgとバージョンが合わない為、 pkgの導入に失敗します。そんな時は、portsから頑張って入れましょう。

普段は、PuTTY上でscreenを動かしているんだけど(先進ユーザーはtmuxらしい)w3mを使うと 文字化けする。screenの文字コード解釈がまずいと思って調べたら、-UをつければUTF-8を 理解するって書いてあったぞ。リナちゃん系は、デフォでそうなってるんだな。 と、いう事は、UTF-8も使い方を間違うと、穴になるぜって事。これぞ親分の気配り。

デフォでtmuxが入っていた。できるtmux-5分でわかる?仮想端末入門- とか、tmuxのすすめを見ると、Mac屋さんに似合いそう。 でも、オイラーはWinユーザーなんで、awesomeで似た事をするのさ。

awesomeがpkgに有った。これを、.xinitrcに指定しておくか、.xsessonに書いておいて、xdmで ふぐに面会してから使うかは、ご自由に。Xを上げておかなければ、実メモリー256Mで、十分過ぎる程の 環境になります。リナちゃんと違って省資源。

何時もはコンパイラーのテストを兼ねてGaucheをソースから入れるんだけど、gcの所でエラー。 微妙な事をやってるので、親分が嫌ったんだな。gambitがpkgになってたので入れた。補完も 効くし、infoにもしっかりドキュメントが揃っていたので、満足です。

bashは普通に入れるんだけど、今回はシステム備え付けのkshで行ってみる事にする。 manを流し読みした限りではオイラーが使う範囲で十分過ぎる程の能力を持ってるようですよ。

$ find . -inum 49940
./ksh
./rksh
./sh

みたいですしね。rkshって何だと思って調べてみたら、

     -r      Restricted shell.  A shell is ``restricted'' if this option is
             used; if the basename the shell was invoked with was ``rksh''; or
             if the SHELL parameter is set to ``rksh''.  The following
             restrictions come into effect after the shell processes any
             profile and ENV files:

             o   The cd command is disabled.
             o   The SHELL, ENV, and PATH parameters cannot be changed.
             o   Command names can't be specified with absolute or relative
                 paths.
             o   The -p option of the built-in command command can't be used.
             o   Redirections that create files can't be used (i.e. `>', `>|',
                 `>>', `<>').

bashにこんな機能有ったかなあ? 一番使うくせに知らない事大杉。

OpenBSD src,sys,ports

BSDを入れたからには、ソースも一緒に入れておきたい。tgzになったやつが有るから、取ってきて、 /usr/srcなり/usr/portsに入れておけばOK。

それぞれがどのぐらいの容量を消費しているか、調べてみた。

# du -sh ports/
234M    ports/
# du -sh sys/
96.8M   sys/
# du -sh src
612M    src

このうち、portsは実際に使うと、容量が増えて行くので、十分に余裕の有るようにして おかないと、後で悲しくなる。とは言え、逃げ道は有る。ports/pobjの下が実際の作業場所に なるから、リンクを貼って、余裕の有る所へ逃がせばOK。

# make install
===>  Faking installation for go-1.4.2
install -d -m 755 /usr/ports/pobj/go-1.4.2/fake-i386
/usr/ports/pobj/go-1.4.2/bin/install -c -s  -m 755 -p /usr/ports/pobj/go-1.4.2/go/bin/go{,fmt} /usr/ports/pobj/go-1.4.2/fake-i386/usr/local/bin
/usr/ports/pobj/go-1.4.2/bin/install -d  -m 755 /usr/ports/pobj/go-1.4.2/fake-i386/usr/local/go
# These get installed via `find' however we need them to be executable
/usr/ports/pobj/go-1.4.2/bin/install -d  -m 755 /usr/ports/pobj/go-1.4.2/fake-i386/usr/local/go/pkg/tool/openbsd_386
/usr/ports/pobj/go-1.4.2/bin/install -c -s  -m 755 -p /usr/ports/pobj/go-1.4.2/go/pkg/tool/openbsd_386/*  /usr/ports/pobj/go-1.4.2/fake-i386/usr/local/go/pkg/tool/openbsd_386
===>  Building package for go-1.4.2
Create /usr/ports/packages/i386/all/go-1.4.2.tgz
Link to /usr/ports/packages/i386/ftp/go-1.4.2.tgz
Link to /usr/ports/packages/i386/cdrom/go-1.4.2.tgz
===>  Verifying specs: c m pthread
===>  found c.78.1 m.9.0 pthread.18.1
===>  Installing go-1.4.2 from /usr/ports/packages/i386/all/
go-1.4.2: ok

ports/packages, /ports/plist なんて所も使われて(diskを消費)いるな。 実際に出来上がったgoを試してみると、

$ go version
runtime: panic before malloc heap initialized
fatal error: runtime: cannot reserve arena virtual address space

runtime stack:
runtime.throw(0x854de92)
        /usr/local/go/src/runtime/panic.go:491 +0x83 fp=0xcfbee34c sp=0xcfbee334
runtime.mallocinit()
        /usr/local/go/src/runtime/malloc.c:223 +0xe9 fp=0xcfbee388 sp=0xcfbee34c
runtime.schedinit()
        /usr/local/go/src/runtime/proc.c:137 +0x34 fp=0xcfbee3a0 sp=0xcfbee388
runtime.rt0_go(0xcfbee434, 0xfff, 0x85480a0, 0x0, 0x0, 0x0, 0x4d37ed2b, 0xcfbee3ec, 0xcfbee430, 0xcfbee3ec, ...)
        /usr/local/go/src/runtime/asm_386.s:100 +0xed fp=0xcfbee3a4 sp=0xcfbee3a0

頭から落ちているぞ。こういう時は、OpenBSDの先輩に聞いてみるに限る。何てったって、 セキュリティ一番の親分の意向を受けてるはずですから。 Go development on OpenBSD に実例が出てた。リソースの使いすぎに制限を設けているとな。それを撤廃しないと動かないよ。

$ ulimit -a
time(cpu-seconds)    unlimited
file(blocks)         unlimited
coredump(blocks)     unlimited
data(kbytes)         524288
stack(kbytes)        4096
lockedmem(kbytes)    253306
memory(kbytes)       757952
nofiles(descriptors) 512
processes            128

現状では、データエリアが不足してるっぽい。プロセス数も少ないのかな。

$ ulimit -n 512
$ ulimit -p 512
$ ulimit -d 2036792
$ go version
go version go1.4.2 openbsd/386

goをちゃんと使おうと思ったら、自分の所にもtreeの基点を用意しておかないとならないので、 それも含めて、.profileに追加した。

PS1="[\h: \W]\\$ "
alias rsync='rsync --progress -avh -e ssh '
alias screen='screen -U'

export GOPATH=/home/sakae/go
export PATH=$PATH:$GOPATH/bin
ulimit -n 512
ulimit -p 512
ulimit -d 2036792

それにしても、デフォの.profile設定に、current-dirが入っているのは、いかがなものかと。

newLISP

新しい革袋には新しい酒って事で、lisp系に新しいのが無いかと探してみたら、そのものずばりの 名前のやつが居た。newlisp。能書きと言うか釣書には、

newLISP is a scripting language for developing web applications and
programs in general and in the domains of artificial intelligence (AI)
and statistics.

こんな記述が有った。これってひょっとしてlisp界のPHP? マニュアルも勇士の方により日本語版が 公開されてた。これはもう、入れてみる鹿。

===>  Building for newlisp-10.6.2
make -f makefile_build
cc -m32 -O2 -pipe -c  -DNEWCONFIG newlisp.c
cc -m32 -O2 -pipe -c  -DNEWCONFIG nl-symbol.c
cc -m32 -O2 -pipe -c  -DNEWCONFIG nl-math.c
cc -m32 -O2 -pipe -c  -DNEWCONFIG nl-list.c
cc -m32 -O2 -pipe -c  -DNEWCONFIG nl-liststr.c
cc -m32 -O2 -pipe -c  -DNEWCONFIG nl-string.c
cc -m32 -O2 -pipe -c  -DNEWCONFIG nl-filesys.c
cc -m32 -O2 -pipe -c  -DNEWCONFIG nl-sock.c
cc -m32 -O2 -pipe -c  -DNEWCONFIG nl-import.c
cc -m32 -O2 -pipe -c  -DNEWCONFIG nl-xml-json.c
cc -m32 -O2 -pipe -c  -DNEWCONFIG nl-web.c
cc -m32 -O2 -pipe -c  -DNEWCONFIG nl-matrix.c
cc -m32 -O2 -pipe -c  -DNEWCONFIG nl-debug.c
cc -m32 -O2 -pipe -c  -DNEWCONFIG pcre.c
cc -m32 -O2 -pipe -c  -DNEWCONFIG nl-utf8.c
cc newlisp.o nl-symbol.o nl-math.o nl-list.o nl-liststr.o nl-string.o nl-filesys.o      nl-sock.o nl-import.o nl-xml-json.o nl-web.o nl-matrix.o nl-debug.o pcre.o nl-utf8.o -m32 -lm -lreadline -lncurses  -o newlisp
nl-math.o(.text+0x6b92): In function `p_randomize':
: warning: random() may return deterministic values, is that what you want?

えっ、これだけ? まあ動けばいいな。サンプルが有ったので、

[ob: newlisp-10.6.2]$ newlisp
newLISP v.10.6.2 32-bit on BSD IPv4/6 UTF-8, options: newlisp -h

> (load (append (env "NEWLISPDIR") "/guiserver.lsp"))
(lambda (gs:id gs:action) (net-send gs:out (string "frame-resized " gs:id " " gs:action
   "\n")))
> (gs:init)
Could not connect to guiserver.jar

はて? マニュアルを見たら使い方が出てた。けど、その通りにやっても接続出来ないぞ。 謎だ。ずっと接続待ちになるんで、OpenBSDの火壁が働いているのかしらん? もう少し易しいのがexampleに有った。

[ob: examples]$ ./client localhost

Connected!

input or 'quit' to exit:hello openbsd

HELLO OPENBSD
input or 'quit' to exit:quit

bye bye!

送った小文字を大文字にして返してくれるやつ。portに1111なんてのを使ってるけど、火壁を すり抜けてるな。えと、火壁の設定を確認しとく。

[ob: examples]$ cat /etc/pf.conf
cat: /etc/pf.conf: Permission denied
[ob: examples]$ sudo cat /etc/pf.conf
Password:
#       $OpenBSD: pf.conf,v 1.54 2014/08/23 05:49:42 deraadt Exp $
#
# See pf.conf(5) and /etc/examples/pf.conf

set skip on lo

block return    # block stateless traffic
pass            # establish keep-state

# By default, do not permit remote connections to X11
block return in on ! lo0 proto tcp to port 6000:6010

火壁の設定は普通の人は見ちゃだめと。ローカルポートはゆるゆる。怪しいパケットは 門前払い。それ以外では、X接続は外部からのを拒否するって仕様だな。

ulimit

goの所で資源制限が出てきた。某国漁民にulimitをかけたいぞ。根こそぎ取るなよ。 折角なので、資源制限がどう実現されてるか、みてみる。ulimitって、kshの組み込み コマンドなんで、/usr/src/bin/kshだな。grepしたら一発Hitで、u_ulimt.c

        getrlimit(l->resource, &limit);
        if (setrlimit(l->resource, &limit) < 0) {

man getrlimitとかしたら、セクション2って出てたから、システムコールなんだな。 emacsからmanを引くと、sys/resource.hなんて所に一発で飛べてとても便利。

/*
 * Resource limits
 */
#define RLIMIT_CPU      0               /* cpu time in milliseconds */
#define RLIMIT_FSIZE    1               /* maximum file size */
#define RLIMIT_DATA     2               /* data size */
#define RLIMIT_STACK    3               /* stack size */
#define RLIMIT_CORE     4               /* core file size */
#define RLIMIT_RSS      5               /* resident set size */
#define RLIMIT_MEMLOCK  6               /* locked-in-memory address space */
#define RLIMIT_NPROC    7               /* number of processes */
#define RLIMIT_NOFILE   8               /* number of open files */

#define RLIM_NLIMITS    9               /* number of resource limits */

#define RLIM_INFINITY   (((rlim_t)1 << 63) - 1)
#define RLIM_SAVED_MAX  RLIM_INFINITY
#define RLIM_SAVED_CUR  RLIM_INFINITY

struct rlimit {
        rlim_t  rlim_cur;               /* current (soft) limit */
        rlim_t  rlim_max;               /* maximum value for rlim_cur */
};

次はこれらがどのように使われているかだな。舞台は/sys/kernに移して

[ob: kern]$ grep RLIMIT_DATA *.c
kern_exec.c:                (epp->ep_dsize > p->p_rlimit[RLIMIT_DATA].rlim_cur))
kern_resource.c:        case RLIMIT_DATA:

さー、どっち見る? 占いで決めるよりも科学的根拠で決めましょう。

[ob: kern]$ wc kern_exec.c kern_resource.c
     886    3145   23327 kern_exec.c
     531    1676   12324 kern_resource.c
    1417    4821   35651 total

行数が少ない方からが、合理的だな。sys_getrlimit等が有ったけど、これは違うな。 もう片方を見ると、

                /* check limits */
                if ((epp->ep_tsize > MAXTSIZ) ||
                    (epp->ep_dsize > p->p_rlimit[RLIMIT_DATA].rlim_cur))
                        error = ENOMEM;

ここがチェックポイントなのね。了解です。

なお、こんな具合にしてカーネルを八苦してる方がおられました。

OpenBSD kernel hack memo