Пятница, 12 Март 2010
слушаем привелегированный порт
В последнее время стало популярно запускать сервисы, которые требуют привелигированого порта (порта с значением меньшем чем 1024) написаные на erlang, java, tcl или других интерпртируемых языках.
Самый популярный путь, который использует большинство это NAT
средствами iptables
. Почему я считаю что это плохой путь? Во-первых, это не решение проблемы, это, факически, маскировка ее. Во-вторых, это лишние накладные расходы (кто-то будет утверждать что NAT
бесплатен?).
Первый предлагаемый мной путь это «повесить» capabilities на erlang или скомпилированное приложение:
setcap cap_net_bind_service=+ep /usr/lib64/erlang/erts-5.7.2/bin/beam
setcap cap_net_bind_service=+ep /usr/lib64/erlang/erts-5.7.2/bin/beam.smp
В чем его минусы? Мы отдаем возможность открывать любые порты. Если хочется более тонкой настройки, то придется брать в руки SELinux.
Совсем минимальная политика xmpp_server.fc:
/usr/lib64/erlang/erts-5.7.2/bin/beam.smp -- gen_context(system_u:object_r:xmpp_server_exec_t,s0)
xmpp_server.if:
interface(`xmpp_server_domtrans',`
gen_require(`
type xmpp_server_t, xmpp_server_exec_t;
')
domtrans_pattern($1, xmpp_server_exec_t, xmpp_server_t)
')
xmpp_server.te:
policy_module(xmpp_server,1.0.0)
type xmpp_server_t;
type xmpp_server_exec_t;
inetd_service_domain(xmpp_server_t, xmpp_server_exec_t)
permissive xmpp_server_t;
type xmpp_server_port_t;
corenet_port(xmpp_server_port_t)
sysnet_dns_name_resolve(xmpp_server_t)
corenet_all_recvfrom_unlabeled(xmpp_server_t)
allow xmpp_server_t self:tcp_socket create_stream_socket_perms;
corenet_tcp_sendrecv_all_if(xmpp_server_t)
corenet_tcp_sendrecv_all_nodes(xmpp_server_t)
corenet_tcp_sendrecv_all_ports(xmpp_server_t)
corenet_tcp_bind_all_nodes(xmpp_server_t)
allow xmpp_server_t xmpp_server_port_t:tcp_socket name_bind;
allow xmpp_server_t xmpp_server_port_t:tcp_socket name_connect;
И потом, собственно сборка, подгрузка и прочее:
make -f /usr/share/selinux/devel/Makefile
/usr/sbin/semodule -i xmpp_server.pp
/sbin/restorecon -F -R -v /usr/lib64/erlang/erts-5.7.2/bin/beam.smp
/usr/sbin/semanage port -a -t xmpp_server_port_t -p tcp 5269
Если вам интересно прочитать побольше про SELinux то очень не плохо описано в у RedHat: SELinux User Guide и SELinux Managing Confined Services Guide
Комментарии
Плохой путь, после форка привелегии остаются только о “родительского” потока, так что не подходит для нормальных демонов ;)
Я делаю запуск от root, выставляю для форкнутого процесса привилегии через cap_set_proc и после этого переключаюсь на “правильного” пользователя.
Форма комментирования для «слушаем привелегированный порт»
У тебя есть lisp, и он умеет такие финты ушами. В случае Erlang форкаться нельзя, как и менять пользователя.
А почему нельзя? Сам CL таких вещей как бы тоже не предусматривает, но есть FFI…
Идеологически в erlang это не нужно. Это имел ввиду я.
а на более других операционках есть ipfw fwd, который истино бесплатный