deepstreamIO / deepstream.io

deepstream.io server
https://deepstreamio.github.io
MIT License
7.14k stars 381 forks source link

Help wanted setting up deepstream 5.0.12 on linux with ssl #1051

Closed LinusBrockmeyer closed 4 years ago

LinusBrockmeyer commented 4 years ago

Hi, I am using your deepstream server to assist webRTC. Over deepstream I share information like if your partner is online or calling you. I want to upgrade to a newer Version of deepstream. At the moment I am running Version 3.1.4 on Ubuntu.

I get your example (https://deepstream.io/tutorials/getting-started/javascript/) running on localhost. But if I try to run deepstream on a different server and/or use the library from the example (https://cdn.deepstream.io/js/client/latest/ds.min.js) in my app (served over https) I can't seem to get it working. Seems like firefox forces wss and can't use ws.

Firefox throws following error: Firefox can’t establish a connection to the server at wss://localhost:6020/deepstream

And the js client throws following error: client error: {"error":{"isTrusted":true},"event":"CONNECTION_ERROR","topic":"CONNECTION"}

I read through everything you offer as tutorials, guides and docs at deepstream.io, as well as what google search offers. In Version 3.1.4 i was able to enable a wss socket in 5.0.12 not. I tried multiple syntax for key, cert, ca in the ws-binary endpoint. My Server (localhost) doesn't show anything. With your example over http it showed user connected, etc.

Can you please give me a hint, how to setup the server to listen to wss requests?

My config:

 serverName: UUID
 showLogo: true
 logLevel: INFO
 dependencyInitializationTimeout: 2000
 libDir: ../lib
 exitOnFatalError: false
 rpc:
   ackTimeout: 1000
   responseTimeout: 10000
 record:
   cacheRetrievalTimeout: 30000
   storageRetrievalTimeout: 30000
 listen:
   shuffleProviderss: true
   responseTimeout: 500
   rematchInterval: 60000
   matchCooldown: 10000
 httpServer:
   type: default
   options:
     healthCheckPath: /health-check
     allowAllOrigins: true
     origins:
       - 'https://example.com'
     # Options required to create an ssl app
     ssl:
       key: fileLoad(deepstream.key)
       cert: fileLoad(deepstream.crt)
       ca: fileLoad(myCA.pem)
 connectionEndpoints:
   - type: ws-binary
     options:
       urlPath: /deepstream
       heartbeatInterval: 30000
       outgoingBufferTimeout: 10
       maxBufferByteSize: 100000
       unauthenticatedClientTimeout: 180000
       maxAuthAttempts: 3
       maxMessageSize: 1048576
   - type: ws-text
     options:
       urlPath: /deepstream-v3
       heartbeatInterval: 30000
       outgoingBufferTimeout: 10
       maxBufferByteSize: 100000
       unauthenticatedClientTimeout: 180000
       maxAuthAttempts: 3
       maxMessageSize: 1048576
   - type: ws-json
     options:
       urlPath: /deepstream-json
       heartbeatInterval: 30000
       outgoingBufferTimeout: 10
       maxBufferByteSize: 100000
       unauthenticatedClientTimeout: 180000
       maxAuthAttempts: 3
       maxMessageSize: 1048576
   - type: http
     options:
       allowAuthData: true
       enableAuthEndpoint: false
       authPath: /api/auth
       postPath: /api
       getPath: /api
       maxMessageSize: 1024
 logger:
   type: default
   options:
     colors: true
 auth:
   - type: none
 permission:
   type: config
   options:
     permissions: fileLoad(permissions.yml)
     maxRuleIterations: 3
     cacheEvacuationInterval: 60000
 monitoring:
   type: none
yasserf commented 4 years ago

Thank you for the detailed message! I'll need to look deeper into this and get back to you

yasserf commented 4 years ago

I'm afraid I'm really busy these few days, so if anyone else would like to take a shot feel free, otherwise I'll look at this as soon as I have time

valentinvichnal commented 4 years ago

Hi, remove the SSL from the deepstream config and setup NGINX with your SSL key where the ds server runs and pass everything to your ds server.

The default deepstream config and the default NGINX config works fine for me in v5.

Yes if you connect to a website using https you must also make any further requests securely, so only https and wss requests. ws still works to test your app without ssl but you must connect with http.

yasserf commented 4 years ago

@valentinvichnal the issue is that the server doesn't support SSL certs correctly, if we go fully with that answer it would mean we have to remove the SSL support entirely. Given it's usually just come config we pass into the server it might be worth having a test case for SSL. Almost every DB / server supports it, and for smaller projects the overhead of nginx is just not worth it.

I'm happy with removing it because I feel like nginx is a perfect middleground, but I feel like it might be worth having for the eligibility of the project.

caracal7 commented 4 years ago

I more prefer native SSL support without Nginx

valentinvichnal commented 4 years ago

@yasserf I see, I couldn't make SSL work in deepstream natively either. Something is wrong since v4.

I'm not sure which would be the correct way. Usually we are advised not to use SSL directly in any node.js server because it is a little slower than using it on nginx level.

Keeping the SSL support in deepstream could be useful for private projects or where nginx is not available, for example Windows.

I think we should fix it and keep it, but disable it by default and mention in the docs to use SSL in nginx.

yasserf commented 4 years ago

It is disabled by default:

httpServer:
  type: default
  options:
    # url path for http health-checks, GET requests to this path will return 200 if deepstream is alive
    healthCheckPath: /health-check
    # -- CORS --
    # if disabled, only requests with an 'Origin' header matching one specified under 'origins'
    # below will be permitted and the 'Access-Control-Allow-Credentials' response header will be
    # enabled
    allowAllOrigins: true
    # a list of allowed origins
    origins:
      - 'https://example.com'
    # Options required to create an ssl app
    # ssl:
    #   key: fileLoad(ssl/key.pem)
    #   cert: fileLoad(ssl/cert.pem)
    #   ca: ...

We also already recommend using a seperate process for SSL termination:

https://deepstream.io/tutorials/concepts/security/#encrypted-connections

So what we really need is to fix the issue, and have a way we can easily test it going forward, using self generated SSL certs. If someone knows how to generate how to generate certs for localhost development using letsencrypt or otherwise please let me know and we can push this forward.

jaime-ez commented 4 years ago

I just tested ssl using the selfsigned package. I had no problems. @LinusBrockmeyer in your config options.ssl.cert has a cert extension, it should be a pem file.

The config.yml example states correctly that for httpServer type default, one must call the ssl files with fileLoad() and for httpServer type uws with file().

When using a .js config file, for the uws server one must give the full path for the ssl file, and for the default server, the file contents should be required before and pass them to the options.ssl object.

NOTE: when using selfsigned certs, one must execut node with the following env variable: NODE_TLS_REJECT_UNAUTHORIZED=0

yasserf commented 4 years ago

Thank you @jaime-ez!

Closing this issue