Nginx:WebSocket通配符位置

huangapple go评论80阅读模式
英文:

Nginx: WebSocket wildcard location

问题

我在一个Go服务前面使用了一个nginx实例。

  • 我想将端口80上的所有请求重定向到https。[完成]
  • 所有(非websocket)的https请求在/上应该转发到https://localhost:8443/。[完成]
  • 所有websocket的https请求在/ws/上应该转发到https://localhost:8443/ws/。[缺失]

我的当前配置:

ssl_certificate                 ...
ssl_certificate_key             ...
ssl_ciphers                     ...
ssl_prefer_server_ciphers       on;

server {
        listen         80;
        location / {
                return 301 https://$host$request_uri;
        }
}

server {
        listen          443 ssl;
        server_name     www.mydomain.com mydomain.com;

        add_header Strict-Transport-Security "max-age=31536000";

        location /ws {   <--- 这只适用于/ws,但不适用于/ws/app1
            proxy_pass http://localhost:8443/ws;
            proxy_http_version 1.1;
            proxy_set_header Host $http_host;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }

        location / {    <--- 捕获任何内容,即使没有通配符 ?!
                proxy_pass http://localhost:8443;
        }
}

server {
        listen 443 ssl;
        server_name *.mydomain.com;
        return 444;
}

为什么需要这样做?嗯,据我了解,您必须显式设置升级标头,所以我猜您必须指定另一个位置。

理想情况下,我只想使用一个位置,但是Websockets被阻止了(因为升级标头从未传递到Go服务...)

我不是nginx专家,所以请谅解=)。

[编辑]

我现在搞定了。我不确定是否总是设置Upgrade/Connection标头,即使它不是一个websocket请求,但是我的Go服务不在乎,所以对我来说可以工作=]

ssl_certificate                 ...
ssl_certificate_key             ...
ssl_ciphers                     ...
ssl_prefer_server_ciphers       on;

server {
        listen         80;
        location / {
                return 301 https://$host$request_uri;
        }
}

server {
        listen          443 ssl;
        server_name     www.mydomain.com mydomain.com;

        add_header Strict-Transport-Security "max-age=31536000";

        location / {    <--- 捕获任何内容,即使没有通配符 ?!
            proxy_pass http://localhost:8443;
            proxy_redirect off;
            proxy_http_version 1.1;
            proxy_set_header Host $http_host;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
}

server {
        listen 443 ssl;
        server_name *.mydomain.com;
        return 444;
}
英文:

I use a nginx instance in front of a Go service.

  • I want to redirect anything on port 80 to https. [done]
  • All (non-websocket) https requests at /* should go to https://localhost:8443/* [done]
  • All websocket https requests at /ws/* should go to https://localhost:8443/ws/* [missing]

My current config:

ssl_certificate                 ...
ssl_certificate_key             ...
ssl_ciphers                     ...
ssl_prefer_server_ciphers       on;

server {
        listen         80;
        location / {
                return 301 https://$host$request_uri;
        }
}

server {
        listen          443 ssl;
        server_name     www.mydomain.com mydomain.com;

        add_header Strict-Transport-Security "max-age=31536000";

        location /ws {   <--- This only works for /ws but not /ws/app1
            proxy_pass http://localhost:8443/ws;
            proxy_http_version 1.1;
            proxy_set_header Host $http_host;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }

        location / {    <--- Catches anything, even without wildcard ?!
                proxy_pass http://localhost:8443;
        }
}

server {
        listen 443 ssl;
        server_name *.mydomain.com;
        return 444;
}

Why is this necessary ? Well, as I understand, you have to set the upgrade headers explicitly, so I guess you have to specify another location.

Ideally, I would just use one location, but then websockets are blocked (because upgrade headers never make it to the Go service...)

I'm not a nginx expert, so bear with me =).

[EDIT]

I got it working now. I'm not sure if its ok to always set_header Upgrade/Connection, even if it's not a websocket request, but my Go service doesn't give a ****, so it works for me =]

ssl_certificate                 ...
ssl_certificate_key             ...
ssl_ciphers                     ...
ssl_prefer_server_ciphers       on;

server {
        listen         80;
        location / {
                return 301 https://$host$request_uri;
        }
}

server {
        listen          443 ssl;
        server_name     www.mydomain.com mydomain.com;

        add_header Strict-Transport-Security "max-age=31536000";

        location / {    <--- Catches anything, even without wildcard ?!
            proxy_pass http://localhost:8443;
            proxy_redirect off;
            proxy_http_version 1.1;
            proxy_set_header Host $http_host;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
}

server {
        listen 443 ssl;
        server_name *.mydomain.com;
        return 444;
}

答案1

得分: 2

请查看以下文章:https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms

您没有使用任何location_match,因此匹配是前缀匹配。

使用~作为位置匹配修饰符,使其被解释为正则表达式。

location /ws应该匹配以/ws开头的每个查询。

英文:

Check out the article at https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms

You are not using any location_match, so the match is a prefix match.

Use ~ as the location match modifier to have it interpreted as a regular expression.

The line location /ws should match every query starting with /ws.

huangapple
  • 本文由 发表于 2016年2月16日 17:35:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/35428731.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定