Table of Contents
Tomcat Installation Hints
Optimize Tomcat Installation
Tomcat can be configured to support compression to increase the performance of the web application:
Open the file Tomcat/conf/server.xml and locate the connector:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
Change the entry to:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" compression="on" compressionMinSize="256" compressibleMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json,image/svg+xml" />
Restart Tomcat.
Tomcat HTTPS Proxy
If there is a proxy in front of the Tomcat server, expecting https traffic, you have to modify your Apache Tomcat to redirect http traffic to https.
Open the file Tomcat/conf/server.xml and locate the connector:
<Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
Insert the proxy name and port. For instance:
<Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" proxyName="proxy.yourdomain.dk" proxyPort="443" scheme="https" secure="true" />
Save the server.xml and restart the Tomcat service to apply your changes
Client IP behind a proxy
Behind a proxy, Tomcat only sees the proxy's IP address. AWP therefore takes the client IP from the X-Forwarded-For header, which the proxy must send. This IP is used by the “Limit to IP addresses” options of the guest access and the Direct URL and in the log files.
The header is only trusted when the request comes from a private IP address (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8 and similar), which covers every Docker network. This is configured in awp/META-INF/context.xml:
<Valve className="org.apache.catalina.valves.RemoteIpValve" protocolHeader="" />
If clients from a private network can reach Tomcat directly, bypassing the proxy, they could send a wrong IP address this way. Restrict the trusted addresses to the proxy with the internalProxies attribute, a regular expression. The same attribute is needed when the proxy has a public IP address:
<Valve className="org.apache.catalina.valves.RemoteIpValve" protocolHeader="" internalProxies="172\.18\.0\.5" />
Upload size
A single asset upload is limited to 10 GB. To change the limit, add the following block to the awp/WEB-INF/web.xml. Both values are in bytes, the example allows 20 GB:
<servlet> <servlet-name>UploadServlet</servlet-name> <multipart-config> <max-file-size>21474836480</max-file-size> <max-request-size>21474836480</max-request-size> </multipart-config> </servlet>
Uploads are stored in Tomcat's temporary directory until they are passed on to Fylr, so it needs enough free space for the largest upload. A proxy in front of Tomcat may have its own limit, e.g. client_max_body_size in nginx.
Security Response Headers
AWP automatically sends several headers to increase the web application's security. In some rare case this might affect integrations with other applications and can therefore be configured with options in the web.xml. After changing any of the options a restart of Tomcat is recommended. It's also a good idea to test modified headers with a service like https://securityheaders.com/.
To disable a header completely the following block can be used:
<context-param> <param-name>header key</param-name> <param-value>disable</param-value> </context-param>
To sent a custom header replace the disable param value with the wanted header value.
The following table lists all sent headers including their default values. Some of the headers are dynamically enriched to automatically enable external data sources, for example when a map provider has been enabled.
| Header | Key |
|---|---|
| Content Security Policy | securityheadersfilter.csp ** default-src 'none'; connect-src 'self' ;font-src 'self' data:; frame-ancestors 'self'; frame-src 'self'; img-src 'self' https: data:; media-src 'self'; object-src 'self' blob:; script-src 'self';style-src 'self' 'unsafe-inline' blob:; base-uri 'self'; form-action 'self'; ** |
| Permissions-Policy | securityheadersfilter.permissions-policy accelerometer=(), autoplay=(), camera=(), encrypted-media=(), fullscreen=(self), geolocation=(self), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), sync-xhr=(self), usb=() |
| Referrer-Policy | securityheadersfilter.referrer-policy same-origin |
| Strict-Transport-Security | securityheadersfilter.strict-transport-security max-age=31536000 Only sent for HTTPS requests, which includes requests forwarded by a proxy with X-Forwarded-Proto: https. Browsers then refuse plain HTTP for this host for one year, so disable the header for instances that are also used via HTTP. |
| X-Content-Type-Options | securityheadersfilter.x-content-type-options nosniff |
Enable SameSite cookie
AWP sends its session cookie with SameSite=Lax, which keeps it away from requests started by other websites. Embedding AWP into a page of another website using an iframe requires SameSite=None instead. This can be changed by editing the awp/META-INF/context.xml:
Change the line
<CookieProcessor sameSiteCookies="lax" />
to
<CookieProcessor sameSiteCookies="none" />
using an UTF-8 compatible text editor, save the changes and restart Tomcat.
The Content Security Policy only allows AWP itself to embed AWP pages (frame-ancestors 'self'). To embed AWP into another website, set securityheadersfilter.csp to the default value from the table above with that website added to frame-ancestors, e.g. frame-ancestors 'self' https://www.example.com;
Secure SSL/TLS Setup
To disable insecure older implementations of SSL/TLS we recommend the following connector configuration:
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false"> <SSLHostConfig protocols="TLSv1.2, TLSv1.3" honorCipherOrder="true" ciphers="TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"> <Certificate certificateKeystoreFile="conf/certificate.pfx" certificateKeystoreType="PKCS12" certificateKeystorePassword="certificate-password" /> </SSLHostConfig> </Connector>
