SELinux имеет репутацию загадочного продукта, и я думаю, что он вполне заслужен.
Насколько я понимаю, контекст запущенной программы определяет, к чему текущая политика разрешает доступ или что делать. Таким образом, как вы уже догадались, типу haproxy_t разрешены некоторые разрешения на основе типа http_port_t.
Теперь давайте попробуем выяснить, как найти эту связь.
Как вы знаете, ps -eZ
выведет список меток SELinux запущенных процессов — в случае с haproxy это user:role:type:sensitivity
] равно system_u:system_r:haproxy_t:s0
. Важным битом является тип, в данном случае haproxy_t.
Теперь, чтобы узнать, какие разрешения имеет этот тип, мы можем использовать sesearch[1]:
sesearch -d -A -s haproxy_t
-d
показывает только прямые результаты — если вы опустите это, это также покажет все объекты из seinfo --type=haproxy_t -x
! -A
ищет правила разрешения -s haproxy_t
определяет тип источника как haproxy_t Теперь мы получаем довольно много результатов (106 на моей виртуальной машине CentOS 7), потому что, как бывает, определено много разных, гранулированных разрешений. На этом этапе вам нужно узнать кое-что еще о том, что вы ищете — либо о классе, к которому применяется разрешение, либо о целевом типе, либо о самом имени разрешения.
Давайте сначала начнем с класса: так мы знаем, что наш исходный тип — haproxy_t
, и мы думаем, что наш класс может иметь какое-то отношение к Интернету, так что это хорошо Держу пари, что это может быть tcp_socket.
sesearch -d -A -s haproxy_t -c tcp_socket
Здесь будут перечислены все разрешающие правила для исходного типа haproxy_t, имеющие какое-либо отношение к tcp_socket. Это немного сузило круг поиска, но все еще остается догадываться, какой из них может быть тем, кого мы ищем.
Далее попробуем с разрешениями — мы знаем, что нам нужен наш прокси для привязки и подключения к определенным портам, верно? поэтому мы пробуем разрешения name_bind и name_connect.
sesearch -d -A -s haproxy_t -p "name_bind, name_connect"
Found 4 semantic av rules:
allow haproxy_t http_cache_port_t : tcp_socket { name_bind name_connect } ;
allow haproxy_t commplex_main_port_t : tcp_socket { name_bind name_connect } ;
allow haproxy_t http_port_t : tcp_socket { name_bind name_connect } ;
allow haproxy_t port_type : tcp_socket name_bind ;
Это показывает только 4 результата, только 3 из которых могут быть нашими виновниками! Эти результаты, с точки зрения SELinux, являются единственными портами, к которым разрешено привязываться любому процессу с контекстом haproxy_t.
Это немного обман, потому что в этом случае мы на самом деле ищем тип цели! Но для полноты — например, если мы хотим узнать, какие разрешения haproxy_t получает от http_port_t, мы можем использовать следующее:
sesearch -d -A -s haproxy_t -t http_port_t
Found 1 semantic av rules:
allow haproxy_t http_port_t : tcp_socket { name_bind name_connect } ;
и это, конечно, дает нам только один результат, и применимые разрешения .
Теперь, когда мы знаем целевые объекты и то, что они являются определениями портов, мы можем выяснить, какие именно порты они охватывают. Что ж, выясним:
semanage port -l | grep -E 'http_cache_port_t|commplex_main_port_t|http_port_t'
commplex_main_port_t tcp 5000
commplex_main_port_t udp 5000
http_cache_port_t tcp 8080, 8118, 8123, 10001-10010
http_cache_port_t upd 3130
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t tcp 5988
Итак, мы видим, что tcp-порта 5601 нигде в этом списке нет. Теперь, что касается SELinux, вы можете добавить этот порт к любому из этих типов с помощью команды semanage port --add --type XXX --proto tcp 5601
, и это сработает. Но поскольку это обслуживает http, http_port_t кажется наиболее подходящим типом.
Надеюсь, это хоть немного демистифицирует ситуацию.
[1] Доступно в пакете setools-console.