SELinuxports

Материал из pNp Wiki
Версия от 14:04, 22 января 2018; Andy (обсуждение | вклад)

(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Конфигурирование SELinux для поддержки сервиса. Манипуляция портами

Предварительные требования

  • Виртуальная машина с двумя сетевыми интерфейсами
  • Установленные пакеты: bash-completion, policycoreutils, policycoreutils-python, policycoreutils-devel, setroubleshoot-server

Применение SELinux на примере Apache

Изменение порта вебсервера

По-умолчанию, вебсервер слушает порт 80. Необходимо изменить настройки таким образом, что бы Apache стал ожидать соединений на другом порту. Прежде чем изменить номер порта, следует убедиться в том, что данный порт не используется в другом контексте:

[root@vm-01 ~]# semanage port -l | grep 8888
[root@vm-01 ~]#

Теперь, изменим конфигурационный файл /etc/httpd/conf/httpd.conf

[root@vm-01 ~]# grep ^Listen /etc/httpd/conf/httpd.conf
Listen 80
[root@vm-01 ~]# sed -in 's#Listen 80#Listen 8888#g' /etc/httpd/conf/httpd.conf
[root@vm-01 ~]# grep ^Listen /etc/httpd/conf/httpd.conf
Listen 8888
[root@vm-01 ~]#

После перезапуска вебсервера, он войдет в failed state, а поглядев в системный журнал, можно извлечь и полезную информацию:

[root@vm-01 ~]# journalctl -xe

Получим текст следующего содержания:

Jan 22 12:50:55 vm-01 setroubleshoot[9510]: SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 8888. For complete SELinux messages. run sealert -l d97a7d35-1491-4a0c-97ed-7aa2db7e294b
Jan 22 12:50:55 vm-01 python[9510]: SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 8888.
                                    
                                    *****  Plugin bind_ports (92.2 confidence) suggests   ************************
                                    
                                    If you want to allow /usr/sbin/httpd to bind to network port 8888
                                    Then you need to modify the port type.
                                    Do
                                    # semanage port -a -t PORT_TYPE -p tcp 8888
                                        where PORT_TYPE is one of the following: http_cache_port_t, http_port_t, jboss_management_port_t, jboss_messaging_port_t, ntop_port_t, puppet_port_t.
                                    
                                    *****  Plugin catchall_boolean (7.83 confidence) suggests   ******************
                                    
                                    If you want to allow system to run with NIS
                                    Then you must tell SELinux about this by enabling the 'nis_enabled' boolean.
                                    
                                    Do
                                    setsebool -P nis_enabled 1
                                    
                                    *****  Plugin catchall (1.41 confidence) suggests   **************************
                                    
                                    If you believe that httpd should be allowed name_bind access on the port 8888 tcp_socket by default.
                                    Then you should report this as a bug.
                                    You can generate a local policy module to allow this access.
                                    Do
                                    allow this access for now by executing:
                                    # ausearch -c 'httpd' --raw | audit2allow -M my-httpd
                                    # semodule -i my-httpd.pp

Запустив команду sealert -l d97a7d35-1491-4a0c-97ed-7aa2db7e294b мы получим подробное руководство к действию, с развернутым объяснением нашей проблемы:

[root@vm-01 ~]# sealert -l d97a7d35-1491-4a0c-97ed-7aa2db7e294b
SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 8888.

*****  Plugin bind_ports (92.2 confidence) suggests   ************************

If you want to allow /usr/sbin/httpd to bind to network port 8888
Then you need to modify the port type.
Do
# semanage port -a -t PORT_TYPE -p tcp 8888
    where PORT_TYPE is one of the following: http_cache_port_t, http_port_t, jboss_management_port_t, jboss_messaging_port_t, ntop_port_t, puppet_port_t.

*****  Plugin catchall_boolean (7.83 confidence) suggests   ******************

If you want to allow system to run with NIS
Then you must tell SELinux about this by enabling the 'nis_enabled' boolean.
You can read 'None' man page for more details.
Do
setsebool -P nis_enabled 1

*****  Plugin catchall (1.41 confidence) suggests   **************************

If you believe that httpd should be allowed name_bind access on the port 8888 tcp_socket by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'httpd' --raw | audit2allow -M my-httpd
# semodule -i my-httpd.pp


Additional Information:
Source Context                system_u:system_r:httpd_t:s0
Target Context                system_u:object_r:unreserved_port_t:s0
Target Objects                port 8888 [ tcp_socket ]
Source                        httpd
Source Path                   /usr/sbin/httpd
Port                          8888
Host                          vm-01
Source RPM Packages           httpd-2.4.6-45.el7.x86_64
Target RPM Packages           
Policy RPM                    selinux-policy-3.13.1-102.el7.noarch
Selinux Enabled               True
Policy Type                   targeted
Enforcing Mode                Enforcing
Host Name                     vm-01
Platform                      Linux vm-01 3.10.0-514.el7.x86_64 #1 SMP Wed Oct
                              19 11:24:13 EDT 2016 x86_64 x86_64
Alert Count                   1
First Seen                    2018-01-22 12:50:53 MSK
Last Seen                     2018-01-22 12:50:53 MSK
Local ID                      d97a7d35-1491-4a0c-97ed-7aa2db7e294b

Raw Audit Messages
type=AVC msg=audit(1516614653.147:1119): avc:  denied  { name_bind } for  pid=9504 comm="httpd" src=8888 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket


type=SYSCALL msg=audit(1516614653.147:1119): arch=x86_64 syscall=bind success=no exit=EACCES a0=3 a1=7f3204e9bcf8 a2=10 a3=7ffd1ca5dcec items=0 ppid=1 pid=9504 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm=httpd exe=/usr/sbin/httpd subj=system_u:system_r:httpd_t:s0 key=(null)

Hash: httpd,httpd_t,unreserved_port_t,tcp_socket,name_bind

[root@vm-01 ~]#

Выясним, какой контекст применяется к стандартным портам вебсервиса:

[root@vm-01 ~]# semanage port -l | grep ^http
http_cache_port_t              tcp      8080, 8118, 8123, 10001-10010
http_cache_port_t              udp      3130
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
[root@vm-01 ~]#

Теперь включаем в контекст http_port_t порт 8888:

[root@vm-01 ~]# semanage port -at http_port_t -p tcp 8888
[root@vm-01 ~]# semanage port -l | grep ^http_port_t
http_port_t                    tcp      8888, 80, 81, 443, 488, 8008, 8009, 8443, 9000
[root@vm-01 ~]#

Снимаем состояние failed с сервиса Apache и перезапускаем сервис:

[root@vm-01 ~]# systemctl reset-failed httpd
[root@vm-01 ~]# systemctl restart httpd
[root@vm-01 ~]# systemctl is-active httpd
active
[root@vm-01 ~]# ss -tulpn | grep http
tcp    LISTEN     0      128      :::8888                 :::*                   users:(("httpd",pid=9723,fd=4),("httpd",pid=9722,fd=4),("httpd",pid=9721,fd=4),("httpd",pid=9720,fd=4),("htt d",pid=9719,fd=4),("httpd",pid=9718,fd=4))
[root@vm-01 ~]#

Открываем порт в файрволе:

[root@vm-01 ~]# firewall-cmd --add-port=8888/tcp --permanent
success
[root@vm-01 ~]# firewall-cmd --reload
success
[root@vm-01 ~]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1
  sources: 
  services: dhcpv6-client dns http ssh
  ports: 3260/tcp 8888/tcp
  protocols: 
  masquerade: yes
  forward-ports: 
  sourceports: 
  icmp-blocks: 
  rich rules: 
	
[root@vm-01 ~]#

Не забываем исправить порт на нашем виртуальном хосте:

[root@vm-01 ~]# sed -in 's#80#8888#g' /etc/httpd/conf.d/test.conf 
[root@vm-01 ~]# cat /etc/httpd/conf.d/test.conf
# Virtual Hosts
#
# Required modules: mod_log_config

# If you want to maintain multiple domains/hostnames on your
# machine you can setup VirtualHost containers for them. Most configurations
# use only name-based virtual hosts so the server doesn't need to worry about
# IP addresses. This is indicated by the asterisks in the directives below.
#
# Please see the documentation at 
# <URL:http://httpd.apache.org/docs/2.4/vhosts/>
# for further details before you try to setup virtual hosts.
#
# You may use the command line option '-S' to verify your virtual host
# configuration.

#
# VirtualHost example:
# Almost any Apache directive may go into a VirtualHost container.
# The first VirtualHost section is used for all requests that do not
# match a ServerName or ServerAlias in any <VirtualHost> block.
#
<VirtualHost *:8888>
    ServerAdmin webmaster@test.example.com
    DocumentRoot "/home/andy/content"
    ServerName test.example.com
    ServerAlias www.test.example.com
    ErrorLog "/var/log/httpd/test.example.com-error_log"
    CustomLog "/var/log/httpd/test.example.com-access_log" common
    Options Indexes FollowSymLinks
<Directory "/home/andy/content">
    Options Indexes FollowSymLinks
    AllowOverride None
    # Allow open access:
    Require all granted
</Directory>

</VirtualHost>
[root@vm-01 ~]#

Еще раз перезапустим Apache и подредактируем нашу страницу:

[root@vm-01 ~]# systemctl restart httpd
[root@vm-01 ~]# systemctl is-active httpd
active
[root@vm-01 ~]# date >> /home/andy/content/index.html

Изменение имеющегося порта

В случае, когда нам надо изменить контекст порта, уже имеющегося в политиках, надо делать следующее:

[root@vm-01 ~]# semanage port -l | grep 8081
transproxy_port_t              tcp      8081
[root@vm-01 ~]# semanage port -dt transproxy_port_t -p tcp 8081
ValueError: Port tcp/8081 is defined in policy, cannot be deleted
[root@vm-01 ~]# semanage port -mt http_port_t -p tcp 8081
[root@vm-01 ~]# semanage port -l | grep 8081
http_port_t                    tcp      8081, 8888, 80, 81, 443, 488, 8008, 8009, 8443, 9000
transproxy_port_t              tcp      8081
[root@vm-01 ~]#

Далее открываем порт в файрволе, перезагружаем вебсервер и проверяем с нужным портом.

Проверка

С виртуальной машины vm-02 обратимся к странице при помощи утилиты curl:

[root@vm-02 ~]# curl "http://192.168.1.1:8888/~andy/index.html"
This is the test configuration file! 
Mon Jan 22 13:52:25 MSK 2018
[root@vm-02 ~]#

Ссылки

SELinux User's and Administrator's Guide