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

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!

Related

How to setup front end and back end on one server and on one port number? [duplicate]

On my aws ubuntu (18.04) machine, I have 2 applications running on 2 ports
(1) I have a .net core 3.1 angular spa with identity server 4 running on 5000 and I set it up using the steps below
The nginx is a reverse proxy only
(2) I have an angular ssr application running on port 4000.
What I want to achieve is for the reverse proxy to proxy social media bots to port 4000 while all other requests are proxied to the 5000.
Currently nginx is only proxying to the .net core app on port 5000
You can use "location and proxy_pass" to access your desire applications which are working on different ports.
If you have all stuffs on a same vm just use localhost insted of ip address i wrote it down.
But if application are running on another vm use its IP address which in my configuration the destination server is : 172.16.0.100
You can edit the hosts file and use "example.com" or whatever to point your site and use in your nginx configuration file instead of IP or localhost.
sudo vi /etc/hosts
172.16.0.100 example.com
and add your desire FQDN to the destination host or if you have a dns, add an AAAA record which would be available in whole local network.
I write this configuration in my nginx server and it works like a charm.
Anyway you can write and edit this configuration base on your environment.
server {
{
listen 80;
server_name 172.16.0.100;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
location /angular {
proxy_pass http://172.16.0.100:5000;
}
location /ssr {
proxy_pass http://172.16.0.100:4000;
}
}

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

Nginx forwards request to local IP

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.

Configuring nginx and docker on EC2 (Jetbrains)

I have setup Jetbrains Upsource and Teamcity on the same EC2 instance for evalution purposes. If I expose each container on port 80 seperately, I can reach it from the outside world. I want to know how to setup nginx so that I can reach each container over a subdomain like eg. "upsource.example.aws.com" and "teamcity.example.aws.com". I exposed the containers on ports 8080 and 8111 to the host. Is it even possible to achieve this ? If so, I dont know how to start. I read on ways to host multiple domains on one machine for a node web app though exposing the static context. But i have no idea how to make it work with the preconfigured docker images.
Can this be achieved via nginx conf file ?
If not, do I have to use two instances or is there another possibility within aws ?
Its possible with nginx. You have to use something called reverse proxy.
You can expose both the containers in different ports and redirect to these with the help of the nginx configuration.
For example if you have some containers running in port 8000 and 8001 in 127.0.0.1 you can redirect like this:
location /1 {
proxy_pass http://127.0.0.1:8000;
}
location /2 {
proxy_pass http://127.0.0.1:8001;
}
Updated Answer
You need to have 3 containers. The nginx server should be running in port 80. The other two containers will host the sites in say port 8000 (upsource.example.aws.com) and port 8111(teamcity.example.aws.com).
Update the configuration file with the location settings as shown above. Make sure that location / forwards to port 8000 and location /teamcity forwards to port 8111 in your host. More details on how to configure nginx is on the docker hub.
Working
When you go to blabla.com the nginx sever forwards it to port 8000 and when you go to blabla.com/teamcity its goes to port 8111.

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.