所以我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; ... }
一些重要的提及点:
您的SSL证书应列出www.example.com和example.com作为主题替代名称。 即使您从example.comredirect,SSL连接在redirect之前仍然build立。 没有用于example.com的有效证书,用户将获得无效的证书警告,并且不会发生redirect。 (这也意味着你必须在https://example.com块中包含证书)
由于redirect需要多个SSL服务器块,所以最好将一些SSLconfiguration移到服务器块之外(进入http块)。 这些包括: ssl_session_timeout , ssl_session_cache , ssl_protocols , ssl_ciphers , ssl_prefer_server_ciphers , ssl_stapling , ssl_stapling_verify , ssl_trusted_certificate , ssl_dhparam和您的HSTS标头。 (另外,我强烈build议您浏览一下Mozilla的服务器端TLS页面)