Попытка создать каталоги с помощью раскрытия фигурных скобок

У вас проблемы с SELinux.

CentOS 7 поставляет правила, которые не позволяют httpd записывать в файлы в /var/wwwиз соображений безопасности.

Вы настраиваете файлы журналов для вашего виртуального хоста, чтобы они находились где-то в этом каталоге:

    ErrorLog /var/www/local.com/error.log
    CustomLog /var/www/local.com/access.log combined

Таким образом, когда httpd (, запущенный systemd ), пытается записать в эти файлы журналов, SELinux предотвратит это, что в конечном итоге приведет к завершению работы httpd с кодом выхода с ошибкой.

Вы можете подтвердить это с помощью команды ausearch, которая проверяет записи в журнале аудита (, который хранится в /var/log/audit/audit.log):

.
$ sudo ausearch -m avc
type=AVC msg=audit(1234567890.123:234): avc:  denied  { write } for  pid=12345 comm="httpd" name="local.com" dev="sda1" ino=12345678 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:httpd_sys_content_t:s0 tclass=dir

В этом сообщении вы увидите, что цель записи помечена тегом httpd_sys_content_t. Если вы используете ls -Zв файлах журналов, вы увидите, что они помечены таким образом :

.
$ ls -Z /var/www/local.com/
-rw-r--r--. root   root   unconfined_u:object_r:httpd_sys_content_t:s0 access.log                                                                                         
-rw-r--r--. root   root   unconfined_u:object_r:httpd_sys_content_t:s0 error.log                                                                                          
drwxr-xr-x. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 public_html

Причина, по которой это влияет только на httpd при запуске systemd, а не на запуск httpd напрямую, заключается в том, что ваш сеанс SSH выполняется в «неограниченном» домене, поэтому запуск httpd там не вызывает никаких переходов SELinux... При запуске через systemd он применит правильные разрешения SELinux при запуске демона.

Вы можете временно обойти это, используя команду chconдля изменения «типа» SELinux этих файлов:

$ sudo chcon -t httpd_log_t /var/www/local.com/*.log
$ ls -Z /var/www/local.com/
-rw-r--r--. root   root   unconfined_u:object_r:httpd_log_t:s0 access.log
-rw-r--r--. root   root   unconfined_u:object_r:httpd_log_t:s0 error.log
drwxr-xr-x. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 public_html

В этот момент запуск httpd через systemctl будет работать нормально...

Но это не лучшее решение, так как тип SELinux будет потерян, если эти файлы будут воссозданы (, например, во время ротации журналов )или если ваша файловая система будет переименована...

Существуют способы сделать этот тип более постоянным (, например, команда semanage fcontext), но здесь эта политика SELinux пытается реализовать предотвращение смешивания веб-контента с журналами, чтобы предотвратить случайное обслуживание файлов журнала или перезапись веб-контента.

Правильный ответ — создать файлы журналов в /var/log/httpdили подкаталогах этого каталога. Если ты так сделаешь,тип SELinux будет правильным с самого начала, будет оставаться правильным при любых операциях, включая перемаркировку SELinux, и все должно работать, как ожидалось.

Таким образом, если вы можете вместо этого иметь свои журналы под /var/log/httpd, это должно решить эту проблему!

0
26.02.2020, 18:37
2 ответа

Нет необходимости сначала сохранять его в переменной. Фигурные скобки в любом случае не расширяются справа от назначения переменной, поэтому ваша переменная становится буквально {5,10,15}dB.

Можно просто:

mkdir {5,10,15}dB

Кроме того, нет необходимости отображать переменную внутри подстановки команд, все, что нужно сделать, это расширить содержимое переменной, поэтому:

mkdir $(echo $noise)

Не отличается от:

mkdir $noise
1
28.04.2021, 23:22

Думаю, вас смутил порядок расширения. Bash выполняет их в определенном порядке, и сначала идет раскрытие фигурной скобки, за которым следует раскрытие переменной. Вот почему расширение скобки не сработало в вашем примере.

Вы можете использовать eval, чтобы заставить bash выполнить расширение:

noise={5,10,15}dB
# BAD IDEA, FOR DEMONSTRATION PURPOSES ONLY
eval mkdir $noise

Однако, как правило, это плохая практика, потому что если внутри $noiseесть вредоносный код, он также будет выполнен.

Как указывает @Archemar в комментарии, использование массива может быть лучшей идеей, например.

noise=(5 10 15)
mkdir "${arr[@]/%/dB}"

Если вы передаете имена каталогов из командной строки, не должно возникнуть проблем с раскрытием фигурных скобок, поскольку это будет сделано интерактивной оболочкой при вызове скрипта. Другими словами, будет работать следующее:

$ cat script.sh
#!/bin/bash
mkdir "$@"

$./script.sh {5,10,15}dB
1
28.04.2021, 23:22

Теги

Похожие вопросы