Note |
---|
This page is under construction, as investigation of Jetty 12 is in the early phases. The material is subject to change. |
Using Jetty 12.0
Note |
---|
These pages are examples and do not reflect any normative requirements or assumptions on the part of the IdP software and may be a mix of suggestions from both the project team and deployers. You should take any of this advice with a grain of local salt and consider general security/deployment considerations appropriate to the use of web software in your local environment. The official information about containers and versions we support is solely maintained on the SystemRequirements page. If you wish to operate without complete responsibility for your Java servlet container, you may consider the Windows package we provide that installs a version of Jetty with very limited configurability. |
...
Migrating from Jetty 11 (or 10 if making the jump) is a “mostly lateral” process except that the version of logback will be different because of the Servlet API changes in this version. If you use the “recommended” approach of using logback with Jetty, you’ll need get a different set of jars appropriate to that version’s logging module(s) when adding that module.
The most significant difference from a Shibboleth perspective is that we do not have a supported mechanism to convince Jetty to accept client TLS certificate authentication on a secondary port from arbitrary certificates. This is the so-called “back-channel” support that, while very much historical at this point, dates to the very early days of the project. The Shibboleth software (both IdP and SP) are fully capable of operating all profiles over port 443, with so-called “back-channel” use cases generally relying on message signing as a substitute for mutual TLS, which is generally not as easy to deploy nowadays due to proxying and load balancers.
...
Code Block |
---|
$ git clone https://git.shibboleth.net/git/java-idp-jetty-base $ cd java-idp-jetty-base $ git checkout 12 $ cp -r jetty-impl/src/main/resources/net/shibboleth/idp/module/jetty/jetty-base /my/desired/location/ |
...
Code Block | ||
---|---|---|
| ||
# Any other required Jetty modules... # Allows setting Java system properties (-Dname=value) # and JVM flags (-X, -XX) in this file # NOTE: spawns child Java process --exec # Uncomment if IdP is installed somewhere other than /opt/shibboleth-idp #-Didp.home=/path/to/shibboleth-idp # Maximum amount of memory that Jetty may use, at least 1.5G is recommended # for handling larger (> 25M) metadata files but you will need to test on # your particular metadata configuration. If MDQ metadata on demand is used, # requirements may be much lower. -Xmx1500m # Prevent blocking for entropy. -Djava.security.egd=file:/dev/urandom # Set Java tmp location -Djava.io.tmpdir=tmp |
Configure HTTP/HTTPS Connectors
...
# May be needed in certain cases depending on content of TLS certificate.
#jetty.ssl.sniHostCheck=false |
Configure HTTP/HTTPS Connectors
File(s): credentials/idp-userfacing.p12, start.d/idp.ini
...
One challenge remains that if you want to use standard ports on Linux, you would need to pick one of these options to avoid running as root:
Use the setuid extension module to support listening on the privileged ports as a non-root user. This extension is now JNA-based and is seems to be undocumented at this point, and has not yet been triedbut works fine.
Use a port forwarding approach (load balancer, iptables rules, etc).
Adjust the range of ports considered privileged if supported by your Linux kernel.
Use POSIX capabilities to allow use of priviledged ports by an unpriviledged process, e.g. when using systemd by setting
AmbientCapabilities=CAP_NET_BIND_SERVICE
Example idp.ini
Expand | ||
---|---|---|
| ||
|
The TLS credential example relies on a PKCS12 file containing the X.509 certificate and private key used to secure the HTTPS channel that users access during authentication and other browser-based message exchanges involving the IdP. This is generally the one you get from a browser-compatible CA, and the example shows it being loaded from a directory inside the JETTY_BASE
tree.
...
Code Block | ||
---|---|---|
| ||
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext">
<Set name="war">/opt/shibboleth-idp/war/idp.war</Set>
<Set name="contextPath">/idp</Set>
<Set name="extractWAR">false</Set>
<Set name="copyWebDir">false</Set>
<Set name="copyWebInf">true</Set>
</Configure> |
...
Code Block |
---|
$ java -jar /opt/jetty-home-1112.0.0/start.jar --add-module=logging-logback |
Jetty will populate a lib/logging folder with the 2 logback libraries it requires. If there are older versions left behind by earlier Jetty versions, you will need to remove them.
Note |
---|
Of course, this is completely insecure. If you want to be appropriately careful, you can compare the 2 jars it downloads to the signed copies available from Maven Central and check their signatures. |
...
The next step is to instruct Jetty to produce its access/request log using the same logging APIs it uses for everything else. This is not a Jetty module at this point, so requires the etc/jetty-requestlog.xml file we provide:
Expand | ||||||
---|---|---|---|---|---|---|
| ||||||
|
A sample logback configuration for both debug and request logging is provided in resources/logback.xml.
...
Jetty has had vulnerabilities related to directory indexing (sigh) so we suggest disabling that feature at this point. There are a few different ways this can be done, but one method that's fairly self-contained within the IdP footprint is to modify web.xml (i.e. copy the original version from idp.home/dist/webapp/WEB-INF/web.xml to idp.home/edit-webapp/WEB-INF/web.xml) and then rebuild the war file.
web.xml addition
...
Code Block | ||
---|---|---|
| ||
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.eclipse.jetty.ee9.servlet.DefaultServlet</servlet-class>
<init-param>
<param-name>dirAllowed</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet> |
...
As noted above, this is no longer something we support via a separate port. You should publish support for SOAP, if you need it, on port 443 in your metadata. The IdP will automatically reject any requests it cannot authenticate using message signatures.
Other Modules
Jetty has a ton of advanced and optional functionality available in the form of modules that can be enabled selectively. They don't function in the way Apache modules do, but they're basically packaged "example" configuration files that will get copied from JETTY_HOME
into JETTY_BASE
when you need them and you get "just" the minimum files needed to support the feature but keep future upgrades simple.
...
Code Block |
---|
$ cd jetty-base $ java -jar /opt/jetty-home-1112.0.0/start.jar --add-module=modulename |
Supporting
...
File(s): modules/idp.mod, start.d/idp.ini
...
X-Forwarded-For Natively
If you are running the Jetty engine behind a proxy or load balancer Jetty has built-in support for forwarding the client address and other details via headers using its http“http-forwarded forwarded” module, and after enabling it as above adding it with the --add-module command (see previous section) you can edit the resulting properties file https-forwarded.ini file it will create to configure it.
Note that this example applies the forwarding rule to all ports, so if you also operate the server on other ports, those must also be proxied/protected or this will lead to exposures due to clients having the ability to smuggle in a false client address.
Local Proxying via Apache
If your IdP is behind Apache rather than proxied via a load balancer, you probably might only need it to listen for HTTP traffic locally. This is not applicable in general to load balancing via an applicance like an F5 or NetScaler.
At present, this involves commenting out or removing two lines from the [depend] section of idp.mod: the lines containing https and ssl.
Next, add modules to be loaded in start.d/idp.ini. Alternatively, create your own start.d/http.ini to keep this configuration separate. Add the following to one of these files.
--module=http
.
The http-forwarded module mentioned above is also required so that requests coming to the IdP aren't seen as coming from localhost. Follow the instructions above to install this module or, since its defaults are acceptable, just add the following to start.d/idp.ini or start.d/http.ini:--module=http-forwarded
Finally, make sure the jetty.http.host and jetty.http.port properties are set apropriately in idp.ini, or remove them from there and add them to http.ini.
...
Since 8080 is the default http port for Jetty, It's also okay to leave this unset. That change will confine Jetty to listen locally only rather than over a network.