!!!OpenBSD Webサーバ (httpd+slowcgi on OpenBSD ==6.8== 7.0) {{category OpenBSD,nolink}}OpenBSD の Webサーバ httpd(relayd) で、[slowcgi(8)|https://man.openbsd.org/slowcgi.8] を使い CGI (Common Gateway Interface) を動かす。 slowcgi は、CGI を実行する FastCGIプロトコルを処理する。httpd で、CGI を実行して表示できるようにする。 httpd 自体を動かす設定は、[[OpenBSD/httpd/68(relayd)]] を参照。 * 関連 man → [httpd(8)|https://man.openbsd.org/httpd.8], [httpd.conf(5)|https://man.openbsd.org/httpd.conf.5], [slowcgi(8)|https://man.openbsd.org/slowcgi.8] !!! slowcgi の起動設定 !! 自動起動 サーバが起動したときに slowcgi も実行されるように、'''/etc/rc.conf.local''' に '''slowcgi_flags''' を指定する。 # FastCGI to CGI wrapper server slowcgi_flags= または、'''rcctl enable slowcgi''' で有効にする( /etc/rc.conf.local に slowcgi_flags= が記載される)。 !! デバッグ root ユーザのコンソールで、'''-dv''' オプションをつけて実行すると、処理の内容が表示される。 # slowcgi -dv slowcgi: sock_user: www slowcgi: socket: /var/www/run/slowcgi.sock slowcgi: slowcgi_user: www slowcgi: chroot: /var/www !!! Webサーバ(httpd) の設定 '''/etc/httpd.conf''' に設定する。サンプルが /etc/examples/httpd.conf にある。 OpenBSD の httpd および slowcgi は、デフォルトで '''/var/www''' に chroot されるようになっている。 そのため、動的リンクされているプログラムや sh や perl などのスクリプトを実行する場合は、chroot されるディレクトリ /var/www 以下に必要なファイルを配置しておく必要がある。 !! 動的ドキュメント '''/var/www/cgi-bin''' 以下のプログラムを実行し結果を表示させる(/var/www に chroot されるので、パスは /cgi-bin)。 server "default" { # :中略 location "/cgi-bin/*" { fastcgi socket "/run/slowcgi.sock" directory no index root "/cgi-bin" request strip 1 } } !! 動的ドキュメント その2 '''/var/www/cgi-bin''' 以下のうち、*.cgi をプログラムとしてを実行し結果を表示させる(/var/www に chroot されるので、パスは /cgi-bin)。ほかの *.html などは、通常のファイルをして返す。 server "default" { # :中略 location "/cgi-bin/*.cgi" { fastcgi socket "/run/slowcgi.sock" directory no index root "/cgi-bin" request strip 1 } location "/cgi-bin/*" { directory no auto index root "/cgi-bin" request strip 1 } } !!! CGI動作確認サンプル !! スタティックリンクプログラム スタティックリンクされたプログラムを実行させる(ダイナミックリンクされたプログラムの場合、必要なライブラリも配置する必要があるため、ファイルサイズが大きくなるがスタティックリンクで作成する)。 !プログラムソース 下記の C言語プログラムを保存する。 「hello world!」という文字列と、動いた時刻、リクエスト元(環境変数)を表示させる。 bbb# cat /var/www/cgi-bin/test_cgi.c #include #include #include #include int main(){ time_t now; char* env; puts("Content-Type: text/plain"); puts(""); puts("hello world!"); now = time(NULL); printf("time is %s", ctime(&now)); env = getenv("HTTP_HOST"); printf("host is %s.\n", env); return 0; } !ビルド スタティックリンクでコンパイルする。 bbb# clang -o test_cgi -static test_cgi.c !確認1 chroot して実行できるか確認する。 bbb# chroot -u www /var/www/ /cgi-bin/test_cgi Content-Type: text/plain hello world! time is Sun Dec 5 05:47:41 2021 host is (null). !確認2 curl でローカルホストに接続して確認する。 bbb# curl -sv http://localhost/cgi-bin/test_cgi * Trying 127.0.0.1:80... * Connected to localhost (127.0.0.1) port 80 (#0) > GET /cgi-bin/test_cgi HTTP/1.1 > Host: localhost > User-Agent: curl/7.72.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Connection: keep-alive < Content-Type: text/plain < Date: Sun, 05 Dec 2021 05:47:48 GMT < Server: OpenBSD httpd < Transfer-Encoding: chunked < hello world! time is Sun Dec 5 05:47:48 2021 host is localhost. * Connection #0 to host localhost left intact !!シェルスクリプト sh シェルスクリプトを実行する。 !プログラムソース 下記の sh シェルスクリプトを保存する。 「hello world!」という文字列と、動いた時刻(date コマンド)、リクエスト元(環境変数)を表示させる。 bbb# cat /var/www/cgi-bin/test_cgi.sh #!/bin/sh echo "Content-Type: text/plain\n"; echo "hello world!"; echo "time is `date`"; echo "host is $HTTP_HOST"; !実行環境の作成 シェルスクリプトが動くように /bin/sh と /bin/date をコピーする。 bbb# cp -p /bin/sh /var/www/bin/ bbb# cp -p /bin/date /var/www/bin/ !確認1 chroot して実行できるか確認する。 bbb# chroot -u www /var/www/ /cgi-bin/test_cgi.sh Content-Type: text/plain hello world! time is Sun Dec 5 06:04:47 GMT 2021 host is このとき、実行に必要な /bin/sh がないと、「chroot: test_cgi.sh: No such file or directory」と言ったエラーメッセージが出る。 また、スクリプト内で呼び出される /bin/date がないと、「/cgi-bin/test_cgi.sh[4]: date: not found」と言ったワーニングメッセージがでる(スクリプトは実行される)。 !確認2 curl でローカルホストに接続して確認する。 bbb# curl -sv http://localhost/cgi-bin/test_cgi.sh * Trying 127.0.0.1:80... * Connected to localhost (127.0.0.1) port 80 (#0) > GET /cgi-bin/test_cgi.sh HTTP/1.1 > Host: localhost > User-Agent: curl/7.72.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Connection: keep-alive < Content-Type: text/plain < Date: Sun, 05 Dec 2021 06:10:03 GMT < Server: OpenBSD httpd < Transfer-Encoding: chunked < hello world! time is Sun Dec 5 06:10:03 GMT 2021 host is localhost * Connection #0 to host localhost left intact !!perl スクリプト perl スクリプトを実行する。 !プログラムソース 下記の perl シェルスクリプトを保存する。 「hello world!」という文字列と perl ヴァージョン、動いた時刻(localtime)、リクエスト元(環境変数)を表示させる。 bbb# cat /var/www/cgi-bin/test_cgi.pl #!/usr/bin/perl print "Content-Type: text/plain\n\n"; print "hello world!\n"; print "perl $^V ($])\n"; my ($sec, $min, $hour, $mday, $mon, $year) = localtime; $mon += 1; $year += 1900; print "time is $year-$mon-$mday $hour:$min:$sec\n"; print "host is $ENV{'HTTP_HOST'}\n"; !実行環境の作成 スクリプトが動くように /usr/bin/perl と必要なライブラリ、perl モジュールをコピーする。 perl のバージョンと使用されている共有ライブラリの確認 bbb# whereis perl /usr/bin/perl bbb# /usr/bin/perl -v This is perl 5, version 32, subversion 1 (v5.32.1) built for arm-openbsd   :後略 bbb# ldd /usr/bin/perl /usr/bin/perl: Start End Type Open Ref GrpRef Name 02ef3000 02f24000 exe 1 0 0 /usr/bin/perl 5c386000 5c658000 rlib 0 1 0 /usr/lib/libperl.so.22.0 52485000 524cf000 rlib 0 2 0 /usr/lib/libm.so.10.1 45ce5000 45ddc000 rlib 0 2 0 /usr/lib/libc.so.96.1 5fa50000 5fa50000 ld.so 0 1 0 /usr/libexec/ld.so bbb# /usr/bin/perl -V Summary of my perl5 (revision 5 version 32 subversion 1) configuration:   :中略 Built under openbsd @INC: /usr/local/libdata/perl5/site_perl/arm-openbsd /usr/local/libdata/perl5/site_perl /usr/libdata/perl5/arm-openbsd /usr/libdata/perl5 bbb# プログラムと共有ライブラリをコピーする bbb# mkdir -p /var/www/usr/{bin,lib,libexec} bbb# cp -p /usr/bin/perl /var/www/usr/bin bbb# cp -p /usr/lib/libperl.so.* /var/www/usr/lib bbb# cp -p /usr/lib/libm.so.* /var/www/usr/lib bbb# cp -p /usr/lib/libc.so.* /var/www/usr/lib bbb# cp -p /usr/libexec/ld.so /var/www/usr/libexec bbb# ls -lF /var/www/usr/* /var/www/usr/bin: total 12 -rwxr-xr-x 1 root bin 5344 Oct 3 18:25 perl* /var/www/usr/lib: total 23904 -r--r--r-- 1 root bin 3175756 Oct 31 15:53 libc.so.96.0 -r--r--r-- 1 root bin 3167336 Nov 21 19:25 libc.so.96.1 -r--r--r-- 1 root bin 401084 Oct 3 18:19 libm.so.10.1 -r--r--r-- 1 root bin 2640156 Oct 7 2020 libperl.so.20.0 -r--r--r-- 1 root bin 2732928 Oct 3 18:26 libperl.so.22.0 /var/www/usr/libexec: total 672 -r--r--r-- 1 root bin 324812 Nov 21 19:25 ld.so bbb# bbb# chroot -u www /var/www/ /usr/bin/perl -v This is perl 5, version 32, subversion 1 (v5.32.1) built for arm-openbsd   :後略 bbb# perl モジュール(と共有ライブラリ)をコピーする bbb# mkdir -p /var/www/usr/libdata/ bbb# cp -p -R /usr/libdata/perl5 /var/www/usr/libdata bbb# mkdir -p /var/www/usr/local/libdata/ bbb# cp -p -R /usr/local/libdata/perl5 /var/www/usr/local/libdata bbb# bbb# find /var/www/usr/libdata -name \*.so -exec ldd \{\} \; | grep rlib 884aa000 884f4000 rlib 0 1 0 /usr/lib/libm.so.10.1 bbb# find /var/www/usr/local/libdata -name \*.so -exec ldd \{\} \; | grep rlib !確認1 chroot して実行できるか確認する。 bbb# chroot -u www /var/www/ ./cgi-bin/test_cgi.pl Content-Type: text/plain hello world! perl v5.32.1 (5.032001) time is 2022-1-23 6:55:19 host is bbb# !確認2 curl でローカルホストに接続して確認する。 bbb# curl -sv http://localhost/cgi-bin/test_cgi.pl * Trying 127.0.0.1:80... * Connected to localhost (127.0.0.1) port 80 (#0) > GET /cgi-bin/test_cgi.pl HTTP/1.1 > Host: localhost > User-Agent: curl/7.72.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Connection: keep-alive < Content-Type: text/plain < Date: Sun, 23 Jan 2022 06:56:51 GMT < Server: OpenBSD httpd < Transfer-Encoding: chunked < hello world! perl v5.32.1 (5.032001) time is 2022-1-23 6:56:51 host is localhost * Connection #0 to host localhost left intact bbb# !!! CGI実行環境の作成 /var/www に chroot されるので、実行バイナリや共有ライブラリなどは、/var/www/usr/bin や /var/www/usr/lib など、/var/www 以下に置いておく必要がある。 また、perl モジュールなども、/var/www 以下のパスに置いておく。 なお、参照される共有ライブラリは ldd コマンドで確認できる。