I'm using Micronaut's RabbitMQ package to connect to my RabbitMQ server (see here: https://micronaut-projects.github.io/micronaut-rabbitmq/latest).
I can easily configure the server to listen on the SSL port, however I cannot understand how can I configure my client to connect via SSL.
All examples I found create the connection manually, but in my case the connection is created behind the hood by Micronaut and I want to configure it by setting only properties.
In this section of the configuration all the rabbitmq properties are listed, however the only thing related to ssl is ssl-context-factory and no explanation or example is provided.
I would have expected something like this answer for Spring where (supposedly) there exist a spring.rabbitmq.ssl.enabled property which switches SSL connections on.
Is there anything similar for micronaut?
If not, is that ssl-context-factory the correct configuration property? And how do you set it up?
Bonus points: how should I configure the keystore to validate the server certificate? Micronaut will automatically use the micronaut.ssl.key-store.* values for the rabbit connection?
Final note: I'm not interested in doing mTLS/client authentication by the server. I simply want my client to use an encrypted SSL connection to speak to the server. So the client should not need any certificate, it only has to validate the server certificate.
I believe I found an answer, even though I'm not sure whether it's the best one.
Micronaut RabbitMQ support allows to specify the uri for the connection instead of the host & port. So it's possible to specify amqps://<host>:5671 and it should connect via SSL. Seems unfortunate that if you are using SSL you cannot use the host & port property though.
Related
I am working with Camunda's ExternalTaskClient Java client. I am able to subscribe to a topic successfully, but this uses a random port on the host machine to communicate with Camunda.
How can I tell the ExternalTaskClient to use a custom outgoing port? Here is my client so far:
ExternalTaskClient client = ExternalTaskClient.create().baseUrl("http://1.2.3.4:8080/engine-rest").build();
client.subscribe("my-topic").handler(new MyHandler()).open();
Thanks!
If it really is necessary to specify a specific source (client) port then these are the steps:
Implement a custom socket factory that implements ConnectionSocketFactory and returns a socket with your preferred local port - Camunda uses Apache HttpClient internally
Register that factory with a scheme through the connection manager and schema registry - httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme(<scheme>, <outgoing port>, <your factory>));
Hope that Camunda uses the HttpClient library as intended and no unpleasant side-effects pop up
In addition to the above you also need to think about handling an SSL context (in the custom factory) if the connection needs to be HTTPS. Also remember that using any port below 1024 means the user running the client needs special permissions.
Why is it a random port? Under the hood the ExternalTaskClient uses the REST-API. The baseURL you are providing in its configuration is the URL of the engine REST-API. It runs on one specific port. In your case on the default port 8080. You can change the server.port if you want the API to run on a different port.
How SSL works is well know as it's quite widely used and described well every where. In short - SSL involves
Verifying server authenticity by client by verifying the servers X.509 certificate.
Then arriving at a symmetric key using diffie-hellman key exchange algorithm.
But I am not sure what happens withsecurity.protocol=SASL_SSL. Clients and Server communication of few technologies like Kafka etc rely on this security protocol as one of the option. Here I am worried about the point 1 above. If i get a wrong broker address (as a trick ) from some one, does SASL_SSL verify the server certificate or not is my question. If it does, then I can be sure that the received broker is not genuine and my application will not publish or subscribe to messages from this server and my data is safe.
Edit 1: Following #steffen-ullrich answer and comments And little more dig, i see below. Looks like the certificate validation is happening when used through chrome and probably its loaded in the cacerts too. So the java code is able to authenticate the server.. so seems ok..
Edit 2: Right the certificates DST and ISRG are preloaded in the JDK 11 cacerts, so the client is able to authenticate the server as commented by Stephen.
SASL is a standard for authentication of the client - see Simple Authentication and Security Layer. SASL_SSL simply means that the client authentication (SASL) is used over a protected connection (SSL) to prevent interception instead of over a plain connection.
What you are asking is related to another configuration please read the following description.
ssl.endpoint.identification.algorithm
The endpoint identification algorithm used by clients to validate server host name. The default value is https. Clients including client connections created by the broker for inter-broker communication verify that the broker host name matches the host name in the broker’s certificate. Disable server host name verification by setting ssl.endpoint.identification.algorithm to an empty string.
Type: string
Default: https
Importance: medium
I have a Spring Boot java app that uses a self-signed certificate to communicate with the android front-end.
I use a tomcat server as my container for the app:
compile 'org.springframework.boot:spring-boot-starter-tomcat'
Now, I have enabled https / ssl:
TomcatEmbeddedServletContainerFactory tomcat = (TomcatEmbeddedServletContainerFactory) container;
tomcat.addConnectorCustomizers(connector -> {
connector.setPort(Integer.parseInt(serverPort));
connector.setSecure(true);
connector.setScheme("https");
I have to enable SSL as I want my android frontend to communicate to my server securely. I use the technique called certificate pinning which means I add the same self-signed certificate to both my server and my android app. For any http communications between the two, the communication will be encrypted with the keys of the same certificate and hence the server and android app will be able to understand one another.
When I load it into Heroku, I get errors each time I try to call the server:
2015-12-11T20:04:32.424629+00:00 heroku[router]: at=error code=H13 desc="Connection closed without response" method=GET path="/getfood?postid=566348364a918a12046ce96f" host=app.herokuapp.com request_id=bf975c13-69f3-45f5-9e04-ca6817b6c410 fwd="197.89.172.181" dyno=web.1 connect=0ms service=4ms status=503 bytes=0
According to this blog by Julie: http://juliekrueger.com/blog/
As a side note, Heroku apps are https enabled by default. The server I
was installing had Tomcat configured to use https, and trying to
access an endpoint was returning a code=H13 desc="Connection closed
without response" error. After I removed that configuration the error
went away.
I can fix the error by just removing the ssl / https from my tomcat server, but as I mentioned, I want to use the certificate pinning technique for secure communications.
I was thinking whether it was possible to disable the SSL on heroku side but keep my tomcat server SSL active but I already contacted Heroku and they told me that disabling the piggyback SSL that comes standard with their service is not possible.
I also looked at the paid alternative here called SSL Endpoint but it seems only userful for custom domains. Since all endpoints are coded within my android app and is not visible to the user, it makes no sense for me to use a custom domain. Furthermore, I don't think it will solve my problem as its sole objective seems to be to create the custom domain:
SSL Endpoint is only useful for custom domains. All default
appname.herokuapp.com domains are already SSL-enabled and can be
accessed by using https, for example, https://appname.herokuapp.com.
I googled for a few days now and cannot seem to come up with a solution. Disabling ssl on my tomcat side would not be acceptable in my mind as it poses too much risks. I would even consider other services (Azure etc) if this would solve my problem.
Any ideas on how I can solve this?
With Heroku, in order to use your own custom SSL, you need to use a custom domain and the SSL Endpoint addon, it will probably won't make sense for your case, but it is the only way to use your own certificate.
And I haven't tried all the providers out there, but with the ones I tried, the scenario is exactly the same, it is possible to use custom SSL cert only if you are using a custom domain.
Although, browsing google a bit, found this blog post where it ilustrates how to use an intermediate DNS service to comunicate with Heroku. In the communication between the DNS service and Heroku, the provided heroku SSL cert is used, but from the client to the DNS service a different certificate is used, so it might be of some help.
Update: A possible solution would be to use Amazon Web Services, where the deal is that you rent VM's and you are allowed to setup your own environment, meaning that you can install your own tomcat and use your own custom SSL.
Update 2: Also there is CloudFront with AWS, where you can use your own certificates explained here
I have a requirement to use client/server architecture and with Open SSL authentication.
Here, how server to know the connect client using their OPen SSL certificate?
Anyone knows the link, sample then please reply me.We have to develop it in Java.
OpenSSL is not Java, so your solution cannot be both - but I think I know what is intended.
Normally OpenSSL is used as part of Apache http as part of mod_ssl. This in turn uses a "connector" to send the requests to an application server, e.g. Apache Tomcat. You can configure this connector to also send the SSL certificates to tomcat if that is required, but normally the authentication/verification is handled within the deamon.
All this is pretty easy to Google, although you should factor in some time to fully understand the connectors. You've the keywords, now use them :)
I have a web-service endpoint and a http connector on port X.
At some point this endpoint needs to switch to https, but on the same port!
(I know this is not the normal way of doing things, but this is what my clients expect from an old server they are using...)
Is there a way to do it in tomcat?
This is not possible with Tomcat.The HTTPS connector will accept SSL connection only.
We have such a proxy developed in house. It's not that hard to do. You just need to check the first incoming packet. Looking for the pattern of SSL handshake. We only look for CLIENT_HELLO. Once you figure out the protocol, you can forward the request accordingly.
This is really ugly. You shouldn't do it if all possible. We have to do it because the legacy clients do this and it's impossible to upgrade them all.
There is such a thing as HTTPS upgrade, whereby a plaintext HTTP connection is upgraded to HTTP by mutual agreement after it has been formed. Is that what you mean? If so, Tomcat doesn't seem to support it out of the box, and neither does Java out of the box either. You can probably write yourself a Tomcat Connector that will do it; on the client end you have a more interesting problem ;-)
But I would ask why? Ports aren't so expensive that you can't use two.
You don't need to run the HTTP & HTTPS on same port, Configure the Tomcat to redirect requests to HTTPS in server.xml file.
well I wonder why they are NOT usually on the same port! wouldn't that be easier?
the reason is probably that related Java APIS (javax.net.ssl) don't allow that; you must have different server sockets. are there any alternative SSL impls for Java? I'm not aware of any.