INDEX
OpenBSD Webサーバ (httpd+slowcgi on OpenBSD 7.7)
OpenBSD の Webサーバ httpd(relayd) で、slowcgi(8) を使い CGI (Common Gateway Interface) を動かす。
slowcgi は、CGI を実行する FastCGIプロトコルを処理する。httpd で、CGI を実行して表示できるようにする。
httpd 自体を動かす設定は、OpenBSD/httpd/77(relayd) を参照。
- 関連 man → httpd(8), httpd.conf(5), 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 <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <time.h>
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 Tue Jul 8 12:06:43 2025 host is (null).
確認2
curl でローカルホストに接続して確認する。
bbb# curl -sv http://localhost/cgi-bin/test_cgi * Host localhost:80 was resolved. * IPv6: ::1 * IPv4: 127.0.0.1 * Trying [::1]:80... * Connected to localhost (::1) port 80 * using HTTP/1.x > GET /cgi-bin/test_cgi HTTP/1.1 > Host: localhost > User-Agent: curl/8.13.0 > Accept: */* > * Request completely sent off < HTTP/1.1 200 OK < Connection: keep-alive < Content-Type: text/plain < Date: Tue, 08 Jul 2025 12:09:18 GMT < Server: OpenBSD httpd < Transfer-Encoding: chunked < hello world! time is Tue Jul 8 12:09:18 2025 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 Tue Jul 8 12:14:53 GMT 2025 host is
このとき、実行権限がついていないと「chroot: /cgi-bin/test_cgi.sh: Permission denied」となり、実行に必要な /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 * Host localhost:80 was resolved. * IPv6: ::1 * IPv4: 127.0.0.1 * Trying [::1]:80... * Connected to localhost (::1) port 80 * using HTTP/1.x > GET /cgi-bin/test_cgi.sh HTTP/1.1 > Host: localhost > User-Agent: curl/8.13.0 > Accept: */* > < HTTP/1.1 200 OK < Connection: keep-alive < Content-Type: text/plain < Date: Tue, 08 Jul 2025 12:25:30 GMT < Server: OpenBSD httpd < Transfer-Encoding: chunked < hello world! time is Tue Jul 8 12:25:30 GMT 2025 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 モジュールをコピーする。
詳細は、下記の「CGI実行環境の作成」参照
確認1
chroot して実行できるか確認する。
bbb# chroot -u www /var/www/ ./cgi-bin/test_cgi.pl Content-Type: text/plain hello world! perl v5.40.1 (5.040001) time is 2025-7-8 12:46:4 host is bbb#
確認2
curl でローカルホストに接続して確認する。
bbb# curl -sv http://localhost/cgi-bin/test_cgi.pl * Host localhost:80 was resolved. * IPv6: ::1 * IPv4: 127.0.0.1 * Trying [::1]:80... * Connected to localhost (::1) port 80 * using HTTP/1.x > GET /cgi-bin/test_cgi.pl HTTP/1.1 > Host: localhost > User-Agent: curl/8.13.0 > Accept: */* > * Request completely sent off < HTTP/1.1 200 OK < Connection: keep-alive < Content-Type: text/plain < Date: Tue, 08 Jul 2025 12:46:47 GMT < Server: OpenBSD httpd < Transfer-Encoding: chunked < hello world! perl v5.40.1 (5.040001) time is 2025-7-8 12:46:47 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 コマンドで確認できる。
perl
perl スクリプトが動くように /usr/bin/perl と必要なライブラリ、perl モジュールをコピーする。
perl のコピー
perl のバージョンと使用されている共有ライブラリの確認
bbb# whereis perl
/usr/bin/perl
bbb# /usr/bin/perl -v
This is perl 5, version 40, subversion 1 (v5.40.1) built for arm-openbsd
:後略
bbb# ldd /usr/bin/perl
/usr/bin/perl:
Start End Type Open Ref GrpRef Name
289e0000 28a11000 exe 1 0 0 /usr/bin/perl
b5d23000 b6016000 rlib 0 1 0 /usr/lib/libperl.so.25.0
a9cbe000 a9d09000 rlib 0 2 0 /usr/lib/libm.so.10.1
ac8a8000 ac9a3000 rlib 0 2 0 /usr/lib/libc.so.100.3
aa9a0000 aa9a0000 ld.so 0 1 0 /usr/libexec/ld.so
bbb# /usr/bin/perl -V
Summary of my perl5 (revision 5 version 40 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 5108 Apr 17 00:05 perl*
/var/www/usr/lib:
total 12864
-r--r--r-- 1 root bin 3232364 Jul 6 22:28 libc.so.100.3
-r--r--r-- 1 root bin 400848 Apr 16 23:54 libm.so.10.1
-r--r--r-- 1 root bin 2868348 Apr 17 00:06 libperl.so.25.0
/var/www/usr/libexec:
total 704
-r--r--r-- 1 root bin 333708 Jul 6 22:28 ld.so
bbb#
bbb# chroot -u www /var/www/ /usr/bin/perl -v
This is perl 5, version 40, subversion 1 (v5.40.1) built for arm-openbsd
:後略
bbb#
perl モジュールのコピー
perl モジュール(と共有ライブラリ)をコピーする
bbb# mkdir -p /var/www/usr/libdata/
bbb# mkdir -p /var/www/usr/local/libdata/
bbb#
bbb# cp -p -R /usr/libdata/perl5 /var/www/usr/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
b4f83000 b4fca000 rlib 0 1 0 /usr/lib/libz.so.7.1
a64ac000 a64f7000 rlib 0 1 0 /usr/lib/libm.so.10.1
bbb# find /var/www/usr/local/libdata -name \*.so -exec ldd \{\} \; | grep rlib
bbb#
bbb# cp -p /usr/lib/libz.so.* /var/www/usr/lib
CPAN やパッケージで追加した場合、(当然だが)再度コピーし直す必要がある。
CPAN でモジュールを追加する
CPAN で、直接 /var/www 配下に入れるってどうするんだろう…
最終更新時間:2025年07月08日 21時48分42秒 指摘や意見などあればSandBoxのBBSへ。