Installing SSL certificate on JBoss - ssl

I have a server that runs JBoss. When I type bad URL to that server it gives me version like this: JBossWeb/2.0.1.GA - what version of JBoss that would be? A SSL certificate will be bought and provided for me so that I could install it in JBoss. I would really appreciate any HOWTO or any information how to install ready SSL certificate on JBoss. Do I need to generate any files with openssl, when this SSL certificate will be bought from some other company that sells SSL certificates?
Thanks in advance for any help.

You can generate your own SSL certificate:
First off you need to create a self-signed certificate. You do this using the keytools application that comes with Java. Open a command prompt and run the following command. You will need to change the path to your Jboss conf directory to reflect your install:
C:\>keytool -genkey -alias tomcat -keyalg RSA -keystore C:\jboss-2.0.1.GA\server\default\conf\localhost.keystore
When prompted use a password of changeit everywhere. It’s important that you answer localhost to the first question:
Enter keystore password: changeit
Re-enter new password: changeit
What is your first and last name?
[Unknown]: localhost
What is the name of your organizational unit?
[Unknown]:
What is the name of your organization?
[Unknown]:
What is the name of your City or Locality?
[Unknown]:
What is the name of your State or Province?
[Unknown]:
What is the two-letter country code for this unit?
[Unknown]: NZ
Is CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=NZ correct?
[no]: yes
Enter key password for
(RETURN if same as keystore password): changeit
Re-enter new password: changeit
Next up you need to configure tomcat to create a SSL connector.
Edit C:\jboss-2.0.1.GA\server\default\deploy\jboss-web.deployer\server.xml and find the commented out SSL connector example, uncomment it and tweak it as follows:
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="${jboss.server.home.dir}/conf/localhost.keystore"
keystorePass="changeit"
/>
Finally add two System properties to your Jboss startup command to get the javax.net.ssl library to use your new keystore. These are only needed if you need to make SSL calls back to yourself. I needed them because I had CAS and 3 apps authenticating with CAS all running in the same dev Jboss instance:
-Djavax.net.ssl.trustStore=C:\jboss-2.0.1.GA\server\default\conf\localhost.keystore
-Djavax.net.ssl.trustStorePassword=changeit
Ok now browse to http://localhost:8443/
Your browser will complain about a self-signed certificate. Just follow your browser’s instructions to add this certificate as a security exception so you won’t be prompted again and you are all done.

I know this post is quite old, bui i want to share the steps needed for a much more recent version of Wildfly (JBoss AS in early times).
First of all you need to create your self-signed certificate. If you already have a keystore, you can skip this steps.
Go to your Wildfly/ Jboss home folder and create a new directory called "keystore"
Download the KeyStore Explorer application.
Open it and choose "Create a new KeyStore"
In the dialog that appears, choose JKS. In most cases it is fine, but in other platform
for example on Android you need to use the BKS format type.
Now right click and choose 'Create new Key Pair'. You can safely accept the default.
(RSA/2048)
In the dialog that appears, customize it to your needs. Anyway i suggest to use the
Version 3 and SHA-256 with RSA.
Click on the 'Edit name' button in the bottom-right area of the dialog, that corresponds
to the Name field. Fill all fields and click ok.
Click ok on the other dialog.
Now it will be asked to insert a neme for an alias. Type jbossWildfly and click ok, and then
insert the password that will be used to unlock this alias. I highly suggest to
save this data somewhere in your computer.
Now you have successfully generated a key pair. Save it with the name keystore.jks in the keystore folder that we have created previously, then insert a new password that
will be used to unlock the keystore. You can use the same of the previously one if
you want.
Now open the standalone.xml file located in:
$WILDFLY_HOME$\standalone\configuration
And add a new Security Realm inside the <security-realms> tag:
<security-realm name="MyNewSecurityRealm">
<server-identities>
<ssl>
<keystore path="$WILDFLY_HOME$\keystore\keystore.jks" keystore-password="keystore_password" alias="jbossWildfly" key-password="alias_password"/>
</ssl>
</server-identities>
</security-realm>
Again change $WILDFLY_HOME$ with the real path to the home dir and change the password to what you've typed.
Now you need to assign your new Security realm to the HTTPS listener of the default-server:
<server name="default-server">
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
<https-listener name="https" socket-binding="https" security-realm="MyNewSecurityRealm" enable-http2="true"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<http-invoker security-realm="MyNewSecurityRealm"/>
</host>
</server>
Remember that by default the HTTPS listener is binded to the 8443 port:
<socket-binding name="https" port="${jboss.https.port:8443}"/>
So your calls to the server would be something like this: (accessing on localhost)
https://localhost:8443/
Hope it can help! :)

Related

Client certificate based authentication HAProxy and a general questions

I want to add to a Tomcat servlet (which is behind a HAProxy server) client based authentication so what I did was
I've updated Tomcat configuration by adding
<Connector port="18443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="want" sslProtocol="TLS"
keystoreFile="conf/cert/server-keystore.jks"
keystorePass="changeit"
truststoreFile="conf/cert/server-truststore.jks"
truststorePass="changeit" />
P.S more info on https://docs.bmc.com/docs/rsso1908/configuring-the-tomcat-server-for-certificate-based-authentication-907302408.html
I also updated my HAProxy configuration by updating several lines, i.e
listen VIP
bind 172.16.200.85:443 transparent ssl crt /etc/haproxy/cert/server.pem ca-file /etc/haproxy/cert/ca.crt verify required crl-file /etc/haproxy/cert/root_crl.pem
P.S more info on https://www.loadbalancer.org/blog/client-certificate-authentication-with-haproxy/
and when I navigate to a page I get prompted for a certificate immediately, and I don't want that. What I want is a specific path, i.e /login/me to prompt for a certificate to choose. Basically, I want the same solution for client certificate authentication as on
https://secure.login.gov/
--> select "Sign in with your government employee ID"
--> click on the button "Insert your PIV/CAC" [you get a certificate list to choose from]
My questions:
How they are able to to accomplish client certificate based authentication via (it seems) a path "/login/piv_cac"?
I'm asking this, because I've found answers on a stackoverflow configure tomcat for client authentication only for specific URL patterns that this is not possible to accomplish. I've also tried my self, but I get always prompted for a client certificate upon connecting to a Tomcat instance (before navigating to an authentication url)
Is it doable with two Tomcat instances behind a HAProxy?
If so, what would be a general HAProxy configuration [or steps] for this?
If not, what do I need to make it happen?
Do I need one Tomcat instance for "casual" human beings and other Tomcat instance for "certified" human beings?

Tomcat 9.x.x Client Authentication using X.509 Certificates

I’m using Tomcat 9.0.19 and trying to enable X.509 cert.-based client authentication (AKA I&A) for a particular Web application.
In summary, the Tomcat works for an application that has basic I&A enabled over one-way TLS. When accessing the Web application that has certificate-based I&A, Tomcat does not seem to request a client certificate as part of the Server Hello message, prior to sending Server Hello Done and it later fails the authentication check:
02-Jan-2020 13:00:40.371 FINE [https-jsse-nio-443-exec-10] org.apache.catalina.authenticator.SSLAuthenticator.doAuthenticate Looking up certificates
02-Jan-2020 13:00:40.830 FINE [https-jsse-nio-443-exec-10] org.apache.catalina.authenticator.SSLAuthenticator.doAuthenticate No certificates included with this request
Traced the TLS flow in Wireshark and saw the TLS 1.2 handshake. Shortly after encrypted data is exchanged, the Tomcat sends an “Encrypted Alert” message and the socket is closed. Trying to contact the Tomcat from the browser, doing a GET. The browser does not prompt me to select a certificate, which also seems to point to Tomcat not requesting it from the browser.
Any help will be greatly appreciated!
More Details:
We have a set of certificates for the Tomcat and the client, issued by an Intermediate CA, which is signed (issued) by a Root CA. The trust stores have been setup on both sides (client and server) as well as key stores with the right certs/keys in them. The Web application is setup to require certificate I&A (web.xml):
<security-constraint>
<web-resource-collection>
<web-resource-name>All by default</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>OTService</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>certificate</realm-name>
</login-config>
The OTService role is setup in the Tomcat-Users.xml, along with a single user account:
Now, the Connector in server.xml is configured as follows:
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="100" SSLEnabled="true" scheme="https" secure="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="/apache-tomcat-9.0.19/conf/km/keyStore.jks"
certificateKeystorePassword="PASSWORD"
certificateKeyAlias="tomcat"
type="RSA" />
truststoreFile="/apache-tomcat-9.0.19/conf/km/trust_store.jks"
truststorePass="PASSWORD"
truststoreType="JKS"
certificateVerification="required"
clientAuth="true"
protocols="TLSv1.2"
</SSLHostConfig>
</Connector>
Any ideas why Tomcat would not request a client certificate?
The first issue that I discovered was that Tomcat ignored the Connector->SSLHostConfig settings for the trust store and used the JRE default trust store anyway. The way I discovered it was to have a browser save the negotiated TLS session key to a file (Google SSLKEYLOGFILE), then configured the Wireshark to use that file, captured the browser-Tomcat session and then was able to see every message in plaintext.
Next, I discovered that Tomcat was actually asking for a client cert., but the list of accepted Root CAs it was sending was from the default JRE cacerts file, not from the file specified by the truststoreFile attribute. Can have Tomcat use a different file across the board by adding a setenv.sh file to the Tomcat bin directory with Java properties to override default trust store location.
Now, I was in business, the browser was able to complete the TLS handshake, but then the authentication and authorization steps were failing. I finally determinate that the proper way to provide the cert. subject field in tomcat_users.xml file was not "CN=OU Client, OU=Control Systems, O=IoTOY, L=Scottsdale, S=AZ, C=US", but "CN=OU Client, OU=Control Systems, O=IoTOY, L=Scottsdale, ST=AZ, C=US". Finally, I had 2-way TLS working.
One thing to keep in mind is if anything running on the Tomcat attempts to connect over TLS to another system that uses commercial CA certs, it will fail because the truststore you're using now does not have commercial Root CAs' certs. One way to remediate it is to make a copy of the default JRE cacerts file and add your system-specific CA cert(s) to it and point to it from the setenv.sh file noted above.
When you have:
<Connector ...>
<SSLHostConfig>
<Certificate A=1 B=2 C=3 />
D=4 E=5 F=6
</SSLHostConfig>
</Connector>
then A,B,C are attributes of the Certificate object but D,E,F are NOT attributes of the SSLHostConfig object -- they are XML content which is different. Attributes need to be put IN THE TAG:
<Connector ... >
<SSLHostConfig certificateVerification="required" truststoreFile=... >
<Certificate ...keystore... />
</SSLHostConfig>
</Connector>
and that does cert-request on the initial handshake as desired (for me, tested on tomcat 9.0.14).

Client authentication on JBoss server

I'm trying to configure client authentication for my application running on JBoss. Expected result is that application requests user for certificate and if trusted one is provided, he will be able to work with application.
I've generated certificate and added one into trustore (JBoss.keystore) and also configured standalone.xml file as follow:
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" enable-lookups="false" secure="true">
<ssl name="ssl" key-alias="ssl alias" password="password" certificate-key-file="..\standalone\configuration\JBoss.keystore" protocol="TLSv1.2" verify-client="true"/>
<virtual-server name="my-host" />
</connector>
I thought that setting secure property true will do the trick, but browser does not ask for user certificate, but immediately returns error ERR_BAD_SSL_CLIENT_AUTH_CERT. Browser is configured to ask for certificate each time, if required.
How to change server configuration into expected behavior?
I have found an answer. The solution was to import CA certificate that signed client certificate into truststore, instead of importing client certificate itself.
After importing CA certificate, each certificate that was signed by CA and imported into browser is displayed to be chosen from.

How configure SSL in Jboss Wildfly 8.1

I have configured SSL in JBoss Wildfly 8.1. I have generated a keystore files and updated the standaolne.xml file as below
<security-realm name="security-realm">
<server-identities>
<ssl>
<keystore path="security/keystore.jks" relative-to="jboss.server.config.dir" keystore-password="changeit" key-password=" changeit"/>
</ssl>
</server-identities>
</security-realm>
The keystore-password and key-password is in cleartext. Simply we cannot show it in clear text. I want to encrypt the password. I tried a lot but could not credible help in this regard. So any body can help me in how to encrypt this password and how to use that in sandalone.xml file.
You can masking passwords for WildFly using the VaultTool.
VaultTool used in WildFly Application Server is used for
creating/using storage for secured attributes (e.g. passwords) which
can be later on used in WildFly configuration files in masked form.
Thus users can use references to their secured attributes instead of
putting them in clear text form to configuration files.
First you need create a Java Keystore to Store Sensitive Strings.
$ keytool -genseckey -alias vault -storetype jceks -keyalg AES -keysize 128 -storepass vault22 -keypass vault22 -validity 730 -keystore WILDFLY_HOME/vault/vault.keystore
Then initialize the Password Vault and store password for ssl keystore:
wildfly-8.1.0.Final/bin$ sh vault.sh
=========================================================================
JBoss Vault Tool
JBOSS_HOME: "wildfly-8.1.0.Final"
JAVA: ""
JAVA_OPTS: ""
=========================================================================
**********************************
**** JBoss Vault ***************
**********************************
Please enter a Digit:: 0: Start Interactive Session 1: Remove Interactive Session 2: Exit
0
Starting an interactive session
Enter directory to store encrypted files:/home/fsierra/vault/
Enter Keystore URL:home/fsierra/vault/vault.keystore
Enter Keystore password:
Enter Keystore password again:
Values match
Enter 8 character salt:12345678
Enter iteration count as a number (e.g.: 44):17
Enter Keystore Alias:Vault
Initializing Vault
ene 13, 2015 12:42:48 PM org.picketbox.plugins.vault.PicketBoxSecurityVault init
INFO: PBOX000361: Default Security Vault Implementation Initialized and Ready
Vault Configuration in WildFly configuration file:
********************************************
...
</extensions>
<vault>
<vault-option name="KEYSTORE_URL" value="/home/fsierra/vault/vault.keystore"/>
<vault-option name="KEYSTORE_PASSWORD" value="MASK-49SI2WfwF1X"/>
<vault-option name="KEYSTORE_ALIAS" value="Vault"/>
<vault-option name="SALT" value="12345678"/>
<vault-option name="ITERATION_COUNT" value="17"/>
<vault-option name="ENC_FILE_DIR" value="/home/fsierra/vault/"/>
</vault><management> ...
********************************************
Vault is initialized and ready for use
Handshake with Vault complete
Please enter a Digit:: 0: Store a secured attribute 1: Check whether a secured attribute exists 2: Exit
0
Task: Store a secured attribute
Please enter secured attribute value (such as password):
Please enter secured attribute value (such as password) again:
Values match
Enter Vault Block:keystore
Enter Attribute Name:password
Secured attribute value has been stored in Vault.
Please make note of the following:
********************************************
Vault Block:keystore
Attribute Name:password
Configuration should be done as follows:
VAULT::keystore::password::1
********************************************
Please enter a Digit:: 0: Store a secured attribute 1: Check whether a secured attribute exists 2: Exit
Finally keystore password has been masked for use in configuration files and deployments.
Eg (standalone.xml):
<extensions>
...
</extensions>
<vault>
<vault-option name="KEYSTORE_URL" value="/home/fsierra/vault/vault.keystore"/>
<vault-option name="KEYSTORE_PASSWORD" value="MASK-49SI2WfwF1X"/>
<vault-option name="KEYSTORE_ALIAS" value="Vault"/>
<vault-option name="SALT" value="12345678"/>
<vault-option name="ITERATION_COUNT" value="17"/>
<vault-option name="ENC_FILE_DIR" value="/home/fsierra/vault/"/>
</vault>
<management>
<security-realms>
...
<security-realm name="SslRealm">
<server-identities>
<ssl>
<keystore path="ssl.jks" relative-to="jboss.server.config.dir" keystore-password="${VAULT::keystore::password::1}"/>
</ssl>
</server-identities>
</security-realm>
</security-realms>
</management>
References:
Masking passwords for WildFly using non-interactive VaultTool
Mask the Keystore Password and Initialize the Password Vault
JBoss AS7 Securing Passwords
AS7: Utilising masked passwords via the vault

Setup SSL (self signed cert) with tomcat

I am mostly following this page:
http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html
I used this command to create the keystore
keytool -genkey -alias tomcat -keyalg RSA -keystore /etc/tomcat6/keystore
and answered the prompts
Then i edited my server.xml file and uncommented/edited this line
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="/etc/tomcat6/keystore"
keystorePass="tomcat" />
then I go to the web.xml file for my project and add this into the file
<security-constraint>
<web-resource-collection>
<web-resource-name>Security</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
When I try to run my webapp I am met with this:
Unable to connect
Firefox can't establish a connection to the server at localhost:8443.
* The site could be temporarily unavailable or too busy. Try again in a few
moments.
* If you are unable to load any pages, check your computer's network
connection.
If I comment out the lines I've added to my web.xml file, the webapp works fine. My log file in /var/lib/tomcat6/logs says nothing. I can't figure out if this is a problem with my keystore file, my server.xml file or my web.xml file.... Any assistance is appreciated
I am using tomcat 6 on ubuntu.
Edit: I changed my server.xml to
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="/etc/tomcat6/keystore"
keystorePass="tomcat" />
incase there was an issue with it being autoconfigured to "APR" as suggested by the tomcat tutorial (not sure if I have that or how to find out if I do). However I am still getting the same error.
Well, I'm an idiot...
I was under the impression that netbeans was restarting my server for me, because eclipse used to know when files that required restarting were changed and it would restart the server for you. Apparently netbeans doesn't have that functionality. Once I've manually restarted the server using the script at /etc/init.d/tomcat6 then everything worked..
Thanks for your help anyway pascal, your questions help me think about what other problems I might be running in to.
I just tested the same setup with a vanilla Tomcat on Ubuntu and :
I generated a keystore
I uncommented the SSL connector in server.xml and pointed on my keystore
I added the security constraint in the web.xml of my-webapp to force the use of SSL
And accessing https://localhost:8443/my-webapp just works on my machine(c).
Are you accessing the application using the right protocol i.e. https:// (notice the s in https)?
By the way, I would recommend to set the redirectPort=8443 attribute in the non-SSL connector so that http://localhost:8080/my-webapp gets redirected to https://localhost:8443/my-webapp.