I need to add SSL to several Node.js services, each of one is listening on its own port, and that have NGINX to map them to our public "api" domain.
Due to the release of a new security policy now all services must be enforced to only work on SSL connections.
Since I'm not used to work with SSL certificates it's not clear to me what can be the advantage of setting the SSL on NGINX and make NGINX itself to proxy-pass to a http:// connection or have the real node.js endpoint to be a SSL server and (then proxy-pass to https://).
I guess with the NGINX solution, I could re-use the same SSL cert adding it to our "api" domain, while each different SSL node server would need a different cert.
Then it's not clear to me if into a production environment like this I should be using self-signed certificates (since the endpoint is touched through other services) or if it should be a CA trusted certificate exactly like it should be a public domain.
What am I missing in this considerations?
I assume the NGINX is public facing, and the nodejs services are internal (ie. not accessed directly by public web users).
You would only secure the connection between the public web to your NGINX. The transport between the NGINX and the NodeJS services is internal, and doesn't need to be secured. it's a big waste of CPU.
For the NGINX you buy a certificate from a valid certificate authority. For internal services you may use self-signed (ie. your own internal certificate authority generated certificates), but as said above, you shouldn't need to use SSL internally.
Related
I'm creating a simple website. The frontend is stored in S3, and hosted by Cloudfront. I managed to add a trusted SSL certificate to my frontend domain (www.xyz.com) using AWS Certificate Manager.
The backend is running on an EC2 instance. I added a self-signed certificate to it. I'm able to hit the APIs using Postman but the requests from frontend are failing because of the self-signed certificate.
I checked the AWS Certificate Manager again if it could provide me with a cert for my backend server, but it requires a domain. My server is running on an IP and port, and I couldn't find any service that provides a certificate for an IP. I don't want to spend extra money to get a domain for my backend.
So how do I get a trusted SSL certificate for a backend server, running on something like 10.12.12.10:9000?
couldn't find any service that provides a certificate for an IP.
This is because you need domain to obtain valid public certificate. You can't register SSL cert for an IP. But if you already have your own domain www.xyz.com, you can get a certificate for its subdomain, e.g. api.xyz.com.
However, ACM certs can't be used on instances. Thus, you need to get a valid public SSL cert from a third party. A popular choice is https://letsencrypt.org/ with certbot which provides free SSL certificates. By the way, StackOverlow is using letsencrypt for its SSL cert provider, thus its widely used and trusted ssl provider.
I am building a C++ application that needs secure connection to an SSL enabled server. I have read that for HTTPs to be fully secure, it requires the client to also use a valid certificate. But for my application, the certificate would be on disk so anyone installing the app would have access to the file. I came to the conclusion that the SSL certificate is not necessary for the application.
Am I right? Does an attacker could, somewhat, intrude into my SSL server?
Thanks a lot!
Secure HTTPs connection
When connecting to a TLS (nowadays)-enabled server, it's the server certificate that is mostly relevant (although some servers request a specific certificate from the client for authentication, but that's rare since a cert isn't as easily managed as a username+password).
That means that you don't need to have a trusted certificate, since one is generated (self signed) at runtime when neeeded as part of the TLS handshake.
The same happens in some TLS-enabled services outside WWW, for example, a SMTP TLS server's certificate is practically never checked against a trusted root.
Now If you are programming a WWW server application, yes you need a trusted cert. Check Let's Encrypt.
My plan is to add HTTPS and SSL to EC2. What I have a problem is that I have my own domain, websites and SSL certificate all on different hosting like Lunarpages. Is there a possible for me to allow my domain like this https://www.example.com/apps/project3/api to connect to EC2 from Lunarpages even though I have already SSL certificate installed on Lunarpages hosting. So I don't need to create SSL certificate on EC2. I don't want to move my websites with www.example.com to EC2, it should remain with Lunarpages hosting.
Is there an option I can connect from my https://www.example.com/apps/project3/api (not subdomain) and SSL certificate from other hosting to EC2?
TL;DR
Use Lunarpages as a reverse proxy.
About DNS
DNS can not manage "subfolders" (URI). When the user is typing your URL in your website (or when you make a request to your API), the web browser will do a DNS resolution of the domain. Therefore, it will connect to www.example.com and then search for /apps/project3/api. It means it is not possible to have www.example.com/a on one server and www.example.com/b on an other one by using a DNS mechanism.
Reverse proxy
To solve this problem, one solution is the reverse proxy. If Lunarpages allows it, you can use their hosting as a proxy to your EC2. Every request of www.example.com will be processed on Lunarpages. Only the requests of /apps/project3/api/* will be proxied to EC2. Lunarpages will do the SSL termination and then proxy the request to EC2.
Drawbacks
As you can imagine, having the request going to Lunarpages then to the EC2 and finally going back to the client throught Lunarpages can have a big impact on performance and response time.
The security is also important because the communication between Lunarpages and the EC2 should be encrypted. It means another SSL certificate (self signed) should be present on the EC2.
Other solutions
I strongly recommand to use the same hosting provider for the same domain name even if there is multiple servers to process the requests. Tree solutions comes to mind:
Host everything on Lunarpages
Host everything on AWS (reconsider this option)
Use a different subdomain for the API (api.example.com) that will point to the EC2 and manage the SSL certificate of api.example.com on this EC2.
I have set up a basic API using AWS API Gateway and I would like to link my endpoints to a service I have running on an EC2 instance (using the "HTTP Proxy" integration type). I have read that in order to lock down my EC2 server from only accepting traffic from the API Gateway, I basically have one of two options:
Stick the EC2 instance behind VPC and use Lambda functions (instead of HTTP proxy) that have VPC permissions to act as a "pass through" for the API requests
Create a Client Certificate within API Gateway, make my backend requests using that cert, and verify the cert on the EC2 instance.
I would like to employ a variation of #2 and instead of verifying the cert on the EC2 service instance itself, I would like to instead do that verification on another instance running Haproxy. I have set up a second EC2 instance with Haproxy and have that pointed at my other instance as the backend. I have locked down my service instance so it will only take requests from the Haproxy instance. That is all working. What I have been struggling to figure out is how to verify the AWS Gateway Client Certificate (that I have generated) on the Haproxy machine. I have done tons of googling and there is surprisingly zero information on how to do this exact thing. A couple questions:
Everything I have read seems to suggest that I need to generate SSL server certs on my Haproxy machine and use those in the config. Do I have to do this, or can I verify the AWS client cert without generating any additional certs?
The reading I have done suggests I would need to generate a CA and then use that CA to generate both the server and client certs. If I do in fact need to generate server certs (on the Haproxy machine), how can I generate them if I don't have access to the CA that amazon used to create the gateway client cert? I only have access to the client cert itself, from what I can tell.
Any help here?
SOLUTION UPDATE
First, I had to upgrade my version of HAproxy to v1.5.14 so I could get the SSL capabilities
I originally attempted to generate an official cert with letsencrypt. While I was able to get the API gateway working with this cert, I was not able to generate a letsencrypt cert on the HAproxy machine that the API gateway would accept. The issue surfaced as an "Internal server error" response from the API gateway and as "General SSLEngine problem" in the detailed CloudWatch logs.
I then purchased a wildcard certificate from Gandi, and tried this on the HAproxy machine, but initially ran into the exact same problem. However, I was able to determine that the structure of my SSL cert was not what the API gateway wanted. I googled and found the Gandi chain here:
https://www.gandi.net/static/CAs/GandiStandardSSLCA2.pem
Then I structured my SSL file as follows:
-----BEGIN PRIVATE KEY-----
# private key I generated locally...
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
# cert from gandi...
-----END CERTIFICATE-----
# two certs from file in the above link
I saved out this new PEM file (as haproxy.pem) and used it in my HAproxy frontend bind statement, like so:
bind :443 ssl crt haproxy.pem verify required ca-file api-gw-cert.pem
The api-gw-cert.pem in the above bind statement is a file that contains a client cert that I generated in the API gateway console. Now, the HAproxy machine properly blocks any traffic coming from anywhere but the gateway.
The reading I have done suggests I would need to generate a CA and then use that CA to generate both the server and client certs.
That's one way to do it, but it is not applicable in this case.
Your HAProxy needs to be configured with a working SSL certificate signed by a trusted CA -- not the one that signed the client certificate, and not one you create. It needs to be a certificate signed by a public, trusted CA whose root certificates are in the trust store of the back-end systems at API Gateway... which should be essentially the same as what your web browser trusts, but may be a subset.
Just as your web browser will not speak SSL to a server sporting a self-signed certificate without throwing a warning that you have to bypass, the back-end of API Gateway won't negotiate with an untrusted certificate (and there's no bypass).
Suffice it to say, you need to get API Gateway talking to your HAProxy over TLS before trying to get it to use a client cert, because otherwise you are introducing too many unknowns. Note also that you can't use an Amazon Certificate Manager cert for this, because those certs only work with CloudFront and ELB, neither of which will support client certs directly.
Once the HAProxy is working with API Gateway, you need then to configure it to authenticate the client.
You need ssl and verify required in your bind statement, but you can't verify an SSL client cert without something to verify it against.
I only have access to the client cert itself, from what I can tell.
And that's all you need.
bind ... ssl ... verify required ca-file /etc/haproxy/api-gw-cert.pem.
SSL certs are essentially a trust hierarchy. The trust at the top of the tree is explicit. Normally, the CA is explicitly trusted and anything it has signed is implicitly trusted. The CA "vouches for" the certificates it signs... and for certificates it signs with the CA attribute set, which can also sign certificates under them, extending that implicit trust.
In this case, though, you simply put the client certificate in as the CA file, and then the client certificate "vouches for"... itself. A client presenting the identical certificate is trusted, and anybody else is disconnected. Having just the certificate is not enough for a client to talk to your proxy, of course -- the client also needs the matching private key, which API Gateway has.
So, consider this two separate requirements. Get API Gateway talking to your proxy over TLS first... and after that, authenticating against the client certificate is actually the easier part.
I think you are mixing up server certs and client certs. In this instance API Gateway is the client, and HAProxy is the server. You want HAProxy to verify the client cert sent by API Gateway. API Gateway will generate the certificate for you, you just need to configure HAProxy to verify that certificate is present in every request it processes.
I'm guessing you might be looking at this tutorial where they are telling you to generate the client cert, and then configure HAProxy to verify that cert. The "generate the cert" part of that tutorial can be skipped since API Gateway is generating the cert for you.
You just need to click the "Generate" button in API Gateway, then copy/paste the contents of the certificate it presents you and save that as a .pem file on the HAProxy server. Now I'm not a big HAProxy user, but I think taking the example from that tutorial your HAProxy config would look something like:
bind 192.168.10.1:443 ssl crt ./server.pem verify required
I need to secure communication between my application and my Web Service.
I own both the application and the Web Service, and I was wondering if it is possible to use HTTPS to do so.
I don't need a certificate to prove to myself who I really am (!), so I don't want to buy an SSL certificate from a Certificate Authority. I just need to make sure no one can intercept the data I pass as WebMethod parameters; Can I create a free certificate and use that to secure communication?
One other thing: I don't want to be forced to get a dedicated, public IP address for my Web Service since it is hosted on a shared Web server.
Definitely it's doable, but hinges on a few conditions.
Create your own self signed certificate. The lack of a certificate authority won't matter in your case because your app is your own consumer.
The host must allow you to configure your IIS site with an SSL cert. Hopefully the tools they provide are good enough.
The shared IP that your web site has currently cannot have more than one certificate bound to it. You're now at the mercy of your host to not move your site to a different IP. It may or may not have an SSL cert on another site at that time. Basically - the first one wins. An IP cannot have more than one cert-secured website.
There are many articles out there showing how to create and install a self signed certificate in IIS. What you need to remember is that this certificate will not be valid as it is not delivered by a certificate authority. Once you set a certificate on the server side you need to indicate to the client to accept the invalid certificate by using the ServerCertificateValidationCallback property:
ServicePointManager.ServerCertificateValidationCallback =
(sender, certificate, chain, sslPolicyErrors) => true;
You can't use a SSL certificate (self signed or otherwise) without a dedicated IP address. Unless your shared hosting provider provides a shared SSL certificate on your IP, you will need to purchase a dedicated IP.
If you want to go through the trouble of doing it, you can use a self-signed certificate and have a tertiary server (or use the IIS server that is self-signing) to be your own certificate authority. This would allow you to generate your own certificate for free, then since you have control over the servers, you could just add your CA server as a trusted and intermediary root certificate authority.
Creating Certificate Authorities and self-signed SSL certificates