Você está tendo problemas com o SELinux.
O CentOS 7 envia regras que impedem o httpd de gravar em arquivos /var/www
, por motivos de segurança.
Você está configurando seus arquivos de log para o seu VirtualHost ir a algum lugar sob esse diretório:
ErrorLog /var/www/local.com/error.log
CustomLog /var/www/local.com/access.log combined
Assim, quando o httpd (iniciado pelo systemd) tentar gravar nesses arquivos de log, o SELinux impedirá isso, o que acaba fazendo o httpd sair com um código de saída de erro.
Você pode confirmar isso usando o comando ausearch
, que verifica entradas no log de auditoria (que é armazenado em /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
Nesta mensagem, você verá que o alvo da gravação está marcado com httpd_sys_content_t
. Se você usar ls -Z
nos arquivos de log, verá que eles estão marcados dessa maneira:
$ 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
A razão pela qual isso afeta apenas o httpd como iniciado pelo systemd e não quando você executa o httpd diretamente é que sua sessão SSH é executada no domínio "unconfined", portanto, a execução do httpd não ativa nenhuma transição do SELinux ... através do systemd, ele aplicará as permissões corretas do SELinux ao iniciar o daemon.
Você pode trabalhar temporariamente com isso usando o comando chcon
para alterar o "tipo" do SELinux desses arquivos:
$ 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
Nesse ponto, iniciar o httpd por meio de systemctl funcionará bem ...
Mas essa não é uma ótima solução, já que o tipo SELinux será perdido se esses arquivos forem recriados (por exemplo, durante a rotação de logs) ou se o sistema de arquivos for remarcado ...
Existem maneiras de tornar esse tipo mais permanente (por exemplo, o comando semanage fcontext
), mas o que esta política do SELinux está tentando implementar aqui é evitar misturar conteúdo da web com logs, a fim de evitar log de acessos acidentalmente arquivos ou sobrescrevendo o conteúdo da Web.
A resposta certa é criar arquivos de log em /var/log/httpd
ou subdiretórios desse diretório. Se você fizer isso, o tipo de SELinux estará correto desde o início, será mantido correto sobre qualquer operação, incluindo as rotulagens do SELinux, e tudo deve funcionar como esperado.
Então, se você pode ter seus logs em /var/log/httpd
, isso deve resolver esse problema!