Can't acces to AWS Kibana VPC-Based with nginx using Cognito - amazon-web-services

I use Elasticsearch VPC-based, for connect to kibana I use nginx reverse proxy.
I'm followed this : https://aws.amazon.com/premiumsupport/knowledge-center/kibana-outside-vpc-nginx-elasticsearch/?nc1=h_ls.
When I try to access to https://ec2-x-x-x-x.region-x.compute.amazonaws.com (EC2 instance containts nginx ).
I have a redirect to https://ec2-x-x-x-x.region-x.compute.amazonaws.com/login?response_type=code&client_id=xxxx... instead https://auth.website.com/login?response_type=code&client_id=xxxx... (auth.website.com is Cognito host)
Then I have an 502 bad gateway.
My nginx config :
server {
listen 443;
server_name $host;
rewrite ^/$ https://$host/_plugin/kibana redirect;
ssl_certificate /etc/nginx/cert.crt;
ssl_certificate_key /etc/nginx/cert.key;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
location /_plugin/kibana {
# Forward requests to Kibana
proxy_pass https://vpc-domain-xxxxx.region.es.amazonaws.com/_plugin/kibana;
# Handle redirects to Amazon Cognito
proxy_redirect https://auth.exmample.com https://$host;
# Update cookie domain and path
proxy_cookie_domain vpc-domain-xxxxx.region.es.amazonaws.com $host;
proxy_cookie_path / /_plugin/kibana/;
# Response buffer settings
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
location ~ \/(log|sign|error|fav|forgot|change|saml|oauth2) {
# Forward requests to Cognito
proxy_pass https://auth.exmample.com;
# Handle redirects to Kibana
proxy_redirect https://vpc-domain-xxxxx.region.es.amazonaws.com https://$host;
# Update cookie domain
proxy_cookie_domain auth.exmample.com $host;
}
}
Thank you

Relaunch the page with browser Developer Tools enabled and "Network" tab is selected. You might able to start the investigation on the cause from here.
access to your EC2 instance, then check the nginx log which located at /var/log/nginx/ directory (for linux based distribution).
Check the security group of your EC2 instance.

Related

Run Daphne in production on (or forwarded to?) port 443

I am trying to build a speech recognition-based application. It runs on Django with Django-channels and Daphne, and Nginx as the web server, on an Ubuntu EC2 instance on AWS. It should run in the browser, so I am using WebRTC to get the audio stream – or at least that’s the goal. I'll call my domain mysite.co here.
Django serves the page properly on http://www.mysite.co:8000 and Daphne seems to run too, the logs show
2022-10-17 13:05:02,950 INFO Starting server at fd:fileno=0, unix:/run/daphne/daphne0.sock
2022-10-17 13:05:02,951 INFO HTTP/2 support enabled
2022-10-17 13:05:02,951 INFO Configuring endpoint fd:fileno=0
2022-10-17 13:05:02,965 INFO Listening on TCP address [Private IPv4 address of my EC2 instance]:8000
2022-10-17 13:05:02,965 INFO Configuring endpoint unix:/run/daphne/daphne0.sock
I used the Daphne docs to set up Daphne with supervisor. There, they use port 8000.
My first Nginx config file nginx.conf (I shouldn't use that one, should I?) looks like this:
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
# server_tokens off;
server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Gzip Settings
gzip on;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
upstream channels-backend {
server mysite.co:80;
}
server {
location / {
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_pass http://mysite.co;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
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 X-Forwarded-Host $server_name;
}}
}
# and the mail settings, but I don't use them
Currently, the homepage of my server just serves a HTML that I set in my first Nginx server block (I set this up while figuring out how to get TLS on Nginx, I don't need the HTML here):
server {
root /var/www/mysite/html;
index index.html index.htm index.nginx-debian.html;
server_name mysite.co www.mysite.co;
location / {
try_files $uri $uri/ =404;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/mysite.co/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/mysite.co/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.mysite.co) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = mysite.co) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name mysite.co www.mysite.co;
return 404; # managed by Certbot
}
I need WebRTC to access the audio stream that should run through Daphne, but for that, I need HTTPS because you can’t access user media via unencrypted protocols. I have created a TLS cert with Let’s Encrypt for Nginx (cf. above), but of course this only works on port 443. I can’t (and probably shouldn’t be able to?) reach port 8000 via HTTPS.
I am a bit lost at this point, my Nginx experience is very limited. Do I need to bind port 8000 to 443? If so, what do I need to do with my Nginx config for the HTML file that is currently served there? Am I on the right track at all?
If I should share other config files from Nginx or supervisor, please let me know.
I was on the wrong track, actually it's very straightforward. There's no need to run it on port 8000, you can run it conveniently on 443.
You don't configure the SSL in the Nginx server blocks, but you do it right in the place where you start the Daphne server adding -e ssl:443:privateKey=key.pem:certKey=crt.pem to your daphne command. You must have generated an SSL certificate previously of course, Let'sEncrypt works just fine here as well. privateKey is privkey.pem and certKey is fullchain.pem then.
(This snippet in itself won't work, depending on your needs you might have to add other flags as well like -u or --endpoint.)

AWS OpenSearch running in vpc behind Nginx dont show the tenants

I have an opensearch instance which is in a VPC behind an nginx proxy
I cannot see the tenantes in Opensearch, I can create them but not see them. And when I want to change the tenante he tells me “Failed to switch tenant. Invalid cookie”
are there people who have encountered the same problems. Thank you
here is my configuration : I took the aws configuration
enter image description here
server {
listen 443;
server_name $host;
rewrite ^/$ https://$host/_dashboards redirect;
ssl_certificate /etc/nginx/cert.crt;
ssl_certificate_key /etc/nginx/cert.key;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
location /_dashboards {
# Forward requests to Dashboards
proxy_pass https://$domain-endpoint/_dashboards;
# Handle redirects to Cognito
proxy_redirect https://$cognito_host https://$host;
# Update cookie domain and path
proxy_cookie_domain $domain-endpoint $host;
proxy_cookie_path / /_dashboards/;
# Response buffer settings
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
location ~ \/(log|sign|fav|forgot|change|saml|oauth2) {
# Forward requests to Cognito
proxy_pass https://$cognito_host;
# Handle redirects to Dashboards
proxy_redirect https://$domain-endpoint https://$host;
# Update cookie domain
proxy_cookie_domain $cognito_host $host;
}
}
The line
proxy_cookie_path / /_dashboards/;
Should be
proxy_cookie_path ~/ /_dashboards/;
Note the ~. Encountered the same issue and this fixed it.

Handling dynamic IP in Django ALLOWED_HOSTS with nginx

I'm having issues with what i believe is my nginx.conf which is causing the instance to be restarted again and again, as the health-checks fail on my managed container service.
I'm running my setup in AWS Lightsail Containers, where I have three containers running:
nginx
django
nextjs
When publishing a new release on my AWS Lightsail instance it runs fine for a few minutes, then I hit a 503 error, which causes the instance to reboot - run a few minutes then reboot again.
Looking at the logs I can see that the health-check failed, and django throws and error saying that I should add the request IP to the allowed hosts:
[28/Aug/2021:13:56:23] Invalid HTTP_HOST header: 'x.x.x.x'. You may need to add 'x.x.x.x' to ALLOWED_HOSTS.
[28/Aug/2021:13:56:23] Bad Request: /health.txt
The problem is that my lightsail container service does not have a static IP (nor do I believe I can get a static IP).
My current nginx.conf is below (feedback is appreciated). My question here is how should I deal with this issue? I feel like setting ALLOWED_HOSTS = ['*'] is not a great approach. Can I hardcode the host for the healthcheck or similar?
nginx.conf:
upstream backend {
server ${BACKEND_HOST}:${BACKEND_PORT};
}
upstream frontend {
server ${FRONTEND_HOST}:${FRONTEND_PORT};
}
server {
listen 80 default_server;
server_name example.com;
server_tokens off;
gzip on;
gzip_proxied any;
gzip_comp_level 4;
gzip_types text/css application/javascript image/svg+xml;
location /robots.txt {
include proxy_params;
proxy_pass http://backend;
}
location /health.txt {
include proxy_params;
proxy_pass http://backend;
}
location /api {
include proxy_params;
proxy_pass http://backend;
}
location /admin {
include proxy_params;
proxy_pass http://backend;
}
location / {
proxy_pass http://frontend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
I use AWS EC2, to pass the health check I get the ip of the instance dynamically and then I insert it into ALLOWED_HOSTS (I think it should work also for Lightsail Containers):
import requests
def get_instance_ip():
try:
ip = requests.get('http://169.254.169.254/latest/meta-data/local-ipv4').text
except requests.exceptions.ConnectionError:
return None
return ip
AWS_IP = get_ec2_instance_ip()
if AWS_IP is not None:
ALLOWED_HOSTS += [AWS_IP]
You can also create a middleware that always returns a 200 status code for the path used by health check (insert the custom middleware before django.middleware.security.SecurityMiddleware in MIDDLEWARE to avoid Invalid HTTP_HOST header error).

How to handle SSL certificates for implementing WhiteLabel option in a web app running on NGINX server

I'm working on a Web App.
My app runs on the subdomain app.mydomain.com
I need to WhiteLabel my app. I'm asking my Customers to point to their own website via CNAME to my app.
design.customerwebsite.com points to app.mydomain.com
Here is what I have tried to solve this.
I created a new file in /etc/nginx/sites-available named customerwebsite.com
Added a symlink to the file.
I installed SSL using certbot with the below command.
sudo certbot --nginx -n --redirect -d design.customerwebsite.com
Here is the code for my NGINX conf file of customerwebsite.com
server
{
server_name www.customerwebsite.com;
return 301 $scheme://customerwebsite.com$request_uri;
}
server {
# proxy_hide_header X-Frame-Options;
listen 80;
listen 443;
server_name design.customerwebsite.com;
ssl_certificate /etc/letsencrypt/live/design.customerwebsite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/design.customerwebsite.com/privkey.pem;
root /opt/bitnami/apps/myapp/dist;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_hide_header X-Frame-Options;
proxy_pass http://localhost:3000;
}
proxy_set_header X-Forwarded-Proto $scheme;
if ( $http_x_forwarded_proto != 'https' )
{
return 301 https://$host$request_uri;
}
}
I'm successfully able to run my web app on https://design.customerwebsite.com
But the SSL certificate shows that it is pointed to app.mydomain.com and shows insecure.
My app.mydomain.com has SSL certificate from Amazon ACM which is attached via Load Balancer.
What should be the approach to solve this?
There are two solutions for this
1- add the ssl certs to the loadbalance: You need to request a cert with all the supported DNS names (app.mydomain.com and design.customerwebsite.com)/ and you need to manage customerwebsite.com domain with Route53. I think that is not possible in your case.
2- Do not use ssl on the load balancer: for this option, we will not terminate ssl on the load balancer, however, it will be passed to nginx to handle. Your loadbalancer configs should look like
you need to generate a new ssl cert that includes both domains
sudo certbot --nginx -n --redirect -d app.mydomain.com -d *.mydomain.com -d design.customerwebsite.com -d *.customerwebsite.com
Nginx configs
server
{
server_name www.customerwebsite.com;
return 301 $scheme://customerwebsite.com$request_uri;
}
server {
listen 80 default_server;
server_name design.customerwebsite.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl default_server;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_certificate /etc/letsencrypt/live/design.customerwebsite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/design.customerwebsite.com/privkey.pem;
server_name design.customerwebsite.com;
root /opt/bitnami/apps/myapp/dist;
location / {
resolver 127.0.0.11 ipv6=off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https
proxy_set_header X-Real-IP $remote_addr;
proxy_hide_header X-Frame-Options;
proxy_pass http://localhost:3000;
}
}
I think that the elements provided to the ACM Load Balancer must match every domain on which you may receive requests. In the certificate, you should have a Subject Alternate Name containing every matching domain.
For example on stackoverflow.com, the certificate has a CN *.stackexchange.com but has that Subject Alternative Name :
DNS:*.askubuntu.com, DNS:*.blogoverflow.com, DNS:*.mathoverflow.net, DNS:*.meta.stackexchange.com, DNS:*.meta.stackoverflow.com, DNS:*.serverfault.com, DNS:*.sstatic.net, DNS:*.stackexchange.com, DNS:*.stackoverflow.com, DNS:*.stackoverflow.email, DNS:*.superuser.com, DNS:askubuntu.com, DNS:blogoverflow.com, DNS:mathoverflow.net, DNS:openid.stackauth.com, DNS:serverfault.com, DNS:sstatic.net, DNS:stackapps.com, DNS:stackauth.com, DNS:stackexchange.com, DNS:stackoverflow.blog, DNS:stackoverflow.com, DNS:stackoverflow.email, DNS:stacksnippets.net, DNS:superuser.com
you're forgetting some details ...
you have to do a configuration for the domain
/////// app.myDominio.com ////////
just as you did for the normal domain and also create SSL only for this domain. You can use the let script.
Configure a path for the NGINX LOG so you can check for errors that NGINX detects.
You can also use it in the NGINX settings
* .domain.com
(where * means app, maybe it detects)

Api Gateway connection with Elastic Beanstalk (client-side SSL Certificate)

I'm trying to connect Api Gateway with my api in Elastic Beanstalk. I want my api only accesible by Api Gateway and for this I use client-side SSL certificate authorization in backend (like this aws publication Link:http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/getting-started-client-side-ssl-authentication.html). So my arquitecture is like this:
API GATEWAY->ELASTIC LOAD BALANCER->EC2 (ELASTIC BEANSTALK)
My EC2 machine have NGINX and Ruby.
The connections work like this:
API GATEWAY -> (80 PORT) -> ELASTIC LOAD BALANCER -> (443 PORT) -> NGINX -> RUBY
I am doing the client auth in NGINX.
When I access the Elastic Load Balancer using a browser, it shows 400 Bad Request - NGINX error: No required SSL certificate was sent (this is correct because I'm not sending the certificate). But when I access using Api Gateway and sending the client certificate I get the same error (I don't understand why).
When I configure the SSL connection in NGINX, I'm using SSL certificates signed by me (maybe this is the problem?)
Other posible cause for my problem is the port configuration in Elastic Load Balancer (in the picture). I have Backend Authentication: Disabled. Is this a problem?
Pictura Port Config ELB
My nginx configuration is:
upstream my_app {
server unix:///var/run/puma/my_app.sock;
}
log_format healthd '$msec"$uri"'
'$status"$request_time"$upstream_response_time"'
'$http_x_forwarded_for';
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name localhost;
root /usr/share/nginx/html;
ssl on;
ssl_certificate /etc/nginx/ssl/dev.crt;
ssl_certificate_key /etc/nginx/ssl/dev.key;
ssl_trusted_certificate /etc/nginx/ssl/api-gateway.pem;
ssl_client_certificate /etc/nginx/ssl/api-gateway.pem;
ssl_verify_client on;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
ssl_prefer_server_ciphers on;
if ($ssl_client_verify = FAILED) {
return 495;
}
if ($ssl_client_verify = NONE) {
return 402;
}
if ($ssl_client_verify != SUCCESS) {
return 403;
}
try_files $uri/index.html $uri #my_app;
location #my_app {
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 X-Forwarded-Host $server_name;
proxy_set_header Client-IP $remote_addr;
proxy_pass http://my_app;
proxy_set_header X-Client-Verify $ssl_client_verify;
}
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
proxy_pass http://my_app; # match the name of upstream directive which is defined above
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header gonzalo1 $ssl_client_verify;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
Amazon API Gateway does not support self-signed certificates for integration endpoints. Have you tried using a certificate from Amazon Certificate Manager or Let's Encrypt?