Installing the Java Module as a Jetty Handler
Last updated 2023-01-20
IMPORTANT
This guide only applies to Next-Gen WAF customers with access to the Next-Gen WAF control panel. If you have access to the Next-Gen WAF product in the Fastly control panel, you can only deploy the Next-Gen WAF with the Edge WAF deployment method.
Requirements
Jetty 9.2 or higher
Supported Application Types
For Jetty specific implementations, we support a HandlerWrapper-based install on Jetty 9.2 or higher.
We also provide a lower-level agent RPC communication API if you are interested in writing an implementation for another Java platform. If you are interested in writing an implementation for another Java platform, reach out to our support team.
Agent Configuration
Like other Next-Gen WAF modules, the Jetty Handler supports both Unix domain sockets and TCP sockets for communication with the Next-Gen WAF agent. By default, the agent uses Unix domain sockets with the address set to unix:/var/run/sigsci.sock
. It is possible to override this or specify a TCP socket instead by configuring the rpc-address
parameter in the Agent.
Additionally, ensure the agent is configured to use the default RPC version: rpc-version=0
. This can be done by verifying the parameter rpc-version
is not specified in the agent configuration or if it is specified, ensure that is specified with a value of 0
. Below is an example Agent configuration that overrides the default Unix domain socket value:
123
accesskeyid = "YOUR AGENT ACCESSKEYID"secretaccesskey = "YOUR AGENT SECRETACCESSKEY"rpc-address = "127.0.0.1:9999"
Download
Download the Next-Gen WAF Java module manually or access it with Maven.
Download manually
- Download the Java module archive from https://dl.signalsciences.net/sigsci-module-java/sigsci-module-java_latest.tar.gz.
- Extract
sigsci-module-java_latest.tar.gz
. - Deploy the jars using one of the following options:
- Copy
sigsci-module-java-{version}-shaded.jar
(an uber jar with all the dependencies bundled) to your application’s classpath (e.g.,%CATALINA_HOME%\webbapps\<APP_FOLDER>\WEB-INF\lib
). - Copy
sigsci-module-java-{version}.jar
and its dependencies in thelib
folder to your application’s classpath (e.g.,%CATALINA_HOME%\webbapps\<APP_FOLDER>\WEB-INF\lib
). If you already have any of the dependency jar files in your application classpath folder (i.e., for Tomcat in theWEB-INF\lib
) then it is not necessary to copy them, even if the version numbers are different. The logging jars are optional based on howslf4j
is configured.
- Copy
Access with Maven
For projects using Maven for build or deployment, the latest version of Next-Gen WAF Java modules can be installed by adding XML to the project pom.xml
file. For example:
123456789101112
<repositories> <repository> <id>sigsci-stable</id> <url>https://packages.signalsciences.net/release/maven2</url> </repository></repositories>
<dependency> <groupId>com.signalsciences</groupId> <artifactId>sigsci-module-java</artifactId> <version>LATEST_MODULE_VERSION</version></dependency>
Be sure to replace LATEST_MODULE_VERSION
with the latest release of the Java module. You can find the latest version in our version file at https://dl.signalsciences.net/sigsci-module-java/VERSION.
Install
The installation of the Jetty module varies slightly depending upon whether you deployed Jetty as an embedded or stand alone application.
If you are embedding Jetty within your web application, follow the instructions for Embedded Jetty.
Alternatively, if you are deploying your web application to a Jetty instance, follow the instructions for Standalone Jetty.
Embedded Jetty
The Next-Gen WAF Jetty module is currently implemented as a Handler. Edit your application to wrap your existing Handlers with the Next-Gen WAF Handler.
A typical Jetty based application will add all of the Handlers to a HandlerList, similar to this:
123456789101112131415161718192021222324252627
Server server = new Server(InetSocketAddress.createUnresolved("0.0.0.0", 8800));ServletContextHandler context = new ServletContextHandler();ServletHolder defHolder = new ServletHolder("default", DefaultServlet.class);HandlerList handlers = new HandlerList();
// Servlet: /defHolder.setInitParameter("pathInfoOnly", "true");defHolder.setInitParameter("dirAllowed", "true");defHolder.setInitParameter("acceptRanges", "true");context.addServlet(defHolder, "/*");context.addServlet(defHolder, "/");
// Existing App Handlershandlers.addHandler(context);handlers.addHandler(new DefaultHandler());
// Add the existing handlers as the server handlerserver.setHandler(handlers);
try {server.start();server.join();} catch (Exception e) {e.printStackTrace();} finally {server.stop();}
Add the Next-Gen WAF Handler around your primary handler. For example:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
Server server = new Server(InetSocketAddress.createUnresolved("0.0.0.0", 8800));ServletContextHandler context = new ServletContextHandler();ServletHolder defHolder = new ServletHolder("default", DefaultServlet.class);HandlerList handlers = new HandlerList();
// Servlet: /defHolder.setInitParameter("pathInfoOnly", "true");defHolder.setInitParameter("dirAllowed", "true");defHolder.setInitParameter("acceptRanges", "true");context.addServlet(defHolder, "/*");context.addServlet(defHolder, "/");
// Existing App Handlershandlers.addHandler(context);handlers.addHandler(new DefaultHandler());
// REMOVED: This is replaced by wrapping with the sigsci handler below//server.setHandler(handlers);
//////////////////////////////////////////////////////////////////////////// BEGIN ADDITION: Next-Gen WAF Handler// Need to also add these imports for SignalSciencesHandler and Timeout:// import com.signalsciences.jetty.SignalSciencesHandler;// import com.signalsciences.rpc.util.Timeout;//////////////////////////////////////////////////////////////////////////// 1. Create a new SignalSciencesHandlerSignalSciencesHandler sigsciHandler = new SignalSciencesHandler();// 2. Specify the URI of the sigsci-agent rpc-address (Unix)sigsciHandler.getSigSciConfig().setRpcServerURI(URI.create("unix:/var/run/sigsci.sock"));// 3. Specify a timeoutsigsciHandler.getSigSciConfig().setRpcTimeout(new Timeout(300, TimeUnit.MILLISECONDS));// 4. Set rpcVersion to 0sigsciHandler.getSigSciConfig().setRpcVersion(0);// 5. Wrap the other handlerssigsciHandler.setHandler(handlers);// 6. Set the SignalSciencesHandler (wrapper) as the server handlerserver.setHandler(sigsciHandler);//////////////////////////////////////////////////////////////////////////// END ADDITION//////////////////////////////////////////////////////////////////////////
try {server.start();server.join();} catch (Exception e) {e.printStackTrace();} finally {server.stop();}
Standalone Jetty
The Next-Gen WAF Jetty module is currently implemented as a handler. To use this, you will need to follow the steps below to update your server configuration.
Update Jetty Server Configuration File
In a default Jetty installation, the server configuration file can be found under {jetty.base}/etc/jetty.xml
. You will need to update the configuration file to wrap the existing Handlers with the Next-Gen WAF Handler. Modify the stanza in the file that specifies the handler collection to include the Next-Gen WAF Handler. Below is an example using the out of the box jetty.xml
file:
1234567891011121314151617181920212223242526272829303132333435
<Set name="handler"> <New id="Wrapper" class="com.signalsciences.jetty.SignalSciencesHandler"> <Call name="setRpcServerURI"> <Arg> <New class="java.net.URI"> <Arg>unix:/var/run/sigsci.sock</Arg> </New> </Arg> </Call> <Call name="setRpcTimeout"> <Arg> <New class="com.signalsciences.rpc.util.Timeout"> <Arg type="long">300</Arg> <Arg> <Get class="java.util.concurrent.TimeUnit" name="MILLISECONDS"/> </Arg> </New> </Arg> </Call> <Set name="handler"> <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection"> <Set name="handlers"> <Array type="org.eclipse.jetty.server.Handler"> <Item> <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/> </Item> <Item> <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/> </Item> </Array> </Set> </New> </Set> </New></Set>
Deploy Signal Sciences Library to the Server ClassPath
There are two options for deploying the jars:
- Copy
sigsci-module-java-{version}-shaded.jar
(an uber jar with all the dependencies bundled) to your server classpath. - Copy
sigsci-module-java-{version}.jar
and its dependencies in thelib
folder to your server classpath.
Although optional, we recommended adding this library to {jetty.base}/lib/ext
, as Jetty automatically loads libraries in this path to the server classpath.
Simple Example Server
For a more complete example, see the sigsci-jetty-simple-example
JAR files included in the distribution. This consists of the binaries, source, and javadoc for a simple working example. The binary JAR is executable and can be run with commands similar to the following. These commands will start the simple server and point it at an agent running on TCP port 5000 on the local host, which require an agent started with rpc-address = "127.0.0.1:5000"
:
$ java -jar examples/sigsci-jetty-simple-example-{version}.jar
That command will produce the following output:
tcp://127.0.0.1:500000:00:00.384 [main] INFO c.s.example.SimpleExampleServer - WebRoot is jar:file:/x/sigsci-jetty-simple-example-0.1.3.jar!/webroot/00:00:00.403 [main] INFO c.s.example.SimpleExampleServer - Signal Sciences WAF: enabled00:00:00.501 [main] INFO c.s.example.SimpleExampleServer - Signal Sciences Simple Example Server started (http://0.0.0.0:8800/)00:00:00.986 [qtp123456789-12] INFO c.s.example.RequestLogger - "GET /test/ HTTP/1.1" 302
This example test server will respond with a simple HTML page on the root directory. It can also be used to do basic tests using the /test/
context. In this test context the following parameters are interpreted:
response_time
: Time in milliseconds to delay the response - to test timeouts.response_code
: The HTTP response code to return in the response.size
: The size of the response body in bytes.
For example:
$ curl -D- "http://127.0.0.1:8800/test/?response_code=302&response_time=10&size=86"
That command will produce the following output:
HTTP/1.1 302 FoundDate: Sat, 01 Sep 2016 00:00:00 GMTLocation: /Content-Length: 86Server: Jetty(9.2.z-SNAPSHOT)
Do not use this form to send sensitive information. If you need assistance, contact support. This form is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.