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

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)

Related

How to host api documentation(abc.com/docs) on docs.abc.com on django+gunicorn+nginx setup

We have Django rest API deployed using Nginx through reverse proxy.
Sample config:
location / {
proxy_set_header Host $host;
include proxy_params;
proxy_pass http://unix:/run/websitebackend.sock;
}
listen 443 ssl http2; # managed by Certbot
ssl_certificate /etc/ssl/private/chain.crt;
ssl_certificate_key /etc/ssl/private/private.key;
}
Now our API documentation(genereted using redoc) is on api.abc.com/docs, which we want to server on subdomain docs.abc.com.
How can I achieve this?
Thanks in advance!

How to redirect HTTP to HTTPS on Elastic Beanstalk Single Instance Environment

I have a Spring Boot web application deployed in Elastic Beanstalk single instance environment using Amazon Linux 2. I have configured SSL in the NGNIX as per the documentation and all HTTPS request are working fine.
However the HTTP requests are not redirected to HTTPS.
Below is my conf file located at \PROJECT_ROOT\.platform\nginx\conf.d\https.conf
# HTTP server
server {
listen 80;
return 301 https://example.com$request_uri;
}
# HTTPS server
server {
listen 443 ssl;
ssl_certificate /etc/pki/tls/certs/server.crt;
ssl_certificate_key /etc/pki/tls/certs/server.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:5000;
proxy_set_header Connection "";
proxy_http_version 1.1;
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-Proto https;
}
}
I have created an A record to map example.com to EB environment URL.
However, when I try to hit http://example.com it simply loads the homepage over HTTP rather then redirecting to HTTPS.
Can someone please help me with this ?

Why does the query service in my Wikibase installed through Docker not contain content added to the main wikibase store?

We've installed wikibase-docker with an Apache server in front of it to handle SSL and proxy two vhosts to the ports from Docker.
api.example.com (to http://127.0.0.1:8181)
query.example.com (to http://127.0.01:8282/)
In the log from the wdqs-updater I see:
org.wikidata.query.rdf.tool.rdf.Munger$BadSubjectException: Unrecognized subjects: [https://api.example.com/entity/statement/Q12-caba1d44-46d5-8598-9185-784a75e4cebb, https://api.example.com/entity/statement/Q12-4c77991e-4674-5301-75f1-5b494612b56b, https://api.example.com/wiki/Special:EntityData/Q12, https://api.example.com/entity/Q12].
Expected only sitelinks and subjects starting with http://wikibase.svc/wiki/Special:EntityData/ and [http://wikibase.svc/entity/]
The 'wikibase.svc' name is used in the docker-compose.yml file and is the internal docker name.
To get the MediaWiki search working I had to update ${DOLLAR}wgServer = WebRequest::detectServer() in LocalSettings.php.template to have the value "https://api.example.com"
What do I need to change to make it work? All references to wikibase.svc in the docker-compose.yml file? Or something else?
I already tried updating WIKIBASE_HOST= for the wdqs-updater container, but that didn't seem to help.
In docker-compose you have a list of variables that work perfectly on a localhost. When you need to deploy it in production you need to change few variables to define the public hostname, Ip and SSL. I did setup a nginx setup to manage the hostname and SSL certificate.
In my setup I have 1 hostname per service, my Nginx that forward the request to the right port number all the wikibase on the same machine.
My query service setting for nginx add the ssl certificate and forward to the port 8282 the request sent to https://query.example.com
On my production machine I "just" need to replaxe example.com by personaldata.io.
server {
listen 80;
server_name query.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443;
server_name query.example.com;
ssl on;
ssl_certificate /etc/letsencrypt/live/query.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/query.example.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
access_log /var/log/nginx/query.example.com.log;
location / {
proxy_pass http://127.0.0.1:8282;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-forwarded-host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
The variables I had to change on my setup:
QS_PUBLIC_SCHEME_HOST_AND_PORT=https://qs.example.com:443 # Public domain name and port
WIKIBASE_SCHEME=https
WIKIBASE_HOST=wiki.example.com
QS_PUBLIC_SCHEME_HOST_AND_PORT=https://qs.example.com:443
WB_PUBLIC_SCHEME_HOST_AND_PORT=https://wiki.example.com:443
WIKIBASE_SCHEME_AND_HOST=https://wiki.example.com

Adding SSL to the Django app, Ubuntu 16+, DigitalOcean

I am trying to add my SSL certificate to my django application according to this tutorial. I can turn on my website using 'https://ebluedesign.online'. But web browsers return something in style 'The certificate can not be verified due to a trusted certificate authority.' After accepting the messages, my page is displayed correctly.
My nginx file looks like this:
upstream app_server {
server unix:/home/app/run/gunicorn.sock fail_timeout=0;
}
server {
#listen 80;
# add here the ip address of your server
# or a domain pointing to that ip (like example.com or www.example.com)
server_name ebluedesign.online;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/ebluedesign.online/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/ebluedesign.online/privkey.pem;
keepalive_timeout 5;
client_max_body_size 4G;
access_log /home/app/logs/nginx-access.log;
error_log /home/app/logs/nginx-error.log;
location /static/ {
alias /home/app/static/;
}
# checks for static file, if not found proxy to app
location / {
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}
server {
listen 80;
listen [::]:80;
server_name ebluedesign.online;
return 301 https://$host$request_uri;
}
My certificates are also visible here:
/etc/letsencrypt/live/ebluedesign.online/...
How can I solve this problem with SSL certificate. I use free SSL by https://letsencrypt.org/.
EDIT:
What is odd is if you go to http://bluedesign.online/ it works fine even though your file makes it seem as if port 80 isn’t listened too at all. Do you happen to have two setup files in nginx? It is possible that the one you posted is not being used.
I’ve followed this tutorial many times with success. You could try using it from scratch if you have the opportunity: https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04

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?