SSL on Elastic Beanstalk with multiple instances (EC2) - ssl

I would like to add Server Certificate to EC2 instances (with NGINX) running in Elastic Beanstalk. And I have a some doubts if it is possible...
My motivation:
I want to validate Client Certificates via NGINX on EC2 instances, which are running behind the Elastic Load Balancer. Client Certificate comes from AWS API Gateway and I want to use verification to restrict access to my Elastic Beanstalk (EB).
As I've tested (however I might be wrong here), NGINX needs to have Server Certificate to validate Client Certificate:
listen 443 ssl;
ssl_certificate xxx;
ssl_certificate_key xxx;
ssl_client_certificate yyy;
ssl_verify_client on;
Questions
Is the server certificate generated for specific domain, subdomain or wildcard subdomains?
Is it possible to use the same server certificate on many instances with private IPs behind Load Balancer? (They are not directly bind to domain)
Or maybe is it possible to verify client certificate without SSL on nginx? like in the following NGINX config snippet:
listen 443;
ssl_client_certificate yyy;
ssl_verify_client on;

Related

Nginx NET::ERR_CERT_COMMON_NAME_INVALID

I'm trying to enable ssl certificates for my web app deployed on DigitalOcean but when I'm accessing the droplet ip I'm getting this error:
NET::ERR_CERT_COMMON_NAME_INVALID
This server could not prove that it is droplet-ip-address; its security certificate is from *.domain.com. This may be caused by a misconfiguration or an attacker intercepting your connection.
This is my nginx configuration:
server {
# SSL configuration
#
listen 443 ssl;
server_name sub.domain.com;
ssl_certificate /etc/nginx/ssl/star-op/__company_com.ca-chain.cert.pem
ssl_certificate_key /etc/nginx/ssl/star-op/__company_com.key;
}
At this moment I don't have any DNS record from sub.domain.com that points to my ip address... can this be the cause of that error?
Without a DNS entry, you are doing something like https://x.x.x.x which nginx associating with https://sub.domain.com most likely as it is the only server block in nginx at this time.
But https://x.x.x.x does not match the cert for https://sub.domain.com so your are getting a mismatch. If you are just testing you could add a host file entry for testing which should get you past this issue. Afterward, you would need to add a DNS entry to your public DNS server for the rest of the world to not have this issue.

Domain without ssl certificate redirecting to different ssl domain

I have two domains set up on a Digital Ocean droplet (with nginx). I've installed a SSL certificate in one of them (domain1) and everything is fine with that one. The second domain (domain2), does not require a SSL certificate but if I try to access https://domain2 is showing me the content of domain1 and giving me a certificate error (This page is not secure).
I understand the certificate error, but I don't want the contents of domain1 being displayed in https://domain2
Is it a configuration problem?
nginx always has a default server, the one that is used if the server_name does not match. If you only have one server block with listen 443, then that is the implicit default server for all https connections irrespective of server name.
You will need to set up an explicit catch-all server for https connections, or add listen 443 ssl to an existing server block to act as the catch-all server.
You can reuse the same certificate file and you will continue to get certificate errors if anyone attempts to use it, but at least your other domains will not be exposed.
For example:
ssl_certificate /path/to/crt;
ssl_certificate_key /path/to/key;
server {
listen 443 ssl;
server_name domain1;
...
}
server {
listen 443 ssl default_server;
return 403;
}
See this document and this document for more.

Disable SSL in cloudflare and using in server side (Ubuntu and Nginx)

I currently use Cloudflare as a CDN and DNS manager and until recently I used the shared and universal SSL that it has for free but, due to needs, I hired an EV SSL. Through the cloudflare panel I can not, for free, insert a custom certificate (only starting at $ 200). I use nginx on my server running with Ubuntu and I have all the settings ready to use my EV SSL that has already been inserted into the server but, by disabling SSL in the cloudflare and keeping the settings in Nginx, I get the ERR_TOO_MANY_REDIRECTS error return. PS: I have currently configured a page rule in Cloudflare to always use HTTPS in requests for this domain.
Below is my nginx configuration and I would like to know if it would be possible to confirm server side SSL, without inserting the certificate in Cloudflare, continuing with the free plan that it has available to me and using my EV SSL.
server{
listen 443;
root /var/www/redeestrela.com.br;
server_name www.redeestrela.com.br;
ssl on;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
ssl_certificate /etc/nginx/ssl/redeestrela.crt;
ssl_certificate_key /etc/nginx/ssl/redeestrela.key;
error_log /var/log/nginx/redeestrela.error.log;
include global/php.conf;
include global/wordpress.conf;
include global/restrictions.conf;
}
server{
listen 443;
server_name redeestrela.com.br;
return 301 https://www.redeestrela.com.br$request_uri;
}
In order to serve an EV SSL certificate from Cloudflare, you would need to upload that certificate as a custom SSL certificate. This is a Business and Enterprise only Cloudflare feature, however is fairly straight-forward to do.
How do I upload a custom SSL certificate? (Business or Enterprise only)
In the future, we're hoping to have EV SSL certs as an add-on at any plan-level. Meaning we acquire, manage and renew the certificate for you. Feel free to email supportATcloudflareDOTcom if you'd be interested in trying the beta when available.

How to put ssl directives in server block instead of http block in nginx configuration?

I am about to use different ssl certificates for different virtual hosts, so I started by moving the existing ssl directives from the http block into one of the server blocks, before I start to add other ssl certificate directives into other server blocks. But as soon as I did this, the web server involved cannot be accessed anymore. Chrome reported connection closed and Nginx's error log read like this:
2016/01/08 20:13:32 [error] 16968#0: *364 no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking, client: x.x.x.x, server: 0.0.0.0:443
The ssl directives I moved include:
ssl_certificate
ssl_certificate_key
ssl_protocols
ssl_dhparam
ssl_prefer_server_ciphers
ssl_ciphers
What could possibly go wrong when moving these directives from http block to server block?
Make sure you haven't a global server configured to listen to 443.
Because you moved the ssl_certificate and ssl_certificate_key within a specific virtual host, that means the default configuration is missing the certificate and key. This is not allowed by Nginx. Each virtual host that is configured to listen on 443, regardless it's the default or not, must be configured to serve a certificate.
The default_server should only be processed when other virtual host listening on 443 is not selected, so why lacking ssl certificates on the default_server could impact access to other virtual hosts?
That's the point. Nginx reject the configuration because, if this scenario should happen, it would not be able to process the request because of the lacking of the ssl_certificate. Therefore, the configuration is invalid.

Nginx serving SSL certificate of another site

I'm serving two sites with Nginx. First site (say A) has a SSL certificate and second site (say B) doesn't. Site A works fine when opening on https and B on http. But when I access site B on https, nginx serves the SSL cert and contents of site A with domain of B, which shouldn't happen.
Nginx config for site A is as follows. For site B, it's just a reverse proxy to a Flask app.
server {
listen 80;
server_name siteA.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name siteA.com;
ssl_certificate /path/to/cert.cert
ssl_certificate_key /path/to/cert_key.key;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:RC4-SHA:AES256-GCM-SHA384:AES256-SHA256:CAMELLIA256-SHA:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
keepalive_timeout 70;
# and then the `location /` serving static files
}
I can't figure out what is wrong here.
Apparently I need a dedicated IP for site A.
Quoting from What exactly does "every SSL certificate requires a dedicated IP" mean?
When securing some connection with TLS, you usually use the certificate to authenticate the server (and sometimes the client). There's one server per IP/Port, so usually there's no problem for the server to choose what certificate to use. HTTPS is the exception -- several different domain names can refer to one IP and the client (usually a browser) connects to the same server for different domain names. The domain name is passed to the server in the request, which goes after TLS handshake. Here's where the problem arises - the web server doesn't know which certificate to present. To address this a new extension has been added to TLS, named SNI (Server Name Indication). However, not all clients support it. So in general it's a good idea to have a dedicated server per IP/Port per domain. In other words, each domain, to which the client can connect using HTTPS, should have its own IP address (or different port, but that's not usual).
Nginx was listening on port 443 and when request for site B went on https, the TLS handshake took place and the certificate of site A was presented before serving the content.
The ssl_certificate parameter should be closed with ; to get expected output.
Also make sure that you have followed the correct syntax in all the config file parameters by using following command and then restart or reload the service:
sudo nginx -t
NGINX supports SNI, so it's possible to serve different domains with different certificates from the same IP address. This can be done with multiple server blocks. NGINX has documented this in
http://nginx.org/en/docs/http/configuring_https_servers.html
For me HTTP2 and IPv6 are important, so I to listen to [::] and set ipv6only=off. Apparently this option should only be set for the first server block, otherwise NGINX will not start.
duplicate listen options for [::]:443
These server blocks
server {
listen [::]:443 ssl http2 ipv6only=off;
server_name siteA.com www.siteA.com;
ssl_certificate /path/to/certA.cert
ssl_certificate_key /path/to/certA_key.key;
}
server {
listen [::]:443 ssl http2;
server_name siteB.com www.siteB.com;
ssl_certificate /path/to/certB.cert
ssl_certificate_key /path/to/certB_key.key;
}
If you host multiple sites in you server and in one Nginx config if you have listen 443 ssl http2 default_server;
The default_server will give the same cert to all domains. removing it will fix the problem.
While following this tutorial I total missed this part:
Note: You may only have one listen directive that includes the default_server modifier for each IP version and port combination. If you have other server blocks enabled for these ports that have default_server set, you must remove the modifier from one of the blocks.