Search Unity

  1. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  4. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

UNET WSS + HTTPS

Discussion in 'WebGL' started by sandy-macpherson, Nov 10, 2016.

  1. sandy-macpherson

    sandy-macpherson

    Joined:
    Sep 25, 2015
    Posts:
    14
    After reading several threads about using secure websockets from a Unity WebGL build, I haven't managed to find a solid, up-to-date answer about whether it is supported or not, and how to workaround it (if possible).

    There are 2 issues here:

    1. WebGL client - is it able to communicate with a secure websocket? If so, how? I have tried including "wss://" in the server address provided in code, and also tried adding a field like "websocket: { url: "wss://my.websocket/" }" to the Module structure in the html index file, but nothing seems to work and it keeps looking for an insecure one which won't work over HTTPS of course.

    2. UNET server - headless server on Linux provides websocket connections just fine, but it seems like these are insecure. From what I've read, people have managed to get around this by using a proxy which is ok, although hardly ideal.

    Has anyone had any success with this?
     
    perevezentsev likes this.
  2. PN3D

    PN3D

    Joined:
    Jul 12, 2013
    Posts:
    3
    I subscribe to the issue! This is extremely important. All social networks require WSS.
     
  3. infuzo

    infuzo

    Joined:
    Aug 22, 2013
    Posts:
    44
    I'm subscribe too!
     
  4. alexsuvorov

    alexsuvorov

    Unity Technologies

    Joined:
    Nov 15, 2015
    Posts:
    317
    Hello sandy-macpherson.

    UNET does not support secure WebSockets at the moment, and for this reason you are not able to use it directly from a secure webpage. However, you are right, it is sufficient to just replace the WebSocket protocol with wss:// in order to make secure WebSockets work, even though there is currently no simple way to do this. For example, you can override the _JS_UNETWebSockets_SocketCreate function, which creates WebSockets. You can achieve this for example by adding the following /Assets/Plugins/UNETSecureWebSockets.jspre plugin to your project:
    Code (JavaScript):
    1. Object.defineProperty(Module, "asmLibraryArg", {
    2.   set: function (value) {
    3.     value._JS_UNETWebSockets_SocketCreate = function (hostId, urlPtr) {
    4.       var url = Pointer_stringify(urlPtr).replace(/^ws:\/\//, "wss://");
    5.       urlPtr = Runtime.stackAlloc((url.length << 2) + 1);
    6.       writeStringToMemory(url, urlPtr);
    7.       return _JS_UNETWebSockets_SocketCreate(hostId, urlPtr);
    8.     };
    9.     Module._asmLibraryArg = value;
    10.   },
    11.   get: function () {
    12.     return Module._asmLibraryArg;
    13.   },
    14. });
    This code will replace all the ws:// sockets created by UNET with wss:// sockets.
    Note: the above solution should also work fine for an already existing WebGL build if you just put this code directly into your index.html right after the var Module = {...} declaration and before the <script src="Release/UnityLoader.js"></script> line.

    In some Unity versions (for example in Unity 5.6) you should be able to achieve the same in a bit less hacky way using the following /Assets/Plugins/UNETSecureWebSockets.jspre plugin:
    Code (JavaScript):
    1. var _JS_UNETWebSockets_SocketCreate_Original = _JS_UNETWebSockets_SocketCreate;
    2. _JS_UNETWebSockets_SocketCreate = function (hostId, urlPtr) {
    3.   var url = Pointer_stringify(urlPtr).replace(/^ws:\/\//, "wss://");
    4.   urlPtr = Runtime.stackAlloc((url.length << 2) + 1);
    5.   writeStringToMemory(url, urlPtr);
    6.   return _JS_UNETWebSockets_SocketCreate_Original(hostId, urlPtr);
    7. };

    On the server side you should have a wss-ws proxy which should connect the incoming wss connections with the UNET server via ws. If this solution does not work for you for some reason (or you are not able to setup a proxy), please specify your exact Unity version and server configuration.
     
    Last edited: Jan 19, 2017
    perevezentsev likes this.
  5. AlekseyKhomenko

    AlekseyKhomenko

    Joined:
    Feb 17, 2016
    Posts:
    7
    Could you tell how make it?
     
  6. Elfinnik159

    Elfinnik159

    Joined:
    Feb 24, 2013
    Posts:
    36




    Hello.
    Please tell me what I did wrong?
    I added to the project folder Plugins. Created in it the .txt file. Recorded in his code:

    Code (JavaScript):
    1. Object.defineProperty(Module, "asmLibraryArg", {
    2.   set: function (value) {
    3.     value._JS_UNETWebSockets_SocketCreate = function (hostId, urlPtr) {
    4.       var url = Pointer_stringify(urlPtr).replace(/^ws:\/\//, "wss://");
    5.       urlPtr = Runtime.stackAlloc((url.length << 2) + 1);
    6.       writeStringToMemory(url, urlPtr);
    7.       return _JS_UNETWebSockets_SocketCreate(hostId, urlPtr);
    8.     };
    9.     Module._asmLibraryArg = value;
    10.   },
    11.   get: function () {
    12.     return Module._asmLibraryArg;
    13.   },
    14. });
    I changed the name and extension to UNETSecureWebSockets.jspre
    After the build when connected via HTTP network stopped working (probably as it should be), but when connecting through HTTPS (secure SSL through cloudflare) network still does not work.

    script code:

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.Networking;
    6.  
    7. public class LLAPITest : MonoBehaviour {
    8.  
    9.     private bool _isStarted = false;
    10.     private bool _isServer = false;
    11.     string ip = "178.170.189.96";
    12.     int port = 7075;
    13.     private int _messageIdx = 0;
    14.  
    15.     private int m_ConnectionId = 0;
    16.     private int m_WebSocketHostId = 0;
    17.     private int m_GenericHostId = 0;
    18.  
    19.     private string m_SendString = "";
    20.     private string m_RecString = "";
    21.     private ConnectionConfig m_Config = null;
    22.     private byte m_CommunicationChannel = 0;
    23.  
    24.  
    25.  
    26.     void Start()
    27.     {
    28.         m_Config = new ConnectionConfig();                                         //create configuration containing one reliable channel
    29.         m_CommunicationChannel = m_Config.AddChannel(QosType.Reliable);
    30.         m_Config.MinUpdateTimeout = 1;
    31.  
    32.     }
    33.  
    34.     void OnGUI()
    35.     {
    36.         GUI.Box(new Rect(5, 5, 450, 450), "window");
    37.         if (!_isStarted)
    38.         {
    39.             ip = GUI.TextField(new Rect(10, 10, 250, 30), ip, 100);
    40.             port = Convert.ToInt32(GUI.TextField(new Rect(10, 40, 250, 30), port.ToString(), 25));
    41. #if !(UNITY_WEBGL && !UNITY_EDITOR)
    42.             if (GUI.Button(new Rect(10, 70, 250, 30), "start server"))
    43.             {
    44.                 _isStarted = true;
    45.                 _isServer = true;
    46.                 NetworkTransport.Init();
    47.  
    48.                 HostTopology topology = new HostTopology(m_Config, 2);
    49.                 m_WebSocketHostId = NetworkTransport.AddWebsocketHost(topology, port, null);           //add 2 host one for udp another for websocket, as websocket works via tcp we can do this
    50.                 m_GenericHostId = NetworkTransport.AddHost(topology, port, null);
    51.                 Debug.LogError(topology.MessagePoolSizeGrowthFactor + ";" + topology.ReceivedMessagePoolSize + ";" + topology.SentMessagePoolSize + ";" + m_Config.FragmentSize + ";" + m_Config.MaxCombinedReliableMessageCount + ";" + m_Config.MaxCombinedReliableMessageSize + ";" + m_Config.MaxSentMessageQueueSize + ";" + m_Config.WebSocketReceiveBufferMaxSize);
    52.             }
    53. #endif
    54.             if (GUI.Button(new Rect(10, 100, 250, 30), "start client"))
    55.             {
    56.                 _isStarted = true;
    57.                 _isServer = false;
    58.                 NetworkTransport.Init();
    59.  
    60.                 HostTopology topology = new HostTopology(m_Config, 2);
    61.                 m_GenericHostId = NetworkTransport.AddHost(topology, 0); //any port for udp client, for websocket second parameter is ignored, as webgl based game can be client only
    62.                 byte error;
    63.                 m_ConnectionId = NetworkTransport.Connect(m_GenericHostId, ip, port, 0, out error);
    64.                 Debug.LogError(error + ";");
    65.             }
    66.         }
    67.         else
    68.         {
    69.             GUI.Label(new Rect(10, 20, 250, 500), "Sent: " + m_SendString);
    70.             GUI.Label(new Rect(10, 70, 250, 50), "Recv: " + m_RecString);
    71.             if (GUI.Button(new Rect(10, 120, 250, 50), "stop"))
    72.             {
    73.                 _isStarted = false;
    74.                 NetworkTransport.Shutdown();
    75.             }
    76.         }
    77.     }
    78.  
    79.     void Update()
    80.     {
    81.  
    82.         if (!_isStarted)
    83.             return;
    84.         int recHostId;
    85.         int connectionId;
    86.         int channelId;
    87.         byte[] recBuffer = new byte[1024];
    88.         int bufferSize = 1024;
    89.         int dataSize;
    90.         byte error;
    91.         NetworkEventType recData = NetworkTransport.Receive(out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);
    92.         Debug.Log(recBuffer.Length);
    93.         if (error != 0)
    94.         {
    95.             Debug.LogError(error);
    96.         }
    97.         switch (recData)
    98.         {
    99.  
    100.             case NetworkEventType.Nothing:
    101.                 break;
    102.  
    103.             case NetworkEventType.ConnectEvent:
    104.                 {
    105.                     if (!_isServer)
    106.                     {
    107.                         string message = "0123456701234567012345670123456701234567" + _messageIdx.ToString();
    108.                         _messageIdx++;
    109.                         byte[] bytes = new byte[message.Length * sizeof(char)];
    110.                         System.Buffer.BlockCopy(message.ToCharArray(), 0, bytes, 0, bytes.Length);
    111.                         Debug.Log(String.Format("connect event and Sent message host {0} connection {1} message length {2}", recHostId, connectionId, bytes.Length));
    112.  
    113.                         NetworkTransport.Send(recHostId, connectionId, m_CommunicationChannel, bytes, bytes.Length, out error);     //when client received connection signal it starts send echo  
    114.  
    115.  
    116.  
    117.                         if (error != 0)
    118.                         {
    119.                             Debug.LogError(error);
    120.                         }
    121.                     }
    122.  
    123.  
    124.                     Debug.Log(String.Format("Connect from host {0} connection {1}", recHostId, connectionId));
    125.                     break;
    126.                 }
    127.  
    128.             case NetworkEventType.DataEvent:  //if server will receive echo it will send it back to client, when client will receive echo from serve wit will send other message
    129.                 {
    130.                     Debug.Log(String.Format("Received event host {0} connection {1} channel {2} message length {3}", recHostId, connectionId, channelId, dataSize));
    131.                     char[] chars = new char[dataSize / sizeof(char)];
    132.                     System.Buffer.BlockCopy(recBuffer, 0, chars, 0, dataSize);
    133.                     m_RecString = new string(chars);
    134.                     if (_isServer)
    135.                         m_SendString = m_RecString;
    136.                     else
    137.                     {
    138.                         m_SendString = "messageb " + _messageIdx.ToString();
    139.                         _messageIdx++;
    140.                     }
    141.                     byte[] bytes = new byte[m_SendString.Length * sizeof(char)];
    142.                     System.Buffer.BlockCopy(m_SendString.ToCharArray(), 0, bytes, 0, bytes.Length);
    143.  
    144.                     Debug.Log(String.Format("receive event and Sent message host {0} connection {1} message length {2}", recHostId, connectionId, bytes.Length));
    145.                     NetworkTransport.Send(recHostId, connectionId, m_CommunicationChannel, bytes, bytes.Length, out error);
    146.                     if (error != 0)
    147.                     {
    148.                         Debug.LogError(error);
    149.                     }
    150.                     Debug.LogError(chars.Length + ";" + bytes.Length);
    151.  
    152.                 }
    153.                 break;
    154.             case NetworkEventType.DisconnectEvent:
    155.                 {
    156.                     if (!_isServer)
    157.                         Debug.Log(String.Format("DisConnect from host {0} connection {1}", recHostId, connectionId));
    158.                     break;
    159.                 }
    160.         }
    161.     }
    162. }
    163.  
    Messages do not go.

    Server - the same build as WebGL only under Windovs.

    Code html:

    Code (JavaScript):
    1. <!doctype html>
    2. <html lang="en-us">
    3.   <head>
    4.     <meta charset="utf-8">
    5.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    6.     <title>Unity WebGL Player | Simple Web Sockets</title>
    7.     <link rel="stylesheet" href="TemplateData/style.css">
    8.     <link rel="shortcut icon" href="TemplateData/favicon.ico" />
    9.     <script src="TemplateData/UnityProgress.js"></script>
    10.   </head>
    11.   <body class="template">
    12.     <div class="template-wrap clear">
    13.       <canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()" height="600px" width="960px"></canvas>
    14.       <br>
    15.       <div class="logo"></div>
    16.       <div class="fullscreen"><img src="TemplateData/fullscreen.png" width="38" height="38" alt="Fullscreen" title="Fullscreen" onclick="SetFullscreen(1);" /></div>
    17.       <div class="title">Simple Web Sockets</div>
    18.     </div>
    19.     <script type='text/javascript'>
    20.   var Module = {
    21.     TOTAL_MEMORY: 268435456,
    22.     errorhandler: null,            // arguments: err, url, line. This function must return 'true' if the error is handled, otherwise 'false'
    23.     compatibilitycheck: null,
    24.     backgroundColor: "#222C36",
    25.     splashStyle: "Light",
    26.     dataUrl: "Release/web.data",
    27.     codeUrl: "Release/web.js",
    28.     asmUrl: "Release/web.asm.js",
    29.     memUrl: "Release/web.mem",
    30.   };
    31.  
    32. </script>
    33.  
    34. <script src="Release/UnityLoader.js"></script>
    35.  
    36.   </body>
    37. </html>
    38.  
    Please tell me what I need to do.








    When connecting to a socket error is displayed in the browser ( "View code (chrome)")
    WebSocket connection to 'wss://178.170.189.96:3000/' failed: Error in connection establishment: net::ERR_CONNECTION_CLOSED
    Ports changed several times, and these
    https://support.cloudflare.com/hc/en-us/articles/200169156-Which-ports-will-CloudFlare-work-with-
    The same situation. Perhaps something in Cloudflare set or on the WinServer (where IIS is hosting website, launched in the same game server).








    P.S.Sorry for my English, it's Google Translator
     
    Last edited: Jan 30, 2017
  7. Jippe

    Jippe

    Joined:
    Mar 6, 2017
    Posts:
    1
    I have been struggling to get exactly this working. I just now got it to work and I can imagine you want to know what I did...

    I have a WebGL game using UNET for networking, no plugins. The server side runs on my linux server as a standalone.
    I use Ubuntu 14.04.5 and Apache 2.4.7. My website is hosted on the same server and has an ssl certificate, https running over port 443
    These are the steps
    - get an ssl certificate (if you dont have one already) and make sure that https works.
    - enable mod_proxy and mod_proxy_wstunnel (a2enmod mod_proxy)
    - edit /etc/apache/apache.conf and add
    ...
    RewriteEngine On
    ProxyRequests Off
    ProxyPreserveHost On
    ProxyPass /myws/ ws://mydomain.com:35002/
    ProxyPassReverse /myws/ ws://mydomain.com:35002/
    ...
    at the bottom where "myws" can be anything you want, "mydomain" is your site's domain and "35002" is the port you want the server side of your unity game to listen to.

    - On the client side of the game I connect to the server with
    ...
    myClient = new NetworkClient();
    myClient.Connect("mydomain.com/myws/", 443);
    ...
    Note: there is a / after the "myws", "myws" should be the same as in apache.conf, 443 is the port that serves https.

    - I have put
    Code (JavaScript):
    1. Object.defineProperty(Module, "asmLibraryArg", {
    2. set: function (value) {
    3. value._JS_UNETWebSockets_SocketCreate = function (hostId, urlPtr) {
    4. var url = Pointer_stringify(urlPtr).replace(/^ws:\/\//, "wss://");
    5. urlPtr = Runtime.stackAlloc((url.length << 2) + 1);
    6. writeStringToMemory(url, urlPtr);
    7. return _JS_UNETWebSockets_SocketCreate(hostId, urlPtr);
    8. };
    9. Module._asmLibraryArg = value;
    10. },
    11. get: function () {
    12. return Module._asmLibraryArg;
    13. },
    14. });
    This code directly into my index.html right after the var Module = {...} declaration and before the <script src="Release/UnityLoader.js"></script> line. (but then on the page of my site that serves the client side)
    For some reason adding the /Assets/Plugins/UNETSecureWebSockets.jspre plugin to my project does not work. It is maybe because I have made my game in C# ?

    - On the server side of the game I have
    ...
    NetworkServer.useWebSockets = true;
    NetworkServer.Listen(35002);
    ...

    I hope this helps you!
    Some debugging problems i had:
    ERR_CONNECTION_REFUSED probably means nothing is listening on the port you are trying to connect to. If that is port 443, apache is not running or not configured right
    "Error during WebSocket handshake: Unexpected response code: 301" probably means there is a "/" missing after /myws/
     
    Last edited: Mar 12, 2017
  8. sandy-macpherson

    sandy-macpherson

    Joined:
    Sep 25, 2015
    Posts:
    14
    Hey Jippe,

    I got this working as well in the same way as you. Thanks for your comments on the '/' at the end of the websocket URL - this caught me out for a while too.
     
  9. GoKman

    GoKman

    Joined:
    Sep 25, 2017
    Posts:
    2
    Hi! There is no "var Module = {...}" in my index.html file. Using Unity 2017.1.1f1. Please, help.
     
  10. Zarkend

    Zarkend

    Joined:
    May 11, 2016
    Posts:
    10
    Hello everyone,

    Having the same trouble here.

    I have the next architecture diagram (https://goo.gl/imw4oL), same as described in first post.

    @alexsuvorov how can we achieve that? "On the server side you should have a wss-ws proxy which should connect the incoming wss connections with the UNET server via ws.".

    Or, anyone knows a best way to achieve that scenario? we just want to host our headless standalone unity exe as gameServer and use itch.io and other social platforms (which all run over HTTPS) as WEBGL Clients....

    Thanks
     
    Femidko and forcepusher like this.
  11. forcepusher

    forcepusher

    Joined:
    Jun 25, 2012
    Posts:
    160
    This really needs to get fixed, wss support is essential these days.

    But oh well, I'm trying to set up wss-ws proxy using Nginx right now, It's probably the best way to do it since Apache isn't really designed for this from ground up.
    I will post more as I progress through this headache. Would be cool if someone with experience doing this could save me some time by posting something relevant here.
     
    Last edited: Feb 8, 2018
    DNS likes this.
  12. forcepusher

    forcepusher

    Joined:
    Jun 25, 2012
    Posts:
    160
    This Nginx proxy config works (modify existing config to include those lines).
    Use port 443 when connecting from client. 1489 port in config is whatever port is specified when starting a Unity server. You will have to create and use a self-signed certificate as well.
    Refer to these guides:
    https://www.digitalocean.com/commun...-signed-ssl-certificate-for-nginx-on-debian-8
    https://www.cyberciti.biz/faq/howto-install-setup-nginx-on-debian-linux-9/
    Code (Text):
    1. listen 443 ssl default_server;
    2. listen[::]:443 ssl default_server;
    3. ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
    4. ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
    5.  
    6. location / {
    7.     proxy_pass http://localhost:1489;
    8.     proxy_http_version 1.1;
    9.     proxy_set_header Upgrade $http_upgrade;
    10.     proxy_set_header Connection "Upgrade";
    11. }
     
    Last edited: Feb 10, 2018
    perevezentsev and DNS like this.
  13. forcepusher

    forcepusher

    Joined:
    Jun 25, 2012
    Posts:
    160
    This thread most likely was abandoned long ago by the devs, so I'm also posting updated version of UNETSecureWebSockets.jspre plugin that doesn't trigger this error:
    "writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!".
    Code (JavaScript):
    1. Object.defineProperty(Module, "asmLibraryArg", {
    2.   set: function (value) {
    3.     value._JS_UNETWebSockets_SocketCreate = function (hostId, urlPtr) {
    4.       var url = Pointer_stringify(urlPtr).replace(/^ws:\/\//, "wss://");
    5.       urlPtr = Runtime.stackAlloc((url.length << 2) + 1);
    6.       stringToUTF8(url, urlPtr, (url.length << 2) + 1);
    7.       return _JS_UNETWebSockets_SocketCreate(hostId, urlPtr);
    8.     };
    9.     Module._asmLibraryArg = value;
    10.   },
    11.   get: function () {
    12.     return Module._asmLibraryArg;
    13.   },
    14. });
    15.  
     
    perevezentsev and DNS like this.
  14. Reelix

    Reelix

    Joined:
    Sep 15, 2014
    Posts:
    3
    In the latest version of Unity, that now triggers multiple instances of

    > ReferenceError: Runtime is not defined,ReferenceError: Runtime is not defined
     
  15. forcepusher

    forcepusher

    Joined:
    Jun 25, 2012
    Posts:
    160
    This topic is irrelevant now, because UNet itself is abandoned.
     
  16. daniel_popescu

    daniel_popescu

    Joined:
    Nov 14, 2016
    Posts:
    4
    Even if it's abandoned, it's still gonna be supported for quite some time.

    Here's a version of the file (UNETSecureWebSockets.jspre) that works with 2018.2 and Wasm target.

    Code (JavaScript):
    1. var _JS_UNETWebSockets_SocketCreate_Original = _JS_UNETWebSockets_SocketCreate;
    2. _JS_UNETWebSockets_SocketCreate = function (hostId, urlPtr) {
    3.   var url = Pointer_stringify(urlPtr).replace(/^ws:\/\//, "wss://");
    4.   urlPtr = stackAlloc((url.length << 2) + 1);
    5.   stringToUTF8(url, urlPtr, (url.length << 2) + 1);
    6.   return _JS_UNETWebSockets_SocketCreate_Original(hostId, urlPtr);
    7. };
     
    Reelix and perevezentsev like this.
  17. Reelix

    Reelix

    Joined:
    Sep 15, 2014
    Posts:
    3
    Thank you daniel_popescu! I can confirm that this works in 2018.2.6, and 2018.2.8!

    @forcepusher: Even if it's abandoned, there are no alternatives for a WebGL build as of 2018.2.3 as UnityEngine.Network was removed, so if we want our own server setup we're left with UnityEngine.Networking - Which requires this fix to work. It doesn't really help if something gets abandoned with nothing in its place for functionality that's still extremely widely used. I use this out of necessity due to lack of other options...
     
    Last edited: Sep 17, 2018 at 3:59 PM
  18. perevezentsev

    perevezentsev

    Joined:
    Nov 5, 2014
    Posts:
    3
    Thank you so much for this config and the nginx configuration tutorial. I'm a noob with nginx but I was able to setup this on my server. I used a CA issued certificate instead of self-signed so that I can use "api.mygame.com" address to connect to the server.

    If anyone needs full config (I've spent a bit of time with this), here it is:
    Code (csharp):
    1.  
    2. http {
    3.     server {
    4.         listen 443 ssl;
    5.         # nginx was complaining about this line
    6.         # listen[::]:443 ssl;
    7.  
    8.         # Change to your paths
    9.         ssl_certificate /app/secrets/mycerts.crt;
    10.         ssl_certificate_key /app/secrets/_.serpent.app_private_key.key;
    11.  
    12.         location / {
    13.             proxy_pass http://localhost:7777;
    14.             proxy_http_version 1.1;
    15.             proxy_set_header Upgrade $http_upgrade;
    16.             proxy_set_header Connection "Upgrade";
    17.         }
    18.     }
    19. }
    20.  
    21. # This was required in my case as well
    22. events {
    23.     worker_connections 1024;
    24. }
    25.  
    Also, either the tutorial is missing one final bit or I've misconfigured something: you should start nginx proxy with
    nginx -c /etc/nginx/sites-available/YOUR_CONFIG.conf
    after
    systemctl reload nginx
    .
     
  19. angusmf

    angusmf

    Joined:
    Jan 19, 2015
    Posts:
    206
  20. perevezentsev

    perevezentsev

    Joined:
    Nov 5, 2014
    Posts:
    3
  21. angusmf

    angusmf

    Joined:
    Jan 19, 2015
    Posts:
    206
    Ok. I just noticed the http section in your file. I'm not an nginx expert, but that normally goes in the main config file, conf.d, which has an include path pointing to sites-enabled. Since your config has the http root defined and so does conf.d, you have to bypass it by starting it as you showed. Remove that, and I expect you'll be able to use nginx normally.