【问题标题】:nginx, Meteor and Docker: Proxy SSL redirection does not work on localhostnginx、Meteor 和 Docker:代理 SSL 重定向在 localhost 上不起作用
【发布时间】:2015-05-25 06:25:16
【问题描述】:

我正在尝试将 nginx 设置为 Meteor 应用程序前面的代理服务器。这些将在 Docker 容器中运行。我想做的是将每个请求/作为 SSL 调用重定向到 Meteor 服务器(在端口 8080 上)。但是,当我这样做时,所有发生的事情都是在浏览器中返回并显示https://localhost 并且没有任何反应,Meteor 应用程序不会显示。请注意,我创建了一个服务器名称为“localhost”的自签名 SSL 证书。但是,如果我删除 SSL 部分,那么重定向会完美运行,并且调用 / 会导致在端口 8080 上成功调用 Meteor。那么,如何使用 SSL 使其正常工作?自签名的本地主机证书是问题吗?下面显示了有效的配置和无效的配置(使用 SSL)。谢谢:)

这行得通

server_tokens off; # for security-by-obscurity: stop displaying nginx version

# This section is needed to proxy web-socket connections
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

# HTTP
server {
    # If this is not a default server, remove "default_server"
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    # These are irrelevant
    root /usr/share/nginx/html;
    index index.html index.htm;

    # The domain on which we want to host the application. Since we set "default_server"
    # previously, nginx will answer all hosts anyway.
    server_name localhost;

     # The redirection.
     location / {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection ‘upgrade’;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

这不起作用

server_tokens off; # for security-by-obscurity: stop displaying nginx version

# This section is needed to proxy web-socket connections
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

# HTTP
server {
    # If this is not a default server, remove "default_server"
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    # These are irrelevant
    root /usr/share/nginx/html;
    index index.html index.htm;

    # The domain on which we want to host the application. Since we set "default_server"
    # previously, nginx will answer all hosts anyway.
    server_name localhost;

    # Redirect non-SSL to SSL
    location / {
        rewrite     ^ https://$server_name$request_uri? permanent;
    }
}

# HTTPS server
server {
    # We enable SPDY here
    listen 443 ssl spdy;

    # This domain must match Common Name (CN) in the SSL certificate
    server_name localhost;

    # Irrelevant
    root html;
    index index.html;

    # Full path to SSL certificate and CA certificate concatenated together
    ssl_certificate /etc/nginx/ssl/server.crt;

    # Full path to SSL key
    ssl_certificate_key /etc/nginx/ssl/server.key;

    # Performance enhancement for SSL
    ssl_stapling on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 5m;

    # Safety enhancement to SSL: make sure we actually use a safe cipher
    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-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK';

    # Config to enable HSTS(HTTP Strict Transport Security)     https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security

    # To avoid ssl stripping     https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping
    add_header Strict-Transport-Security "max-age=31536000;";

    # 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;
    }

    # Pass all requests to Meteor
    location / {
        proxy_pass http://localhost:8080;
        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 days). The root path (/) MUST NOT be cached
        if ($uri != '/') {
            expires 30d;
        }
    }
}

【问题讨论】:

    标签: ssl nginx meteor localhost


    【解决方案1】:

    我无法让它在“本地主机”上工作,但这是一个工作生产版本,其中有很多描述可以帮助人们:

    # This configuration provides strong SSL security on the nginx webserver. We do
    # this by disabling SSL Compression to mitigate the CRIME attack, disable SSLv3
    # and because of vulnerabilities in the protocol and we will set up a strong
    # ciphersuite that enables Forward Secrecy when possible. We also enable HSTS and
    # HPKP. This way we have a strong and future proof ssl configuration and we get
    # an A on the Qually Labs SSL Test.
    #
    # This configuration passes all the requests to a Meteor server.  In order for
    # this to work you have to ensure that Meteor does NOT implement force-ssl.
    
    # Enables or disables emitting nginx version in error messages and in the Server
    # response header field.
    server_tokens off;
    
    # This turns a connection between a client and server from HTTP/1.1 into a WebSocket,
    # the protocol switch mechanism available in HTTP/1.1 is used.  In this implementation
    # the Connection header field in a request to the proxied server depends on the
    # presence of the Upgrade field in the client request header.
    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }
    
    # Nginx upstream services.  Nginx connects to nodejs on the IPv6 loopback [::1] and so
    # you must specify the IP address here or nodejs will just listen on IPv4.
    upstream meteor-server {
        server 127.0.0.1:8080;
    }
    
    # HTTP.  This is not the default server and will redirect all the calls
    # to the https server.
    server {
        # Listen on port 80 for ipv4 traffic and on [::]:80 for ipv6 traffic
        listen 80;
        listen [::]:80 ipv6only=on;
    
        # File paths - these are ignored.  The path is specific for nginx on Ubuntu.
        root /usr/share/nginx/html/;
        index index.html index.htm;
    
        # The domain on which we want to host the application.
        server_name <your server>;
    
        # Redirect non-SSL to SSL
        location / {
            rewrite     ^ https://$server_name$request_uri? permanent;
        }
    }
    
    # HTTPS.  This is the default server.
    server {
        # Listen on port 443 for ipv4 traffic and on [::]:443 for ipv6 traffic.
        # This is the default server
        listen 443 ssl spdy;
        listen [::]:443 ssl spdy ipv6only=on;
    
        # File paths - these are ignored.  The path is specific for nginx on Ubuntu.
        root /usr/share/nginx/html/;
        index index.html index.htm;
    
        # The domain on which we want to host the application.
        server_name <your server>;
    
        # Full path to SSL Certificate and CA Certificate concatenated together
        ssl_certificate /etc/nginx/ssl/server.crt;
    
        # Full path to SSL Key
        ssl_certificate_key /etc/nginx/ssl/server.key;
    
        # When choosing a cipher during an SSLv3 or TLSv1 handshake, normally the
        # client's preference is used. If this directive is enabled, the server's
        # preference will be used instead.
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
    
        # The ciphers
        ssl_ciphers 'AES128+EECDH:AES128+EDH:!aNULL';
    
        # This is for backwards compatibility with IE6/WinXP
        #ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK';
    
        # SSL Protocols
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    
        # Online Certificate Status Protocol (OCSP) stapling
        ssl_stapling on;
        ssl_stapling_verify on;
    
        # Enforce the use of the Google DNS servers to resolve addresses
        resolver 8.8.4.4 8.8.8.8 valid=300s;
        resolver_timeout 10s;
    
        # Forward Secrecy & Diffie Hellman Ephemeral Parameters
        ssl_dhparam /etc/ssl/certs/dhparam.pem;
    
        # HTTP Strict-Transport-Security (HSTS) enforces secure (HTTP over SSL/TLS)
        # connections to the server. This reduces impact of bugs in web applications
        # leaking session data through cookies and external links and  defends against
        # Man-in-the-middle attacks. HSTS also disables the ability for user's to ignore
        # SSL negotiation warnings (ssl stripping). See: https://developer.mozilla.org/en-US/docs/Security/
        # and https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping
        add_header Strict-Transport-Security max-age=63072000;
    
        # Provides for Clickjacking protection by denying the ability of the browser to
        # render a page in a <frame>, <iframe> or <object>.
        add_header X-Frame-Options DENY;
    
        # This prevents Internet Explorer and Google Chrome from MIME-sniffing a response
        # away from the declared content-type.
        add_header X-Content-Type-Options nosniff;
    
        # This header enables the Cross-site scripting (XSS) filter built into most
        # recent web browsers. It's usually enabled by default anyway.
        add_header X-XSS-Protection 1;
    
        # 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;
        }
    
        # Handle the root route.  This will pass everything onto the Meteor
        # server.
        location / {
            # Pass upstream
            proxy_pass http://meteor-server;
    
            # Socket.IO Support (WebSockets)
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $http_upgrade;
    
            # This ensure that the Host header that the client sent nginx is
            # sent on to the backend
            proxy_set_header Host $host;
    
            # Defines conditions under which the response will not be taken from a cache.
            proxy_cache_bypass $http_upgrade;
    
            # This provides the real client IP rather than the one from the nginx proxy system.
            # This is very useful for logging etc.
            proxy_set_header X-Real-IP $remote_addr;
    
            # This is similar to X-Real-IP, but provides added connection source entries
            # for the entire chain of proxies the connection's passed through.
            proxy_set_header X-Forwarded-For $remote_addr;
    
            # A de facto standard for identifying the originating protocol of an HTTP request,
            # since a reverse proxy may communicate with a web server using HTTP even if the
            # request to the reverse proxy is HTTPS.
            proxy_set_header X-Forwarded-Proto $scheme;
    
            # This simply acts as as a marker that the proxy is used.  It not really needed.
            proxy_set_header X-NginX-Proxy true;
    
            # Sets the text that should be changed in the Location and Refresh header
            # fields of a proxied server response.
            proxy_redirect off;
    
            # 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 days). The root path (/) MUST NOT be cached
            if ($uri != '/') {
                expires 30d;
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      我在 Meteor 0.8 应用程序中遇到了类似的问题,我通过将 X-Real-IPHost 标头添加到代理请求来修复它。该应用程序正在使用force-ssl 包,(我认为)它会根据Host 标头发出重定向。

      这是我的配置中的位置块:

      # pass all requests to Meteor
      location / {
          proxy_pass http://localhost:8080;
          proxy_http_version 1.1;
          proxy_set_header X-Real-IP $remote_addr;  # http://wiki.nginx.org/HttpProxyModule
          proxy_set_header Host $host;  # pass the host header - http://wiki.nginx.org/HttpProxyModule#proxy_pass
          proxy_set_header Upgrade $http_upgrade; # allow websockets
          proxy_set_header Connection $connection_upgrade;
      
          # Browser can cache everything except the root
          if ($uri != '/') {
              expires 30d;
          }
      }
      

      【讨论】:

      • 我从来没有得到这个与本地主机一起工作。我需要 proxy_pass 将请求传递给我在 proxy_pass 参数中设置的本地 IP,但我一直被重定向到“localhost”。我猜这是因为“localhost”在 SSL 证书中,因此无论您做什么,SSL 实现都会强制重定向到该地址。因此,我找不到开启 SSL 并使用自签名“localhost”证书的方法,但随后将请求传递给“localhost”以外的 IP。最后我在 localhost 上禁用了 SSL,只在生产中使用它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-23
      • 1970-01-01
      • 1970-01-01
      • 2018-05-31
      • 1970-01-01
      • 2019-05-03
      • 2019-03-11
      相关资源
      最近更新 更多