Apache HTTP Server (Português)

From ArchWiki

O Apache HTTP Server, ou simplesmente Apache, é um web server muito popular desenvolvido por Apache Software Foundation.

Este artigo descreve como configurar o Apache e como opcionalmente integrá-lo com PHP.

Instalação

Instale o pacote apache.

Configuração

Os arquivos de configuração do Apache estão localizados em /etc/httpd/conf. O principal arquivo de configuração é /etc/httpd/conf/httpd.conf, que inclui vários outros arquivos de configuração. O principal arquivo de configuração deve ser o suficiente para uma configuração simples. Por padrão, será fornecido o diretório /srv/http para qualquer um que queira acessar seu website.

Para iniciar o Apache, inicie httpd.service usando o systemd.

O Apache deverá estar executando agora. Teste-o visitando o endereço http://localhost/ em um navegador da web. Isto deverá exibir uma simples página web inicial.

Para configurações adicionais, veja as seções a seguir.

Opções avançadas

Veja a lista completa de diretivas de configuração do Apache e o guia de referência rápido.

Estas opções em /etc/httpd/conf/httpd.conf poderão ser interessantes:

User http
Por razões de segurança, assim que o Apache é iniciado pelo usuário root (diretamente ou via scripts de inicialização) ele altera para este identificador de usuário. A identificação padrão é http, a qual é automaticamente criada durante a instalação.
Listen 80
Esta é a porta a qual o Apache irá monitorar. Para acesso da internet através de roteador, você terá que fazer um encaminhamento de porta.
Se desejar configurar Apache para desenvolvimento local, talvez queira que somente o seu computador seja capaz de acessá-lo. Para isso, altere esta linha para Listen 127.0.0.1:80.
ServerAdmin [email protected]
Este será o endereço de email apresentado em, por exemplo, páginas de erro.
DocumentRoot "/srv/http"
Este é o endereço onde deverão ser localizadas suas páginas web..
Altere, se desejar, mas não se esqueça de também alterar <Directory "/srv/http"> para onde você apontou seu DocumentRoot, caso contrário você irá obter um erro 403 (que é de falta de privilégios) ao tentar acessar sua nova raiz de páginas. Não se esqueça de alterar a linha Require all denied para Require all granted, caso contrário você obterá um erro 403. Lembre-se de que o diretório e seus diretórios-pai devem ter permissão de execução para outros (o que pode ser alterado com chmod o+x /path/to/DocumentRoot), do contrário também obterá um erro 403.
AllowOverride None
Esta diretiva na seção <Directory> faz com que o Apache completamente ignore arquivos .htaccess. Perceba que este é o comportamento padrão para o Apache 2.4, então você deverá explicitamente permitir sobreposições caso planeje usar arquivos .htaccess. Caso planeje usar mod_rewrite ou outras configurações em .htaccess files, você será capaz de permitir tais diretivas declaradas em cada arquivo que irá sobrepor as configurações do servidor. Para mais informações, consulte a documentação do Apache.
Dica: Se houver problemas com suas configurações do Apache, você poderá checá-las com: apachectl configtest

Mais configurações que podem ser encontradas em /etc/httpd/conf/extra/httpd-default.conf:

Desativar a assinatura do servidor:

ServerSignature Off

Para ocultar informações do servidor e versão do PHP:

ServerTokens Prod

Diretórios do usuário

Diretórios do usuário estão disponíveis por padrão através de http://localhost/~yourusername/ e exibem o conteúdo de ~/public_html (isto pode ser alterado em /etc/httpd/conf/extra/httpd-userdir.conf).

Se não desejar que diretórios do usuário estejam disponíveis através da web, apenas comente a seguinte linha em /etc/httpd/conf/httpd.conf:

Include conf/extra/httpd-userdir.conf

Tango-inaccurate.pngThe factual accuracy of this article or section is disputed.Tango-inaccurate.png

Reason: Não é necessário ajustar +x para cada usuário, ajuste apenas para o webserver via sufixos ACL (veja Access Control Lists#Granting execution permissions for private files to a web server). (Discuss in Talk:Apache HTTP Server (Português)#User Directories)

Você deverá ter certeza de que seu diretório home está com suas permissões configuradas corretamente para que o Apache possa alcançá-lo. Seu diretório home e ~/public_html devem ser executáveis para outros ("para todo o mundo"):

$ chmod o+x ~
$ chmod o+x ~/public_html
$ chmod -R o+r ~/public_html

Reinicie httpd.service para aplicar quaisquer alterações. Veja também Umask#Set the mask value.

TLS

Atenção: Se você for implantar TLS, certifique-se de seguir o guia de weakdh.org para evitar vulnerabilidades. Para mais informações, veja Server-side TLS.

Primeiramente, obtain a certificate. Caso tenha seu próprio domínio público, você poderá usar Transport Layer Security#ACME clients.

Em /etc/httpd/conf/httpd.conf, descomente as três linhas a seguir:

LoadModule ssl_module modules/mod_ssl.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
Include conf/extra/httpd-ssl.conf

Se estiver usando certbot --apache, a linha a seguir também deverá ser descomentada:

LoadModule rewrite_module modules/mod_rewrite.so

Após obter uma chave e um certificado, certifique-se que as linhas SSLCertificateFile e SSLCertificateKeyFile em /etc/httpd/conf/extra/httpd-ssl.conf apontam para a chave e o certificado. Se uma cadeia de certificados CA também foi gerada, adicione seu nome de arquivo em SSLCertificateChainFile.

Finalmente, reinicie httpd.service para aplicar quaisquer alteralções.

Dica: A Mozilla tem um artigo chamado SSL/TLS article muito útil bem como uma ferramenta chamada automated tool para ajudar a criar uma configuração segura.

Hosts virtuais

Note: Você precisará adicionar uma seção <VirtualHost *:443> para suporte ao SSL em hosts virtuais. Veja #Gerenciando vários hosts virtuais para um exemplo de arquivo.

Se desejar ter mais de um host, descomente a seguinte linha em /etc/httpd/conf/httpd.conf:

Include conf/extra/httpd-vhosts.conf

Em /etc/httpd/conf/extra/httpd-vhosts.conf configure seus hosts virtuais. O arquivo padrão contém um exemplo elaborado que o ajudará.

Para testar os hosts virtuais em sua máquina local, adicione seus respectivos nomes no arquivo /etc/hosts:

127.0.0.1 nomedodominio1.dom 
127.0.0.1 nomedodominio2.dom

Reinicie httpd.service para aplicar as alterações.

Gerenciando vários hosts virtuais

Caso tenha uma grande quantidade de hosts virtuais, você poderá querer facilmente desativá-los e ativá-los. Para isso, é recomendado criar um arquivo de configuração para cada host virtual e armazená-los em uma pasta, por exemplo: /etc/httpd/conf/vhosts.

Primeiro, crie a pasta:

# mkdir /etc/httpd/conf/vhosts

Então coloque cada arquivo de configuração nela:

# nano /etc/httpd/conf/vhosts/nomedodominio1.dom
# nano /etc/httpd/conf/vhosts/nomedodominio2.dom
...

No último passo, use Include para incluir cada arquivo de configuração em seu /etc/httpd/conf/httpd.conf:

#Enabled Vhosts:
Include conf/vhosts/nomedodominio1.dom
Include conf/vhosts/nomedodominio2.dom

Você poderá ativar e desativar seus hosts virtuais apenas comentando ou descomentando-os.

Um arquivo muito simples de um host virtual é semelhante a este:

/etc/httpd/conf/vhosts/nomedodominio1.dom
<VirtualHost *:80>
    ServerAdmin [email protected]
    DocumentRoot "/home/user/http/nomedodominio1.dom"
    ServerName nomedodominio1.dom
    ServerAlias nomedodominio1.dom
    ErrorLog "/var/log/httpd/nomedodominio1.dom-error_log"
    CustomLog "/var/log/httpd/nomedodominio1.dom-access_log" common

    <Directory "/home/user/http/nomedodominio1.dom">
        Require all granted
    </Directory>
</VirtualHost>

<VirtualHost *:443>
    ServerAdmin [email protected]
    DocumentRoot "/home/user/http/nomedodominio1.dom"
    ServerName nomedodominio1.dom:443
    ServerAlias nomedodominio1.dom:443
    SSLEngine on
    SSLCertificateFile "/etc/httpd/conf/server.crt"
    SSLCertificateKeyFile "/etc/httpd/conf/server.key"
    ErrorLog "/var/log/httpd/nomedodominio1.dom-error_log"
    CustomLog "/var/log/httpd/nomedodominio1.dom-access_log" common

    <Directory "/home/user/http/nomedodominio1.dom">
        Require all granted
    </Directory>
</VirtualHost>

Extensões

PHP

Primeiro, instale o PHP, então siga uma das próximas subseções abaixo. Finalmente, teste a instalação como descrito no final da subseção.

Usando libphp

Este método é provavelmente o mais fácil, mas também o menos escalável: é adequado para um baixo número de requisições. Ele também requer que você altere o módulo mpm, o que poderá causar problemas com outras extensões (por exemplo, não é compatível com #HTTP/2).

Instale php7-apache para PHP 7 ou php-apache para PHP 8, o que for apropriado.

Em /etc/httpd/conf/httpd.conf, comente a linha:

#LoadModule mpm_event_module modules/mod_mpm_event.so

e descomente a linha:

LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
Note: O passo acima é requerido, porque libphp.so incluído com o pacote não funciona com mod_mpm_event, mas em vez disso, irá funcionar apenas com mod_mpm_prefork. (FS#39218)

Do contrário, você obterá o seguinte erro:

Apache is running a threaded MPM, but your PHP Module is not compiled to be threadsafe.  You need to recompile PHP.
AH00013: Pre-configuration failed
httpd.service: control process exited, code=exited status=1
Como alternativa, você pode usar mod_proxy_fcgi (veja #Usando php-fpm e mod_proxy_fcgi abaixo).

Para habilitar o PHP, adicione as seguintes linhas ao /etc/httpd/conf/httpd.conf:

  • Adicione esta ao final da lista LoadModule:
LoadModule php_module modules/libphp.so
AddHandler php-script .php
  • Adicione esta ao final da lista Include:
Include conf/extra/php_module.conf

Reinicie httpd.service usando systemd.

Usando apache2-mpm-worker e mod_fcgid

Este método fornece uma melhor performance e melhor consumo de memória ao lidar com múltiplas requisições.

Instale mod_fcgidAUR e php-cgi.

Crie o diretório necessário e um link simbólico para o wrapper PHP:

# mkdir /srv/http/fcgid-bin
# ln -s /usr/bin/php-cgi /srv/http/fcgid-bin/php-fcgid-wrapper

Crie /etc/httpd/conf/extra/php-fcgid.conf com o seguinte conteúdo:

/etc/httpd/conf/extra/php-fcgid.conf
# Required modules: fcgid_module

<IfModule fcgid_module>
    AddHandler php-fcgid .php
    AddType application/x-httpd-php .php
    Action php-fcgid /fcgid-bin/php-fcgid-wrapper
    ScriptAlias /fcgid-bin/ /srv/http/fcgid-bin/
    SocketPath /var/run/httpd/fcgidsock
    SharememPath /var/run/httpd/fcgid_shm
        # If you don't allow bigger requests many applications may fail (such as WordPress login)
        FcgidMaxRequestLen 536870912
        # Path to php.ini – defaults to /etc/phpX/cgi
        DefaultInitEnv PHPRC=/etc/php/
        # Number of PHP childs that will be launched. Leave undefined to let PHP decide.
        #DefaultInitEnv PHP_FCGI_CHILDREN 3
        # Maximum requests before a process is stopped and a new one is launched
        #DefaultInitEnv PHP_FCGI_MAX_REQUESTS 5000
    <Location /fcgid-bin/>
        SetHandler fcgid-script
        Options +ExecCGI
    </Location>
</IfModule>

Altere /etc/httpd/conf/httpd.conf:

  • Descomente o carregamento de actions_module:
    LoadModule actions_module modules/mod_actions.so
  • Carregue o módulo FCGID após o carregamento do módulo unixd (do qual é dependente) - você talvez queira colocá-lo dentro do bloco <IfModule unixd_module>:
    LoadModule fcgid_module modules/mod_fcgid.so
  • Certifique-se de que a inclusão da configuração do MPM está descomentada (não vem comentado na versão padrão instalada deste arquivo):
    Include conf/extra/httpd-mpm.conf
  • Adicione uma inclusão para a sua nova configuração do FCGID:
    Include conf/extra/php-fcgid.conf

Reinicie httpd.service.

Usando php-fpm e mod_proxy_fcgi

Este método fornece "uma implementação alternativa do PHP FastCGI com alguns recursos adicionais (geralmente) úteis para sites com alto nível de requisições" [1].

Note: Diferente da configuração difundida com ProxyPass, a configuração do proxy com SetHandler respeita outras diretivas do Apache, como DirectoryIndex. Isto garante uma melhor compatibilidade com software desenvolvido para libphp, mod_fastcgi e mod_fcgid. Caso queira testar com ProxyPass, experimente com uma linha semelhante a esta:
ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/run/php-fpm/php-fpm.sock|fcgi://localhost/srv/http/$1

Instale php-fpm.

Habilite os módulos de proxy:

/etc/httpd/conf/httpd.conf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so

Crie /etc/httpd/conf/extra/php-fpm.conf com o seguinte conteúdo:

DirectoryIndex index.php index.html
<FilesMatch \.php$>
    SetHandler "proxy:unix:/run/php-fpm/php-fpm.sock|fcgi://localhost/"
</FilesMatch>

E inclua-o no final de /etc/httpd/conf/httpd.conf:

Include conf/extra/php-fpm.conf
Note: O pipe entre sock e fcgi não admite espaços ao seu redor! localhost pode ser substituído por qualquer string. Mais informações aqui

Você pode configurar o PHP-FPM em /etc/php/php-fpm.d/www.conf, mas a configuração padrão deverá funcionar adequadamente.

Inicie e habilite php-fpm.service. Reinicie httpd.service.

Teste a instalação do PHP

Para testar se o PHP foi configurado corretamente, crie um arquivo chamado test.php no diretório DocumentRoot de seu Apache (por exemplo, /srv/http/ ou ~<username>/public_html/) com o seguinte conteúdo:

<?php phpinfo(); ?>

Então vá para http://localhost/test.php ou http://localhost/~<username>/test.php conforme o caso.

HTTP/2

Note:
  • Enquanto Apache suporta HTTP/2 não-criptografado sobre TCP (h2c), navegadores comuns não o fazem. Portanto, para uso com o último, #TLS precisa ser ativado primeiro.
  • Se os clientes de suporte não usam HTTP/2 em vez de HTTP/1.1 e o gerador de configurações da Mozilla (o qual já tem incluída a linha Protocols abaixo) foi utilizado para realizar a configuração do #TLS, tente usar Include para incluí-lo em httpd-ssl.conf após a saída do último.
  • Maneiras de testar a inclusão curl -sI https://your.website ou esta extensão do Chrome.

Para habilitar o suporte ao HTTP/2 sobre TLS, descomente a seguinte linha em httpd.conf:

LoadModule http2_module modules/mod_http2.so

E adicione a seguinte linha:

Protocols h2 http/1.1

Para depuração, você poderá definir apenas o módulo (em vez de todo o servidor) usando debug ou info:

<IfModule http2_module>
    LogLevel http2:info
</IfModule>

Para mais informações – incluindo configurações adicionais do HTTP/2 – veja a mod_http2 documentação.

Atenção: O módulo http2_module não é compatível com o módulo mpm_prefork_module cujas configurações antigas são largamente usadas para configurar o PHP. Considere usar php-fpm em vez disso.

Soluções de problemas

Logs e Status do Apache

Veja o status do Apache usando o systemctl.

Logs do Apache podem ser encontrados em /var/log/httpd/

Error: PID file /run/httpd/httpd.pid not readable (yet?) após inicializar

Comente a linha unique_id_module em httpd.conf: #LoadModule unique_id_module modules/mod_unique_id.so

Diretório /run/httpd não é criado durante o boot

Se systemd-tmpfiles --create como usuário root resulta em algo como "unsafe path transition", verifique as definições de propriedade de seu diretório root.

ls -la /
chown root:root /

Apache is running a threaded MPM, but your PHP Module is not compiled to be threadsafe.

Se durante o carregamento de php_module o serviço httpd.service falha e você obtém um erro como este no log diário (journal) do sistema:

Apache is running a threaded MPM, but your PHP Module is not compiled to be threadsafe.  You need to recompile PHP.

Isto ocorre porque o PHP inclui suporte para um módulo que não é threadsafe, e você está tentando usar um MPM em modo threaded. Uma solução para corrigir isto é usar um módulo MPM non-threaded. Tente substituir mpm_event_module com mpm_prefork_module:

/etc/httpd/conf/httpd.conf
LoadModule mpm_event_module modules/mod_mpm_event.so
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

e reinicie httpd.service.

AH00534: httpd: Configuration error: No MPM loaded.

Você poderá encontrar este erro após uma atualização recente. Trata-se apenas de uma recente alteração em httpd.conf que você pode não ter reproduzido em sua configuração local. Para corrigir, descomente a seguinte linha:

/etc/httpd/conf/httpd.conf
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

E reinicie httpd.service.

AH00072: make_sock: could not bind to address

Isto pode ser causado por várias razões. A mais comum delas é devido a algo estar já usando a porta fornecida, verifique via netstat se isto não está ocorrendo:

# netstat -lnp | grep -e :80 -e :443

Se você obtiver alguma saída, pare o serviço indicado que está usando a porta ou encerre o processo que está causando o limite da porta e tente novamente.

Outra possível causa é o fato do Apache não puder ser iniciado como root por alguma razão - tente iniciá-lo manualmente e veja se você continua obtendo o erro AH00072.

# httpd -k start

Finalmente, você tembém pode obter um erro com sua configuração por comandar Listen duas vezes sobre a mesma porta. A configuração a seguir é um exemplo de uma configuração incorreta que irá ocasionar o problema:

Listen 0.0.0.0:80
Listen [::]:80

AH01071: Got error 'Primary script unknown'

Isto pode ser causado por ProtectHome=true no arquivo unit do systemd relacionado ao php-fpm se você estiver usando arquivos fornecidos em /home, como ocorre em um ambiente de host virtual. Você pode desabilitar este recurso editando o arquivo de unit do php-fpm e reiniciando php-fpm. Alternativamente, mova seu DocumentRoot.

Alterar max_execution_time no php.ini não surte qualquer efeito

Se você alterou max_execution_time no arquivo php.ini para um valor superior a 30 (segundos), você acabará obtendo uma resposta 503 Service Unavailable do Apache após 30 segundos. Para solucionar isto, adicione uma diretiva ProxyTimeout no httpd.conf antes do bloco <FilesMatch \.php$>:

/etc/httpd/conf/httpd.conf
ProxyTimeout 300

e reinicie httpd.service.

PHP-FPM: erros não estão sendo registrados individualmente para cada host virtual

Caso tenha múltiplos hosts virtuais, você talvez queira que cada um tenha seu próprio log de erros em arquivos separados (usando a diretiva ErrorLog do Apache). Se isto não funcionar para você, confirme que PHP-FPM está configurado para registrar erros em seu syslog:

/etc/php/php-fpm.conf
error_log = syslog

Também é possível que a configuração do pool esteja sobrepondo. Verifique se a seguinte linha está comentada:

/etc/php/php-fpm.d/www.conf
;php_admin_value[error_log] = /var/log/fpm-php.www.log

Veja também