Tomcat 8.5.29 HTTP/2 is not supporting GZIP compression - gzip

I am using Tomcat 8.5.29 and using the respective configuration,I have enabled the HTTP2 support for the site. Below is the configuration in server.xml file.
<Connector port="443" protocol="org.apache.coyote.http11.Http11AprProtocol"
maxThreads="150" SSLEnabled="true" compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json" compression="on" compressionMinSize="1024"
>
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
<SSLHostConfig>
<Certificate certificateKeyFile="conf/localhost-key.pem"
certificateFile="conf/localhost-cert.pem"
certificateChainFile="conf/cacert.pem"
type="RSA" />
</SSLHostConfig>
</Connector>
When i tried to compare the page load time for the site which is supporting HTTPS 1.1 and HTTP2, it is not consistent. Sometime it is taking more time to load and sometime it is taking less time to load compare to HTTPS 1.1.
To measure the page load time i am using Developer tools from Chrome Browser.
Later, I have found that Load time for HTTP/2 is higher because "content-encoding" in response is not gzip. Using HTTP/1.1, a script file size is 4 MB ( gzip) where as with HTTP/2, same file is of 8 MB ( no content-encoding). Compression is not happening. We have also tried with useSendfile and compression as "force" but it did not work.
We have also tried with Tomcat version 8.5.31 but no luck !! Facing same issue.
We have used Tomcat version 9 and using following configuration, got content in gzip (compressed). Now file size got reduced by 2 MB with a quick page load.
<Connector port="443" protocol="org.apache.coyote.http11.Http11AprProtocol"
maxThreads="150" SSLEnabled="true"
>
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json" compression="on" compressionMinSize="1024" />
<SSLHostConfig>
<Certificate certificateKeyFile="conf/localhost-key.pem"
certificateFile="conf/localhost-cert.pem"
certificateChainFile="conf/cacert.pem"
type="RSA" />
</SSLHostConfig>
</Connector>
It looks like Tomcat version 8.5 is not supporting gzip with HTTP2. Any idea on this?

According to the Tomcat documentation:
Note: There is a tradeoff between using compression (saving your bandwidth) and using the sendfile feature (saving your CPU cycles). If the connector supports the sendfile feature, e.g. the NIO2 connector, using sendfile will take precedence over compression. The symptoms will be that static files greater that 48 Kb will be sent uncompressed. You can turn off sendfile by setting useSendfile attribute of the protocol, as documented below, or change the sendfile usage threshold in the configuration of the DefaultServlet in the default conf/web.xml or in the web.xml of your web application.
So try adding useSendfile="false" to your UpgradeProtocol setting
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json" compression="on" compressionMinSize="1024" useSendfile="false" />
Note this option does not appear in the 8.5 documentation so not sure if it exists for that (there is a reference to it "You can turn off sendfile by setting useSendfile attribute of the protocol, as documented below" but then nothing below), though you can also turn off at a server level.
Weirdly I wouldn't have expected this to work in Tomcat 9 either without turning off this option, but you say it does? Are you sure you have not turned this off? Or are you testing with a smaller than 48KB file on that?

Tomcat 8.5.33 fixes this issue; compression works with http/2 then.

Related

Unexpected behavior difference between Nio and Nio2 connectors in Tomcat 8.5

I've run across some peculiar behavior with the NIO2 connector in Tomcat 8.5.23
Here is how I am using it:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
SSLEnabled="true"
sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation"
maxThreads="200"
minSpareThreads="25"
scheme="https"
secure="true"
keystoreFile="/path/to/keystore.jks"
keystorePass="key-pass"
clientAuth="false"
ciphers="long,list,of,ciphers"/>
Now what happens is, if I happen to POST and the request includes the Header: 'Cache-Control: max-age=0' then the form parameters are not there when I try to retrieve them. I've tried putting in a filter to try and grab them and/or the body itself at the very beginning of the filter chain but it is already too late - the body has been consumed, and there are no parameters. The request structure does however show that the body is of the correct size, so it would appear not to be a network issue.
I would normally think I had something configured incorrectly, but everything works fine under Http11NioProtocol.
Any suggestions - aside from not using Nio2?

How to resolve Sweet32 vulnerability on Apache Tomcat?

I am having some trouble getting rid of a server vulnerability. The Sweet32 vulnerability deals with medium strength cipher suites on my web server. The scanner output reads as follows, "The remote host supports the use of SSL ciphers that offer medium strength encryption. Nessus regards medium strength as any encryption that uses key lengths at least 64 bits and less than 112 bits, or else that uses the 3DES encryption suite."
The following medium strength ciphers were found on the server:
EDH-RSA-DES-CBC3-SHA;
ECDHE-RSA-DES-CBC3-SHA;
DES-CBC3-SHA
I tried editing the server.xml file for Apache Tomcat. There is a SSL connector portion of the server.xml file that I have been editing. It reads as follows, but the vulnerability is still getting flagged. I've also played around with disabling certain ciphers suits in the registry, such as 3DES. Any ideas on how to fix this vulnerability would be so helpful.
<Connector URIEncoding="UTF-8"
clientAuth="false"
port="443"
scheme="https"
minSpareThreads="5"
enableLookups="true"
acceptCount="100"
maxThreads="200"
secure="true"
SSLEnabled="true"
keystoreFile="**********"
keystorePass="*********"
sslProtocol="TLSv1.2"
algorithm="IbmX509"
compression="on"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/xml,text/css,text/plain,text /javascript,application/javascript,application/x-javascript"
SSLCipherSuite="TLS_EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:ECDHE-RSA-AES128-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA128:DHE-RSA-AES128-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA128:ECDHE-RSA-AES128-SHA384:ECDHE-RSA-AES128-SHA128:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA384:AES128-GCM-SHA128:AES128-SHA128:AES128-SHA128:AES128-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4:!3DES:!ECDHE-RSA-DES-CBC3-SHA"
/>
Removing the Ciphers you listed from the server.xml file should fix this.
Like this:
SSLCipherSuite="TLS_EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:ECDHE-RSA-AES128-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA128:DHE-RSA-AES128-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA128:ECDHE-RSA-AES128-SHA384:ECDHE-RSA-AES128-SHA128:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:AES128-GCM-SHA384:AES128-GCM-SHA128:AES128-SHA128:AES128-SHA128:AES128-SHA:AES128-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4:!3DES"

Turn off SSLv3 on JBoss AS 7.1.1

I have Spring MVC App running on JBoss AS 7.1.1. I need to turn off SSLv3 to protect against Poodle vulnerability. JBoss documentation at https://access.redhat.com/solutions/1232233 suggests I need to make sure that SSLv3 is not listed in the SSL Protocol attributes.
I have tried that but I can still connect to my website after only enabling SSL in Internet explorer options displayed below. Below is my standalone.xml configuration:
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
<ssl name="foo-ssl" key-alias="foo" password="secret" certificate-key-file="C:\Dev\Java\jdk1.6.0_34\bin\foo.keystore" protocol="TLSv1"/>
</connector>
Can someone suggest what I'm missing here?
I finally figured a way to fix it. If you change 'protocol' to 'protocols' in the above mentioned configuration and make sure sslv3 is not in the protocol list then it disables SSLv3.
Notice the protocols attribute in the config below
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
<ssl name="foo-ssl" key-alias="foo" password="secret" certificate-key-file="C:\Dev\Java\jdk1.6.0_34\bin\foo.keystore" protocol="TLSv1,TLSv1.1,TLSv1.2"/>
</connector>
After making this change, if you open IE and disable all other protocols except SSL 3.0 - and then try to access the web page, you should not be able see the web page.
More details available here: http://abhirampal.com/2015/07/23/disable-ssl-v3-on-jboss-as-7-1-1/

Multiple Tomcat instances, starting one kills the other

I have 2 different java applications running in two Tomcat instances (Ubuntu OS, Tomcat 7.0.57). For my Tomcat configuration, I follow instructions provided by this video, but as far as I saw, it is a very standard way to do it.
Running each application separately is working fine, but as soon as I try to run both at same time, the first started one becomes unavailable (HTTP 503 error). Tomcat instance logs do not provide any information about any kind of shutdown, keeping the last "INFO: Server startup in xxx ms". It seems the first tomcat process is simply killed. If I re-start that first application, then the same scenario applies to the second app.
All troubleshooting information I could find talk about port issues. I double checked my port numbers, they are different:
app-1: conf/server.xml:
<Server port="8105" shutdown="SHUTDOWN">
<Connector port="8180" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8143" />
<Connector port="8109" protocol="AJP/1.3" redirectPort="8143" />
...
</Server>
app-2: conf/server.xml:
<Server port="8205" shutdown="SHUTDOWN">
<Connector port="8280" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8243" />
<Connector port="8209" protocol="AJP/1.3" redirectPort="8243" />
...
</Server>
app1.sh
export CATALINA_HOME=/home/tomcat/apache-tomcat-7
export CATALINA_BASE=/home/tomcat/app-1
cd $CATALINA_HOME/bin
./startup.sh
app2.sh
export CATALINA_HOME=/home/tomcat/apache-tomcat-7
export CATALINA_BASE=/home/tomcat/app-2
cd $CATALINA_HOME/bin
./startup.sh
Any idea on what can happen, or how I can get any logs to dig this?
My server was hosted on a EC2 t1.micro instance, with 600MB memory.
I finally decide to update it to an instance with more memory and the problem disappear.

How to Change SSL Version for HTTPS Connections in JBoss EAP 6.1

I have a simple HTTPS connector configured on my JBoss EAP 6.1 server for SSL connections to a bunch of RESTful web services I am working on. I am not sure if JBoss EAP 6.1 comes with TLS 1.2 (or SSL 3.2, since I believe TLS is really just later versions of SSL), but I want to use that version of TLS or later.
What is the default SSL version of JBoss EAP 6.1 , if my standalone.xml file tags that handle this connector look like this? :
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
<ssl name="https" key-alias="localhost" password="something" certificate-key-file="${jboss.server.config.dir}/localhost.jks"/>
</connector>
There is no SSL version information given in the standalone.xml entry above, as you can see, so I've no idea.
I have read on the JBoss community web site that you can add something like sslProtocol="TLS" in the tag, and protocol="TLSv2" in the tag, but is that really all there is to it?
i.e.
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true" sslProtocol="TLS">
<ssl name="https" key-alias="localhost" password="something" certificate-key-file="${jboss.server.config.dir}/localhost.jks" protocol="TLSv2" />
</connector>
Will the above work, and if so, how can I tell?
According to redhat documentation for EAP 6.1
protocol
The version of the SSL protocol to use. Supported values include SLv2, SSLv3, >TLSv1, SSLv2+SSLv3, and ALL. The default is ALL
Adding sslProtocol="TLS" and protocol="TLSv2" should work fine. Not to sound condescending, but the easiest way to see if it works is by testing it.
If this question did get moved to another SE site could you please provide the link?