wordpress nginx sslredirect循环

所以我build立了一个nginx服务器并安装了wordpress和SSL。

该网站在http和https上运行良好,但是当我尝试通过nginx的服务器块将httpredirect到https时,http和https都会导致无限的redirect循环。

这是我的服务器块

server { listen 80; return 301 $server_name$request_uri; listen 443 ssl spdy; root /var/www/wordpress; index index.php index.html index.htm; server_name www.example.com; ssl_session_cache shared:SSL:20m; ssl_session_timeout 10m; spdy_headers_comp 6; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_certificate /etc/ssl/certs/www.example.com.certchain.crt; ssl_certificate_key /etc/ssl/private/www.example.com.key; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; add_header Alternate-Protocol 443:npn-spdy/2; proxy_set_header X-Forwarded-Proto https; access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error.log; error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } location / { proxy_set_header X-Forwarded-Proto $scheme; # try_files $uri $uri/ =404; try_files $uri $uri/ /index.php?q=$uri&$args; if ($http_referer ~* (buttons-for-website.com)) { return 444; } if ($http_referer ~* (semalt.com)) { return 444; } } location ~ \.(hh|php)$ { proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-Ssl on; fastcgi_keep_conn on; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; fastcgi_cache microcache; fastcgi_cache_valid 200 60m; } location ~ \.php$ { location @fallback { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; fastcgi_cache microcache; fastcgi_cache_valid 200 60m; } # Cache Static Files For As Long As Possible location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|$ { access_log off; log_not_found off; expires max; } # Security Settings For Better Privacy Deny Hidden Files location ~ /\. { deny all; access_log off; log_not_found off; } # Return 403 Forbidden For readme.(txt|html) or license.(txt|html) if ($request_uri ~* "^.+(readme|license)\.(txt|html)$") { return 403; } # Disallow PHP In Upload Folder location /wp-content/uploads/ { location ~ \.php$ { deny all; } } } 

我真的很感激任何人的帮助。 我注意到,第三行的“return 301”和谷歌索引同一页面的http和https版本,并取消索引我的大部分页面,并放弃了几个关键字的排名。

预先感谢一堆!

当Nginx处理请求时,它首先识别将处理请求的服务器块。 这意味着它将匹配server_name和listen指令。

在你的情况下,你有一个单一的服务器块包含:

 server { listen 80; return 301 $server_name$request_uri; listen 443 ssl spdy; root /var/www/wordpress; index index.php index.html index.htm; server_name www.example.com; ... 

这将在端口80和443上侦听。你在这两者之间有一个返回指令的事实并不重要,因为在这一点上return指令没有被处理。

一旦服务器块匹配,Nginx将继续处理其他指令。 在重写指令(例如返回)的情况下, 按列出的顺序处理它们。 在位置指令的情况下,它们是基于匹配的特殊性进行处理的(具体的规则在这里列出)。

为了实现你的redirect,你应该把你的rewrite指令分离到一个单独的服务器块中:

 server { listen 80; server_name www.example.com; return 301 https://www.example.com$request_uri; } server { listen 443 ssl spdy; server_name www.example.com; root /var/www/wordpress; index index.php index.html index.htm; ... } 

请注意,您需要指定您正在返回HTTPS版本,而不是相同的(HTTP)版本的页面。 在某些情况下,最好对服务器名称进行硬编码(例如,如果您想将www和非wwwstream量redirect到同一个HTTPS页面)。


编辑:要解决您的评论:

您需要从https://www.example.com内容,并且您需要以下redirect:

  • http://(www.)?example.comredirect到https://www.example.com
  • https://example.comredirect到https://www.example.com

要做到这一点,你需要3个服务器块:

 server { #Redirect non-https to https - match both www and non-www listen 80; server_name www.example.com example.com; return 301 https://www.example.com$request_uri; } server { #Redirect https, non-www to https, www listen 443 ssl spdy; server_name example.com; ssl_certificate /etc/ssl/certs/www.example.com.certchain.crt; ssl_certificate_key /etc/ssl/private/www.example.com.key; return 301 https://www.example.com$request_uri; } server { #Main server block listen 443 ssl spdy; server_name www.example.com; root /var/www/wordpress; index index.php index.html index.htm; ssl_certificate /etc/ssl/certs/www.example.com.certchain.crt; ssl_certificate_key /etc/ssl/private/www.example.com.key; ... } 

一些重要的提及点:

  1. 您的SSL证书应列出www.example.com和example.com作为主题替代名称。 即使您从example.comredirect,SSL连接在redirect之前仍然build立。 没有用于example.com的有效证书,用户将获得无效的证书警告,并且不会发生redirect。 (这也意味着你必须在https://example.com块中包含证书)

  2. 由于redirect需要多个SSL服务器块,所以最好将一些SSLconfiguration移到服务器块之外(进入http块)。 这些包括: ssl_session_timeoutssl_session_cachessl_protocolsssl_ciphersssl_prefer_server_ciphersssl_staplingssl_stapling_verifyssl_trusted_certificatessl_dhparam和您的HSTS标头。 (另外,我强烈build议您浏览一下Mozilla的服务器端TLS页面)