Files
homework15/README.md
2026-01-25 22:23:37 +03:00

14 KiB
Raw Blame History

Домашнее задание 15

Selinux

Задание 1 Обеспечить работоспособность приложения при включенном selinux

Для выполнения ДЗ будет использоваться Fedora Server 43

Наша задача запустить nginx на нестандартном порту 3-мя разными способами

Утсанавливаем nginx

root@fedora:~/otus$ dnf install nginx

Теперь изменим немного конфигурацию, добавив нестандартный для nginx порт 8880, дописав строки в /etc/nginx/nginx.conf

 server {
        listen       80;
        listen       8880;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;

Перезапустим nginx

[root@fedora ~]# systemctl restart nginx
Job for nginx.service failed because the control process exited with error code.
See "systemctl status nginx.service" and "journalctl -xeu nginx.service" for details

Мы сразу видим ошибку запуска

С помощью audit2why посмотрим что в логах selinux (можно так же использовать ausearch)

[root@fedora ~]# cat /var/log/audit/audit.log | grep nginx | audit2why
type=AVC msg=audit(1769366311.648:1693): avc:  denied  { name_bind } for  pid=8420 comm="nginx" src=8880 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket permissive=0

    Was caused by:
    The boolean nis_enabled was set incorrectly. 
    Description:
    Allow nis to enabled

    Allow access by executing:
    # setsebool -P nis_enabled 1

Способ 1

Видим, что selinux запретил запуск на порту 8880, и нам сразу дается подсказка, что можно разрешить через выполнение команды setsebool -P nis_enabled 1

Выполним данную команду но без -P, так как этот параметр сохранит конфиг, и применит его после перезагрузку, нам пока этого не нужно!

[root@fedora ~]# setsebool nis_enabled 1

Команда выполнилась пробуем запустить nginx

[root@fedora ~]# systemctl start nginx
[root@fedora ~]# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: disabled)
    Drop-In: /usr/lib/systemd/system/service.d
             └─10-timeout-abort.conf
     Active: active (running) since Sun 2026-01-25 18:43:51 UTC; 3min 27s ago
 Invocation: 4e5110d7d45949f2a26939276808600a
    Process: 8522 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
    Process: 8524 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
    Process: 8526 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
   Main PID: 8527 (nginx)

Видим, что nginx и работает.

Но командой setsebool nis_enabled 1 разрешает открывать любые порты, отключаем ее

[root@fedora ~]# setsebool nis_enabled 0

Способ 2

Создадим совой разрешающий модуль nginx-custom с помощью audit2allow

[root@fedora ~]# ausearch -c 'nginx' | audit2allow -M nginx-custom
******************** IMPORTANT ***********************
To make this policy package active, execute:

semodule -i nginx-custom.pp

Тут нам сразу дается подсказка как импортировать созданный модуль, импортируем его

[root@fedora ~]# semodule -i nginx-custom.pp

Перезапускаем nginx

[root@fedora ~]# systemctl restart nginx

Nginx перезапустился без ошибок

Данный модуль так же как и в первом случае разрашает открывать любые порты! Удалим наш модуль

[root@fedora ~]# semodule -r nginx-custom
libsemanage.semanage_direct_remove_key: Removing last nginx-custom module (no other nginx-custom module exists at another priority).

Способ 3

С помощью semanage добавим наш порт 8880 в http_port_t

[root@fedora ~]# semanage port -a -t http_port_t -p tcp 8880

Проверим что он там появился

[root@fedora ~]# semanage port -l | grep  http_port_t
http_port_t                    tcp      8880, 80, 81, 443, 488, 8008, 8009, 8443, 9000
http_port_t                    udp      80, 443
pegasus_http_port_t            tcp      5988

И перезапусти nginx

[root@fedora ~]# systemctl restart nginx

проверим какие порты слушает nginx

[root@fedora ~]# ss -tlupn | grep nginx
tcp   LISTEN 0      511          0.0.0.0:80        0.0.0.0:*    users:(("nginx",pid=9000,fd=8),("nginx",pid=8999,fd=8))  
tcp   LISTEN 0      511          0.0.0.0:8880      0.0.0.0:*    users:(("nginx",pid=9000,fd=9),("nginx",pid=8999,fd=9))  
tcp   LISTEN 0      511             [::]:80           [::]:*    users:(("nginx",pid=9000,fd=10),("nginx",pid=8999,fd=10))

Способ 3 считаю наилучшим решением!

Все успешно!

Задание 1 успешно выполнено!

Задание 2 Обеспечить работоспособность приложения

Подготовка

Клонирум репозиторий

alex@ubuntu-pc:~/otus$ git clone https://github.com/mbfx/otus-linux-adm
Клонирование в «otus-linux-adm»...
remote: Enumerating objects: 558, done.
remote: Counting objects: 100% (456/456), done.
remote: Compressing objects: 100% (303/303), done.
remote: Total 558 (delta 125), reused 396 (delta 74), pack-reused 102 (from 1)
Получение объектов: 100% (558/558), 1.38 МиБ | 5.36 МиБ/с, готово.
Определение изменений: 100% (140/140), готово.

Переходим в каталог с заданием

alex@ubuntu-pc:~/otus$ cd otus-linux-adm/selinux_dns_problems

Запускам vagrant

alex@ubuntu-pc:~/otus/otus-linux-adm/selinux_dns_problems$ vagrant up
Bringing machine 'ns01' up with 'virtualbox' provider...
Bringing machine 'client' up with 'virtualbox' provider...
==> ns01: Box 'centos/7' could not be found. Attempting to find and install...
    ns01: Box Provider: virtualbox
    ns01: Box Version: >= 0
==> ns01: Loading metadata for box 'centos/7'
    ns01: URL: https://vagrantcloud.com/api/v2/vagrant/centos/7
==> ns01: Adding box 'centos/7' (v2004.01) for provider: virtualbox
    ns01: Downloading: https://vagrantcloud.com/centos/boxes/7/versions/2004.01/providers/virtualbox/unknown/vagrant.box
Progress: 73% (Rate: 10.8M/s, Estimated time remaining: 0:00:12)
...
...

TASK [install packages] ********************************************************
fatal: [ns01]: FAILED! => {"changed": false, "msg": "Failure talking to yum: Cannot find a valid baseurl for repo: base/7/x86_64"}

PLAY RECAP *********************************************************************
ns01                       : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

Ansible failed to complete successfully. Any error output should be
visible above. Please fix these errors and try again.

Видим, что ansible завершается с ошикой "Failure talking to yum: Cannot find a valid baseurl for repo: base/7/x86_64"

Попровим Vagrantfile, добавив туда скрипт, который будет менять url до репозиотрия centos

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|
  config.vm.box = "centos/7"

  config.vm.provision "shell", inline: <<-SHELL
    sudo sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/CentOS*
    sudo sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/CentOS*
    sudo sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/CentOS*
  SHELL

  config.vm.provision "ansible" do |ansible|
    #ansible.verbose = "vvv"
    ansible.playbook = "provisioning/playbook.yml"
    ansible.become = "true"
  end

  config.vm.provider "virtualbox" do |v|
      v.memory = 256
  end

  config.vm.define "ns01" do |ns01|
    ns01.vm.network "private_network", ip: "192.168.50.10", virtualbox__intnet: "dns"
    ns01.vm.hostname = "ns01"
  end

  config.vm.define "client" do |client|
    client.vm.network "private_network", ip: "192.168.50.15", virtualbox__intnet: "dns"
    client.vm.hostname = "client"
  end

end

Вновь запускаем Vagrant

alex@ubuntu-pc:~/otus/otus-linux-adm/selinux_dns_problems$ vagrant up
Bringing machine 'ns01' up with 'virtualbox' provider...
Bringing machine 'client' up with 'virtualbox' provider...
==> ns01: Checking if box 'centos/7' version '2004.01' is up to date...
==> ns01: Machine already provisioned. Run `vagrant provision` or use the `--provision`
==> ns01: flag to force provisioning. Provisioners marked to run always will still run.
==> client: Importing base box 'centos/7'...
==> client: Matching MAC address for NAT networking...
==> client: Checking if box 'centos/7' version '2004.01' is up to d
...
...
TASK [copy motd to the client] *************************************************
changed: [client]

TASK [copy transferkey to client] **********************************************
changed: [client]

PLAY RECAP *********************************************************************
client                     : ok=7    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Теперь все запустилось как нужно

Подключаемся в консоль VM client

alex@ubuntu-pc:~/otus/otus-linux-adm/selinux_dns_problems$ vagrant ssh client
Last login: Sun Jan 25 11:28:02 2026 from 10.0.2.2
###############################
### Welcome to the DNS lab! ###
###############################

- Use this client to test the enviroment
- with dig or nslookup. Ex:
    dig @192.168.50.10 ns01.dns.lab

- nsupdate is available in the ddns.lab zone. Ex:
    nsupdate -k /etc/named.zonetransfer.key
    server 192.168.50.10
    zone ddns.lab 
    update add www.ddns.lab. 60 A 192.168.50.15
    send

- rndc is also available to manage the servers
    rndc -c ~/rndc.conf reload

###############################
### Enjoy! ####################
###############################
[vagrant@client ~]$

Пытаемся обновить зону ddns.lab

[vagrant@client ~]$ nsupdate -k /etc/named.zonetransfer.key
> server 192.168.50.10
> zone ddns.lab
> update add www.ddns.lab. 60 A 192.168.50.15
> send
update failed: SERVFAIL

Получаем ошибку.

Подключаемся на VM ns01

alex@ubuntu-pc:~/otus/otus-linux-adm/selinux_dns_problems$ vagrant ssh ns01
Last login: Sun Jan 25 11:19:21 2026 from 10.0.2.2
[vagrant@ns01 ~]$ 

Смотрим логи selinux с помощью audit2why

[vagrant@ns01 ~]# sudo cat /var/log/audit/audit.log | audit2why
type=AVC msg=audit(1769341839.490:2068): avc:  denied  { create } for  pid=5356 comm="isc-worker0000" name="named.ddns.lab.view1.jnl" scontext=system_u:system_r:named_t:s0 tcontext=system_u:object_r:etc_t:s0 tclass=file permissive=0

    Was caused by:
        Missing type enforcement (TE) allow rule.

        You can use audit2allow to generate a loadable module to allow this access.

Видим , что файл имеет контекст etc_t а изменить мы пытаемся из конеткста named_t, из за этого selinux и не дает произвести изменения

Посмотрим, какие контесты на файлах в каталоге /etc/named

[vagrant@ns01 ~]$ sudo ls -lZ /etc/named
drw-rwx---. root named unconfined_u:object_r:etc_t:s0   dynamic
-rw-rw----. root named system_u:object_r:etc_t:s0       named.50.168.192.rev
-rw-rw----. root named system_u:object_r:etc_t:s0       named.dns.lab
-rw-rw----. root named system_u:object_r:etc_t:s0       named.dns.lab.view1
-rw-rw----. root named system_u:object_r:etc_t:s0       named.newdns.lab

Видим, что везде контекст etc_t.

Для сравнения посмотрим существующую зону (localhost) и её контекст:

[vagrant@ns01 ~]$ sudo ls -lZ /var/named/named.localhost
-rw-r-----. root named system_u:object_r:named_zone_t:s0 /var/named/named.localhost

Видим, что в данном случае, контекст named_zone_t

Изменим контекст для каталога /etc/named на named_zone_t

[vagrant@ns01 ~]$ sudo chcon -R -t named_zone_t /etc/named

Проверим

[vagrant@ns01 ~]$ sudo ls -lZ /etc/named
drw-rwx---. root named unconfined_u:object_r:named_zone_t:s0 dynamic
-rw-rw----. root named system_u:object_r:named_zone_t:s0 named.50.168.192.rev
-rw-rw----. root named system_u:object_r:named_zone_t:s0 named.dns.lab
-rw-rw----. root named system_u:object_r:named_zone_t:s0 named.dns.lab.view1
-rw-rw----. root named system_u:object_r:named_zone_t:s0 named.newdns.lab

Видим, контексты изменились, перейдем на client и попробуем обновить зону еще раз

[vagrant@client ~]$ nsupdate -k /etc/named.zonetransfer.key
> server 192.168.50.10
> zone ddns.lab                                           
> update add www.ddns.lab. 60 A 192.168.50.15
> send
> 

Теперь ошибок не выдается, проверим также с помощью nslookup

[vagrant@client ~]$ nslookup www.ddns.lab
Server:     192.168.50.10
Address:    192.168.50.10#53

Name:   www.ddns.lab
Address: 192.168.50.15

Все готово!