Ihara's Weblog
Webサーバのroot特権排除してセキュアに
世の中の外向けのWebサーバは、ポート80番で動いているものがほとんどだと思います。ご存知のとおり、標準では1024番以下は特権ポートと呼ばれ、通常rootでないとbindすることができません。このため、Webサーバの場合ポート80番で起動という、ただそれだけでスーパーユーザのrootが必要になっているのが実情です。
Solaris10では、最小特権という概念が含まれており、UID=0(root)をチェックする代わりに、特権コールを実施する際には、それに必要な特権を持っているか否かをチェックしています。つまり、単なるWebサーバであればrootではなく"一般ユーザ + 1024番以下でbindできる特権"で起動することができます。これによってWebサーバの脆弱性をついたroot特権の奪取を防ぐことができます。以下にその設定手順を記載します。
まずは、普通に起動して確認してみます。
# cd /etc/apache2/
# cp httpd.conf-example httpd.conf
# svcadm enable apache2
# svcs -a | grep apache2
online 18:23:33 svc:/network/http:apache2
# ps -ef | grep httpd
webservd 1684 1681 0 18:23:34 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 1685 1681 0 18:23:34 ? 0:00 /usr/apache2/bin/httpd -k start
root 1681 1 0 18:23:33 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 1686 1681 0 18:23:34 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 1683 1681 0 18:23:34 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 1682 1681 0 18:23:34 ? 0:00 /usr/apache2/bin/httpd -k start
子プロセスは、apache側の設定でwebservdにsetuidされていますが、親プロセスはrootです。しかも以下でわかるように全特権持っています。
# ppriv 1681
1681: /usr/apache2/bin/httpd -k start
flags = <none>
E: all
I: basic
P: all
L: all
次に、apache2を止めて最小特権の設定をしてみます。設定は、SMFのプロパティに追加していくだけです。なお、Solaris10ではwebservdというユーザ、グループ名が最初から用意されていますので、これを使うことにします。
# svcadm disable apache2
# svcs -a | grep apache2
disabled 18:24:26 svc:/network/http:apache2
# svccfg -s apache2
svc:/network/http:apache2> setprop start/user = astring: webservd
svc:/network/http:apache2> setprop start/group = astring: webservd
svc:/network/http:apache2> setprop start/privileges = astring: basic,!proc_session,!proc_info,!file_link_any,net_privaddr
svc:/network/http:apache2> setprop start/limit_privileges = astring: basic,!proc_session,!proc_info,!file_link_any,net_privaddr
svc:/network/http:apache2> setprop start/use_profile = boolean: false
svc:/network/http:apache2> setprop start/supp_groups = astring: :default
svc:/network/http:apache2> setprop start/working_directory = astring: :default
svc:/network/http:apache2> setprop start/project = astring: :default
svc:/network/http:apache2> setprop start/resource_pool = astring: :default
svc:/network/http:apache2> end
変更内容をupdateします。
# svcadm refresh apache2
ログファイルの所有者をwebservd:webservdにします。
# cd /var/apache2/logs
# chown webservd:webservd access_log error_log
httpd.confを編集しpid、lockファイルの保存先を変更します。
# cd /etc/apache2
# vi httpd.conf
変更は、以下の2点です。
#LockFile /var/apache2/logs/accept.lock
↓
LockFile /var/apache2/logs/accept.lock
PidFile /var/run/apache2/httpd.pid
↓
PidFile /var/apache2/run/httpd.pid
ディレクトリとして新規に/var/apache2/runを作成し、所有者をwebservd:webservdにします。
# mkdir /var/apache2/run
# chown webservd:webservd /var/apache2/run
以上で設定は完了ですので、再度apache2を起動し動作確認します。
# svcadm enable apache2
# svcs apache2
STATE STIME FMRI
online 18:28:21 svc:/network/http:apache2
bash-3.00# ps -ef | grep httpd
webservd 1722 1719 0 18:28:22 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 1720 1719 0 18:28:22 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 1719 1 0 18:28:21 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 1721 1719 0 18:28:22 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 1723 1719 0 18:28:22 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 1724 1719 0 18:28:22 ? 0:00 /usr/apache2/bin/httpd -k start
上記のとおり、親プロセスも含めすべてwebservdで実行されていることがわかります。次に以下のように特権を確認してみると最低限必要な特権3つしか持っていません。
# ppriv -v 1719
1719: /usr/apache2/bin/httpd -k start
flags = <none>
E: net_privaddr,proc_exec,proc_fork
I: net_privaddr,proc_exec,proc_fork
P: net_privaddr,proc_exec,proc_fork
L: net_privaddr,proc_exec,proc_fork
もちろん、80番ポートで待っています。
# telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
HEAD / HTTP/1.0
HTTP/1.1 200 OK
Date: Tue, 26 Dec 2006 09:34:43 GMT
Server: Apache/2.0.58 (Unix) DAV/2
・
・
・
ついでですが、apache2のプロパティを最小特権設定前に戻す方法を以下に記載します。
# svcadm disable apache2
# svccfg -s apache2
svc:/network/http:apache2> listsnap
last-import
running
initial
start
svc:/network/http:apache2> revert initial
svc:/network/http:apache2> exit
# svcadm refresh apache2
# svcadm enable apache2
# ps -ef | grep http
webservd 1759 1755 0 18:42:02 ? 0:00 /usr/apache2/bin/httpd -k start
root 1755 1 0 18:42:01 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 1760 1755 0 18:42:02 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 1758 1755 0 18:42:02 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 1757 1755 0 18:42:02 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 1756 1755 0 18:42:02 ? 0:00 /usr/apache2/bin/httpd -k start
Posted at 02:21午前 12 29, 2006 by ihara in Solaris10 | 投稿されたコメント[1]