I have a Java app deployed in tomcat 6. The app sends messages to another service via socket and it needs to use ONLY TLSv1.2 protocol.
In my tomcat6.conf file I put this configuration:
JAVA_HOME=/usr/lib/jvm/jre1.7.0_75
JAVA_OPTS="${JAVA_OPTS} -Djavax.sql.DataSource.Factory=org.apache.commons.dbcp.BasicDataSourceFactory -Dhttps.protocols=TLSv1.2"
But stll use the older tls version.
It there any configuration to apply in java or tomcat to force use TLSv1.2?
Edit 1:
The answer provided by #Peter Walser is good and could work. The problem is I can't modify the code because is a jar provided by third party, and I can only configure the enviroment, not the code.
The https.protocols system property is only considered for HttpsURLConnection and URL.openStream(), as stated in Diagnosing TLS, SSL, and HTTPS
Controls the protocol version used by Java clients which obtain https connections through use of the HttpsURLConnection class or via URL.openStream() operations. ...
For non-HTTP protocols, this can be controlled through the SocketFactory's SSLContext.
You can configure the SSLSocket as follows:
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
socket.setEnabledProtocols(new String[] {"TLSv1.2"});
When working with REST-clients, most of them support configuring the protocols over the SSLContext. Example (JAX-RS client):
Client client = ClientBuilder.newBuilder()
.sslContext(SSLContext.getInstance("TLSv1.2"))
// more settings, such as key/truststore, timeouts, logging
.build();
If you are trying to force the server to use TLSv1.2 the following link may provide what you need.
The Apache Tomcat 5.5 Servlet/JSP Container - SSL Configuration HOW-TO
As the doc specifies edit the Tomcat Configuration File as below,
The implementation of SSL used by Tomcat is chosen automatically unless it is overridden as described below. If the installation uses APR - i.e. you have installed the Tomcat native library - then it will use the APR SSL implementation, otherwise it will use the Java JSSE implementation.
To avoid auto configuration you can define which implementation to use by specifying a classname in the protocol attribute of the Connector.
To define a Java (JSSE) connector, regardless of whether the APR library is loaded or not do:
<Connector protocol="org.apache.coyote.http11.Http11AprProtocol" port="8443" .../>
Configure the Connector in the $CATALINA_BASE/conf/server.xml file, where $CATALINA_BASE represents the base directory for the Tomcat 6 instance. An example <Connector> element for an SSL connector is included in the default server.xml file installed with Tomcat. For JSSE, it should look something like this:
<!--
<Connector
port="8443" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
SSLCertificateFile="/usr/local/ssl/server.crt"
SSLCertificateKeyFile="/usr/local/ssl/server.pem"
clientAuth="optional" SSLProtocol="TLSv1"/>
-->
You will note that the example SSL connector elements are commented out by default. You can either remove the comment tags from around the the example SSL connector you wish to use or add a new Connector element of your own. In either case, you will need to configure the SSL Connector for your requirements and environment.
The port attribute (default value is 8443) is the TCP/IP port number on which Tomcat will listen for secure connections. You can change this to any port number you wish (such as to the default port for https communications, which is 443). However, special setup (outside the scope of this document) is necessary to run Tomcat on port numbers lower than 1024 on many operating systems.
After completing these configuration changes, you must restart Tomcat as you normally do, and you should be in business. You should be able to access any web application supported by Tomcat via SSL.
Try changing the SSLProtocol attribute in <Connector> element to SSLProtocol="TLSv1.2".
<Connector
port="8443" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
SSLCertificateFile="/usr/local/ssl/server.crt"
SSLCertificateKeyFile="/usr/local/ssl/server.pem"
clientAuth="optional" SSLProtocol="TLSv1.2"/>
Related
The third party tool we used for security test is giving Slow HTTP POST Vulnerability on Tomcat 8. We have a simple Spring Controller and JSP in the application.
Existing Tomcat connector config is below:
<Connector port="8643" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true" compression="on"
clientAuth="false" sslProtocol="TLS" maxPostSize="20480"
maxSwallowSize="20480" maxHeaderCount="25" maxParameterCount="100"/>
Note that we don't have Apache or Nginx in front of tomcat. Please suggest the configs that we can use directly on Tomcat.
An example of Slow HTTP Attack is SLOWLORIS
To mitigate it with Tomcat, the solution is to use the NIO Connector, as explained in this tutorial.
What is unclear with your problem, is that Tomcat already uses the NIO connector by default on Tomcat 8, which is your configuration :
The default value is HTTP/1.1 which uses an auto-switching mechanism
to select either a non blocking Java NIO based connector or an
APR/native based connector.
Maybe should you set some other Connector parameters to specifically limit POST abuse, I suggest :
maxPostSize="1048576" (1 MByte)
connectionTimeout="10000" (10 seconds between the connection and the URI request)
disableUploadTimeout="false" (activate the POST maximum time allowed)
connectionUploadTimeout="20000" (maximum POST of 20 seconds)
An option is also to limit the headers number (default being 100), but this can have side effects with people using smartphones (which are known to send many headers) :
maxHeaderCount="25"
But it depends if your traffic is coming from Internet, or if it is a pro intranet with known users. In this latter case you could adjust the settings to be more permissive.
Edit 1: hardening with MultipartConfig
As stated on some other posts, maxPostSize might not work for limitting uploads. When using Java 7 built-in uploads, it is possible to configure limits by an annotation to the Servlet, or by configuration. It's not a pure Tomcat configuration as you asked, but it is necessary to know about it and talk with the DEV team as security must be taken in account since the early stages of development.
Edit 2: disabling chunked Transfer-Encoding
Some Slow HTTP POST attacks are based on requests sent with a Transfer-Encoding : chunked header, and then send many or an infinite number of chunks. To counter this attack, I suggest configuring a Rewrite Valve.
To achieve this, add the valve in your Host definition in server.xml :
<Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
Supposing your host name is the default one (localhost), you need to create $CATALINA_BASE/conf/Catalina/localhost/rewrite.config file with this content :
RewriteCond %{HTTP:Transfer-Encoding} chunked
RewriteRule ^(.*)$ / [F]
If necessary, you can adapt the RewriteRule to reply with something else than a 403 Forbidden which is due to the F flag. This is pure Tomcat config and flexible.
I have secured apache reverse proxy configured in front of my websphere 8 application server. I have set generic JVM arguments -Dhttps.proxyHost and -Dhttps.proxyPort but the requests on response.sendRedirect are not directed to peoxy server. It is directed to defualt port 9080.
How to solve this issue ?
I have solved this issue on Tomcat & Jboss by modifying my connector port as follows
connector name="http" protocol="HTTP/1.1" socket-binding="http" scheme="https" proxy-name=" 192.168.1.1 " proxy-port="443" secure="true"
How do I solve this for Websphere ?
I assume that you are using like below
response.sendRedirect(request.getContextPath() +
"/my/main.jsp");
Here - request.getContextPath gives the proxied server info.
As a quick fix I resolved it using the proxy server values from properties files.
response.sendRedirect("get proxy server name from prop file" +
"/my/main.jsp");
Solved this problem by following below steps.
Add following in Apache web server's virtual host tag . What you actually need is to forward along the protocol that was used to access the server.
VirtualHost *:443>
RequestHeader set X-Forwarded-Proto "https"
….
/VirtualHost>
For more explanation refer site
https://www.nczonline.net/blog/2012/08/08/setting-up-apache-as-a-ssl-front-end-for-play/
Following properties needs be added in Websphere webcontainer properties through admin console.
Go to Application servers > server1 > Web container > Custom properties
Add Following properties
httpsIndicatorHeader -
X-Forwarded-Proto (Request header value set in web server (in our case it is https) )
com.ibm.ws.webcontainer.extractHostHeaderPort -
true (To obey request port no)
trusthostheaderport -
true (To obey request port no)
Refered the below site for this settings
http://www-01.ibm.com/support/docview.wss?uid=swg21569667
http://129.33.205.81/support/knowledgecenter/SSEQTP_8.5.5/com.ibm.websphere.base.iseries.doc/ae/rweb_custom_props.html
In our case (Websphere Liberty 21.0.0.9), we simply added a couple of directives in the corresponding Apache virtual host configuration:
RequestHeader set X-Forwarded-Proto "https"
ProxyPreserveHost On`
These directives are valid only from Apache 2.3.3 on
Both are mentioned in the article mentioned below by #Darshan Shah
I have a web app hosted on two Tomcat servers, identical WARs and server.xml.
I don't have access to change any of the Apache settings - as such, I know that load balancing works as we have tested by shutting down one server and not the other, etc. Based on Tomcat logs I see both being used.
When using the default Tomcat HTTP port 8080 (in my case that was changed to 8083, nonissue) sessions are retained fine.
However, I made a change to use SSL, port 443 and now sessions are invalidated anywhere from 30 seconds - 5 minutes after creation. I assume this has something to do with session replication as I have not made any changes to the server.xml or web.xml besides pointing to the keystore :
<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true" secure="true" scheme="https" sslProtocol="TLS"
maxThreads="150"
clientAuth="false" keystoreFile="ssl/keystore.jks" keystorePass="123" />
I'm not exactly sure what else to copy here as the only change to the server.xml has literally be these few lines - I assume the added security is for some reason invalidating the session.
I currently have a test server serving the application on HTTP and HTTPS - even accessing the app at the same time, HTTP goes through fine and retains the session, HTTPS refuses to hold on to the session for longer than 5 minutes.
For what it's worth the SSL cert is installed to both Tomcat servers rather than at the load balancer - according to https://serverfault.com/questions/248139/apache-ssl-losing-session-over-load-balancer that may be the issue? I've only coded the application and changed some of the xml configurations - not sure if this is necessarily an issue I can fix.
I'm having regarding a java web app running on apache.
One of the pages is invoking an applet which code is an external server.
The company responsible of the applet told us to use HTTPS when invoking the page showing the applet as we had problems when we invoked the page using HTTP.
The problem is that when I browse the page in HTTPS , I have an ssl_error_rx_record_too_long error.
The address I want to browse looks like :
https://www.myurl.com:8084/myWebApp/pageContainingApplet.jsp?parameter1=value1¶meter2=value2
I looked for the server.xml file under /conf and added this tag:
<Connector port="8084" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
Still nothing
Error code: ssl_error_rx_record_too_long
This usually means the implementation of SSL on your server is not correct. The error is usually caused by a server side problem which the server administrator will need to investigate. Below are some things we recommend trying.
Ensure that port 443 is open and enabled on your server. This is the
standard port for https communications.
If SSL is using a non-standard port then FireFox 3 can sometimes give
this error. Ensure SSL is running on port 443.
If using Apache2 check that you are using port 443 for SSL. This can
be done by setting the ports.conf file as follows
Listen 80 Listen 443 https Make sure you do not have more than one
SSL certificate sharing the same IP. Please ensure that all SSL
certificates utilise their own dedicated IP.
If using Apache2 check your vhost config. Some users have reported
changing to default resolved the error.
Make sure that your SSL certificate is not expired
Try to specify the Cipher:
SSLCipherSuite
ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM:+SSLv3
Also check this : https://support.servertastic.com/error-code-ssl-error-rx-record-too-long/
I have a client/server process with one server and one client.
The connect setup looks like:
System.setProperty("javax.net.ssl.trustStore", "path/to/store");
System.setProperty("javax.net.ssl.trustStorePassword", "passwd");
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
sslsocket = (SSLSocket) sslsocketfactory.createSocket(InetAddress.getLocalHost(), port);
1:1, this works fine. Now I am expanding it such that the server is listening on multiple ports for multiple clients. Each client that connects to the server should do so on a specific port with a specific truststore.
If I register two trust stores on the server side, when I try to make the client connection I get the error:
javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown Received fatal alert: certificate_unknown
I've been looking through stack overflow for an example, but everything seems overly complicated. Is there a simple way to manage this? Or a compelling reason that one process shouldn't use multiple key stores?
I don't think using your method this is possible. Since you are setting a system property (which is a hashtable), the last one you write will overwrite the earlier ones.
But also, I do not understand the usecase. In general truststore is a client side concept. It is about determining what server to trust. Most of the time (unless you are using certificate based authentication) a client's trustworthiness is not relevant.
Having said this, it is possible to set different keystores for different ports. In tomcat, for instance
<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystoreFile="${user.home}/.keystore1"
keystorePass="changeit"
clientAuth="false" sslProtocol="TLS" />
The above snippet states that on port 443 ~/.keystore1 should be used. On another port, keystore2 could be used.
Should you want to use client authentication, you can force the client to send a certificate, in the above example by setting clientAuth to true, and adding truststoreFile and truststorePass.
Digging in tomcat's source code may help you in setting up your environment. In particular the file java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java will perhaps have exactly what you want.