SSL between microservices
The SSL (Secure Socket Layer) protocol is a security protocol that creates an encrypted link between a web server and a web browser – which allows us to create a digital certificate that authenticates the identity of a website and enables an encrypted connection.
One of its most widespread uses is the one carried out together with the HTTP protocol, giving rise to HTTPS, which is used to transfer websites securely. This way, the information transmitted between a website and a user (in both directions) is secured, which is especially important when it comes to sensitive information.
SSL certificates are installed on the server, but display visual cues in the browser, indicating to users that they are protected by a lock icon in the address bar, or with green font in the same place. They also show sites that lack these certificates, with a red padlock, an un-locked padlock, a line through the website address, or a warning triangle at the top of the padlock icon.
The TLS (Transport Layer Security) protocol is just an updated and more secure version of SSL. It works similarly to SSL, using encryption that protects the transfer of data and information. The two terms are often used interchangeably in the industry, although the term SSL remains the dominant term.
By securing communications with TLS, we guarantee the following protections:
- Authentication: at the beginning of the communication, client and server exchange their certificates to establish a secure communication.
- Confidentiality: the information is encrypted and is only readable by those involved.
- Integrity: the messages contain encrypted data information, guaranteeing that the information has not been manipulated.
The SSL protocol uses both asymmetric and symmetric cryptography. The later is used to exchange the keys, which in turn will be used to encrypt the communication using a symmetric algorithm. In the case of websites, for the operation of this protocol, an SSL certificate must be used. The web server will have one installed and, when a client tries to access it, it will send it with the public key of the server, in order to send the key that will be used to make the connection securely through symmetric encryption.
To start secure communication, the parties need certificates that have been signed by a trusted CA (Certified Authority). This guarantees the participants that the certificates that are presented are trustworthy and can start negotiating the communication (handshake).
How can I get a trusted certificate?
We could say this is the million-dollar question. Each participant needs to generate a pair of keys, public and private. This can be done with different libraries such as: openssl, keytool, keyExplorer, etc. Bear in mind that the private key must be kept in a safe place; if the private key is compromised, then communications with these keys will not be secure.
From the public key, we generate a certificate request (Certificate Signing Request) to a CA, so that it generates in turn a valid certificate. The certificate request will contain the public part of our key.
When a CA signs our certificate, we can start a secure communication with another party that also has the CA as a trusted certificate authority.
Below is a diagram of the flow of actions that are carried out to obtain our trusted certificate and the verification of the certificate. The CA certificate must be in our truststore, which can be in our computer, browser, cacert.pem file or in a certificate store.
The diagram above works as follows:
- Microservice 1 performs the Certificate Signing Request. It sends its public key to the CA, and the CA generates a unique certificate for the microservice.
- Microservice 2 performs the same operation.
- The CA sends the certificate to microservice 1, and microservice 1 is responsible for saving it in its truststore, that is, in the trusted key store.
- Microservice 2 performs the same operation.
- Microservice 1 communicates with microservice 2, including the certificate in its request.
- Microservice 2 checks that the received certificate is in its truststore.
- It checks that it trusts that certificate, because the certificate has been signed by a well-known CA, and then it adds certificate 1 to its truststore.
Practical recipe
Here is a solution for secure communication between microservices using HTTPS.
The microservices of the Onesait Platform are secured by means of a self-signed certificateby its own CA. Regarding the microservices external to the Onesait Platform, we want communication via HTTPS with the internal ones, or with any other located on a different machine. This solution proposes to create a key store (truststore) that is responsible for storing the certificates of those microservices with which we want to communicate securely. A CA is responsible for generating a certificate from its public keym for each microservice that wants to use secure communication. Once this certificate is created, it will be sent in a communication with a second microservice, and this second one will be in charge of checking whether that certificate is valid or not, by asking the common CA.
The proposed example is made up of two projects, sender and receiver. We propose request via REST between both, using HTTPS:
- Sender: it has inside the necessary configuration to make an HTTPS request (SecurityConfig.java) and the SSL socket configuration, which includes the inclusion of the .p12 certificate that can be found in the «resources/keystore» folder, in addition to the Feign configuration. All this is in the FeignClientConfig.java class. Additionally, a controller and a service are provided; they will allow a test to be carried out in which certain information is sent to the receiver.
In the «application.properties», certain configuration parameters of the SSL communication are specified, in addition to the destination URL to reach the receiver. Making the controller request, we should see the response sent by the receiver after receiving the request. - Receiver: This project contains the same configuration as the sender to receive HTTPS requests in the SecurityConfig.java class. In addition to this, an access point to the application is provided through a controller, to ensure that the sender can obtain the information it needs and send it back.
In the «application.properties», the same SSL communication configuration parameters are specified as in the sender, in addition to the context path with which it must access the receiver.
Header image: adapted from Joshua Sortino at Unsplash