如何强制或redirect到Nginx的SSL?

我有一个像https://signup.example.com这样的子域的注册页面

它应该只能通过HTTPS访问,但我担心人们可能会以某种方式通过HTTP绊倒,并获得404。

我在nginx中的html / server块看起来像这样:

 html { server { listen 443; server_name signup.example.com; ssl on; ssl_certificate /path/to/my/cert; ssl_certificate_key /path/to/my/key; ssl_session_timeout 30m; location / { root /path/to/my/rails/app/public; index index.html; passenger_enabled on; } } } 

我可以添加什么,以便http://signup.example.comredirecthttps://signup.example.com ? (仅供参考,我知道有Rails插件可以强制SSL但希望避免这种情况)

    根据nginx的陷阱 ,使用$request_uri代替忽略不必要的捕获略好一些。 在这种情况下,追加一个问号来防止nginx将所有查询参数加倍。

     server { listen 80; server_name signup.mysite.com; rewrite ^ https://$server_name$request_uri? permanent; } 

    在正式的方法中描述的最好的方法是使用return指令:

     server { listen 80; server_name signup.mysite.com; return 301 https://$server_name$request_uri; } 

    如果你想把它全部保存在一个服务器块中,这是正确和最有效的方法:

     server { listen 80; listen [::]:80; listen 443 default_server ssl; server_name www.example.com; ssl_certificate /path/to/my/cert; ssl_certificate_key /path/to/my/key; if ($scheme = http) { return 301 https://$server_name$request_uri; } } 

    上面的一切,使用“重写”或“如果ssl_protocol”等是越来越慢。

    这是相同的,但更有效的,只需要在http协议上执行重写,避免了在每个请求上检查$ schemevariables。 但严重的是,这是一件小事,你不需要把它们分开。

     server { listen 80; listen [::]:80; server_name www.example.com; return 301 https://$server_name$request_uri; } server { listen 443 default_server ssl; server_name www.example.com; ssl_certificate /path/to/my/cert; ssl_certificate_key /path/to/my/key; } 

    如果您正在使用新的双重HTTP和HTTPS服务器定义,则可以使用以下方法:

     server { listen 80; listen [::]:80; listen 443 default ssl; server_name www.example.com; ssl_certificate /path/to/my/cert; ssl_certificate_key /path/to/my/key; if ($ssl_protocol = "") { rewrite ^ https://$server_name$request_uri? permanent; } } 

    这似乎为我工作,不会导致redirect循环。

    编辑:

    取代:

     rewrite ^/(.*) https://$server_name/$1 permanent; 

    与Pratik的重写线。

    还有另外一个变体,它保留了Host:request头,并遵循nginx陷阱中的“GOOD”示例:

     server { listen 10.0.0.134:80 default_server; server_name site1; server_name site2; server_name 10.0.0.134; return 301 https://$host$request_uri; } 

    这是结果。 请注意,使用$server_name而不是$host将始终redirect到https://site1

     # curl -Is http://site1/ | grep Location Location: https://site1/ # curl -Is http://site2/ | grep Location Location: https://site2/ # curl -Is http://site1/foo/bar | grep Location Location: https://site1/foo/bar # curl -Is http://site1/foo/bar?baz=qux | grep Location Location: https://site1/foo/bar?baz=qux 

    确保你在任何cookies上设置了“安全”,否则他们将被发送HTTP请求,并可能被诸如Firesheep之类的工具抓取。

     server { listen xxxx:80; server_name domain.tld; server_name www.domian.tld; server_name ipv4.domain.tld; rewrite ^ https://$server_name$request_uri? permanent; } 

    这更好,我认为。 xxxx是指您的服务器的IP。 如果您正在使用Plesk 12,则可以通过更改目录“/var/www/vhosts/system/domain.tld/conf”中的“nginx.conf”文件来完成所需的任何域。 保存configuration后,请不要忘记重新启动nginx服务。

    我认为这是最简单的解决scheme。 强制将非HTTPS和非WWWstream量仅限HTTPS和www。

     server { listen 80; listen 443 ssl; server_name domain.tld www.domain.tld; # global HTTP handler if ($scheme = http) { return 301 https://www.domain.tld$request_uri; } # global non-WWW HTTPS handler if ($http_host = domain.tld) { return 303 https://www.domain.tld$request_uri; } }