Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to upgrade websocket connection #5386

Closed
demedos opened this issue Feb 13, 2017 · 37 comments
Closed

Failed to upgrade websocket connection #5386

demedos opened this issue Feb 13, 2017 · 37 comments

Comments

@demedos
Copy link

demedos commented Feb 13, 2017

Summary

After setting up a reverse proxy the log is full of those messages:

[2017/02/13 08:53:13 PST] [EROR] websocket connect err: websocket: could not find connection header with token 'upgrade'
[2017/02/13 08:53:13 PST] [EROR] /api/v3/users/websocket:connect code=500 rid=czz3h9kqtjfb9jz3jo1sqmujne uid=1erjogmb7jraucpy1e1wifcmfy ip=192.168.10.1:56489 Failed to upgrade websocket connection [details: ]

Steps to reproduce

Set up mattermost and do a reverse proxy with IIS

Expected behavior

No error messages

Observed behavior

My website, abc.company.com goes on a Windows Server with IIS, passes the request to an internal ubuntu server machine 192.168.x.x:8065. Everything is fine except those ws:// error messages

The error messages:
The error messages

The reverse proxy on IIS:
The reverse proxy on IIS

The error message appearing on the website:
cattura3

Possible fixes

--

@jasonblais
Copy link
Contributor

Thanks @demedos for the report,

Did you try these troubleshooting steps? https://docs.mattermost.com/install/troubleshooting.html?highlight=unreachable#please-check-connection-mattermost-unreachable-if-issue-persists-ask-administrator-to-check-websocket-port

Also, could we have your help posting this to the Troubleshooting Forum? There are more forum visitors than GitHub issue visitors, which means a potentially faster response. Please link back to your new post from this issue?

@demedos
Copy link
Author

demedos commented Feb 16, 2017

It seems that the problem is about IIS 7.5 not supporting WebSockets, as stated here:

ws
https://www.iis.net/learn/get-started/whats-new-in-iis-8/iis-80-websocket-protocol-support

Unluckly the only solutionn is to upgrade, so tomorrow I'll try out a reverse proxy with a newer version and will let you know if it's solved

@esethna esethna added the Awaiting Submitter Action Blocked on the author label Feb 22, 2017
@demedos
Copy link
Author

demedos commented Mar 1, 2017

I would like to close the issue but I've had no luck so far.
I've upgraded my whole system to a Windows Server 2012 and IIS 8, with the WebSockets option installed and enabled, hoping that everything would be ok, but there's still some issue.

for testing purposes I've added only 1 rewrite rule to IIS, defined as below

cattura

Now that means that whatever is passed before "://" will be used as protocol in the request to the internal machine, so http remains http and ws remains ws, so the proxy works fine.

The logs are repeatedly reporting

[2017/03/01 06:45:24 PST] [EROR] websocket connect err: websocket: origin not allowed [2017/03/01 06:45:24 PST] [EROR] /api/v3/users/websocket:connect code=500 rid=nz5r9k6f63ba7e9hyskwb5ikie uid=1erjogmb7jraucpy1e1wifcmfy ip=192.168.10.1:55120 Failed to upgrade websocket connection [details: ]

and the Developer Console
WebSocket connection to 'ws://example.com/api/v3/users/websocket' failed: Error during WebSocket handshake: Unexpected response code: 403
(see image below)
cattura2

But in the System Console from Mattermost CORS is enabled.
cattura3

What could possibly be wrong? This is quite a show-stopper for me

@demedos
Copy link
Author

demedos commented Mar 1, 2017

Could this be related to the fact that the log shows ip=192.168.10.1:55120, which I suppose is the router address, and not the caller?

@BRH-Enrian
Copy link

BRH-Enrian commented Mar 2, 2017

This is a problem with a recent change to web socket processing in Mattermost. Specifically, 1a9891f

Try reverting the change to CheckOrigin. This really should mimic what is being done for HTTP connections in the server.go file (see ServeHTTP where there is the check for Origin header).

We had the same problem recently and reverting this change fixed our web socket issues.

@demedos
Copy link
Author

demedos commented Mar 2, 2017

I'm a windows user, any chance you branch and compile it?

@jasonblais
Copy link
Contributor

jasonblais commented Mar 3, 2017

@demedos @BRH-Enrian are you using multiple Mattermost URLs through proxy forwarding?

If so, what is your SiteURL field in config.json (or in System Console > General > Configuration)?

We have a ticket to investigate a cross-origin issue introduced by 3.6.2: https://mattermost.atlassian.net/browse/PLT-5635

@demedos
Copy link
Author

demedos commented Mar 6, 2017

@jasonblais What do you mean by multiple Mattermost URLs? My current flow is
Externail IP -> IIS Server -> Linux Server.

My SiteURL property was set as https://website.com.
About the CORS, it's not working with the * nor with https://website.com.

It seems like this has something to do with the fact that Application Request Routing is stripping off the Request-Origin header from the request, or something like that.
http://stackoverflow.com/questions/34316825/websockets-reverse-proxy-in-iis-8

I hope this will be fixed asap as this is a showstopper for us since IIS is the only available web server.

@BRH-Enrian
Copy link

BRH-Enrian commented Mar 6, 2017 via email

@demedos
Copy link
Author

demedos commented Mar 6, 2017

@BRH-Enrian That makes sense now, it almost drove me crazy. That means that it doesn't matter the Web server, the cross-origin requests will be refused.
Could you or @jasonblais compile me a working version please? I've already spent a whole day just trying to set up a go envoironment to compile without the edit in this commit 1a9891f

@bradhowes
Copy link
Contributor

@demedos
Copy link
Author

demedos commented Mar 6, 2017

@bradhowes Thank you, but as soon I click the Save button everything in the Enable cross-origin requests from: field gets wiped out.
I just stopped the mattermost-service and replaced the content of the /opt/mattermost folder with the one you provided, supposing it's enough to make it work.

@bradhowes
Copy link
Contributor

bradhowes commented Mar 6, 2017

The build contains a stock config.json file which will overwrite anything you may already have there if you just blast it into /opt/mattermost. Sorry. Best bet is to untar in a tmp directory and then move the bin/platform executable into /opt/mattermost/bin. Alternatively, save the config.json file first, do what you did, and then restore the file. The build was packaged using Mattermost own Makefile.

@demedos
Copy link
Author

demedos commented Mar 6, 2017

That's exactly what I did. Saved the config.json, replaced all and then restored it. Anyway, changing the value manually works, the value is shown in the system console.

Now the error is changed:

WebSocket connection to 'ws://website.com/api/v3/users/websocket' failed: Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value

This is the web request sent from the browser
immagine2

This may be related to the stack overflow post i mentioned before

@demedos
Copy link
Author

demedos commented Mar 7, 2017

@bradhowes Any way to tell it this is the correct header?

image

@bradhowes
Copy link
Contributor

bradhowes commented Mar 7, 2017 via email

@demedos
Copy link
Author

demedos commented Mar 7, 2017

You are right, it doesn't match.

Given en81vWzPOxZRZye6CzZeZA== as the key, and concatenating it with the magic string, the key is

en81vWzPOxZRZye6CzZeZA==258EAFA5-E914-47DA-95CA-C5AB0DC85B11
which converted to sha1 hash, gives the resulting base64 string
ePXOJuIT6J656wlvecIwVSJJFmQ=

While my browser gets this Response Header:
Sec-WebSocket-Accept: YDYcdpVyxmj4L4mwi1OQA0KuvZU=.

I should test the connection from whitin the reverse proxy server I suppose.

@demedos
Copy link
Author

demedos commented Mar 8, 2017

@bradhowes
FWIW I'm using an Nginx web server right now and everything is just fine. This has totally to do with IIS and more specifically ARR 3, as stated here, which doesn't support the Sec-WebSocket-Extensions header.
Is there any way, or could it be implemented, to create the WebSocketServer without the perMessageDeflate attribute?
like the SO post says:
const wss = new WebSocketServer({ port: 3011, perMessageDeflate: false });
This would make Mattermost scalable to Windows Server 2012 and IIS 8.5.

@jasonblais
Copy link
Contributor

@bradhowes would your PR resolve the issues described here? #5667

@jasonblais jasonblais removed the Awaiting Submitter Action Blocked on the author label Mar 13, 2017
@BRH-Enrian
Copy link

@jasonblais Not sure. @demedos reported that something worked under Nginx, but not clear if that was with my patch or not.

@demedos
Copy link
Author

demedos commented Mar 13, 2017

@jasonblais The patch @bradhowes provided here worked for me, but I have to edit the config file manually because the web system console is not persisting my changes after I hit the save button, not sure if it is a normal behaviour using that patch.

Moreover, it is working using Nginx, because (at least) IIS 8.5 in Windows Server 2012, more specifically its Application Request Routing (ARR) module used to do reverse proxy, has a bug which tells the browser that he supports the per-message compression permessage-deflate, but in fact it doesn't, so it ends up giving back a wrong Sec-WebSocket-Accept key.

So yes, the patch is working, but IIS 8.5 is not supported because of its module bug (ref. here).

@attzonko
Copy link

I am seeing the exact same error/behavior with my installation. I am using Apache for the reverse proxy. One other difference is I have TLS enabled so my error is with wss://

I tried the patch provided above but the issue did not go away.

Please, let me know if I should file a new issue, where I can attach configuration and screen-captures.

@demedos
Copy link
Author

demedos commented Mar 14, 2017

@attzonko Have you edited the config file manually? Do you see the correct value in the System Console after editing the config.json file?

@attzonko
Copy link

@demedos I assume you mean when I tried the patch above. Yes I did edit the config.json file manually to match my setup.

Since my post I ended up installing Nginx alongside Apache, and have nginx doing the reverse proxy with SSL and the upgrade for websocket and it is indeed working. Nginx passes through all my legacy apps traffic on to Apache.

@demedos
Copy link
Author

demedos commented Mar 14, 2017

@attzonko Yes, I meant that. What was the exact error you had though? I'd still like to know if ARR is being buggy.

@attzonko
Copy link

attzonko commented Mar 14, 2017

That was exactly the error I had. Here is a quick cut/paste from my logs:

[2017/03/13 13:33:51 PDT] [EROR] /api/v3/users/websocket:connect code=500 rid=1raacdn1dbnmbqcuf36p6ghf6o uid=jtpx4pgkw7ny7ekeojuf8ut65r ip=10.19.142.6 Failed to upgrade websocket connection [details: ]
[2017/03/13 13:33:57 PDT] [EROR] websocket connect err: websocket: origin not allowed
[2017/03/13 13:33:57 PDT] [EROR] /api/v3/users/websocket:connect code=500   rid=nxakyx3kx7dpzpxgmbc648ms5a uid=jtpx4pgkw7ny7ekeojuf8ut65r ip=10.19.142.6 Failed to upgrade websocket connection [details: ]
[2017/03/13 13:34:01 PDT] [EROR] websocket connect err: websocket: origin not allowed
[2017/03/13 13:34:01 PDT] [EROR] /api/v3/users/websocket:connect code=500 rid=kjypmbtbbif1xqhgu3tt1zu3to uid=jtpx4pgkw7ny7ekeojuf8ut65r ip=10.19.142.6 Failed to upgrade websocket connection [details: ]
[2017/03/13 13:34:09 PDT] [EROR] websocket connect err: websocket: origin not allowed
[2017/03/13 13:34:09 PDT] [EROR] /api/v3/users/websocket:connect code=500 rid=adna1bi5hfyh38mps7rtnb1xgw uid=jtpx4pgkw7ny7ekeojuf8ut65r ip=10.19.142.6 Failed to upgrade websocket connection [details: ]
[2017/03/13 13:37:21 PDT] [EROR] websocket connect err: websocket: origin not allowed
[2017/03/13 13:37:21 PDT] [EROR] /api/v3/users/websocket:connect code=500 rid=mc1jcyf9itbzimkifbbdis96ey uid=jtpx4pgkw7ny7ekeojuf8ut65r ip=10.19.142.6 Failed to upgrade  websocket connection [details: ]
[2017/03/13 13:41:24 PDT] [EROR] websocket connect err: websocket: origin not allowed`

@attzonko
Copy link

attzonko commented Mar 14, 2017

Here is what my apache config looked like:

<VirtualHost *:443>
  ServerName mm.example.com:443
  ServerAlias mm.example.com
  CustomLog /var/log/apache2/mm_access.log combined
  ErrorLog /var/log/apache2/mm_error.log
  <Proxy *>
      Order deny,allow
      Allow from all
  </Proxy>

  SSLEngine on
  SSLProxyEngine on
  SSLCertificateFile /etc/apache2/ssl/mm_ssl.crt
  SSLCertificateKeyFile /etc/apache2/ssl/ssl.key

  RewriteEngine On
  RewriteCond %{REQUEST_URI} ^/api/v3/users/websocket [NC,OR]
  RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR]
  RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
  RewriteRule .* wss://mm.example.com:8065%{REQUEST_URI} [P,QSA,L]
  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
  RewriteRule .* https://mm.example.com:8065%{REQUEST_URI} [P,QSA,L]
  RequestHeader set X-Forwarded-Proto "https"

    <Location /api/v3/users/websocket>
      Require all granted
      ProxyPassReverse wss://mm.example.com:8065/api/v3/users/websocket
    </Location>

    <Location />
      Require all granted
      ProxyPassReverse https://mm.example.com:8065/
    </Location>

</VirtualHost>

@demedos
Copy link
Author

demedos commented Mar 16, 2017

I've upgraded to 3.7.1 and nothing broke, even if the websocket.go has the CheckOrigin: nil row. I suppose only Nginx is supported then. This may be related to the headers in the image below

immagine

@jasonblais
Copy link
Contributor

Hi all,

PR to add websocket CORS support got merged last Thursday: #5667

This should help resolve most of the issues described here.

We've also created a PR to add the following troubleshooting steps to our install guide:

1. Upgrade to a Mattermost server v3.8.0 or later, which adds WebSocket CORS support
2. Follow the installation guide to configure NGINX as a proxy for Mattermost server: https://docs.mattermost.com/install/install-ubuntu-1604.html#configuring-nginx-as-a-proxy-for-mattermost-server
3. If you're doing reverse proxy with IIS, upgrade to IIS 8.0 and later, as WebSocket protocol is not supported in earlier versions: https://www.iis.net/learn/get-started/whats-new-in-iis-8/iis-80-websocket-protocol-support

Please let me know if there's anything else to address, otherwise we'll close the issue in a couple of days.

@demedos
Copy link
Author

demedos commented Mar 28, 2017

In IIS WebSockets must be enabled, since the option is not on by default. Maybe it could help in the documentation. Right now I'm using NGINX so afaik that's all

@jasonblais
Copy link
Contributor

Ah okay, I'll add that note as well, doesn't hurt. Thanks @demedos!

@lindy65 lindy65 closed this as completed Mar 30, 2017
@zwiglm
Copy link

zwiglm commented Apr 4, 2017

Erm. Read it all... since I got the same error.
Have I missed something? There is no final solution for IIS atm, right?

Edit: Running Community 3.7.3 on IIS 8 with MySql (Websockets enabled and the Rewrite Rules from Unofficial Enhancements - Production Install on Windows 2012)

Edit 2: Ah, I see. A bug in IIS 8.x with ARR

@zwiglm
Copy link

zwiglm commented Apr 4, 2017

In regard to:

FWIW I'm using an Nginx web server right now and everything is just fine. This has totally to do with IIS and more specifically ARR 3, as stated here, which doesn't support the Sec-WebSocket-Extensions header.
Is there any way, or could it be implemented, to create the WebSocketServer without the perMessageDeflate attribute?
like the SO post says:
const wss = new WebSocketServer({ port: 3011, perMessageDeflate: false });
This would make Mattermost scalable to Windows Server 2012 and IIS 8.5.

Can it be fixed to this in a close future version?

@zwiglm
Copy link

zwiglm commented Apr 24, 2017

AWESOME. Works for me as of 3.8.2

@tstkenny
Copy link

Sorry to bring this thread up again. I am using mattermost 4.9.0 with apache 2.4. Trying to setup https proxy via apache and no luck. I followed and tried all of the solutions above. I supposed all those patches are included in 4.9.0 already.

Anyone would kindly provide the "ServiceSettings" part of the config.json for this setup please?

My goal is: access mm via https://hostname.domain.com:443 and apache proxy all traffic to http://127.0.0.1:8065 and ws://127.0.0.1:8065.

Thank you.

@lindy65
Copy link
Contributor

lindy65 commented Apr 20, 2018

Hi @tstkenny,

Thanks for your feedback,

As this thread is very old and was closed, may I ask you to open a new issue, stating what you have tried, which set-up documentation you have followed and Mattermost server version? Perhaps you can also include the logs which will help us to troubleshoot.

This way, it will be easier for our devs to help. Also, we don't officially support Apache but here are the unofficial docs we have - not sure whether you have looked at them?

For continuity, please link in this issue to the new issue you open.

@yansern
Copy link

yansern commented Oct 24, 2018

In a nutshell, make sure you have: IIS 8 + ARR 3 + WebSockets IIS extension.

Then here's a sample web.config settings (modify as necessary as this config is for somedomain.com/mattermost):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Mattermost Inbound" stopProcessing="true">
                    <match url="(.*)" />
                    <action type="Rewrite" url="{C:1}://localhost:8065/mattermost/{R:1}" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="true">
                        <add input="{CACHE_URL}" pattern="^(.+)://" />
                        <add input="{HTTP_HOST}" pattern="^somedomain\.com$" />
                    </conditions>
                    <serverVariables>
                        <set name="HTTP_SEC_WEBSOCKET_EXTENSIONS" value="client_max_window_bits" />
                    </serverVariables>
                </rule>
            </rules>        
        </rewrite>
        <security>
            <requestFiltering allowDoubleEscaping="true" />
        </security>
    </system.webServer>
</configuration>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants