
Preciso que minha configuração do Nginx redirecione os usuários para www.example.com se eles digitarem example.com no navegador. A razão é que nosso consultor de SEO disse que deveria haver apenas um domínio preferencial, caso contrário, o Google verá isso como duplicação de conteúdo. De qualquer forma . . .
A questão é que também tenho SSL do Letsencrypt configurado no servidor, mas não consigo redirecionar de example.com para www.example.com (o servidor aceita ambas as versões). Aqui está a configuração que estou usando:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
server_name example.com www.example.com;
root /home/my_site;
index index.php index.html index.htm;
# for letsencrypt
location ~ /.well-known {
allow all;
}
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
==== Atualização ====
Agora mudei minha configuração conforme recomendado por Tim (e sempre mudei nginx -t
) restart
em uma das respostas para o seguinte:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.example.com;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
root /home/ankush/wp_ankushthakur;
index index.php index.html index.htm;
# for letsencrypt
location ~ /.well-known {
allow all;
}
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
Aqui está a saída curl -k
e os logs de acesso para todas as variações (não criei o Nginx a partir do código-fonte porque espero uma solução mais simples e não quero bagunçar o servidor):
curl -k http://example.com
Curl output: 301 - Moved permanently
Access logs: "GET / HTTP/1.1" 301 194 "-" "curl/7.47.0"
curl -k http://www.example.com
Curl output: 301 - Moved permanently
Access logs: "GET / HTTP/1.1" 301 194 "-" "curl/7.47.0"
curl -k https://example.com
Curl output: 301 - Moved permanently
Access logs: "GET / HTTP/1.1" 301 194 "-" "curl/7.47.0"
curl -k https://www.example.com
Curl output: <Blank>
Access logs: "GET / HTTP/1.1" 301 5 "-" "curl/7.47.0"
Observe a última seção, onde a saída CURL está em branco e os logs de acesso ainda fornecem um redirecionamento permanente.
Curiosamente, se eu comentar o segundo server
bloco e reiniciar o Nginx, acabo tendo o efeito oposto ao que queria: www redireciona para não www! Estou surpreso que isso esteja acontecendo, porque a versão HTTPS de www.example.com não é mencionada em nenhum lugar desta (terceira) versão da configuração.
Responder1
Provavelmente é porque você está redirecionando apenas em HTTP, mas não em HTTPS. Você deve adicionar um HTTPS ao seu vhost de redirecionamento e deixar apenas example.com
o nome.
Além disso, o que você está fazendo é o oposto do que as pessoas realmente fazem hoje em dia - a abordagem comum é enterrar o legadowwwprefixos da era antiga e usam apenas nomes de domínio simples, sem owww.
Responder2
A chave aqui é que você precisa lidar com quatro URLS - versões http e https dos domínios www e não www. Seu problema é que você está encaminhando a versão http do domínio www e não www para ohttps://wwwdomínio, mas seu bloco de servidor principal está escutando amboshttps://example.comehttps://www.exemplo.com
Tudo que você precisa fazer é criar um bloco de servidor separado para encaminhar ohttps://example.compara ohttps://www.exemplo.comservidor. Você precisa incluir a configuração https nisso.
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
server_name www.example.com;
# Main server block for main server continues
}
Exemplo padrão
Eu tenhoum tutorialcom arquivos de configuração para download. Um exemplo padrão está abaixo.
Se isso não funcionar, você enrola cada variação (http e https, www e não www) com a opção -k para mostrar cabeçalhos e editar sua pergunta para incluí-los.
# Main server
server {
server_name www.example.com;
listen 443 ssl http2;
# etc, add all locations, call PHP or servers, etc
}
# Forward http requests to https www server
server {
listen 80;
server_name example.com www.example.com;
return 301 https://www.example.com$request_uri;
}
# Forward https non-www requests to the https www server
# Requires https setup for this server
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /var/lib/acme/certs/***CERT_DIRECTORY/fullchain;
ssl_certificate_key /var/lib/acme/certs/***CERT_DIRECTORY/privkey;
# Set up preferred protocols and ciphers. TLS1.2 is required for HTTP/2
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
return 301 https://www.example.com$request_uri;
}
Solução de problemas A melhor maneira de diagnosticar problemas é:
- use "curl -k" (mostrar cabeçalhos) em cada uma das variantes de domínio, em conjunto com o log de acesso. Os códigos de status http retornados informam o que está acontecendo. 200 é a página, 301 é o redirecionamento permanente, 302 é o redirecionamento temporário
- Certifique-se de que o Nginx tenha o módulo headers_more, o que você pode fazerconstruindo Nginx a partir da fonte, o que é bastante fácil. Isso permite adicionar cabeçalhos https à resposta. Esta é uma ótima ferramenta de diagnóstico. Você pode usar instruções como esta para descobrir quais blocos estão sendo executados
add_header Z_DEBUG "nome_local_ou_mensagem";
Responder3
Finalmente consegui convencer nosso especialista em SEO a considerar o domínio não www como principal. A configuração que funcionou para redirecionar www para não www foi a seguinte. Embora minha tentativa de conseguir o inverso tivesse uma configuração semelhante, não tenho certeza do que o impedia.
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
server_name www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
server_name example.com;
root /home/mysite;
index index.php;
location ~ /.well-known {
allow all;
}
location / {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
try_files $uri $uri/ /index.php?$query_string;
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
}
}