Як я можу сказати SELinux дозволити nginx доступ до unix-сокета без audit2allow?


10

У мене є запити на переадресацію nginx для перенаправлення через unix-сокет за адресою /run/gunicorn/socket. За замовчуванням SELinux така поведінка заборонена:

grep nginx /var/log/audit/audit.log
type=SERVICE_START msg=audit(1454358912.455:5390): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=nginx comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
type=AVC msg=audit(1454360194.623:7324): avc:  denied  { write } for  pid=9128 comm="nginx" name="socket" dev="tmpfs" ino=76151 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=sock_file
type=SYSCALL msg=audit(1454360194.623:7324): arch=c000003e syscall=42 success=no exit=-13 a0=c a1=1f6fe58 a2=6e a3=7ffee1da5710 items=0 ppid=9127 pid=9128 auid=4294967295 uid=995 gid=993 euid=995 suid=995 fsuid=995 egid=993 sgid=993 fsgid=993 tty=(none) ses=4294967295 comm="nginx" exe="/usr/sbin/nginx" subj=system_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(1454361591.701:13343): avc:  denied  { connectto } for  pid=9128 comm="nginx" path="/run/gunicorn/socket" scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:initrc_t:s0 tclass=unix_stream_socket
type=SYSCALL msg=audit(1454361591.701:13343): arch=c000003e syscall=42 success=no exit=-13 a0=c a1=1f6fe58 a2=6e a3=7ffee1da5950 items=0 ppid=9127 pid=9128 auid=4294967295 uid=995 gid=993 euid=995 suid=995 fsuid=995 egid=993 sgid=993 fsgid=993 tty=(none) ses=4294967295 comm="nginx" exe="/usr/sbin/nginx" subj=system_u:system_r:httpd_t:s0 key=(null)

Скрізь, де я шукаю (наприклад, тут і тут ), інструкції, що дозволяють цьому сказати, зробити запит на nginx, якщо запит буде відхилено SELinux, а потім запустіть, audit2allowщоб дозволити майбутні запити. Я не можу зрозуміти жодної команди chconчи semanageкоманди, яка дозволяє це поведінка явно.

Це єдиний спосіб? Здається смішним, що ви не можете налаштувати політику, яка дозволяє nginx писати в сокет, не спершу спроба відхилена, а потім запущений інструмент, який дозволяє те, що було відхилено. Як ви точно знаєте, що ввімкнено? Як це має працювати, якщо ваші налаштування машин знаходяться під автоматизацією?

Я використовую CentOS 7.


Вам потрібно показати нам повідомлення відхиленого AVC, і було б добре знати, яку ОС та версію ви також запустите.
користувач9517

@lain хороший момент.
др

Відповіді:


23

Здається смішним, що ви не можете налаштувати політику, яка дозволяє nginx писати в сокет, не спершу спроба відхилена, а потім запущений інструмент, який дозволяє те, що було відхилено.

Ну ні, SELinux є обов'язковим контролем доступу, речі за замовчуванням відмовляються, і ви повинні явно щось дозволити. Якщо автори політики не розглядали певний (відвертий) стек або автори демона не давали про це знати SELinux і писати політику щодо цього, то ви самостійно. Ви повинні проаналізувати, чим займаються ваші служби, і як вони взаємодіють із SELinux, і придумати власну політику, щоб це дозволити. Є доступні інструменти, які допоможуть вам audit2why , audit2allow etc.

... Це єдиний спосіб?

Ні, але це залежить від того, що ви намагаєтеся зробити, і як ви намагаєтесь це зробити, що таке рішення. Наприклад, ви можете прив’язати nginx (httpd_t) до порту 8010 (без застереження_port_t). Коли ви запускаєте nginx, це не вдається

Starting nginx: nginx: [emerg] bind() to 0.0.0.0:8010 failed (13: Permission denied)

і ви (зрештою) заглянете в журнал аудиту і знайдете

type=AVC msg=audit(1457904756.503:41673): avc:  denied  { name_bind } for
pid=30483 comm="nginx" src=8010 scontext=unconfined_u:system_r:httpd_t:s0
tcontext=system_u:object_r:port_t:s0 tclass=tcp_socket

Ви можете запустити це через audit2alllow і наївно прийняти його результати

allow httpd_t port_t:tcp_socket name_bind;

який дозволяє httpd_t підключатися до будь-якого порту tcp. Це може бути не те, що ви хочете.

Ви можете скористатися пошуком пошуку, щоб дослідити політику та побачити, до яких типів портів httpd_t можна назвати посилання

sesearch --allow -s httpd_t | grep name_bind
...
allow httpd_t http_port_t : tcp_socket name_bind ;
allow httpd_t http_port_t : udp_socket name_bind ;
...

Серед інших типів http_t може прив'язуватися до http_port_t. Тепер ви можете використовувати senanage, щоб копати трохи глибше.

semanage port -l | grep http_port_t
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
...

Порт 8010 не вказаний. Оскільки ми хочемо, щоб nginx прив’язувався до порту 8010, нерозумно додавати його до списку http_port_t

semanage port -a -t http_port_t -p tcp 8010

Тепер nginx буде дозволено назначати name_bind до порту 8010 і не кожного порту tcp, як зазначено вище.

Як ви точно знаєте, що ввімкнено?

Зміни в політиці досить легко читати, запускаючи ваші повідомлення вище через audit2дозволити нам

allow httpd_t httpd_sys_content_t:sock_file write;
allow httpd_t initrc_t:unix_stream_socket connectto;

які здаються досить зрозумілими.

Перший із них стосується файлу з inum 76151. Ви можете скористатися функцією find, щоб отримати її ім'я (find / -inum 76151), а потім використати semanage fcontext -a -t ...для зміни політики та відновленняconcon для виправлення контексту.

Друга стосується того, /run/gunicorn/socketщо знову має неправильний контекст. Використовуючи sesearch, ми можемо побачити, що http_t може підключитися до unix_stream_sockets типу (серед інших) http_t. Отже, ми можемо відповідно змінити контекст

semanage fcontext -a -t httpd_t "/run/gunicorn(/.*)?"
restorecon -r /run

Це задає контекст / run / gunicorn та дерево | файли під ним до httpd_t.

Як це має працювати, якщо ваші налаштування машин знаходяться під автоматизацією?

Вам потрібно проаналізувати систему та внести відповідні зміни в тест. Потім ви використовуєте свої інструменти автоматизації для розгортання змін, маріонетка та ансібель мають підтримку для цього.

Звичайно, ви можете зробити все це у виробництві, якщо SElinux встановлений на вседозволене. Зберіть всі повідомлення, проаналізуйте їх, визначте ваші зміни та розгорніть їх.

Про SELinux можна дізнатися набагато більше, але це межа моїх навичок, Майкл Хемптон кращий, а Метью Іфе - знову кращий, вони можуть ще додати.


1
Ваша порада є грунтовною і наближає мене до вирішення цих питань самостійно, хоча все ще залишає мене трохи короткою. allow httpd_t httpd_sys_content_t:sock_file write;не так само мені пояснюється, як ви сподівалися. Що це за приказка, потрібно змінити політику щодо цього файлу (тобто, що відбувається -tв semanageкоманді?
др

Також я отримую інструкції з використання semanageбезпосередньо під час використання ваших команд. Мені потрібно додати --addаргумент.
1616

Власне, я також повинен сказати, що після зміни типу файлу сокета на те, httpd_var_run_tяк зазначав Майкл Хемптон, audit2allowповідомлення:allow httpd_t var_run_t:sock_file write;
1616

Схоже , що ви встановите його , щоб var_run_tНЕ httpd_var_run_t.
користувач9517

@lain, хм .. без кісток. Тепер audit2allowкажеallow httpd_t var_run_t:sock_file write;
др

2

Тип, який ви хочете використовувати, - це ні httpd_sys_content_t. Це для статичних файлів, які веб-сервер призначений для обслуговування користувальницьких агентів.

Для розетки, яка використовується для міжпроцесорного зв'язку, потрібний тип httpd_var_run_t.

Хоча зауважте, що через те, що ви керували рушницею нерозбірливо, можуть виникнути додаткові проблеми, пов’язані з цим.


3
Дякую! Схоже, це вирішило одну з проблем SELinux. Будь-які вказівки про те, як налаштувати обмежувальну зброю (чи будь-яку іншу службу)?
вр

1

Попередні відповіді я пробував безрезультатно. У моєму випадку я використовую сервер nginx як інтерфейс для програми uwsgi, використовуючи unix-сокети для передачі їх, моя ОС Це сервер Fedora 26.

Unix-сокети створюються в каталозі /var/local/myapp:

/var/local/myapp/server.sock    
/var/local/myapp/stats.sock

Для налаштування SELinux мені довелося додати тип контексту: httpd_sys_rw_content_t

semanage fcontext -at httpd_sys_rw_content_t "/var/local/myapp(/.*)?"
restorecon -R -v '/var/local/myapp' 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.