Niginx Server: SSL_ERROR_RX_RECORD_TOO_LONG - http

I recently hosted a react app on EC2 with nginx. The react app is running on port 3000.
So I redirected HTTP & HTTPS requests to port 3000 using -
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 3000
sudo service netfilter-persistent save
I have added the domain name and certificate details in the conf file in /etc/nginx/sites-available. The conf file is -
server {
listen 443 ssl;
root /var/www/myapp/client/build;
server_name example.com;
index index.html index.htm;
ssl_certificate /etc/ssl/bundle.crt;
ssl_certificate_key /etc/ssl/mykey.key;
location / {
}
}
server {
listen 80;
server_name example.com ip_address;
return 301 https://example.com$request_uri;
}
When I run this -
sudo lsof -i -P -n
I get this-
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd-n 630 systemd-network 19u IPv4 25765 0t0 UDP 172.11.25.109:68
systemd-r 641 systemd-resolve 12u IPv4 15768 0t0 UDP 127.0.0.53:53
systemd-r 641 systemd-resolve 13u IPv4 15769 0t0 TCP 127.0.0.53:53 (LISTEN)
sshd 973 root 3u IPv4 19516 0t0 TCP *:22 (LISTEN)
sshd 973 root 4u IPv6 19533 0t0 TCP *:22 (LISTEN)
sshd 1388 root 3u IPv4 21610 0t0 TCP 172.11.25.109:22->95.91.208.58:60491 (ESTABLISHED)
sshd 1523 ubuntu 3u IPv4 21610 0t0 TCP 172.11.25.109:22->95.91.208.58:60491 (ESTABLISHED)
node 1743 root 24u IPv4 23414 0t0 TCP *:3000 (LISTEN)
nginx 1924 root 8u IPv4 25687 0t0 TCP *:443 (LISTEN)
nginx 1924 root 9u IPv4 25688 0t0 TCP *:80 (LISTEN)
nginx 1928 www-data 8u IPv4 25687 0t0 TCP *:443 (LISTEN)
nginx 1928 www-data 9u IPv4 25688 0t0 TCP *:80 (LISTEN)
I am able to see the website on http://example.com but I get an error when I try to go to https://example.com. I get the error -
SSL received a record that exceeded the maximum permissible length. Error code: SSL_ERROR_RX_RECORD_TOO_LONG
How can I correctly host the web app on HTTPS?

So I redirected HTTP & HTTPS requests to port 3000 using ...
This is directing IP packets to port 80 and 443 directly to port 3000, which means that nginx will completely be bypassed. Any configuration for nginx is thus irrelevant.
The access to https://example.com will try a TLS handshake on port 443 which is essentially port 3000 (because of the redirect of the IP packets) - but port 3000 does not understand TLS. The server on port 3000 will instead expect plain HTTP and return an HTTP error since the start of the TLS handshake obviously is no valid HTTP request. This error message then will be interpreted as the TLS response which causes this strange error message.
What you need to do instead of the iptables rules is to configure nginx as reverse proxy, see for example here how to do this.

Related

How to make Nginx proxy pass work with external requests to nodes

Below is what I want to achieve;
Forward traffic from http://myip.com to http://localhost:8081
Forward traffic from http://gitlab.myip.com to http://localhost:8443
The following snippet is the content of my Nginx configuration file;
# /etc/nginx/sites-available/two-applications.conf
server {
listen 80;
server_name myip.com;
location / {
# Proxy pass to Apache server
proxy_pass http://localhost:8081;
}
}
server {
listen 80;
server_name gitlab.myip.com;
location / {
# Proxy pass to GitLab server
proxy_pass http://localhost:8443;
}
}
It works as expected within my network but hangs when accessed from outside my network except when port 8081 and 8443 are appended to http://myip.com and http://gitlab.myip.com respectively.
My router is forwarding traffic from ports 80, 8443, 8081 to the computer hosting these applications and my firewall was disabled by running ufw disable.
This is my (abbreviated) output from running sudo netstat -tulpn:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 20603/nginx: master
tcp 0 0 0.0.0.0:8443 0.0.0.0:* LISTEN 13513/nginx: master
tcp6 0 0 :::8081 :::* LISTEN 685/apache2
What am I doing wrong and how can I fix it?
EDIT
The problem here was with the ISP blocking port 80

Nginx not redirecting to https

I have a problem with http requests with my Nginx configuration.
server {
listen 80;
listen [::]:80;
server_name www.queroemprego.pt queroemprego.pt;
return 301 https://www.queroemprego.pt$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name queroemprego.pt;
return 301 https://www.queroemprego.pt$request_uri;
ssl on;
{...}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name www.queroemprego.pt;
{...}
}
Nginx is listening to both ports and my iptables looks okay
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 0 4204048 12064/nginx: master
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 0 4204050 12064/nginx: master
https requests are working and accessing it via https://www.queroemprego.pt should work and has been working for the past month.
But I noticed that http requests are failing for some people and I have no idea why.
The following page tries to get the http version and the requests fails.
http://downforeveryoneorjustme.com/queroemprego.pt
I have 2 more subdomains with similar configurations, redirecting http to https.
Any ideas?
Edit:
Here are my iptables
iptables --list
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere tcp dpt:https
ACCEPT tcp -- localhost anywhere tcp dpt:smtp
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
So, the problem was with my iptables.
I though it was accepting requests to port 80, but nope.
Here's the solution:
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

A websocket via nginx proxy?

Hi I have a question ~ I want to use nginx proxy to distribute websocket connect to other port. like this .
client ====> proxy =====> ws server
but my question is the websocket tunnel is build on the client and ws server or client and proxy and ws server.
client === proxy ==== ws server
Or
client ===== ws server
Thanks ~~~
You don't skip proxy as such. The proxy makes the connection on behalf of you. See the below excerpt from https://www.nginx.com/blog/websocket-nginx/
A WebSocket application keeps a long‑running connection open between the client and the server, facilitating the development of real‑time applications. The HTTP Upgrade mechanism used to upgrade the connection from HTTP to WebSocket uses the Upgrade and Connection headers. There are some challenges that a reverse proxy server faces in supporting WebSocket. One is that WebSocket is a hop‑by‑hop protocol, so when a proxy server intercepts an Upgrade request from a client it needs to send its own Upgrade request to the backend server, including the appropriate headers. Also, since WebSocket connections are long lived, as opposed to the typical short‑lived connections used by HTTP, the reverse proxy needs to allow these connections to remain open, rather than closing them because they seem to be idle.
Edit-1 - Connections Comparisons between Nginx and direct NodeJS
So finally I did some test to make sure. Started a socket.io app on 3000 and nginx on 80 to forward to request to the Socket.io
Nginx
When I access the app using http://IP/ in two browser windows, the open connection are as below
$ lsof -i
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 4443 vagrant 11u IPv6 25730 0t0 TCP *:3000 (LISTEN)
node 4443 vagrant 13u IPv6 28591 0t0 TCP localhost:3000->localhost:42698 (ESTABLISHED)
node 4443 vagrant 14u IPv6 28626 0t0 TCP localhost:3000->localhost:42712 (ESTABLISHED)
nginx 5144 vagrant 6u IPv4 28402 0t0 TCP *:http (LISTEN)
nginx 5144 vagrant 13u IPv4 28589 0t0 TCP 192.168.33.100:http->192.168.33.1:64799 (ESTABLISHED)
nginx 5144 vagrant 14u IPv4 28590 0t0 TCP localhost:42698->localhost:3000 (ESTABLISHED)
nginx 5144 vagrant 15u IPv4 28625 0t0 TCP localhost:42712->localhost:3000 (ESTABLISHED)
nginx 5144 vagrant 16u IPv4 28624 0t0 TCP 192.168.33.100:http->192.168.33.1:64826 (ESTABLISHED)
Now after closing both the tabs
$ lsof
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 4443 vagrant 11u IPv6 25730 0t0 TCP *:3000 (LISTEN)
nginx 5144 vagrant 6u IPv4 28402 0t0 TCP *:http (LISTEN)
NodeJS
Opening two browser tabs with direct connection to NodeJS http://<IP>:3000. Then the results are as below
$ lsof -i
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 4443 vagrant 11u IPv6 25730 0t0 TCP *:3000 (LISTEN)
node 4443 vagrant 13u IPv6 30014 0t0 TCP 192.168.33.100:3000->192.168.33.1:52550 (ESTABLISHED)
node 4443 vagrant 14u IPv6 30015 0t0 TCP 192.168.33.100:3000->192.168.33.1:52551 (ESTABLISHED)
node 4443 vagrant 15u IPv6 30016 0t0 TCP 192.168.33.100:3000->192.168.33.1:52552 (ESTABLISHED)
node 4443 vagrant 16u IPv6 30017 0t0 TCP 192.168.33.100:3000->192.168.33.1:52553 (ESTABLISHED)
node 4443 vagrant 17u IPv6 30018 0t0 TCP 192.168.33.100:3000->192.168.33.1:52554 (ESTABLISHED)
node 4443 vagrant 18u IPv6 30020 0t0 TCP 192.168.33.100:3000->192.168.33.1:52556 (ESTABLISHED)
node 4443 vagrant 19u IPv6 30024 0t0 TCP 192.168.33.100:3000->192.168.33.1:52578 (ESTABLISHED)
nginx 5144 vagrant 6u IPv4 28402 0t0 TCP *:http (LISTEN)
This may look a bit strange, but this is because the connections used to open the site are also kept alive for few seconds. So after waiting for sometime
$ lsof -i
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 4443 vagrant 11u IPv6 25730 0t0 TCP *:3000 (LISTEN)
node 4443 vagrant 18u IPv6 30020 0t0 TCP 192.168.33.100:3000->192.168.33.1:52556 (ESTABLISHED)
node 4443 vagrant 19u IPv6 30024 0t0 TCP 192.168.33.100:3000->192.168.33.1:52578 (ESTABLISHED)
nginx 5144 vagrant 6u IPv4 28402 0t0 TCP *:http (LISTEN)
As you can see no. of connections will be always be higher when you use Nginx

Access NGINX on router from WAN

i am configuring my home router ASUS N18U with Tomato by Shibby FW. I would like to set up a home webserver NGINX on it. I know, it is not ideal. The only problem I have is that I cant access the server from Wan. Moreover I have dynamic IP, which I have resolved with DDNS Service. It works fine, if I want to access config page of router or SFTP or when I type myddnsdomain and I am inside LAN. I opened port 80 on my modem(from ISP) and add the code below to routers(ASUS N18U) config, I cannot just port forward it in admin menu, because it allows forward only to lan(my web server is on "router").
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT
None of this solved my problem. I have also tried different ports. I tracerouted it and it seems, that router blocks it. Accessing my server through Wan IP have not helped. Folder "www" is owned by nobody. Thank you for your help
# NGinX generated config file
user nobody;
worker_processes 1;
worker_cpu_affinity 0101;
master_process off;
worker_priority 10;
error_log /tmp/var/log/nginx/error.log;
pid /tmp/var/run/nginx.pid;
worker_rlimit_nofile 8192;
events {
worker_connections 512;
}
http {
include /tmp/etc/nginx/mime.types;
include /tmp/etc/nginx/fastcgi.conf;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
client_max_body_size 100M;
server {
listen 80;
server_name mydynamicdomain.net;
access_log /tmp/var/log/nginx/access.log main;
location / {
root /tmp/mnt/CORSAIR/www;
index index.html index.htm index.php;
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location /50x.html {
root /tmp/mnt/CORSAIR/www;
SOLVED
This example will help you as i have achieved this with below iptable rules
Dynamic values:
(change according to your environment values)
WAN Interface: vlan10
LAN Interface: br0
LAN Web server IP: 192.168.1.1
LAN Web server Port: 8080
Router WAN IP: 192.168.10.129
Router LAN IP: 192.168.1.254
With above values insert below rules:
1. Port-Forwarding rules
iptables -I FORWARD 1 -i vlan10 -p tcp -d 192.168.1.1 --dport 8080 -j ACCEPT
iptables -A PREROUTING -t nat -i vlan10 -p tcp --dport 8080 -j DNAT --to 192.168.1.1
2. NAT loopback rules
iptables -t nat -A PREROUTING -i br0 -s 192.168.1.0/24 -d 192.168.10.129/32 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.168.1.1
iptables -t nat -A POSTROUTING -o br0 -s 192.168.1.0/24 -d 192.168.1.1/32 -p tcp -m tcp --dport 8080 -j SNAT --to-source 192.168.1.254
I had the same problem with my tomato shibby router today. Running on port 85 would accept connections from internal lan but not WAN so I simply forwarded port 85 to 10.0.0.1 (my router's lan address) and it worked.
I had the same issue when trying to connect from WAN. Port forwarding to the router's IP did not help. Added this to the Administration > Scripts > Firewall and then rebooting sorted out my issue:
iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 443 -j ACCEPT

Redirecting ports for a service can iptables be used instead of mod_proxy

I have a service which is running on http port 8080 and https port 8443 and all traffic to port 8080 is being redirected to https 8443 which is configured on server.xml itself.
Requirement :
All traffic when using ports 80,8080,443,8443 should be diverted to 8443 without port number getting displayed under URL
Possible solutions :
I know that using mod_proxy,masking and reverse proxy we can implement it (http://www.pothireddy.com/knowledge/environment/masking/)
Question here is can we use IPTABLES to implement that instead of mod_proxy solution, if so how can do we achieve it....
Already tried something like this :
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443
Fixed problem when someone is hitting port 443
When someone hits port 8443 explicitly then port 8443 is showing
up on the url ? Can we implement something like .... just to mask
the port 8443 iptables -t nat -A PREROUTING -p tcp --dport 8443 -j
REDIRECT --to-port 8443
How to redirect traffic from port 80 to port 8443, when I tried
using below command, looks like it is getting confused diverting
traffic from http port to https port ? iptables -t nat -A PREROUTING
-p tcp --dport 8443 -j REDIRECT --to-port 8443
Any Possible solution for fixing the above 2 questions ?
if you are using apache web-server, you can make new virtualhost in some port like
http://wiki.apache.org/httpd/RedirectSSL
NameVirtualHost *:8080
<VirtualHost *:8080>
ServerName mysite.example.com
DocumentRoot /usr/local/apache2/htdocs
Redirect permanent /secure https://mysite.example.com/secure:8443
</VirtualHost>
<VirtualHost _default_:8443>
ServerName mysite.example.com
DocumentRoot /usr/local/apache2/htdocs
SSLEngine On
# etc...
</VirtualHost>

Resources