我有一个网站@www.eshipp.com,所有域名都由 SSL 保护,因此任何 HTTP 流量都会由 NGINX 重定向到 HTTPS 等效 URL。
然而,似乎有些用户没有被重定向,然后收到“无法访问”的 http 错误。
由于我自己在浏览器上没有遇到错误,所以很难调试,但幸运的是我发现使用 Curl 会导致此错误发生:
$ curl -v http://eshipp.com/
* Hostname was NOT found in DNS cache
* Trying 198.199.96.110...
* connect to 198.199.96.110 port 80 failed: Connection timed out
* Failed to connect to eshipp.com port 80: Connection timed out
* Closing connection 0
curl: (7) Failed to connect to eshipp.com port 80: Connection timed out
上面的命令不起作用,但下面的命令起作用:
curl -v https://eshipp.com/
* Hostname was NOT found in DNS cache
* Trying 198.199.96.110...
* Connected to eshipp.com (198.199.96.110) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using ECDHE-RSA-AES128-GCM-SHA256
* Server certificate:
* subject: OU=Domain Control Validated; OU=Gandi Standard SSL; CN=eshipp.com
* start date: 2015-07-13 00:00:00 GMT
* expire date: 2016-07-13 23:59:59 GMT
* subjectAltName: eshipp.com matched
* issuer: C=FR; ST=Paris; L=Paris; O=Gandi; CN=Gandi Standard SSL CA 2
* SSL certificate verify ok.
> GET / HTTP/1.1
> User-Agent: curl/7.35.0
> Host: eshipp.com
> Accept: */*
>
< HTTP/1.1 200 OK
* Server nginx is not blacklisted
< Server: nginx
< Date: Sat, 08 Aug 2015 22:10:56 GMT
< Content-Type: text/html; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Vary: Accept-Encoding
< Strict-Transport-Security: max-age=31536000; includeSubdomains
<
<!DOCTYPE html>
以下是 NGINX 配置:
# HTTP
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name www.eshipp.com eshipp.com;
return 301 https://$server_name$request_uri;
}
# HTTPS
server {
listen 443 ssl spdy;
server_name www.eshipp.com eshipp.com;
keepalive_timeout 10m;
# Certificats SSL
ssl_certificate /etc/nginx/ssl/eshipp.com.crt;
ssl_certificate_key /etc/nginx/ssl/eshipp.com.key;
# Amélioration des performances SSL
ssl_stapling on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Amélioration de la sécurité SSL
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SH$
# Active le HSTS to avoid SSL stripping
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
# If your application is not compatible with IE <= 10, this will redirect visitors to a page advising a browser update
# This works because IE 11 does not present itself as MSIE anymore
if ($http_user_agent ~ "MSIE" ) {
return 303 https://browser-update.org/update.html;
}
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # allow websockets
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $remote_addr; # preserve client IP
# this setting allows the browser to cache the application in a way compatible with Meteor
# on every application update the name of CSS and JS file is different, so they can be cache infinitely (here: 30 da$
# the root path (/) MUST NOT be cached
if ($uri != '/') {
expires 30d;
}
}
}
编辑
好的,我发现问题出在防火墙的一条规则上,但我不知道哪一个阻止了 HTTP 流量,有人能帮帮我吗?
# INPUT rules
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -m limit --limit 50/second --limit-burst 50 -j ACCEPT
iptables -A INPUT -p icmp -m limit --limit 1/sec -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -m state --state NEW -m limit --limit 50/minute --limit-burst 200 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -m state --state NEW -m limit --limit 50/minute --limit-burst 200 -j ACCEPT
iptables -A INPUT -j LOG
iptables -A INPUT -j DROP
编辑2
我必须添加此规则来解锁流量,但这有问题,因为我不想在互联网上公开端口 3000,它仅由 NodeJS 应用程序在本地使用。我尝试过,-i lo
但没有用。
iptables -A INPUT -i eth0 -p tcp --dport 3000 -j ACCEPT
答案1
CURL 命令失败的原因是您没有遵循重定向:http://curl.haxx.se/docs/faq.html#How_do_I_tell_curl_to_follow_HTT
尝试:curl -Lvhttp://eshipp.com/
查看您的 IP 表规则,您非常积极地限制 443 和 80 的连接速率。这可能是原因一些您的客户无法收款。
此外,在这 2 条规则中,您只允许新连接(并限制其速率),我建议您将它们更改为包括 ESTABLISHED 和 NEW。
iptables -A INPUT -p tcp --dport 80 -m state --state NEW -m limit --limit 50/minute --limit-burst 200 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -m state --state NEW -m limit --limit 50/minute --limit-burst 200 -j ACCEPT
改变--state NEW
为--state NEW,ESTABLISHED
FWIW:我可以很好地卷曲 URI
另外,请注意,SPDY 支持已被谷歌删除,因为它的功能已内置于 HTTP/2 中 http://blog.chromium.org/2015/02/hello-http2-goodbye-spdy-http-is_9.html