SMF y Privilegios
Ha diferencia de las versiones anteriores de Solaris 6 y 7 donde para establecer privilegios teniamos que recurrir a software externo al sistema, como SUDO... y Solaris 8, 9 donde podiamos realizar este tipo de acciones con RBAC ya como parte del mismo. En Solaris 10 y OpenSolaris con la inclusión de SMF (Service Management Facility) la pespectiva cambia y podemos ser capaces de definir que usuario y que acciones puede realizar (parar, arrancar...) sobre un servicio del sistema que incluso levante un socket tcp/udp por debajo del puerto 1024 sin ser root.
En este ejemplo lo vamos a realizar con Apache2 gestionado como servicio a traves de SMF.
# svcs apache2
STATE STIME FMRI
disabled 19:12:02 svc:/network/http:apache2
# svcadm -v enable -s apache2
svc:/network/http:apache2 enabled.
# ps -aef | grep apache | grep -v grep
webservd 14836 14835 0 15:25:04 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 14837 14835 0 15:25:04 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 14839 14835 0 15:25:04 ? 0:00 /usr/apache2/bin/httpd -k start
root 14835 10895 0 15:25:03 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 14838 14835 0 15:25:04 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 14840 14835 0 15:25:04 ? 0:00 /usr/apache2/bin/httpd -k start
# ptree 14835
10895 zsched
14835 /usr/apache2/bin/httpd -k start
14836 /usr/apache2/bin/httpd -k start
14837 /usr/apache2/bin/httpd -k start
14838 /usr/apache2/bin/httpd -k start
14839 /usr/apache2/bin/httpd -k start
14840 /usr/apache2/bin/httpd -k start
Vemos como por defecto el proceso que realmente levanta el socket abierto en el puerto tcp 80 es iniciado como root y no tiene ningun tipo de privilegios.
# ppriv -S 14835
14835: /usr/apache2/bin/httpd -k start
flags =
E: zone
I: basic
P: zone
L: zone
Esto lo vamos a cambiar para el usuario webservd, asi:
# svcadm -v disable svc:/network/http:apache2
svc:/network/http:apache2 inhabilitado.
# 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: :default
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
# svcprop -v -p start apache2
start/exec astring /lib/svc/method/http-apache2\ start
start/timeout_seconds count 60
start/type astring method
start/user astring webservd
start/group astring webservd
start/privileges astring
basic,!proc_session,!proc_info,!file_link_any,net_privaddr
start/limit_privileges astring :default
start/use_profile boolean false
start/supp_groups astring :default
start/working_directory astring :default
start/project astring :default
start/resource_pool astring :default
# svcadm -v refresh apache2
Action refresh set for svc:/network/http:apache2.
# svcadm -v enable -s apache2
svc:/network/http:apache2 habilitado.
# ps -fea|grep apache
webservd 3957 3953 0 19:21:13 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 3956 3953 1 19:21:13 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 3953 1 2 19:21:11 ? 0:01 /usr/apache2/bin/httpd -k start
webservd 3955 3953 1 19:21:13 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 3954 3953 0 19:21:13 ? 0:00 /usr/apache2/bin/httpd -k start
webservd 3958 3953 0 19:21:13 ? 0:00 /usr/apache2/bin/httpd -k start
# netstat -an|grep -i listen
*.22 *.* 0 0 49152 0 LISTEN
*.111 *.* 0 0 49152 0 LISTEN
*.59597 *.* 0 0 49152 0 LISTEN
*.80 *.* 0 0 49152 0 LISTEN
*.22 *.* 0 0 49152 0 LISTEN
*.80 *.* 0 0 49152 0 LISTEN
Y teniendo en cuenta lo que significa cada privilegios, vemos los que le hemos asignado.
# ppriv -v -l proc_exec proc_fork net_privaddr
proc_exec
Allows a process to call execve().
proc_fork
Allows a process to call fork1()/forkall()/vfork()
Configuring the Apache2 Service 7
net_privaddr
Allows a process to bind to a privileged port number.
The privilege port numbers are 1-1023 (the traditional
UNIX privileged ports) as well as those ports marked as
"udp/tcp_extra_priv_ports" with the exception of the ports
reserved for use by NFS.
# ppriv -S 3953
3953: /usr/apache2/bin/httpd -k start
flags =
E: net_privaddr,proc_exec,proc_fork
I: net_privaddr,proc_exec,proc_fork
P: net_privaddr,proc_exec,proc_fork
L: all
Luego hemos conseguido que el usuario webservd sea capaz de arrancar y para el servicio apache2, levantando un socket en el puerto tcp 80 sin necesidad de cambiar la identidad a root en ningún momento.