# Домашнее задание 15 ## Selinux ## Задание 1 Обеспечить работоспособность приложения при включенном selinux Для выполнения ДЗ будет использоваться Fedora Server 43 Наша задача запустить nginx на нестандартном порту 3-мя разными способами Утсанавливаем nginx ```bash root@fedora:~/otus$ dnf install nginx ``` Теперь изменим немного конфигурацию, добавив нестандартный для nginx порт 8880, дописав строки в /etc/nginx/nginx.conf ```bash server { listen 80; listen 8880; listen [::]:80; server_name _; root /usr/share/nginx/html; ``` Перезапустим nginx ```bash [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) ```bash [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**, так как этот параметр сохранит конфиг, и применит его после перезагрузку, нам пока этого не нужно! ```bash [root@fedora ~]# setsebool nis_enabled 1 ``` Команда выполнилась пробуем запустить nginx ```bash [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** разрешает открывать любые порты, отключаем ее ```bash [root@fedora ~]# setsebool nis_enabled 0 ``` ### Способ 2 Создадим совой разрешающий модуль **nginx-custom** с помощью **audit2allow** ```bash [root@fedora ~]# ausearch -c 'nginx' | audit2allow -M nginx-custom ******************** IMPORTANT *********************** To make this policy package active, execute: semodule -i nginx-custom.pp ``` Тут нам сразу дается подсказка как импортировать созданный модуль, импортируем его ```bash [root@fedora ~]# semodule -i nginx-custom.pp ``` Перезапускаем nginx ```bash [root@fedora ~]# systemctl restart nginx ``` Nginx перезапустился без ошибок Данный модуль так же как и в первом случае разрашает открывать любые порты! Удалим наш модуль ```bash [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 ```bash [root@fedora ~]# semanage port -a -t http_port_t -p tcp 8880 ``` Проверим что он там появился ```bash [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 ```bash [root@fedora ~]# systemctl restart nginx ``` проверим какие порты слушает nginx ```bash [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 Обеспечить работоспособность приложения ### Подготовка Клонирум репозиторий ```bash 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), готово. ``` Переходим в каталог с заданием ```bash alex@ubuntu-pc:~/otus$ cd otus-linux-adm/selinux_dns_problems ``` Запускам vagrant ```bash 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 ```bash # -*- 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 ```bash 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** ```bash 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 ```bash [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 ```bash 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 ```bash [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 ```bash [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) и её контекст: ```bash [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 ```bash [vagrant@ns01 ~]$ sudo chcon -R -t named_zone_t /etc/named ``` Проверим ```bash [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 и попробуем обновить зону еще раз ```bash [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 ```bash [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 ``` Все готово!