Consul Check HTTPS self signed - consul

I use Consul to register a web application. The web app use Java Consul client to register with check. I am able to activate TLS and encryption using a self signed CA to encrypt exchanges between consul agents and between my webapp and consul agent. But I am not able to make checks onto a HTTPS with self signed CA signed certificate.
My web application is secured and listens only on HTTPS with a self signed certificate. When I register a session with consul and provide a https://... URL for check, I am rejected:
com.orbitz.consul.ConsulException: Consul request failed with status [500]: rpc error: rpc error: Check 'service:a4cHealthCheck:172.17.0.3' is in critical state
In consul agent logs, I can see:
2016/07/23 08:24:45 [WARN] agent: http request failed 'https://172.17.0.3:8443/rest/latest/health/check': Get https://172.17.0.3:8443/rest/latest/health/check: x509: certificate signed by unknown authority
It seems that the consul agent don't accept self signed certificates for checks. How can I disable SSL verify only for checks or provide a truster for checks ?

You can disabled the HTTPS checks with the property tls_skip_verify. It is described in the section HTTP of the Consul checks documentation.
If you use a JSON file to configure your agent, here is an example of configuration.
{
"services": [
{
"id": "instance-1",
"name": "ManagementService",
"address": "localhost",
"port": 11080,
"checks": [
{
"id": "api",
"name": "HTTP API",
"http": "https://localhost:11081/service/monitoring/ping",
"tls_skip_verify": true,
"interval": "5s",
"timeout": "1s"
}
]
}
]
}

Golang crypto lib have a set paths he looks for trustworthy authorities. This varies by OS, but for Linux systems you can check the following link.
https://golang.org/src/crypto/x509/root_linux.go
So, you can have your issue solved by installing your CA into the system defaults.
For how to install a root certificate, see
https://superuser.com/questions/437330/how-do-you-add-a-certificate-authority-ca-to-ubuntu
or for others OS
http://kb.kerio.com/product/kerio-connect/server-configuration/ssl-certificates/adding-trusted-root-certificates-to-the-server-1605.html

Related

SSLHandshakeException when trying to access ES instance from Docker

I am trying to access 6.x ES instance using High Level REST Client 6.7.2.
Access to this ES instance is provided to me via hostname (https://****.azureedge.net), username & password.
My Spring Boot application is getting data from the same ES without issues when it runs from my dev environment (IDE), but throws SSLHandshakeException as soon as I try run it from Docker container (from my development machine or K8s cluster in cloud).
Container is made with base image: FROM debian:stretch-slim & OpenJDK 11.0.2 with Spring Boot necessary modules.
I made some progress debugging with -Djavax.net.debug=all. It turns out that while running in docker image just few first steps of usual SSL handshaking happen:
Produced ClientHello handshake message
WRITE: TLS13 handshake, length = 2352
Raw write
Raw read (0000: 15 03 03 00 02 02 28 ......( )
READ: TLSv1.2 alert, length = 2
Received alert message (
"Alert": {
"level" : "fatal",
"description": "handshake_failure"
}
)
followed by SSLHandshakeException:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at org.elasticsearch.client.RestClient$SyncResponseListener.get(RestClient.java:938)
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:227)
at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1764)
at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1749)
at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1708)
at org.elasticsearch.client.SecurityClient.getSslCertificates(SecurityClient.java:508)
....
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at java.base/sun.security.ssl.Alert.createSSLException(Unknown Source)
at java.base/sun.security.ssl.Alert.createSSLException(Unknown Source)
at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Unknown Source)
at java.base/sun.security.ssl.TransportContext.dispatch(Unknown Source)
at java.base/sun.security.ssl.SSLTransport.decode(Unknown Source)
at java.base/sun.security.ssl.SSLEngineImpl.decode(Unknown Source)
at java.base/sun.security.ssl.SSLEngineImpl.readRecord(Unknown Source)
at java.base/sun.security.ssl.SSLEngineImpl.unwrap(Unknown Source)
at java.base/sun.security.ssl.SSLEngineImpl.unwrap(Unknown Source)
at java.base/javax.net.ssl.SSLEngine.unwrap(Unknown Source)
at org.apache.http.nio.reactor.ssl.SSLIOSession.doUnwrap(SSLIOSession.java:271)
at org.apache.http.nio.reactor.ssl.SSLIOSession.doHandshake(SSLIOSession.java:316)
at org.apache.http.nio.reactor.ssl.SSLIOSession.isAppInputReady(SSLIOSession.java:509)
at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:120)
at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:162)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:337)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:276)
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:591)
When running from my local environment handshake looks uninterrupted:
Produced ClientHello handshake message
WRITE: TLS13 handshake, length = 460
Raw write
Raw read
READ: TLSv1.2 handshake, length = 155
Consuming ServerHello
ServerHello
Negotiated protocol version: TLSv1.3
Session initialized: Session(1560119025211|TLS_AES_256_GCM_SHA384)
WRITE: TLS13 change_cipher_spec, length = 1
Raw write
Raw read
READ: TLSv1.2 change_cipher_spec, length = 1
Consuming ChangeCipherSpec message
Raw read
READ: TLSv1.2 application_data, length = 27
...
Raw read
READ: TLSv1.2 application_data, length = 8469
Consuming server Certificate handshake message
... // here is the list of 3 certificates with "SHA256withRSA", "SHA256withRSA", "SHA1withRSA" signature algorithms
Found trusted certificate ⇢ SHA1withRSA
...
While running locally I noticed CN=Microsoft IT TLS CA 2, OU=Microsoft IT, O=Microsoft Corporation, L=Redmond, ST=Washington, C=US, as well as CN=Baltimore CyberTrust Root, OU=CyberTrust, O=Baltimore, C=IE as issuers, maybe this is important, but I guess it is expected considering ES host address (Azure).
At the end I wanted to emphasise that I didn't need to do anything special to make this work in my macOS Java 11.0.2 development environment.
I already tried following, but that didn't change anything:
Changing base Docker image from "slim" to non slim version
Using OpenJDK 11.0.1 or 11.0.2
Added cert from host to TrustStore that JVM is using in a runtime. (I checked in Docker container that there is indeed one more cert, but considering when handshake failure happens I imagine this is irrelevant)
tried to enforce App with: "-Dcom.sun.net.ssl.enableECC=false", "-Djdk.tls.client.protocols=TLSv1.3", "-Dhttps.protocols=TLSv1.3", didn't help
Interesting: curl from Docker image with BasicAuth "talks" with same URL without issues (handshake completes) & small query returns results. I guess that curl and JVM are using different sources of trusted CAs inside the Docker, different algorithms for handshaking etc..
Thanks in advance for any help
TLDR: enforcing TLSv1.2 for client in the app made handshaking complete from inside the docker
After a lot of try/fail attempts I made it work. Following things didn't make any difference:
using non "slim" debian base image insead of "slim"
using OpenJDK 11.0.2 instead of 11.0.1
adding host's certificate to JVM TrustedStore while building docker image so it is available when container starts.
enforcing com.sun.net.ssl.enableECC=false
enforcing TLSv1.3 for https.protocols and/or jdk.tls.client.protocols
enforcing TLSv1.2 for https.protocols
What fixed handshake with host, was enforcing TLSv1.2 for client by using -Djdk.tls.client.protocols=TLSv1.2 in Dockerfile, so app runs with this flag inside container. This allowed SSL handshake to complete as it should work anyways. For some reason actual negotiation about protocol version didn't work without enforcing lower version of protocol for client. Logs from local vs docker environment doesn't show any difference but this helped in docker.
What helped me to find out was:
setting of javax.net.debug=ssl:handshake or even more detailed javax.net.debug=all so I could see details of handshake attempts
confirming that "at least someone" can establish outbound communication from inside the docker by using curl to send same request as app is trying, which worked because curl somehow figured out how to proceed handshaking with host.
pure luck
Thanks everyone for support & ideas

Unable to start Angular 7 with SSL certificate connecting to spring cloud applications - PEM_READ_BIO_PRIVATEKEY:bad password read

we are developing a Spring cloud application with microservice architecture and have a self signed certificate.We have written the code and completed the SSL settings in back end successfully.
Now we try to set up the certificate in front end in Angular 7.
we made the following changes
1.Generated the SSL .crt and .key files.placed in SSL folder
2.Modified Angular.json file and included
"ssl": true,
"sslKey": "ssl/server.key",
"sslCert": "ssl/server.crt"
but when I start i am getting the following error
error:0907B068:PEM routines:PEM_READ_BIO_PRIVATEKEY:bad password read
I have found 2 helpful links
NodeJS & SSL - "bad password read"
https://github.com/angular/angular-cli/issues/1576
Please note that I don't want these two solutions
1.Running the front end code in back end server by placing the Angular 7 code in static folder
2.Removing the passphrase from the key.
Link1 says that we need to add the code
var credentials = {
key: fs.readFileSync('XXX.key', 'utf8'),
cert: fs.readFileSync('XXX.crt', 'utf8'),
passphrase: 'XXXX'
}
but where in Angular 7 we need to add the these settings
Thanks
Mahidhar

KeystoneJS with letsencrypt - certificate files required

I am following this tutorial Let’s Encrypt KeystoneJS! in an attempt to get letsencrypt working on my KeystoneJS project.
However, when I start the server I am getting the error:
SSL Not Started: Invalid SSL Configuration (certificate files required)
I've generated the standalone certificate with certbot to the directory /home/example/letenscrypt resulting in:
- accounts
- csr
- keys
- letsencrypt.log
- renewal
- renewal-hooks
I've also tried defining the configdir in my keystone init:
keystone.init({
...
letsencrypt: (process.env.NODE_ENV === 'production') && {
email: 'admin#myapp.com',
domains: ['www.myapp.com', 'myapp.com'],
register: true,
tos: true,
configDir: '/home/example/letsencrypt'
},
...
})
I've also tried configDir: '/home/example/letsencrypt/keys' but I always get the same error, I'm wondering what I'm missing?
Ok, so the issue was the NODE_ENV wasn't correctly set to production. Setting it properly in my .env solved this issue (but raised another unfortunately with an invalid certificate being generated)
https://github.com/keystonejs/keystone/wiki/Deployment-Checklist

Unable to Resolve PKIX Path Building Failed

I try to connect to https web service using below code.
adapter.xml:
<connectivity>
<connectionPolicy xsi:type="http:HTTPConnectionPolicyType">
<protocol>https</protocol>
<domain>somewhere.com</domain>
<port>443</port>
<connectionTimeoutInMilliseconds>30000</connectionTimeoutInMilliseconds>
<socketTimeoutInMilliseconds>30000</socketTimeoutInMilliseconds>
<maxConcurrentConnectionsPerNode>50</maxConcurrentConnectionsPerNode>
</connectionPolicy>
</connectivity>
impl.js:
function getTest() {
var input = {
method : 'GET',
returnedContentType : 'json',
path : "WS.svc"
};
return WL.Server.invokeHttp(input);
}
Unfortunately, this error appears when I try to call the adapter:
{
"errors": [
"Runtime: Http request failed: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target"
],
"info": [
],
"isSuccessful": false,
"warnings": [
]
}
I have added the public certificate of the WS (accessed from browser and get it from certificate details) into my Java folder in Program Files (C:\Program Files\Java\jdk_version\jre\lib\security), however the issue still persists.
Is there any advise?
The instructions you've followed are incorrect when using MobileFirst Platform.
Follow the steps described in this user documentation topic (for Worklight 6.2, but valid for MFPF 6.3 and above as well).
Do not export the certificate from a browser because this action adds browser metadata and other artifacts which shouldn't be there. Instead use a tool such as OpenSSL to get the certificate (described in the documentation)
The certificate should then be stored in the keystore of the application server and not in your Java's JVM.

Apache WEB server still responds to requests used SSLv2 protocol. When SSLv2 protocol was disabled

Here is my configuration ...
SSLProtocol -ALL +SSLv3 TLSv1
but Apache WEB server still responds to requests used SSLv2 protocol.
The following is my test log.( Sorry, I cannot attach image because my reputation is under the 10 )
SSLv2 Record Layer: Server Hello[Version: SSL 2.0 (0x0002)]Length: 955Handshake Message Type: Server Hello (4)Session ID Hit: FalseCertificate Type X.509 Certificate (1)Version: SSL 2.0 (0x0002)Certificate Length: 928Cipher Spec Length: 0Connection ID Length: 16Certificate blah~blah~Connection ID
thank you
The configuration should set as:
SSLProtocol= "ALL:-SSLv2"
If that does not work also set the cipher suite as:
SSLCipherSuite="ALL:+HIGH:+MEDIUM:+LOW:!SSLv2"

Resources