I have an Undertow container for a Spring Boot application (Java 11) which is started using https.
The application is communicating with a IOS (Swift) and Android phone. I noticed that after not using the phone for a while
( 1 minute), the first request takes more time because the SSL handshake is performed.
I am wondering if there would be an option to cache/ invalidate the https session so that the first request after a longer period of time does not do the hanshake again.
Based on Robert's comment I will elaborate an answer.
I used
-Djavax.net.debug=ssl:handshake:verbose
to help me track the ssl handshakes.
Then, after seeing logs in the console I found out the classes responsible for the implementation of the TLS. Using debug I found this property for undertow. I think that for Tomcat should be similar.
server.undertow.no-request-timeout which I set in my application.properties to -1
No changes were required on the clients (phones: IOS and Android).
Related
We have a spring-boot application that runs perfectly fine by itself on both Java 11 and Java 17.
The spring-boot application is packaged as a docker container and runs inside gcp/gke kubernetes.
We use the nginx ingress to forward the traffic with tls-passthrough.
We use a Let's Encrypt certificate for our application.
The nginx does not have access to it (AFAICT), but considers it valid.
When using Java 11 everything works fine.
However, when using Java 17 the first (few) requests pass fine, but then I get a certificate error. The nginx generates/has a default ingress certificate, that it uses for the later requests. But I don't understand why it does serve that (sometimes) in the first place.
The error is reproducible with browsers and Java applications.
I did not manage to preproduce it with curl/openssl though.
After a short time/few minutes the error vanishes for the next (few) requests before it emerges again.
When adding the ingress certificate to the trusted certs in browsers I can see that the ingress requests are upgraded to HTTP2, the first few HTTP1 requests all use the correct certificate.
We tried with different java 17 base images (openjdk/eclipse-temurin + alpine/ununtu).
We tried to explicitly disable http2 in Java and the browser.
Nothing seems to work except for adding the self-signed certificate to the trust-store (which is obviously a no go for production).
We weren't able to reproduce this locally, but might be due to our local dev setup being only a simplified version of the cloud environments.
If I use kubectl port-forward into the java app container, I cannot reproduce the issue.
We use the following versions:
nginx-ingress-1.41.3
gke v1.21.6-gke.1500
eclipse-temurin 17
spring-boot 2.6.3 with the default tomcat
TLDR: The nginx-ingress sometimes does not tls-passthrough to our Java 17 app correctly and thus serves an invalid certificate for those requests. (All responses contain the expected/same/valid content except for the certificate).
Has anyone an idea what is happening and how to fix/avoid that?
I'm setting up a new dev environment on a windows 10 pro installation. Therefore i am exporting my spring-boot applications as .jar file and start it as windows service on different ports.
Spring boot app 1 on port 10001
Spring boot app 2 on port 10002
and so on
I already unlocked those ports in my firewall and everything seems working perfectly fine.
When I log into the application with port 10001, everything seems fine as well. However as soon as i log into another application (10002) i get automatically logged off on the 10001 application.
To sum it up, I am only able to be logged into one application at a time.
I am using a MySql8 Server installation. All applications have their own databaseschema. Additionally i am using spring security for authentication.
Because all those applications are running perfectly fine on our productive server (jelastic web hosting) it should have something to do with my dev environment instead of a code issue.
I'm happy you solved your problem. I don't think that using SSL and subdomains is the most simplistic solution to your problem though, especially if you are running automated tests in that environment, ssl might slow you down a bit.
There is a well known address you can bind your application to: 127.0.0.1. However, most people don't know, that your loop back device is actually listening to 127.0.0.1/8 in other numbers 127.0.0.1 with a netmask of 255.0.0.0 which means you can bind your services to any address in a whole class a subnet.
TLDR: try binding your application 1 to 127.0.0.2 and application 2 to 127.0.0.3. That should help with the cookies and later on, if you add monitoring ports, will make your life of managing port numbers easier.
As already mentioned in my comment above, the problem is not related to any software bug, instead its just how http is defined:
"Cookies do not provide isolation by port. If a cookie is readable by a service running on one port, the cookie is also readable by a service running on another port of the same server."
Are HTTP cookies port specific?
I solved my issue by using SSL encryption and different subdomains.
We are using Apache Tomcat 8.0.18 as our web server.We are getting expected output when the client is sending about 5 to 8 concurrent requests.
But when the client is sending about 30 to 40 concurrent request , client is getting some unexpected error related to some packet loss while the request reaching the web server hosted in tomcat through Internet.
We are not facing the issue while we testing the application in our local environment.
We have examined the web server logs and we are seeing only part of the requests are reaching the web servers. We have installed the Tomcat 8.0.18 with default configuration.
Can any one please guide us whether we need to change any configuration in Tomcat level to resolve this kind of packet loss issue?
Thanks
Dinesh
I suggest that you should install a packet sniffer on the host where Tomcat is installed. Maybe the problem doesn't come from tomcat.
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've got backend running on the tomcat server and client running in the browser. Application is built on Spring 3 MVC + Spring security framework. How to secure the communication ? Is there other option than just to set the server to be accessed only via HTTPS ? I've got no experience with this so it might be a stupid question, but will this affect my application and do I have to set something up in my app, when the server shall communicate with client via GET/POST request via https ?
It depends somewhat what you mean by "secure." If you want privacy, you must use TLS (SSL) as a transport.
If you're only concerned with authentication, then you have another option: Digest Authentication.
Digest Authentication allows the client (browser, usually) and the server to exchange authentication credentials in a secure manner without securing the entire communication. If you use Digest Authentication, then third parties can still:
See what data the client and server exchange
Insert themselves between the client and server and alter the exchange
What third parties cannot do is spoof the authentication or steal username/passwords in transit.
If that's not secure enough, you need TLS. You do not necessarily have to purchase a certificate. You can use OpenSSL to generate your own. This certificate will not automatically be trusted by browsers, however, so you can't really use it for public sites.
You will need to consult your server documentation for how to set up HTTPS or Digest Authentication, depending on which fits your needs.
Your application should not be affected by switching from HTTP to HTTPS, Tomcat handles this or maybe an Apache in front. It's important to understand, that HTTPS is a server-thing, not an application topic, because the client makes a connection to the server (Tomcat), not to your application. Check out the Tomcat documentation, it's pretty clear about how things work.
And, like the others said: From what you've said it's best to use HTTPS (TLS/SSL). Certificates are a bit frightning at the beginning, but it's worth to invest the time.
HTTPS is the (S)ecure form of HTTP, since you have an HTTP client server application I would certainly used HTTPS. All you need is to create an SSL certicate for your website and restrict access to your website to HTTPS only, then you are 99.99% secure.
Your certicate can be either commercial from Versign or equivalent or some open source engine.
for the clients nothing needs to be done to support HTTPS