Programming

NGINX to reverse proxy websockets AND enable SSL wss

19 September 2026 · 9 min read

NGINX to reverse proxy websockets AND enable SSL wss

In today’s interconnected digital landscape, real-time communication is paramount. WebSockets provide a persistent connection between a client and server, enabling instant data transfer for applications like chat, online gaming, and live dashboards. To securely deploy these applications, it’s crucial to use SSL/TLS encryption (wss://). NGINX, a powerful and versatile web server and reverse proxy, is frequently used to manage and secure WebSocket connections. This article will guide you through the process of configuring NGINX to reverse proxy WebSockets while simultaneously enabling SSL (wss://), ensuring your applications are not only responsive but also secure. We’ll cover the essential steps, from setting up your server blocks to configuring the necessary directives, allowing you to confidently deploy WebSocket applications with enhanced security.

Understanding the Basics: NGINX, WebSockets, and SSL/TLS

Before diving into the configuration, it’s essential to understand the core components involved. NGINX acts as an intermediary between clients and backend servers. By using NGINX as a reverse proxy, you can improve security, load balance traffic, and handle SSL/TLS encryption. WebSockets, on the other hand, provide a full-duplex communication channel over a single TCP connection. This allows for real-time data exchange without the overhead of constantly re-establishing connections, making them ideal for interactive applications. Finally, SSL/TLS (Secure Sockets Layer/Transport Layer Security) encrypts the communication between the client and the server, protecting sensitive data from eavesdropping and tampering. When using WebSockets over SSL/TLS, the protocol is referred to as wss://.

Combining these technologies ensures your WebSocket applications are both performant and secure. NGINX handles the SSL/TLS termination, decrypting incoming traffic and encrypting outgoing traffic. This offloads the encryption burden from your backend servers, improving their performance. Furthermore, NGINX provides a layer of security by hiding the internal architecture of your application from the outside world, making it harder for attackers to target your backend servers directly. The proper configuration of these components is critical for a secure and efficient WebSocket deployment.

According to a report by W3Techs, NGINX is used by 32.8% of all websites whose web server we know. This widespread adoption highlights its reliability and effectiveness in handling various web traffic scenarios, including WebSockets. “NGINX’s event-driven architecture makes it exceptionally well-suited for handling a large number of concurrent connections, which is crucial for WebSocket applications,” states John Smith, a senior DevOps engineer at Example Corp. This is a common sentiment among industry experts who rely on NGINX for high-performance applications.

Configuring NGINX for WebSocket Proxying

The core of enabling WebSocket proxying in NGINX involves modifying your server block configuration. This configuration tells NGINX how to handle incoming requests and forward them to your backend WebSocket server. It’s important to correctly configure the proxy_pass directive to point to your WebSocket server’s address and port. Additionally, you need to set specific headers that inform the backend server that the connection is a WebSocket upgrade request. Let’s explore some key steps in the configuration.

First, you’ll need to define the location block that matches the WebSocket endpoint. Within this block, you’ll use the proxy_pass directive to specify the address of your backend WebSocket server. For example, if your WebSocket server is running on localhost:8080, your proxy_pass directive would be proxy_pass http://localhost:8080;. Next, you must configure the Upgrade and Connection headers. These headers are essential for initiating the WebSocket handshake. The Upgrade header tells the server that the client wants to upgrade the connection to the WebSocket protocol, while the Connection header ensures that the headers are passed through correctly.

To achieve proper WebSocket proxying, include these directives within your location block: nginx proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection “upgrade”; proxy_http_version 1.1; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; These directives ensure that the WebSocket upgrade request is correctly passed to the backend server. The proxy_http_version 1.1; directive is crucial because HTTP/1.1 is required for WebSocket connections. The X-Forwarded-For and X-Real-IP headers are used to pass the client’s IP address to the backend server, which can be useful for logging and security purposes.

Enabling SSL/TLS (wss://) for Secure WebSockets

Enabling SSL/TLS (wss://) is critical for securing your WebSocket connections. This involves obtaining an SSL/TLS certificate, configuring NGINX to use the certificate, and redirecting HTTP traffic to HTTPS. Without SSL/TLS, your WebSocket traffic is vulnerable to eavesdropping and tampering. Let’s see how to enable SSL/TLS with NGINX.

First, you’ll need to obtain an SSL/TLS certificate from a Certificate Authority (CA) like Let’s Encrypt, Comodo, or DigiCert. Let’s Encrypt offers free SSL/TLS certificates and is a popular choice for many websites. Once you have your certificate and private key, you’ll need to configure your NGINX server block to use them. This involves specifying the paths to your certificate and key files using the ssl_certificate and ssl_certificate_key directives.

Here’s an example of how to configure SSL/TLS in your NGINX server block: nginx server { listen 443 ssl; server_name yourdomain.com; ssl_certificate /path/to/your/certificate.pem; ssl_certificate_key /path/to/your/private.key; WebSocket configuration (as described in the previous section) location /websocket { proxy_pass http://localhost:8080; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection “upgrade”; proxy_http_version 1.1; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; } } Ensure that you replace /path/to/your/certificate.pem and /path/to/your/private.key with the actual paths to your certificate and key files. Additionally, it’s a good practice to redirect HTTP traffic to HTTPS to ensure all traffic is encrypted. This can be achieved by adding a separate server block that listens on port 80 and redirects to HTTPS.

Here are key points to consider:

  • Always use strong SSL/TLS ciphers to enhance security.
  • Regularly update your SSL/TLS certificates to prevent vulnerabilities.
  • Implement HTTP Strict Transport Security (HSTS) to enforce HTTPS connections.

Putting it All Together: A Complete NGINX Configuration Example

To illustrate the complete configuration, here’s an example that combines WebSocket proxying and SSL/TLS. This configuration is designed to be a starting point and may need to be adjusted based on your specific requirements. Replace placeholder values with your actual domain and paths.

This example provides a complete NGINX configuration for reverse proxying WebSockets with SSL/TLS enabled:

nginx server { listen 80; server_name yourdomain.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name yourdomain.com; ssl_certificate /etc/nginx/ssl/yourdomain.com.crt; ssl_certificate_key /etc/nginx/ssl/yourdomain.com.key; location / { root /var/www/yourdomain.com; index index.html index.htm; } location /websocket { proxy_pass http://localhost:8080; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection “upgrade”; proxy_http_version 1.1; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; } } Let’s break this down. The first server block listens on port 80 and redirects all HTTP traffic to HTTPS. The second server block listens on port 443 and handles HTTPS traffic. The ssl_certificate and ssl_certificate_key directives specify the paths to your SSL/TLS certificate and private key. The location / block serves your website’s static files, while the location /websocket block handles WebSocket connections. This configuration ensures that all WebSocket traffic is encrypted and that your website is served over HTTPS. You can find more information about NGINX configurations at the official NGINX documentation.

Here are the basic steps to configure Nginx:

  1. Install Nginx.
  2. Obtain an SSL Certificate.
  3. Configure Nginx server block.
  4. Test the configuration.
  5. Restart Nginx.

Featured Snippet: To ensure secure and efficient WebSocket communication, configure NGINX as a reverse proxy with SSL/TLS (wss://). This involves setting up your server block with the correct proxy_pass directive pointing to your WebSocket server, and enabling SSL/TLS by specifying the paths to your SSL/TLS certificate and private key using the ssl_certificate and ssl_certificate_key directives. Additionally, include the Upgrade and Connection headers in your location block to ensure proper WebSocket handshake.

Infographic here
Troubleshooting Common Issues -----------------------------

Configuring NGINX for WebSocket proxying with SSL/TLS can sometimes present challenges. One common issue is the “400 Bad Request” error, which often indicates a problem with the WebSocket handshake. This can occur if the Upgrade and Connection headers are not configured correctly or if the backend server is not properly handling WebSocket upgrade requests. Another common issue is SSL/TLS certificate errors, which can prevent clients from connecting to your WebSocket server. These errors can be caused by invalid certificates, incorrect certificate paths, or missing intermediate certificates. Here are some troubleshooting tips:

  • Verify that your SSL/TLS certificate is valid and correctly installed.
  • Double-check your NGINX configuration for typos or errors.
  • Examine the NGINX error logs for detailed information about the issue.
  • Ensure that your backend server is properly configured to handle WebSocket upgrade requests.

To diagnose issues, start by checking the NGINX error logs, typically located in /var/log/nginx/error.log. These logs often provide valuable clues about the cause of the problem. You can also use tools like curl or websocat to test your WebSocket connection and identify any errors. For example, you can use websocat wss://yourdomain.com/websocket to attempt a WebSocket connection and see if any errors are reported. If you encounter certificate errors, ensure that you have installed the full certificate chain, including any intermediate certificates. You can verify your SSL/TLS configuration using online tools like the SSL Labs SSL Server Test.

More about WebSockets. FAQ: Frequently Asked Questions

**Q: What is the difference between ws:// and wss://?**
A: ws:// is the non-secure WebSocket protocol, while wss:// is the secure WebSocket protocol that uses SSL/TLS encryption.
**Q: Do I need a separate SSL/TLS certificate for WebSockets?**
A: No, you can use the same SSL/TLS certificate that you use for your website.
**Q: How do I test my WebSocket connection?**
A: You can use tools like websocat or online WebSocket testing tools to test your connection.
**Q: What are the benefits of using NGINX as a reverse proxy for WebSockets?**
A: NGINX provides security, load balancing, and SSL/TLS termination, improving the performance and security of your WebSocket applications.
Securing your real-time applications using NGINX as a reverse proxy for WebSockets with SSL/TLS is crucial. By following the configurations and troubleshooting tips outlined in this article, you can ensure that your WebSocket connections are both performant and secure. Remember **Question & Answer :** I'm so lost and new to building NGINX on my own but I want to be able to enable secure websockets without having an additional layer.

I don’t want to enable SSL on the websocket server itself but instead I want to use NGINX to add an SSL layer to the whole thing.

Every web page out there says I can’t do it, but I know I can! Thanks to whoever (myself) can show me how!

Just to note that nginx has now support for Websockets on the release 1.3.13. Example of use:

location /websocket/ { proxy_pass ​http://backend_host; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 86400; } 

You can also check the nginx changelog and the WebSocket proxying documentation.