Nginx forwards request to local IP - web-services

It's the first time I really work with nginx so please forgive me if I misuse terminology here.
So our companies network has a static IP to which I send requests from multiple sub-domains:
jitsi.domain.ext -> public IP
sub2.domain.ext -> public IP
...
Those requests pass through the firewall and port forwarding to my dedicated nginx server and shall be routed from there to other local servers like so:
jitsi.domain.ext -> local server (jitsi server)
sub2.domain.ext -> local server (website)
...
For this I created besides the untouched global config a separate config for each subdomain and put it in
/etc/nginx/sites-available and via ln -s linked to /etc/nginx/sites-enabled
like so:
# jitsi.domain.ext
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/nginx/cert/jitsiCert.pem;
ssl_certificate_key /etc/nginx/cert/jitsiKey.pem;
server_name jitsi.domain.ext;
location / {
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
proxy_pass http://192.168.0.139;
proxy_redirect off;
}
}
The config is called just fine but it literally redirects me to the URL "192.168.0.139" in the browser. Which of course doesn't work when I am outside of the network and want to access it.
The .pem I use is the one I created for the Jitsi server. I figured that's the easiest way to do it since the dedicated Jitsi server uses nginx as well and I don't want to tamper with it to not break any future updates it gets.
If anyone has a clue for me, I'd be grateful. I tried to get something out of the docs and countless other similar issues discussed on the internet, but nothing seemed to do the trick for me. Thanks in advance!

With the help of Ivan Shatsky I came to realise that the "problem" indeed is the redirection of jitsi's nginx and not the configuration of my "gateway" nginx.
Russel August helped me solve that problem here and here.

Related

How to provide https requests in EC2 Instances?

I have deployed a python script which works using Uvicorn. I have installed nginx on my Ubuntu ec2 instance and installed all requirements to run my script. I have created a file named as Hosting in directory /etc/nginx/sites-enabled/ . My file looks like this
server {
listen 80;
server_name 12.34.56.78 (this is an pseudo IP);
location / {
proxy_pass http://127.0.0.1:8000;
}
}
When I run my script using this command, it starts serving the application on Ip 12.34.56.78
gunicorn3 -k uvicorn.workers.UvicornWorker app:app
To access the API urls I have to use http://12.34.56.78 (not https) and it works correctely but I want it to work on https://12.34.56.78 (with https) .
I tried to change the Hosting file and change the listen 80 to listen 443
server {
listen 443 <- made changes;
server_name 12.34.56.78 (this is an pseudo IP);
location / {
proxy_pass http://127.0.0.1:8000;
}
}
But unfortunately it is not working, I changed the Inbound secrity rules in AWS to accept https and http but it's not working too.
When I try to go https://12.34.56.78 , the webpage says
This site can’t provide a secure connection 12.34.56.78 sent an invalid response.
ERR_SSL_PROTOCOL_ERROR
Could anyone find the mistake ? Thank you in advance

Django won't get https header

Intro
I am building a web app using the latest Django version along with python3.7. The app is dockerized and I plan to deploy with docker-compose. Inside the container, I use nginx to proxy traffic to the application and not expose it directly. Also, I use apache in server level to proxy traffic to various other containers hosted on the same machine.
In the Django application, I use oauth2 to authenticate to Fitbit Web API and the issue I am facing is that the django-social-auth is passing the hostname automatically as a redirect_uri which now, after a lot of configuration with all those proxies, works perfectly in HTTP but when I use HTTPS although the app responds normally the redirect_uri is still http which obviously is not allowed by fitbit and very risky.
Although it is very hard for me to locate in which level the problem occurs I have tried various things but nothing seems to work out.
What I have tried
First
I tried to make my container listen to https request which seemed the most appropriate solution to me but ended getting 502 errors from the Apache.
I tried to find a solution on this by adding some configuration to the virtual host file like
#Solution 1
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
ProxyPass / https://localhost:83/ Keepalive=On #Solution 2 (keep alive)
ProxyPassReverse / https://localhost:83
But at last, I found out that it was not an apache issue but that the nginx inside the container was not responding although the traffic was routed to 443 port using HTTPS
Second
I tried to route traffic from the apache https to containerd nginx HTTP ( which does not make so much sense to me ) which makes the application respond normally but and results the redirect_uri error I mentioned above
As you can see I more or less confused and any kind of hint or help could be very useful
Update 1
The nginx configuration as requested in the comments
server {
listen 80;
listen 443 default_server ssl;
server_name localhost;
charset utf-8;
location /static {
alias /app/static/;
}
location /upload {
alias /app/media/;
}
location / {
proxy_pass http://web:8000;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
I was able to fix the issue by adding the following configuration on the settings.py. I also added a control conditional in order to be able to run the container in development.
# Was already present before the issue resolved but is also needed
USE_X_FORWARDED_HOST = True
# The actual solution
if eval(os.environ.get('DEPLOY', default=False)):
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

nginx connection refused after config

I was setting up nginx on my aws ubuntu instance. At first every time went well, but after I config nginx and try to connect django, I can't even see the welcome page from either public ip nor the localhost(which was able to access from both sides). The nginx status command shows nginx is running.
Here's my nginx config:
/nginx/sites-available/mysite.com
server{
charset utf-8;
listen 80;
server_name my_aws_ip;
location /static{
alias my_django_static_path;
}
location / {
proxy_set_header Host $host;
proxy_pass http://unix:tmp/mysite.socket;
}
}
And I made a link to /nginx/sites-enabled/
It appears that every time I restarted nginx, I will be able to see the welcome page. However, after that, nginx refuses connections.
I didn't change anything in nginx.conf. Do I need to?
server_name should be your domain name, IP address should be specified as part of the listen directive
proxy_pass http://unix:tmp/mysite.socket;
Not sure where you are hoping this will end up, but you need to decide if you are sending it via http or to a socket. Not both. Having said that if it's for django then it's not proxy_pass you want at all
I'm guessing you mean:
uwsgi_pass unix:/tmp/mysite.socket;
You'll also need to include these somewhere in your config

django-uWSGI-nginx deployment issue: No public access behind VPN and proxy

I am trying to deploy a django application with uWSGI & nginx.
I followed this tutorial to the end and everything seems to be working fine, but for accessing the app from an external IP.
I do not own a domain name yet so my relevant nginx settings look like:
server {
listen 80;
server_name "";
}
Also, I have disabled the firewall:
iptables -S gives:
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
Now the CentOs 6.7 machine I am deploying on, has no direct access to the internet as it is behind a proxy (i.e. I need to do pip install django --http_proxy=myproxy.mynet:myport for it to work).
Among other things I have tried to use proxy_pass in my nginx configuration. One attempt:
http {
upstream corporate_proxy {
server myproxy.mynet:myport;
}
server {
listen 80;
rewrite_log on;
location / {
proxy_set_header Host "";
proxy_pass http://corporate_proxy;
}
}
}
Finally, let me add that I cannot access the machine from outside the network either, as it is inside a VPN. So in order to ssh onto it, I first need to connect to the VPN (through FortiClient console).
It is not quite clear to me how all this VPN/proxying really works and how it affects the communication between nginx and external requests. Any solutions or ways to further troubleshoot more than welcome!

How to run Django in development on EC2 so that it is accessible to the internet?

I have Django app. It's running on an EC2. The EC2 has a private IP address and an elastic public IP address.
I want the web app to be available locally as well as Developer's IP address which is outside the network.
Let's define these three IP addresses as:
EC2_PRIVATE_IP
EC2_PUBLIC_IP
DEVELOPER_IP
So what I did was ran on the EC2:
python manage.py runserver 0.0.0.0:8000
Went into my EC2 security settings, and opened up inbound and outbound port 8000 to DEVELOPER_IP.
Then asked Developer to go to the EC2_PUBLIC_IP address on his browser.
Unfortunately that doesn't work as he gets the error:
Gateway Timeout: can't connect to remote host
Update #1
I previously tried:
python manage.py runserver {EC2_PUBLIC_IP}:8000
But I got the error:
Error: That IP address can't be assigned-to.
The server should be started with below url
python manage.py runserver 0.0.0.0:8000
In EC2 security settings add following in INBOUND settings
HTTP TCP 8000 0.0.0.0/0
Then you should be accessing this machine with URL
http://EC2_PUBLIC_IP:8000
If you want to access the url as
http://EC2_PUBLIC_IP
then run your webserver on port 80 and accordingly change the EC2 security settings.
I figured it out. I need to open up the port on Windows Firewall as well!
All answers here give a solution, I want to post this for completeness.
By default, the runserver command starts the development server on the internal IP at port 8000.
If you want to change the server’s port (the standar port for internet access is 80), pass it as a command-line argument. For instance, this command starts the server on port 80:
$ python manage.py runserver 80
Note: You don't want users have to type :port_number after the url in the browser. Another thing is you might not be the owner of the host machine, so you might not have access to configure firewall settings to allow others ports than 80.
If you want to change the server’s IP, pass it along with the port. So to listen on all public IPs (useful if you want to show off your work on other computers on your network), use:
$ python manage.py runserver 0.0.0.0:80
The documentation on all you need to know about development server can be found here.
Make sure your firewall is not blocking anything.
Try
iptable -F
That will delete all your firewall rules on the machine itself.
Edit: However, you should not use it. If want to add a port to your firewall use the following commend if you're running redhat based distros (e.g centos, rhel)
system-config-firewall
If it not there, try to install it
# yum install system-config-firewall # run it after becoming a root
Delete all rules from your outbound security group and replace with an "all traffic" permissive rule.
Your machine is getting the inbound packet but its reply is getting dropped by the security filter. Your dev's box is going to be sending a packet in with a (semi-) arbitrary source port number.
(Also, you can't bind to the public address on the EC2 instance as that's translated from the private address by routing infrastructure, so it's not actually "on" your box.)
In addition to adding firewall rules that will allow traffic to port 8000/Other
You will have to run the development server such that it listens to requests on all interfaces and not just the local one
python manage.py runserver 0.0.0.0:8000
or any other port you may choose
Leave the Django app as to run locally and try to install nginx in the ec2 instance and proxy the trafic on port 80 to localhost:8000.
Something like this:
server {
listen 80;
server_name www.yoursite.com;
client_max_body_size 1000M;
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_connect_timeout 1000;
proxy_read_timeout 1000;
proxy_pass http://127.0.0.1:8080/; # This is the trick !
proxy_buffering off;
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
}
}
You can add the control to serve only for the Developers IP.
Nginx is a lightweight, FAST, SECURE, & SCALABLE Web/Proxy server. The world’s busiest websites use NGINX !
It will run as service, it will listen for all traffic coming from, outgoing to the external world (Internet) and in your case, you would want to tell it to listen for web (port 80) traffic, and redirect it to your Django app (running on port 8000); It is really a nice idea, it is transparent, and, if well tuned, it will empower up your website !
Furthermore, Nginx is very suitable for application delivery for web and mobile. The installation and configuration of nginx is very easy, and you should integrate something similar to the above example to it in order to get your app open to Internet.