Protect your servers and your data!
To protect the integrity of your environment it is strongly recommended to encrypt and authenticate the network trafficbetween the different FitNesse processes. Both will be achieved with SSL.
Without this
- passwords will be send unencrypted over the network
- your system under test would accept commands from any server which can access it over the network.
- this is especially an issue if the system under test runs in demon mode.
In addition to this also enable user authentication with a Password Cipher .
Only with self created certificates you achieve security!
SSL requires certificates which identify uniquely each server.It just takes 1 minutes to create your own certificates, please take the time to do this.
The certificates in the fitnesse distribution are just there for running junit tests. Never use them for your fitnesse instance.
1. Creating your private SSL keys and certificates
The below just gives the commands how you can create certificates and how to sign them yourself to get started.In a professional environment your company might have further guidelines. Please contact your network or security administrator.
If you are new to SSL browse the web to understand how it works.
A minimum SSL configuration consists of
value used in sample commands | Must be changed by you | ||
1 | A keystore file per server with the private key of each of your server which has been certified | fitnesse.jks | No |
2 | A password for this keystore file | PutYourKeyStorePasswordHere | Yes |
3 | A truststore file which defines with whom your servers should be allowed to communicate | fittrust.jks | No |
4 | A password for this truststore file | PutYourTrustPasswordHere | Yes |
The first three must be known by FitNesse at runtime. To do this you expand the class fitnesse.socketservice.SslParameters
The last one is only required when you want to modify the truststore. For running FitNesse it is not required.
The tool keytool is used to generate the keys. It is part of the jdk.
Below are sample commands to get started. You might add or change values according to your setup.
1.2 Create your server keys and certificate
When asked for your first and last name enter your server name with the domain instead like www.fitnesse.org.
The remaining items don't matter.
When asked for the key password just press enter.
After this step a new file fitnesse.jks is in your current folder
1.3 Protect the fitnesse.jks with all measures your operating system supports
Remove read and write access for anybody else.
1.4 Tell FitNesse your password and the name and location of the keystore file
Create the following class and add it to the classpath of FitNesse
custom SSL Parameter class
import fitnesse.socketservice.SslParameters;
public class YourServerSslParameters extends SslParameters {
public YourServerSslParameters(){
super();
// Below is only for demonstration purpose
// Don't hard code passwords in clear text
// A) Ask the user to enter it each time the system starts. That's the most secure way but often not convenient.
// B) Read it from a file where it is stored obfuscated.
String password = "PutYourKeyStorePasswordHere";
setKeyStorePassword(password);
setKeyStoreFilename("fitnesse.jks");
setTrustStoreFilename("fitnesse.jks");
}
}
You can use the same class also for YourSutSslParameters in the following steps.
2. Secure Communication between the browser and the Wiki Server
Instead of http the communication will be https2.1 Add the following to plugins.properties
plugins.properties
# Wiki Server uses https
wiki.protocol=https
wiki.protocol.ssl.parameter.class=your.package.YourServerSslParameters
2.2 In your browser
Enter https://localhost:port in your webbrowser to connect to the wiki serverIf you signed the certificates yourself your browser will give a security warning.
Accept this warning after you checked the certificate. Add a permanent exception for this certificate to your browser
to avoid that you get this warning each time in the future.
2.3 Client Authentication
If users have certificates, client authentication may be required. To enable client authentication set the following plugins.properties:plugins.properties
# Wiki Server uses https
wiki.protocol=https
wiki.protocol.ssl.parameter.class=your.package.YourServerSslParameters
wiki.protocol.ssl.client.auth=required
Authorization can be accomplished with client certificates with the creation of a custom Authenticator. The Authenticator has access to the peer dn from the Request. Access can be granted or denied based on the dn.
3. Secure Communication between the Test System and the System Under Test
This is currently only supported for the SLIM java client.
FIT and SLIM clients for other programming languages must still be enhanced.
3.1. Configuring SSL on the Test System
The FitNesse Test System and the FitNesse Wiki server are a single process and share the same SSL configurationIf you have not enabled https for the wiki you have to add the below to configure SSL for the test system.
plugins.properties
3.2. Configuring SSL on the SUT
Either enable this for individual test pages by defining the variableor enable this for all SLIM Test Systems on all pages by adding below to 'plugins.properties'.
This configuration takes precedents above an individual page configuration.
plugins.properties
# Enable SSL on the Test Systems
slim.ssl=your.package.YourSutSslParameters
If you use remote debugging and started the SUT manually add the following additional parameter to the command line
4. Troubleshooting SSL configuration
4.1. Start FitNesse with the following two extra parameters to get more output to identify any issues
- -v
- -Djavax.net.debug=ssl,keymanager
Example
4.2. Define the following on your test page to get more output from the SUT
variables on test pages
!define COMMAND_PATTERN (java -Djavax.net.debug=ssl,keymanager -cp %p %m)
4.3. Define the following properties to speed up troubleshooting
This reduces the number of connection attempts. A test with a faulty configuration is then aborted quicker.4.4. Typical error messages in the output from the SUT
Error while executing SLIM instructions: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
Error while executing SLIM instructions: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: null cert chain
java.security.NoSuchAlgorithmException: Error constructing implementation ... java.io.IOException: Keystore was tampered with, or password was incorrect
5. Configuring SSL for a multi server environment
If your system under test doesn't runs on the same server as your Wiki Server consider the blow setup.1.1 Command to create your server keys and certificate
keytool -export -alias selfsigned -file fitnesse.cer -keystore fitnesse.jks -storepass PutYourKeyStorePasswordHere
When asked for your first and last name enter your server name with the domain instead like www.fitnesse.org.
The remaining items don't matter.
When asked for the key password just press enter.
If you have more then one server on which you run SUT you should do this for each server.
To not overwrite the keystores and certificates change each time the fitnesse.jks and fitnesse.cer parameters.
IMPORTANT: Protect the fitnesse.jks with all measures your operating system supports! Give only read access to users who need this.
Remove read and write access for anybody else.
1.2 Commands to create your trust store
same truststore file fittrust.jks
1.3 Configure FitNesse with your certificates
Once you have run these commands you have two types of files in your current directory fitnesse.jks and fittrust.jksCopy both into your FitNesse directoy from which you start FitNesse or your SUT. Make again sure that your fitnesse.jks
and fittrust.jks are protected.
Create the following class and add it to the classpath of FitNesse
custom SSL Parameter class
import fitnesse.socketservice.SslParameters;
public class YourServerSslParameters extends SslParameters {
public YourServerSslParameters(){
super();
// Below is only for demonstration purpose
// Don't hard code passwords in clear text
// A) Ask the user to enter it each time the system starts. That's the most secure way but often not convenient.
// B) Read it from a file where it is stored obfuscated.
String password = "PutYourKeyStorePasswordHere";
setKeyStorePassword(password);
setKeyStoreFilename("fitnesse.jks");
setTrustStoreFilename("fittrust.jks");
}
}
Create identical classes named YourSutSslParameters for each server running SUT but give the values of the
fitnesse.jks you created for each server and add the class to the classpath of the SUT.