Quero que um domínio no Apache exista puramente como um redirecionamento. Para esse fim, crio /etc/apache2/sites-available/redirect.example.info.conf
o seguinte:
<VirtualHost *:80>
ServerName redirect.example.info
ServerAdmin webmaster@localhost
Redirect / https://example.com/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Quando executo certbot --apache
, isso é reescrito para:
<VirtualHost *:80>
ServerName redirect.example.info
ServerAdmin webmaster@localhost
Redirect / https://example.com/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =redirect.example.info
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
E um novo arquivo /etc/apache2/sites-available/redirect.example.info-le-ssl.conf
é criado:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName redirect.example.info
ServerAdmin webmaster@localhost
Redirect / https://example.com/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLCertificateFile /etc/letsencrypt/live/ca-webs.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/ca-webs.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
Isso funciona como desejado. Os redirecionamentos são executados http://redirect.example.info
→ https://redirect.example.info
→ https://example.com
. Mas não é óbvio para mim como está funcionando. O arquivo reescrito tem um Redirect
comando e um RewriteRule
comando, e eu pensei que o Redirect
(vindo primeiro) teria precedência. Como esse arquivo é realmente avaliado?
AFAIK
certbot --apache
não faz um exame rigoroso do HTTP VirtualHost existente, ele simplesmente copia todas as diretivas existentes e adiciona diretivas TLS para gerar um novo HTTPS VirtualHost.O HTTP VirtualHost simples é então modificado para incluir um redirecionamento condicional HTTP --> HTTPS (para redirecionar apenas URIs para os quais o certbot configurou um certificado).
A configuração resultante é adequada para a maioria dos casos de uso, mas no seu caso o resultado é subótimo e eu sugeriria que você editasse manualmente o HTTP Virtual Host simples. Remova as
Rewrite*
diretivas que o certbot adicionou e reverta para sua configuração original que envia visitantes diretamente dehttp://redirect.example.info
parahttps://example.com
para evitar aquela visita intermediária redundante parahttps://redirect.example.info
.Quanto ao motivo pelo qual as
Rewrite*
diretivas têm precedência, embora apareçam depois daRedirect
diretiva: isso ocorre porque a configuração efetiva do httpd do Apache não é somente o resultado de onde, em qual ordem e em qual contêiner as diretivas de configuração são colocadas e agrupadas, mas também depende de qual(is) módulo(s) as diretivas pertencem.Essa informação não é imediatamente óbvia na seção "mesclagem" do manual https://httpd.apache.org/docs/current/sections.html#merging
Para mod_rewrite o detalhe sutil provavelmente está na frase "cada módulo tem uma chance de executar e realizar quaisquer tarefas que eles gostem" .
Os módulos podem/devem se registrar por meio de ganchos de processamento de solicitação para serem capazes de "fazer o que eles gostam" no momento certo e mod_rewrite usa isso para vir primeiro (ou pelo menos mais cedo) com o
APR_HOOK_FIRST
gancho https://github.com/apache/httpd/blob/c72b74ccef72fb56becd55888a3aa783c4ab5b6b/modules/mappers/mod_rewrite.c#L5702Até onde eu sei, é assim que
Rewrite*
as diretivas ganham precedência sobre as outras, independentemente de como/onde essas outras diretivas são ordenadas.Você pode obter insights sobre os ganchos e todos os módulos habilitados e sua ordenação habilitando mod_info (não se esqueça de adicionar ACLs à URL server-info).