how to configure dynamic Virtual host with dynamic SSL configuration in nginx? - dynamic

Is it possible to configure dynamic SSL certificate path in nginx same as like dynamic virtual host.
ssl_certificate and ssl_certificate_key are not accepting the variables in nginx.
Thanks

Unfortunately, it's not possible because nginx needs to load the whole SSL server configuration at start time.
Source: https://t37.net/the-good-the-bad-and-the-ugly-of-virtual-hosting-with-nginx.html

Since Nginx version 1.15.9 variables are supported in "ssl_certificate" and "ssl_certificate_key" directives.

You can load them dynamically by using lua.
You need to figure out how you want to map and fetch them though.
Here is an example of loading them from a database:
https://github.com/Vestorly/nginx-dynamic-ssl/blob/master/conf/nginx.conf

You can refer shared video to make it happen.
Here you can pass dynamic variable with ssl param in nginx.conf.
https://www.youtube.com/watch?v=aeLE988jmlo
Variable is $ssl_server_name.
Store your SSL certificate with name of domain name.
ex. example.com.cert

Related

nginx configure wildcard domains with different certificates

In my little virtual-hosts config with nginx I encountered a new problem.
I tried to setup a "webmail" subdomain for every one of my virtual hosts using a server_name wildcard
server_name ~^(webmail\.)?(?<domain>.+)$;
as all my domains have their own ssl-certificate I would like to use the right one for the webmail-subdomains too. The certificates are configured as wildcard-certs as in *.domain1.com etc.
So webmail.domain1.com should use the cert for *.domain1.com whereas webmail.domain2.net should use the *.domain2.net cert.
I tried the following as a first guess but could not start nginx because it does not accept the variable in the path:
ssl_certificate /etc/letsencrypt/live/$domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$domain/privkey.pem;
Is there a way to achieve this configuration with a single config-file covering all webmail.* subdomains?
Yes, but not the way you are hoping...
The problem you have is that nginx needs to terminate the SSL before it can read the stream content to get the Host header to set the server_name to decide which certificate and key are needed to terminate the SSL. That's why variables and maps will never work, because they can't yet exist at the point when nginx needs to read the certificate.
(I believe there are Lua functions in OpenResty that deal with certificate handling, but I think this is more about certificate life-cycles rather than choosing one on-the-fly per request which is what you want.)
The way to achieve this is to script your conf generation, using perl, python, bash, whatever you're comfortable with. Describe a common server block template that only needs to be given the domain name, and generate a copy of that for each domain. They can be all in one file, or included from separate files, whatever works for you.
Tip: If you name a conf file with a dot prefix, like .server-tpl.conf, then it will be ignored by the usual include conf.d/*.conf. That way, you can keep this template together with your other conf files, but only the populated copy(s) will be loaded.

SSL for pointed domains

I have an app that is "multi-domain", Other domain just have to point to the IP address to run on my app on the web-server.
Using letsencrypt, I have also generated SSL for those pointed domain using "HTTP" challenges.
Now, my problem is - how do I tell my webserver to read that generated SSL files for the pointed domain.
They are not hosted on my server with config settings. They are just pointed with the IP address to my App and My app renders the content based on a domain name.
I am using VestaCP to manage server, domain, and email
Pointed domains have no config file on my server. They work on the web-application level.
How do I set https for that pointed domain? On a note, I already have valid SSL files - just not sure, where to post or point them, since there is no config.
Can they be kept using "htaccess" or at a web-application level?
E.g, My app runs at "http://example.com" and shows content for example.com, and for the second domain that is pointed to my server "http://anotherExample.com" - my app shows the content for "anotherExample.com" and so on and so forth. "example.com" is hosted on my server with Nginx and apache config, so SSL is set. But anotherExample.com is not hosted on server level but only at the app level - now, where do I set SSL for it? I have already successfully generated SSL using letsencrypt with HTTP challenge.
Update: I run a platform like Blogspot.com Multi-Domain blogs - How to serve SSL for pointed domain?
Thanks
I don't think what you want is directly possible. From your question, I think you are creating multiple A records which points to your application IP address, from which your application decides what data to serve.
So what you have to do is to get SSL certificate for each and every domain you want to serve. Then configure the web server to send the corresponding certificate. This can be done easily with most web servers. Eg: On nginx
server {
listen *:443 ssl;
server_name domain1.com;
ssl_certificate /path/to/domain1.crt;
ssl_certificate_key /path/to/domain1.key;
...
}
server {
listen *:443 ssl;
server_name domain2.com;
ssl_certificate /path/to/domain2.crt;
ssl_certificate_key /path/to/domain2.key;
...
}
Incase you are serving on different subdomains like domain1.example.com and domain2.example.com, then you could get a wildcard certificate which will do the trick.

How to let nginx do SSL pass-through for multiple virtual hosts?

I have multiple local https servers running on different ports with their own certificate. Now, I would like to use nginx to make these https servers available under different host names, port 443 and ssl secured.
My current configuration per hostname looks like
server {
listen 443 ssl;
server_name hostname1;
ssl_certificate /etc/nginx/hostname1.cert.pem;
ssl_certificate_key /etc/nginx/hostname1.privkey.pem;
location / {
proxy_pass ...
}
}
But using the listen 443 ssl; directive forces me to specify certificate and key. Instead, I would like to simply pass-through that traffic from my servers, so I do not have to maintain a second level of certificates in nginx and my local environment comes closer to the production environment.
For targeting a single server, F.X. offers a solution with streams in SSL Pass-Through in Nginx Reverse proxy?
However, as he/her points out, as it simply forwards TCP, there is no way to peek into the hostname and make it work for multiple servers.
Are there any other ways?
Is there some fundamental limitation that this cannot work?
The magic concept here is Server Name Indication, a TSL extensions which adds the host name desired by the client in the TSL Client Hello and allows the server to map the connection to one of multiple virtual hosts.
It turns out that the answer by F.X. was outdated and Dave T. has a solution
using two newer nginx modules, ngx_stream_ssl_preread and ngx_stream_map. See his answer on this network for details.

Tomcat hosting multiple virtual host with single SSL certificate

I have a server hosting multiple web applications using Tomcat 8.0, each one in their virtual host, for example
Virtual Host "a.example.com" points to https://example.com/a
Virtual Host "b.example.com" points to https://example.com/b
My question is that, is there a way I could setup my multiple virtual hosts to use my single SSL certificate? Do i need tomcat SNI support for that?
In order to connect to a.example.com, you'll need a valid certificate for a.example.com. Same for any connection to b.example.com - and as I assume that SNI is ubiquituous by now, I don't know if the answer "yes" would require you to do something different than "no".
In the very special case that you use in your question, you can also work with wildcard certificates for *.example.com - ideally with an alternative name for example.com. It depends on the certification authority that you intend to use if it's available and how much you'll have to pay for it. Of course, if this was only an example, and the actual domain names are more diverse, it's no longer an option.
Just assume you need SNI - there's no problem using it.

Need a Kubernetes 1.2 Ingress bare metal controller with SSL tutorial

The closest tutorial I can find in getting an SSL terminating Ingress and an nginx based controller running on bare metal (Digital Ocean, for example) is this:
https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx
but it leaves so many assumptions unexplained.
My ingress requirements are simply:
default backend at port 80 for all hosts that:
file access to location ^~ /.well-known/acme-challenge/ which allows my LetsEncrypt cert renewals to work
404 on location /.well-known/acme-challenge/
301 on location /
subdomain based routing to different backend services on port 443
each subdomain points to a different SSL key/cert (generated by my LetsEncrypt, and stored in K8S as a secret I suppose??)
What I think need is this:
full documentation on writing Ingress rules
can I configure SSL certs (on port 443) for each backend individually?
is / the "path" that's a catchall for a host?
updating Ingress rules in place
what nginx controller do I use? nginx? nginx-alpha? nginx-ingress docker container -- and where is the documentation for each of these controllers?
is there a base controller image that I can override the nginx.conf template that gets populated by Ingress changes from the API server?
how do you store SSL keys and certs as secrets?
boo my answers apply to https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx
default backend at port 80 for all hosts that:
404 on location /.well-known/acme-challenge/
this is not possible using Ingress rules
301 on location /
This is already supported. If the server contains a SSL certificate it will redirect to httpsautomatically
subdomain based routing to different backend services on port 443
each subdomain points to a different SSL key/cert (generated by my LetsEncrypt, and stored in K8S as a secret I suppose??)
You need to create multiple Ingress rules, one per subdomain. Each rule can use a different secret name (this will create multiple servers, one per subdomain)
What I think need is this:
full documentation on writing Ingress rules
http://kubernetes.io/docs/user-guide/ingress/
(I don't know id there's additional information besides the go code)
can I configure SSL certs (on port 443) for each backend individually?
is / the "path" that's a catchall for a host?
yes
updating Ingress rules in place
what nginx controller do I use? nginx? nginx-alpha? nginx-ingress docker container -- and where is the documentation for each of these controllers?
This depends on what you need, if you want to build you custom Ingress controller you can use nginx-alpha as reference. If nginx-ingress is not clear in the examples please open an issue and mention what could be improved in the examples or it's missing
is there a base controller image that I can override the nginx.conf template that gets populated by Ingress changes from the API server?
No. The reason for this is that the template is tied to the go code that populates the template. That said, you can build a custom image changing the template but this requires you deploy the image to tests the changes
how do you store SSL keys and certs as secrets?
yes, as secrets like this http://kubernetes.io/docs/user-guide/ingress/#tls
For the letsencrypt support please check this comment https://github.com/kubernetes/kubernetes/issues/19899#issuecomment-184059009
Here is a complete example https://gist.github.com/aledbf/d88c7f7d0b8d4d032035b14ab0965e26 added to examples in #766