gunicorn reverse proxy accessible from internet - nginx

I configured nginx and gunicorn to serve flask app. And I started gunicorn with this command
gunicorn --bind 0.0.0.0:5000 wsgi:app My website is accessible from my provided ip address on port 80. However It is accessible on port 5000 as well. It seems my reverse proxy works as it should be, but gunicorn server can be accessible as well.
I'm planning to disable port 5000, but not sure this is the correct, secure way to solve such problem.
This is my nginx conf file:
server {
server_name <my_ip_adress>;
access_log /var/log/nginx/domain-access.log;
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 10;
proxy_read_timeout 10;
# This line is important as it tells nginx to channel all requests to port 5000.
# We will later run our wsgi application on this port using gunicorn.
proxy_pass http://127.0.0.1:5000/;
}
}

You're binding gunicorn to 0.0.0.0 hence it's available on the external interfaces. Assuming this is just one box, instead:
gunicorn --bind 127.0.0.1:5000 wsgi:app
This no longer listens for requests from external interfaces, meaning all requests must come through nginx.
Of course if you did bind gunicorn to 0.0.0.0 you could make a firewall rule with iptables to DROP traffic to that port from external interfaces.
If you are using a cloud provider they may implement this firewall functionality natively on their platform - for example Security Groups on AWS EC2 would allow you to create a 'webserver' group which only allows traffic through for ports 80 & 443.

Related

cannot visit minio server dashboard from ubuntu

i am working on nginx and minio on the ubuntu.
the minio server is started from
'nohup /usr/local/bin/minio server /data/tenant1 --address :9001 > /opt/logs/minio.log 2>&1 &#',
and it is working.
then I started the nginx and configure the nginx server with the following configuration.
nano /etc/nginx/sites-available/default
server {
listen 9000;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:9001;
}
}
sudo systemctl restart nginx
from the opening ports, it is clear to see the minio is running on port 9001
minio 9349 root 12u IPv6 35833021 0t0 TCP *:9001 (LISTEN)
nginx 12416 www-data 8u IPv4 36153228 0t0 TCP *:9000 (LISTEN)
At last, the gateway is inactive from the output of ufw status. and my server security group also allows 9000.
however when I tried to visit the minio server dashboard from http://IP:9000/minio , it is not working,
any problem with my configuration?
The MinIO console dashboard listens on a separate port - you need to specify this with the option --console-address :10000 - if you do not specify this, a random port is chosen for you and it will be displayed in MinIO's logs in your /opt/log/minio.log file. The 9001 port in your setup is for the S3 storage API only.

Block access to rocket.chat via http port in reverse proxy mode

I have installed rocket.chat version 0.72.3 on CentOS 7.6 as a private local team chat.
Then for configuring a reverse proxy to force rocket.chat use SSL protocol I installed nginx version 1.12.2 and followed this link https://rocket.chat/docs/developer-guides/mobile-apps/supporting-ssl/ to configure nginx as a reverse proxy.
After the configuration was successful, I have two urls both pointing to my rocket.chat application (http://localhost:3000 and https://localhost:443). I mean rocket.chat is accessible under both of these two links which the http access is redundant.
How can I disable access to rocket.chat via http://localhost:3000?
You need to 1) bind rocketchat service only to localhost interface and 2) let nginx to listen on public interface and to act as proxy (what you probably already did).
So, first open your rocketchat.service file (possibly in /lib/systemd/system/rocketchat.service, but this depends on how you did configure rocketchat service) and in [Service] section add this line:
[Service]
Environment=BIND_IP=127.0.0.1
Don't worry that you already have one (or some) Environment entries, these are aggregated (as for me I have single Environement entry for each variable).
Then open your nginx config (possibly /etc/nginx/sites-enabled/default, but this may differ) and make sure, that server block listens only on port 443 and does its proxy job. My nginx relevant entries look like this:
# Upstreams
upstream backend {
server 127.0.0.1:3000;
}
server {
listen 443;
server_name mydomain.com;
error_log /var/log/nginx/rocketchat.access.log;
ssl on;
ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
location / {
proxy_pass http://127.0.0.1:3000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_redirect off;
}
}
You probably need to reload/restart nginx and rocketchat services and reload config issuing
$ sudo systemctl daemon-reload
command.
For me it works flawlessly.
I resolved this issue by blocking external connections to localhost and allowing internal connections to localhost using iptables:
iptables -A INPUT -p tcp --dport 3000 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --dport 3000 -j DROP
But I'm still wondering isn't there any config related to nginx to sort the issue out?

Despite hosting on nginx works fine in local web, it does not work with external ip

I have configured .net and nginx on ubuntu and it works in local web perfectly. I have static external ip, I have configured port forwarding on my router (I had done it for postgresql and it works fine from external web so I think I have done it properly) When it comes to nginx and when i type my ip f.e: xx.xx.x.xx:80 in url on computer in another web site is unreachable.
I have opened ports in firewall on linux:
sudo apt-get install ufw
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Here is my nginx config:
server {
listen 80;
server_tokens off;
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
I hope, I find solution but still I don't know why it works this way. I have changed listen port to 9000 or any different instead 80 in nginx config and in my router forwarding. Now everything works fine, why port 80 does not work?

ActiveMQ and NGINX

I can get my head wrapped around ... We have requirement using ActiveMQ hidden behind NGINX proxy, but I have no idea how to set it up.
For the ActiveMQ I've setup different ports for all protocols
<transportConnectors>
<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
<transportConnector name="openwire" uri="tcp://0.0.0.0:62716?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="amqp" uri="amqp://0.0.0.0:5782?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="stomp" uri="stomp://0.0.0.0:62713?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1993?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:62714?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
And the nginx configuration like this:
server {
listen *:61616;
server_name 192.168.210.15;
index index.html index.htm index.php;
access_log /var/log/nginx/k1.access.log combined;
error_log /var/log/nginx/k1.error.log;
location / {
proxy_pass http://localhost:62716;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_redirect off;
proxy_method stream;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
}
}
(same for all other five redefined ports)
I though that this would expose default ports ActiveMQ ports and Nginx would map it to the new definition, but this doesn't work.
For communication, we're using NodeJs library amqp10 in version 3.1.4.
And all the ports are enabled on the server ... if using standard ports without nginx proxy, it works.
Anyone idea what am I missing? Thanks for any thoughts.
You can hide ActiveMq behind nginx proxy, even if you are trying to proxy OpenWire for a AMQP client.
If you are adding your configuration inside http block, its bound to fail.
But get it that, nginx not only supports http, but also tcp block.
If you proxy activemq over tcp, then what happens at http level won't matter and you would still be able to proxy.
Off-course you would lose flexibility that comes along with http.
Open your nginx.conf (at /etc/nginx/nginx.conf).
This would have http block, which in turn would have some include statements.
Outside this http block, add another include statement.
$ pwd
/etc/nginx
$ cat nginx.conf | tail -1
include /etc/nginx/tcpconf.d/*;
The include statement is directing nginx to look for additional configurations in directory "/etc/nginx/tcpconf.d/".
Add desired configuration in this directory. Let's call it amq_stream.conf.
$ pwd
/etc/nginx/tcpconf.d
$ cat amq_stream.conf
stream {
upstream amq_server {
# activemq server
server <amq-server-ip>:<port like 61616.;
}
server {
listen 61616;
proxy_pass amq_server;
}
}
Restart your nginx service.
$ sudo service nginx restart
You are done
Nginx is a HTTP server that is capable of proxying WebSocket and HTTP.
But you are trying to proxy OpenWire for a AMQP client. Which does not work with Nginx or Node.js.
So - if you really need to use Nginx, you need to change client protocol to STOMP or MQTT over WebSocket. Then setup a WebSocket proxy in Nginx.
Nginx-example with TLS. More details at https://www.nginx.com/blog/websocket-nginx/
upstream websocket {
server amqserver.example.com:62714;
}
server {
listen 8883 ssl;
ssl on;
ssl_certificate /etc/nginx/ssl/certificate.cer;
ssl_certificate_key /etc/nginx/ssl/key.key;
location / {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade websocket;
proxy_set_header Connection upgrade;
proxy_read_timeout 120s;
}
}
However, since you have to rewrite all client code, I would rethink the Nginx idea. There are other software and hardware that can front TCP based servers and do TLS termination and whatnot.

How does supervisord and nginx handle what tornado port is used?

I am using supervisord to spool 2 instances of tornado on different ports and I use nginx as a reverse proxy to these ports. I have noticed that all traffic is directing to only one port. How does supervisord or nginx decide which instance of tornado is used when a user makes a request from the web service?
nginx config:
http {
upstream frontends {
server xx.xxx.x.xxx:8001;
server xx.xxx.x.xxx:8002;
}
server {
listen 80;
server_name xx.xxx.x.xxx;
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass http://frontends;
}
}
}
From the nginx docs:
Requests are distributed according to the servers in round-robin manner with respect of the server weight.
By default, servers are given equal weight. Are you sure all requests are going to one port?
Also note that supervisord's role is simply process management - only nginx decides how to distribute traffic to the ports you've configured.

Resources