About proxy man-in-middle attack - ssl

I have a website that run under a H2O Proxy, let's call it A server. The backend is WordPress site running with EasyEngine script, let's call it B server.
Now it running like this:
User --(Let's Encrypt SSL)--> A (H2O Proxy) --(self-signed SSL)--> B (nginx backend).
I wonder if attackers know my backend's IP address, so can he decrypt or do harmful thing or see what user send to proxy? And how to setup a better strategy?
I have thought to setup Let's Encrypt SSL from A server to B server too. But I think the problem will occur when Let's Encrypt can only renew certificate on A server because the domain is pointing to A's IP address. And the backend (B server) can't renew it.
Found this answer but I don't really know how to do it: https://serverfault.com/a/735977.

It sounds like what you're trying to do is to put LetsEncrypt into as many places as possible, possibly facing the issues of not having the desired Fully-Qualified-Domain-Name for the applicable backend on the backend itself in order to get the certificate, especially for automated renewal.
But the whole and only purpose of LetsEncrypt is that it gives you certificates that would expectedly be recognised by all the major browsers, such that the users would not have to manually verify and install your certificate into their respective cacert.pem.
But if you just need a secure connection between your own backend and front-end server, then you're not facing the same issue; as such, using LetsEncrypt provides little, if any, extra protections. What you have to do is use something like proxy_ssl_trusted_certificate, together with proxy_ssl_verify, both on the front-end, to pin the backend's certificate and/or certificate authority on the front-end, which will be an order of magnitude more secure (due to the pinning) than using LetsEncrypt on the backend.

Related

Does using a SSL certificate for an API server require a domain?

I'm using a React frontend application on a domain with a valid SSL certificate, which makes calls to a Django backend application on a VPS (Ubuntu 20.04, apache2), which doesn't have a domain name registered (instead the calls are being made using the IP of the server). The server doesn't yet have a valid SSL certificate which prevents the React app from receiving the resources. Self-signed won't work since it's then not valid in the browser (I might be wrong here).
Do I also need to register a domain name for the backend API server for the SSL certificate to be valid or can I just buy an SSL certificate and work from there?
To even get an SSL certificate back from the vendor, you need a fqdn (fully qualified domain name). That information is used to sign and create the certificate request. Your webserver won't even properly encrypt until you have valid signed certificate for the server in question. You can expand the number of hosts that a certificate will serve by buying a wildcard certificate (*.example.com vs specifichost.example.com)
If your back end server is on some cloud or hosted service, you can use self signed certificates but you would have to disable "strictness" in your front end. If you're at any time performing financial transactions this is not advisable.
If you're making axios calls, here's a pretty good article on disabling https strictness (https://github.com/axios/axios/issues/535).
Your vendor for the VPS might have some helpful information on how to harden up the server.
If this is not how you'll be doing this in production and the setup you describe is for testing only, then probably you want to use the environment to set a variable indicating 'strict' or 'test' and switch your calls accordingly. That way, a relaxed setup will work in test or in your sanbox, but production would use a properly configured host with a valid certificate.

How to implement browser-friendly SSL/HTTPS without a domain name?

I have a backend application that creates temporary servers via the Digital Ocean API. There is a browser frontend that needs to send AJAX requests to the servers.
Let's Encrypt isn't an option because they require a domain name, like most SSL certificate providers. I could create my own self-signed certificate, but then the browser would not trust it.
Although I could probably assign a subdomain to each temporary server, it may take some time for the DNS to recognize the assignment.
Is there a solution for secure and browser-accepted communication to my temporary servers?

Do we need ssl certificate for both front end and backend?

We have 2 Rails app (one for front end and other for backend(api) hosted on 2 different servers. User comes to our front end app and fills the order form. We then send json request to backend and backend send confirmation json response to front end. Backend is only accessible from our office address and is setup to communicate to only our front end app.
Today we purchased EV ssl certificate for our front end app from DigiCert and everything is work fine. But since we don't have ssl certificate on backend, does that means that what ever data we are passing from our front end to backend will be unencrypted?
Do we need ssl certificate for both front end and back end servers?
Our backend only servers request to our front end app and no other clients are connect to our backend? So can I use a self-signed or cheap SSL certificate for backend?
Or shall I buy another ssl certificate from DigiCert? (bit expensive)
I have already gone through couple of stack overflow questions, and looks like suggestion is to install ssl in both servers. This is my first time trying to set up ssl certificates on servers, so just want to double check before I buy another ssl certificate for our backend app.
Update
I found few cheap ssl certificate provides, what are people suggestions towards cheaper provider like this one https://cheapsslsecurity.com.au/
SSL only encrypts data between the server and the client.
It does not make a server secure.
It only prevents sending unencrypted data over the all the little hops that data makes between client and server.
Your back-end may be in a completely separate geo location or in the the server farm next door. But, it still may travel through several routers to get there. Without SSL, the data is sent in the raw. I have a few servers, some in a different rack with the same host, and some are hundreds of miles apart. Going from rack to rack in the same geo loaction still requires hops over various routers -assuming no VPN. So, yes, if you are very paranoid and do not have a VPN between the front end and back-end, then secure the back-end. But all this does is encrypt the data between the two. It does not make a server 'secure'.
What does this mean? Asuming your back end has no http presence (not discoverable on the web) then SSL on the backend is probably overkill. Why? Becaue the only people who know it exists are employees - and no amount of SSL is gonna protect the server from anyone who knows it exists or how to access it.
Neither will SSL protect you against other attacks such as SQL Injection. For example, the Equifax breach which Equifax claim was a bug in Apache Struts (although my guess is that there was more to that than meets the eye).
SSL is a band-aid on a flawed system. It does not make a server secure. All it does is encrypt data between the server and the client.
Yes, you will need SSL for your backend. that is the important place where all the logic and data is being stored. On the front-end not so important, but if you are tackling with payment or any other confidential information yes, you do need it in front-end.
Risk of Using Self-Signed on Public Sites
The security warnings associated with self-signed SSL Certificates
drive away potential clients for fear that the website does not secure
their credentials. Both brand reputation and customer trust are
damaged.
I will totally agree with this article, not to use self-signed SSL, especially when dealing with payment. For internal testing, you may. But while in production, highly recommended not to use it. Instead go with SSLs that are with Certificate Authority
Ref: https://www.thawte.com/ssl/

Certificates, install in local machine before calling a service

I am trying to wrap my head around certificates and any help is appreciated. So far this is what I understand, please correct me if I am wrong.
When using the browser when I navigate to the https site the browser downloads the certificate(without the private key) and then continues to send the data over https?
I have come across some sites (especially when developing) that require you to install the certificate on the local machine before making a service call. What is the purpose here and how does it work?
I have also seen some scenarios where you need to install the certificate on the client machine for authentication purposes for example if you are using an email client, how does this work?
When using the browser when I navigate to the https site the browser downloads the certificate(without the private key) and then continues to send the data over https?
No, the browser and the server stablish a SSL/TLS secure channel with a symmetric encryption key. During the handshake process the server presents the https certificate and digitally signs some data with the private key as a proof of authenticity.
I have come across some sites (especially when developing) that require you to install the certificate on the local machine before making a service call. What is the purpose here and how does it work?
The client must trust the server certificate. Usually it has a list with the Certification Authorities for which certificates are accepted. For other certificates is needed to add them to the trust list. If not, the communication will be rejected
I have also seen some scenarios where you need to install the certificate on the client machine for authentication purposes for example if you are using an email client, how does this work?
Probably the same case as the previous one. Also the public part of the certificate of a user can be used to encrypt a message for him

How to implement a SSL Client Certificate on an Apache Server for a REST api?

Background:
Imagine a website, visible to the world, https://www.example.com, with a static IP address, 1.1.1.1. This site is hosted in an Apache server and it already possess an SSL Server Certificate.
On the other hand, inside a protected internal network, not visible to the world, a server (https://www.myinternalserver.com), with a static IP address (2.2.2.2), also running Apache, runs some internal web-based applications.
A static IP address (3.3.3.3), that maps to a subdomain (myapps) of the external site (https://myapps.example.com) serves as an entry point to the server where the internal web-based applications reside.
A firewall that protects the internal network does the redirect/proxying so all external traffic going to 3.3.3.3 is redirected internally to 2.2.2.2.
The firewall also limits all external traffic so any calls going to 3.3.3.3 must have been originated at 1.1.1.1, in essence, making the external website (https://www.example.com) the only authorized caller to the internal server (https://www.myinternalserver.com).
Scenario
With this infrastructure in place, I can make REST calls from the external website into the internal network and send back data to use in the pages. So, in this scenario, the external site is the client and the internal application, the server.
Question:
But beyond that, I want the server in the internal network to issue an "SSL Client Certificate" that would be "installed" (I don't know if this is the correct term), in the external website so all calls from the external site would have to be authenticated against this certificate.
How do I accomplish this?
Breaking the question:
I know that the question above is very broad, so let me try to break it into three (not so) "smaller" questions:
1 - How to I create the key/certificate? Using OPENSSL and some online recipes (this is one of them: http://www.impetus.us/~rjmooney/projects/misc/clientcertauth.html), I was able to generate the certificate file and learned (or so I believe) what I have to do with it and what to change in the httpd.conf file. In any case, I would like to feel more secure about what I have done so any suggestions/guidance here would be highly appreciated. For example, is the recipe I used any good?
2 - How to "install/transfer" this certificate to the external site? Do I simply copy/send one of the files created when generating the certificate? If so, which one? Where specifically does it go in the client server (external site)? Do they have to do anything at their end? If not, what is the process? I tried to contact the hosting company but I don't know if Icouldn't explain it to them or if they don't have experience with "SSL Client Certificate". All they told me is that there's already an SSL Certificate installed (SSL Server Certificate). They don't even seem to know what a "SSL Client Certificate" is.
3 - Once the certificate in place, what can I do to guarantee that ALL calls to the internal server, by default, come with the Certificate, without the need to code it into each API I create? I know very little about certificates so it might be possible that it happens "by default" always, but I read online about certificates that are "embedded" in the header of the API call, so I just want to be sure.
Thank you.
After some more research, this is what I found...
1 - How do I create the key/certificate?
I had to try other recipes and use a combination of them to get what I wanted. What I learned is that I have to create a certificate (CA Certificate) first, and generate the Server and Client certificates based on that first one. So look for recipes that encompass all three certificates: CA, Server, Client.
2 - How to install/transfer this certificate to the external site?
Actually you simply copy the necessary ones (client/CA) to a safe place in your share of the external site. A place outside the "www" tree.
3 - Once the certificate in place, what can I do to guarantee that ALL calls...
Well, here is what I did.
I "objectified my API call using php/libcURL and place it too, outside the "www" tree. For any developer in my site to use it, all they have to do is create an instance of the object and make the call by passing the URL as a parameter. In other words, you don't install the certificate. Instead, you make a call to the certificates each time you make a call to the internal server.
I hope it helps someone out there.