I want to apply compression to my responses at tomcat level however it does not work. It seems like an esay protocol, however somehow I am unable to apply it. Here is my connector conf in server.xml
<Connector port="80" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
maxThreads="500"
processorCache="500"
maxConnections="10000"
acceptCount="5000"
URIEncoding="UTF-8"
useSendfile="false"
compression="force"
compressionMinSize="4"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript"/>
I disabled antivirus on my local macihne(Client-side) and the requests have Accept-Encoding:gzip header. Thank you in advance.
Too late but:
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.
Related
I am using Tomcat 8.5 to host a WAR which is used for java REST services.
In my rest service, I create a connection and take a multi-part form data file from user, scan it using a scan engine and return the result. At the start, tomcat is running fine and giving a speed of almost 57-58 Mbps but degrades over time (degrades to nearly half in 5-8 min)
My setenv.bat file looks like this.
"set "JAVA_OPTS=%JAVA_OPTS% -Xms1024m -Xmx5120m -XX:MaxMetaspaceSize=512m -Xincgc -server""
JVM is using ParNewGC for garbage collection.
my server.xml file looks like this
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="100" minSpareThreads="8" maxSpareThreads="10" acceptorThreadCount="16" acceptCount="500"/>
<!--acceptCount :The maximum queue length for incoming connection requests when all possible request processing threads are in use. Any requests received when the queue is full will be refused. The default value is 100.
A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
-->
<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" socket.rxBufSize="10000000" socket.txBufSize="3000000" socket.directBuffer="true" />
<!-- A "Connector" using the shared thread pool-->
As my response is completely dynamic. I am not using any type of caching. please help me with this issue.
It may be a error due to a large number of open tcp/ip connections .Try connecting with server for once and send data check for sockets when you see a performance degradation.
In windows, you can use netstat-an to check the open sockets.
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"/>
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 get following error when I try to access some JasperReports Server pages:
Request Entity Too Large The requested resource
/jasperserver/olap/viewOlap.html does not allow request data with GET
requests, or the amount of data provided in the request exceeds the
capacity limit.
I checked the Apache log files and got following error in mod_jk.log
[Thu Nov 10 10:25:00 2016][8964:3876] [error]
ajp_marshal_into_msgb::jk_ajp_common.c (517): failed appending the
query string of length 7417
I already tried many different ways to solve it.
I added the maxHttpHeaderSize and max_packet_size attributes to the ajp connect of Tomcat (server.xml):
<Connector port="8010" protocol="AJP/1.3" connectionTimeout="20000" redirectPort="8443" maxHttpHeaderSize="65536" max_packet_size="65536" />
Also I added the LimitRequestLine, LimitRequestBody, LimitRequestFieldSize and LimitRequestFields to the Apache httpd.conf file (added it to the end of the file without any VirtualHost):
LimitRequestLine 65536
LimitRequestBody 0
LimitRequestFieldSize 65536
LimitRequestFields 10000
I am still getting the error above.
I also found some suggestions to add the max_packet_size to the workers.properties of Apache. But if I add the attribute I get a HTTP 400 error and a white page. That's why I commented the property in workers.properties:
#worker.jasper.max_packet_size=65536
I restarted all services after changing the configurations.
When I access the same pages via HTTP-Connector of Tomcat (http://HOSTNAME:8081/jasperserver/..) it works fine. Only when I access it via AJP-Connector of Apache (http://HOSTNAME/jasperserver/..) I get the error. So I think there should be any problem with the AJP-Connector.
Apache: 2.4.12
JasperReports Server: 6.2.1
Apache Tomcat Version 8.0.14:
Does anyone have a suggestion what I have to do to solve the issue?
I figured out the problem.
The attribute in server.xml for Tomcat has to be
packetSize
and not
max_packet_size
See also documentation AJP Connector
After renaming it, it works fine.
Here are my configurations:
Tomcat server.xml:
Connector port="8010" protocol="AJP/1.3" redirectPort="8443" packetSize="65536"
Apache workers.properties:
worker.jasper.max_packet_size=65536
If you get afterwards the error:
Request-URI Too Long
The requested URL's length exceeds the capacity limit for this server.
You have to set following attributes in Apache httpd.conf file:
LimitRequestLine 65536
LimitRequestBody 0
LimitRequestFieldSize 65536
LimitRequestFields 10000
I hope this answer helps others too.
Need Step-by-Step Overview for Compression on Tomcat 7 ... I've been at this for days. Particularly interested in compressing text/xml in response from a servlet, but would also like to test other compressions.
From my googling and reading, it seems like I only need to add a few lines to configure the http connector in server.xml (see below). But I'm checking on sites like webpagetest.org and not seeing any results (not even gzip in the response header). What more do I need? Filters? Use of GZip methods within my app? Specifying the servlet(s) for output compression in web.xml? I'll be more than happy to continue getting the details right and would be happy just now to be sure I know what all the necessary parts are.
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
compression="on"
compressionMinSize="2048"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/xml,application/xml,text/javascript,text/css" />
UPDATE. SOLVED ... see comments under accepted answer below.
Did you restart Tomcat after editing server.xml file ?
Did you check the logs (logs/catalina.out) to see if there is any error on server startup ? (ie. typo in the config files)
compression="on"
should work.
Maybe webpagetest.org doesn't support gzip compression. Why don't you use Chrome Developper Tools (F12, you can see headers in the Network tab) ? or Firefox Web Console (Ctrl+Shift+K) ?