How to provide https requests in EC2 Instances? - amazon-web-services

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

Related

Prevent Nginx from changing host

I am building an application which is right now working on localhost. I have my entire dockerized application up and running at https://localhost/.
HTTP request is being redirected to HTTPS
My nginx configuration in docker-compose.yml is handling all the requests as it should.
I want my application accessible from anywhere hence i tried using Ngrok to route the request to my localhost. Actually i have a mobile app in development so need a local server for apis.
Now, when i enter ngrok's url like abc123.ngrok.io in the browser, the nginx converts it to https://localhost/. That works for my host system's browser, as my web app is working there only, but when i open the same in my mobile emulator. It doesn't work.
I am newbie to nginx. Any suggestions will be welcomed.
Here's my nginx configuration.
nginx.conf
upstream web {
ip_hash;
server web:443;
}
# Redirect all HTTP requests to HTTPS
server {
listen 80;
server_name localhost;
return 301 https://$server_name$request_uri;
}
# for https requests
server {
# Pass request to the web container
location / {
proxy_pass https://web/;
}
location /static/ {
root /var/www/mysite/;
}
listen 443 ssl;
server_name localhost;
# SSL properties
# (http://nginx.org/en/docs/http/configuring_https_servers.html)
ssl_certificate /etc/nginx/conf.d/certs/localhost.crt;
ssl_certificate_key /etc/nginx/conf.d/certs/localhost.key;
root /usr/share/nginx/html;
add_header Strict-Transport-Security "max-age=31536000" always;
}
This configuration i got from a tutorial.
First of all, you set redirection from every HTTP request to HTTPS:
# Redirect all HTTP requests to HTTPS
server {
listen 80;
server_name localhost;
return 301 https://$server_name$request_uri;
}
You are using $server_name variable here, so every /some/path?request_string HTTP request to your app would be redirected to https://localhost/some/path?request_string. At least change the return directive to
return 301 https://$host$request_uri;
Check this question for information about difference between $host and $server_name variables.
If these are your only server blocks in your nginx config, you can safely remove the server_name localhost; directive at all, those blocks still remains the default blocks for all incoming requests on 80 and 443 TCP ports.
The second one, if you are using self-signed certificate for localhost be ready for browser complains about mismatched certificate (issued for localhost, appeared at abc123.ngrok.io). If it doesn't break your mobile app, its ok, but if it is, you can get the certificate for your abc123.ngrok.io domain from Lets Encrypt for free after you start your ngrok connection, check this page for available ACME clients and options. Or you can disable HTTPS at all if it isn't strictly requred for your debug process, just use this single server block:
server {
listen 80;
# Pass request to the web container
location / {
proxy_pass https://web/;
}
location /static/ {
root /var/www/mysite/;
}
}
Of course this should not be used in production, only for debugging.
And the last one. I don't see any sense encrypting traffic between nginx and web containers inside docker itself, especially if you already setup HTTP-to-HTTPS redirection with nginx. It gives you nothing in the terms of security but only some extra overhead. Use plain HTTP protocol on port 80 for communications between nginx and web container:
upstream web {
ip_hash;
server web:80;
}
server {
...
location / {
proxy_pass http://web;
}
}

Django & Certbot - unauthorized, Invalid response (HTTPS)

I'm trying to configure Certbot (Letsencrypt) with Nginx.
I get this error :
- The following errors were reported by the server:
Domain: koomancomputing.com
Type: unauthorized
Detail: Invalid response from
http://koomancomputing.com/.well-known/acme-challenge/xvDuo8MqaKvUhdDMjE3FFbnP1fqbp9R66ah5_uLdaZk
[2600:3c03::f03c:92ff:fefb:794b]: "<html>\r\n<head><title>404 Not
Found</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>404
Not Found</h1></center>\r\n<hr><center>"
Domain: www.koomancomputing.com
Type: unauthorized
Detail: Invalid response from
http://www.koomancomputing.com/.well-known/acme-challenge/T8GQaufb9qhKIRAva-_3IPfdu6qsDeN5wQPafS0mKNA
[2600:3c03::f03c:92ff:fefb:794b]: "<html>\r\n<head><title>404 Not
Found</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>404
Not Found</h1></center>\r\n<hr><center>"
To fix these errors, please make sure that your domain name was
entered correctly and the DNS A/AAAA record(s) for that domain
contain(s) the right IP address.
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
in /etc/nginx/sites-available/koomancomputing :
server {
listen 80;
server_name koomancomputing.com www.koomancomputing.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /staticfiles/ {
root /home/kwaku/koomancomputing;
}
location /media/ {
root /home/kwaku/koomancomputing;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
my DNS A/AAAA records :
I didn't know what to do, so I did a search and find django-letsencrypt app, but I don't know hot to use :
Your domain has a proper AAAA record configured to your server over IPv6, and certbot chose that to validate your server.
However, your server block as configured under nginx only listens to port 80 on IPv4 for your domain. When certbot requests Let's Encrypt to access your challenge and issue a certificate, nginx isn't configured to properly respond with the challenge on IPv6. It often in this case returns other things (such as a 404 in your case, or a default site).
You can resolve this by modifying the first two lines to also listen on all IPv6 addresses for your server:
server {
listen 80;
listen [::]:80;
# other configuration
}
After editing, restart nginx and run certbot again.
Your Nginx server is responding with a 404 error because it does not define a route to /.well-known needed by certbot to verify challenges. You need to modify the Nginx config file to tell it how to respond to certbot's challenges.
Certbot can update the Nginx config file for you.
First, make sure your config file is enabled. Run sudo service nginx reload and check for the presence of a file called /etc/nginx/sites-enabled/koomancomputing.
Then, run certbot --nginx -d koomancomputing.com -d www.koomancomputing.com
The --nginx flag tells certbot to find an Nginx config file with a matching server name and update that file with SSL info.
server {
listen 80;
listen [::]:80;
# other configuration
}
Works for both IPV4 and IPV6 after adding this restart nginx.
For me, it worked after I removed and installed the latest certbot version using snapd.
I use cloudflare proxy option and it failed for certbot 0.31.0.
After installing certbot 1.27 and configuring the cert newly, it works fine even proxy toggle is on in cloudflare.

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!

Amazon EC2 Deployment Not Working When IP Address Typed Into Browser Suspect Ngnix Problems

I am nearing the last step of deploying my Django app and I think I am having a Nginx problem. This is my first time deploying, so give me a break.
Basically, the problem is that when I navigate to my public IP on my browser I am getting a webpage is not available error.
I am thinking it is an issue with how I am writing out my directory structure in my Nginx configuration script, but am unsure. I am following a tutorial and don't really understand the script they are asking me to run.
Here is my app's directory structure within my server...
/home/ubuntu/flower_shop/flowershop
Here is my Nginx's file that configures Nginx
server {
listen 80;
server_name 54.213.141.60;
location = /favicon.ico { access_log off; log_not_found off;}
location /static/ {
root /home/ubuntu/flower_shop/flowershop;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/ubuntu/flower_shop/flowershop/flowershop.sock;
}
I am creating the above file by typing the following into my command line...
sudo vim /etc/nginx/sites-available/flower_shop
Can you see anything obvious that I am doing wrong? Gunicorn is set up fine and my app works on my local host. I have tried restarting Nginx, but I get the same results.
Hope you have done the following step:
sudo ln -s /etc/nginx/sites-available/flower_shop /etc/nginx/sites-enabled/flower_shop
Some other diagnostic commands which will help pin down the problem:
Supply nginx error and access logs
output of netstat -tulpn | grep nginx
In ssh session do curl -D - http://localhost:80
Try replacing the above snippet with the following extremely simple server config. Notice the only filtering it has for now is for port 80. It assumes your gunicorn is serving at 8080. Change port appropriately, if required.
```
server{
listen 80;
location / {
proxy_pass http://localhost:8080;
}
}
```

Nginx: listen to 8080 for proxy_pass, but not 80

I can't seem to make this nginx config work on port 80. I tried to deploy a django application using nginx and gunicorn. I used the following command to run gunicorn:
gunicorn myproj.wsgi:application --bind=127.0.0.1:8001 --workers=9
The following is the nginx config file /etc/nginx/sites-enabled/myproj:
server {
listen 8080;
location / {
proxy_pass http://127.0.0.1:8001;
}
location /static/ {
root /webapps/myproj/;
}
}
Everything works fine except that I have to enter http://localhost:8080/ locally or http://xxx.xxx.xxx:8080/ for the application to run correctly. Without the port number 8080, the page would not be found.
However, if I change the listen 8080; into listen 80; in the config file (myproj) and enter http://localhost/ locally or http://xxx.xxx.xxx/ remotely, the page only shows the welcome message from nginx. Nginx seems not forwarding the request to my application. What was the problem?
You need to specify domain or IP to bind to.
listen XXX.XXX.XXX:80;
Probably because other server with listen 80; exists.
You can remove other server defenition. Or change listen 80; to listen 80 default_server;. Or use server_name directive for name-based process.
Read this about how nginx decides which server should process the request: http://nginx.org/en/docs/http/request_processing.html