Configure SSL on Jetty - ssl

I am trying to configure SSL on my Jetty.
I read this:
http://docs.codehaus.org/display/JETTY/How+to+configure+SSL
and created a key store.
Then, I jumped directly to section 4. But where is this configuration file I should configure Jetty?
I tried to serach for jetty.xml, but there is no such on my computer...

I had a lot of problems making it work but I finally foud out how to make it happend. I'm using ubuntu 10.04 with java 7. It may be possible to do it under windows but all the comands lines are bash commands, maybe possible to do the same with cigwin/mingw
I used Jetty 8.1.8. Download it from codehaus and choose the .tar.gz file for linux (.zip for windows).
Unzip the file in any directory you wish, this will be your {jetty} home folder for the sake of this article/answer.
Go to the {jetty}/etc directory.
Execute all the following command lines in order. Whenever a password is asked, input the same password all the time. The passwords are used to protect the key file, the key store and the certificate itself. Sometimes, a password will be asked to unlock the key store or to use a generated key. Once you will understand what everything is and how to use the passwords correctly, you may change those passwords when you feel ready (safer for production use). Otherwise, input the requested informations when asked.
openssl genrsa -des3 -out jetty.key
openssl req -new -x509 -key jetty.key -out jetty.crt
keytool -keystore keystore -import -alias jetty -file jetty.crt -trustcacerts
openssl req -new -key jetty.key -out jetty.csr
openssl pkcs12 -inkey jetty.key -in jetty.crt -export -out jetty.pkcs12
keytool -importkeystore -srckeystore jetty.pkcs12 -srcstoretype PKCS12 -destkeystore keystore
Now you have to edit {jetty}/etc/jetty-ssl.xml and configure your password to match the one you used during certificate generation. If you want to obfuscate your password, go back to the command line. Go tho your {jetty} home directory and execute the following:
java -cp lib/jetty-util-8.1.8.v20121106.jar org.eclipse.jetty.util.security.Password "{PASSWORD}"
Change {PASSWORD} for your actual password then past the obfuscated password, including the "OBF:" in all password fields found in jetty-ssl.xml. Note that a password obfuscated like that is hard to read for humans but easily unobfiscated programmatically. It just prevent developpers to know the password when they edit the file. All configuration files should be secured properly and their accesses be as restrictive as possible.
Edit {jetty}/start.ini and uncomment the line #etc/jetty-ssl.xml (just remove the #).
Start jetty:
java -jar start.jar
Now contact your server at: https://localhost:8443
Done!
Note that this answer is a quick way to enable SSL with jetty. To make it secure for production, you have to read some more on the subject.

Answer updated after more experience with keystores. I assure you this solution works perfectly with intermediate certificates (29/07/2015).
Note: PEM format means a readable file, certificates start with ---BEGIN CERTIFICATE--- and private keys start with -----BEGIN PRIVATE KEY----- line.
Here's an easy step by step guide. Start with an empty directory.
Skip to Step 2 if you have private key (PEM encoded .key)
Skip to Step 3 if you have certificate signing request (PEM encoded .csr)
Skip to Step 4 if you have your certificate (PEM encoded .crt or .pem)
Prepare (password-less) private key.
openssl genrsa -des3 -passout pass:1 -out domain.pass.key 2048
openssl rsa -passin pass:1 -in domain.pass.key -out domain.key
rm domain.pass.key
Prepare certificate signing request (CSR). We'll generate this using our key. Enter relevant information when asked. Note the use of -sha256, without it, modern browsers will generate a warning.
openssl req -key domain.key -sha256 -new -out domain.csr
Prepare certificate. Pick one:
a) Sign it yourself
openssl x509 -req -days 3650 -in domain.csr -signkey domain.key -out domain.crt
b) Send it to an authority
Your SSL provider will supply you with your certificate and their intermediate certificates in PEM format.
Add to trust chain and package it in PKCS12 format. First command sets a keystore password for convenience (else you'll need to enter password a dozen times). Set a different password for safety.
export PASS=LW33Lk714l9l8Iv
Pick one:
a) Self-signed certificate (no need for intermediate certificates)
openssl pkcs12 -export -in domain.crt -inkey domain.key -out domain.p12 -name domain -passout pass:$PASS
keytool -importkeystore -deststorepass $PASS -destkeypass $PASS -destkeystore domain.keystore -srckeystore domain.p12 -srcstoretype PKCS12 -srcstorepass $PASS -alias domain
b) Need to include intermediate certificates
Download intermediate certificates and concat them into one file. The order should be sub to root.
cat sub.class1.server.ca.pem ca.pem > ca_chain.pem
Use a -caname parameter for each intermediate certificate in chain file, respective to the order they were put into the chain file.
openssl pkcs12 -export -in domain.crt -inkey domain.key -out domain.p12 -name domain -passout pass:$PASS -CAfile ca_chain.pem -caname sub1 -caname root -chain
keytool -importkeystore -deststorepass $PASS -destkeypass $PASS -destkeystore domain.keystore -srckeystore domain.p12 -srcstoretype PKCS12 -srcstorepass $PASS -alias domain
Important note: Although keytool -list will only list one entry and not any intermediate certificates, it will work perfectly.
Configure jetty.
Move domain.keystore file to JETTY_HOME/etc/.
Pick one:
a) You're using new start.ini style configuration (Jetty 8+):
jetty.keystore=etc/domain.keystore
jetty.truststore=etc/domain.keystore
jetty.keystore.password=LW33Lk714l9l8Iv
jetty.keymanager.password=LW33Lk714l9l8Iv
jetty.truststore.password=LW33Lk714l9l8Iv
b) You're using old style configuration with .xml files (you should upgrade to new style!):
Edit JETTY_HOME/etc/jetty-ssl.xml file and change the part below. Replace password parts to match your password. We don't define KeyManagerPassword because our key has no password.
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<New id="sslContextFactory" class="org.eclipse.jetty.http.ssl.SslContextFactory">
<Set name="KeyStore"><Property name="jetty.home" default="." />/etc/keystore</Set>
<Set name="KeyStorePassword">LW33Lk714l9l8Iv</Set>
<Set name="TrustStore"><Property name="jetty.home" default="." />/etc/keystore</Set>
<Set name="TrustStorePassword">LW33Lk714l9l8Iv</Set>
</New>
<Call name="addConnector">...</Call>
</Configure>
Edit start.ini file to include jetty-ssl.xml file.
(Re)start jetty.
Note that this keystore file can also be used with other containers like Tomcat. Good luck!

A default configuration file for Jetty and is located at $JETTY_HOME/etc/jetty.xml
If you are using maven's jetty plugin you will need to specify ssl keystore details in your pom.xml file. See this question for details

Just bought a cert from godaddy for mere $6/year. Great deal while it lasts. Here are the steps I followed to set it up on Amazon EC2/Ubuntu/Jetty based on these sites and Jean-Philippe Gravel's answer.
http://docs.codehaus.org/display/JETTY/How+to+configure+SSL
http://community.xmatters.com/docs/DOC-1228#.UgWsI1MU7lc
keytool -keystore keystore -alias jettykey -genkey -keyalg RSA
Note that "First and last name" must be your FQDN (without http://). On my first attempt I had dutifully put my first and last name, but godaddy has good warnings and rejected it.
Generate a CSR file for Godaddy:
keytool -certreq -alias jetty -keystore keystore -file jetty.csr
Submit this in the Godaddy form to create the certificate, including the BEGIN/END "NEW CERTIFICATE REQUEST".
(Godaddy requires you to verify its your site. There a couple methods for this and since I bought the domain name via a proxy, I found it easiest and quickest to verify by hosting an html page generated by godaddy.)
Download the zip containing both certificate and intermediary certificate from godaddy. There is a list of server types to choose from. I choose "other". Then combine cert with intermediary cert.
cat mydomain.com.crt gd_bundle.crt > certchain.txt
export my private key
keytool -importkeystore -srckeystore keystore -destkeystore intermediate.p12 -deststoretype PKCS12
openssl pkcs12 -in intermediate.p12 -out jettykey.pem -nodes
combine private key and certificate
openssl pkcs12 -export -inkey jettykey.pem -in certchain.txt -out jetty.pkcs12
import pkcs12 cert (alias becomes 1)
keytool -importkeystore -srckeystore jetty.pkcs12 -srcstoretype PKCS12 -destkeystore keystore
(I backed up the keystore then deleted the original key. I did this while troubleshooting and this may or may not be required by Jetty.)
keytool -delete -keystore keystore -alias jettykey
sudo cp keystore /usr/share/jetty/etc/
sudo vi /usr/share/jetty/etc/jetty-ssl.xml
Modify your.store.password, your.key.password, and your.trust.password accordingly. If you want to obfuscate it, use
java -cp /usr/share/jetty/lib/jetty.jar:/usr/share/jetty/lib/jetty-util.jar org.mortbay.jetty.security.Password <your.password>
Indicate to Jetty to load the jetty-ssl.xml file.
sudo echo "/etc/jetty/jetty-ssl.xml" >> /etc/jetty/jetty.conf
sudo /sbin/iptables -t nat -I PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443
(Also modify Amazon EC2 security group to allow 443)
sudo service jetty start

If you happen to work with Jetty 9.3 then you should change configuration in start.d/ssl.ini:
jetty.sslContext.keyStorePath=mystore.jks
jetty.sslContext.keyStorePassword=X
jetty.sslContext.keyManagerPassword=X
jetty.sslContext.trustStorePath=mystore.jks
jetty.sslContext.trustStorePassword=X
Where:
mystore.jks is your store generated with the keytool
X is your password in plain text (I would recommend skipping obfuscation as it only gives you false security)
The store is exactly the same as you would generate for Tomcat. Even if you used different Java version to generate the keystore that should not be a problem.

When trying on Windows with Jetty as Maven plugin the following steps can help:
pom.xml
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.11.v20130520</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<webApp>
<contextPath>/yourappcontext</contextPath>
</webApp>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>9090</port>
<maxIdleTime>1</maxIdleTime>
</connector>
<connector implementation="org.eclipse.jetty.server.ssl.SslSocketConnector">
<port>9443</port>
<keystore>src/test/resources/keystore</keystore>
<keyPassword>123456</keyPassword>
<password>123456</password>
</connector>
</connectors>
</configuration>
</plugin>
Generate key/certificate using the JDK tool keytool:
keytool -keystore keystore -alias jetty -genkey -keyalg RSA
This command will generate a file keystore which we need to put at the following (or what ever you like until it is configured in the keystore element) path src/test/resources/keystore.

Related

Create a self signed certificate for localhost and import it in Glassfish

I am developing a REST server that runs with Jersey on Glassfish, and I want to make it run on HTTPS on localhost.
I have found many tutorials for generating a CA cert, others for generating .cer / .crt / .key / .csr / ... files, others for generating a jks keystore.
But they do not answer my (very basic) question: how to generate a self signed certificate and use it in my app that runs on Glassfish, on localhost? From scratch to the integration for a real usage, without any prerequiresite having a crt, a jks or any other file.
(For information I use Linux)
Thanks
EDIT: I have finally created a certificate with the following commands
openssl req -x509 -out localhost.crt -keyout localhost.key \
-newkey rsa:2048 -nodes -sha256 \
-subj '/CN=localhost' -extensions EXT -config <( \
printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
openssl pkcs12 -export -name localhostServerCert -in localhost.crt -inkey localhost.key -out localhostP12Keystore.p12
keytool -importkeystore -destkeystore localhostKeystore.jks -srckeystore localhostP12Keystore.p12 -srcstoretype pkcs12 -alias localhostServerCert
copy localhostKeystore.jks into /glassfish/domains/domain1/config
keytool -importkeystore -srckeystore localhostKeystore.jks -destkeystore keystore.jks
And I have modified http-listener-2 in the admin console with certificate nickname localhostServerCert, but I got an error page on https://localhost:8181 (ERR_CONNECTION_REFUSED)
EDIT 2 : I think there should be a problem with the certificate, since openssl s_client -showcerts -connect localhost:8181 returns no peer certificate available, No client certificate CA names sent
COMMON GOALS
It can be useful to run with SSL locally, and I like to start with real world URLs. This can also help you to think ahead to your production deployment design, which often involves a Private PKI these days, based on a self issued Root CA.
Web and API domains can sometimes be related these days, eg if an API issues secure cookies for the web origin. So for localhost development I first define URLs such as these:
https://api.mycompany.com
https://web.mycompany.com
DEVELOPER SETUP
Then add entries such as this to my hosts file:
127.0.0.1 localhost web.mycompany.com api.mycompany.com
:1 localhost
Then, in terms of certificates, I produce these deployable files:
Certificate
Filename
Usage
Root CA
mycompany.ca.pem
The root certificate authority that is trusted by the Java runtime
Wildcard Certificate
mycompany.ssl.p12
A password protected PKCS12 file deployed with the API
My Development Certificates Repository has an example of how to issue the certs using openssl, including a bash script you can use for your own domains. Essentially this is a Private PKI for a development computer.
CONFIGURING TRUST
You then just need to trust the Root CA in the Java runtime used by Glassfish. Personally I tend to avoid JKS files where possible, since they are specific to Java, whereas PKCS12 files are a more portable concept:
sudo "$JAVA_HOME/bin/keytool" -import -alias mycompanyroot -cacerts -file ~/Desktop/mycompany.ca.pem -storepass changeit -noprompt
FURTHER DEVELOPER SETUP INFO
These resources on a portable way to manage SSL development certs are provided below, which completes the architecture work:
My Developer SSL Blog Post
My Java API uses the above certs and loads the wildcard certificate via this code, where a P12 file is used as a keystore:
System.setProperty(
"server.ssl.key-store",
configuration.getApi().getSslCertificateFileName());
System.setProperty(
"server.ssl.key-store-password",
configuration.getApi().getSslCertificatePassword());
GLASSFISH
If Glassfish based setups mean the API itself does not load the PKCS12 file, then there may be a specific task to import the PKCS12 file. Many systems provide a GUI or API option for loading a PKCS12 file into a keystore. This may result in a command like this being run, which you can do manually if needed:
keytool -importkeystore -srckeystore mycompany.ssl.p12 -srcstoretype pkcs12 -destkeystore keystore.jks -deststoretype jks -v

Grails 3.3.5 with SSL certificate

I have _client-cert.pem and client-key.pem and ca.pem files which I am trying to add to my grails project.
I used following commands :
Convert client keys/certificate files to PKCS#12 before creating a keystore
openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem \
-name “mysqlclient” -passout pass:mypassword -out client-keystore.p12
Create a Java Keystore using the client-keystore.p12 file
keytool -importkeystore -srckeystore client-keystore.p12 -srcstoretype pkcs12 \
-srcstorepass mypassword -destkeystore keystore -deststoretype JKS -deststorepass mypassword
Then Modified my application.yml file with that path :
enabled: true
key-store: /..../proxreg
key-store-password:kjsfghsfjlhgl
keyStoreType: pkcs12
keyAlias: tomcat
I was wondering if I am missing any step or what am I doing wrong. I am getting access denied error but when I try to connect thro mysql wokbench it works
You can generate a self-signed certificate using the openssl command-line utility.
We can use openssl's req command to create a self-signed certificate:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
Above will prompt you to supply metadata about the certificate, such as Country, Organization, etc. Moreover, it will ask you to provide a PEM pass phrase. Enter a random password and keep it safe; we will need in the next step.
Now you have you self-signed certificate. Unfortunately Grails (and Spring Boot) doesn’t support the PEM format directly. Instead, we need to use the PKCS12 format for our keys. Fortunately, there is another openssl command to make the conversion:
openssl pkcs12 -export -in cert.pem -inkey key.pem -out keystore.p12 -name tomcat -caname root
Update grails-app/conf/application.yml with the following lines:
server:
port: 8443
ssl:
keyStore: /certificates/keystore.p12
keyStorePassword: secret
# keyAlias: tomcat
Above all worked fine with me. for more information please refer this and this
Hope this will help you.

I want to create a ssl certificate for zeppelin server

I am running a zeppelin server on aws ec2 instance. I want to launch it on https, currently on http and its working fine.
How can I launch my zeppelin server on https.
I followed the steps given on http://carminedimascio.com/2015/06/running-zeppelin-with-ssl/
but its still not working.
I have checked the security groups as well.
Please help
Well , the one point where you can be doing mistake is after generating CSR are you using the same CSR file to request SSL certificate from CA authority or not ? If not, then again generate a new key store with all correct information and then use that keystore to generate CSR . Then important point is to paste the contents of this CSR file when requesting a certificate from CA authority. After then, install your certificates into the keystore. Then provide the path of your keystore in Zeppelin Server configuration. If carefully followed, this will definitely work :) .
The steps at http://carminedimascio.com/2015/06/running-zeppelin-with-ssl/ actually work. Provided an export password is set, which is different from the keystore password set in a previous step.
To give an idea,
mkdir ~/.mykeystore
cd ~/.mykeystore
openssl genrsa -des3 -out jetty.key 2048
passwd abcd
openssl req -new -x509 -key jetty.key -out jetty.crt
Enter pass phrase for jetty.key: abcd
keytool -keystore keystore -import -alias jetty -file jetty.crt -trustcacerts
Enter keystore password ABCDEF
Re-enter new password: ABCDEF
Trust this certificate? [no]: yes
Certificate was added to keystore
openssl req -new -key jetty.key -out jetty.csr
Enter pass phrase for jetty.key: abcd
openssl pkcs12 -inkey jetty.key -in jetty.crt -export -out jetty.pkcs12
Enter pass phrase for jetty.key: abcd
Enter Export Password: BCDEFG
Verifying - Enter Export Password: BCDEFG
keytool -importkeystore -srckeystore jetty.pkcs12 -srcstoretype PKCS12 -destkeystore keystore
Enter destination keystore password: ABCDEF
Enter source keystore password: BCDEFG
Entry for alias 1 successfully imported.
Import command completed: 1 entries successfully imported, 0 entries failed or cancelled
(export passwd then becomes the source passwd in this last step)
Also, paths to the keystore in zeppelin-site.xml must be of the form,
/home/to/something/keystore (it's not the just the path it requires but the path with the keystore filename included).

acivemq, secure websockets, CA, security and same origin restrictions - How do I install a CA certificate?

Has anyone managed to install a CA certificate into an activemq instance? I've been doing google searches and reading the activemq documentation but I haven't found anything on how to use a pre-existing CA certificate in activemq.
I assume I install it into the activemq keystore. Is that correct? I'll be using it with websockets and mqtt on the client end.
Also, just in case my assumptions are incorrect, here's why I think I need to use my current CA certificate.
1) I have a web application and our users require communication with the server to be secure. All http traffic is secure.
2) All modern web browsers have a same-origin policy for websockets. They also seem to have a no-mixed-content policy. And so because my http traffic is secure I also have to use secure websockets. (I also have to run the activemq server at the same url)
I'd rather not tunnel the websocket traffic over http because then I have to worry about the apache configuration in addition to the activemq configuration - just another place for things to potentially go wrong.
Also, I don't transfer any sensitive information over the websocket so I could potentially leave it unsecured, but first, my users probably wouldn't understand that, but also it looks like browsers have a no-mixed-content policy.
Has anyone gone through what I'm going through? Any tips?
I eventually got this working, but ultimately I decided to tunnel my websockets communication through apache using the ws_tunnel module.
But to answer my question above, basically what you have to do is create a new java keystore based on your webserver keys, and then replace the apachemq java keystore with this new keystore. I was never able to successfully import the keys into the existing keystore.
For example, on my ubuntu server, my keys are:
SSLCertificateFile /etc/apache2/ssl/star_astracorp_com.crt
SSLCertificateKeyFile /etc/apache2/ssl/star_astracorp_com.key
SSLCertificateChainFile /etc/apache2/ssl/astracorp.com.intermediate.sha1.chcrt
I then export the key as pkcs12:
openssl pkcs12 -export -in /etc/apache2/ssl/star_astracorp_com.crt -inkey /etc/apache2/ssl/star_astracorp_com.key -out server.p12 -name emsu1 -CAfile ca.crt -caname root
I then import the pkcs12 into a new java keystore:
keytool -importkeystore -deststorepass password -destkeypass password -destkeystore server.keystore -srckeystore /etc/apache2/ssl/server.p12 -srcstoretype PKCS12 -srcstorepass password -alias emsu1
Then, in my apachemq directory I move the old broker.ks out of the way and rename server.keystore as kroker.ks and restart activemq.
One of my servers had .pem files for its keys. The process was still similar, however I had to go into OS X's keystore utility to get the password of the key.
openssl pkcs12 -export -in /etc/certificates/ems-dev.local.EDA65671FF2C9CE7DAA56E9AD8E4E5F3F2675C79.cert.pem -inkey /etc/certificates/ems-dev.local.EDA65671FF2C9CE7DAA56E9AD8E4E5F3F2675C79.key.pem -out server.p12 -name emsdev -CAfile ca.crt -caname root
you will then be asked for the key - copy and paste it from the key util.
Then, the process to create a new keystore is the same:
keytool -importkeystore -deststorepass password -destkeypass password -destkeystore server.keystore -srckeystore /etc/certificates/server.p12 -srcstoretype PKCS12 -srcstorepass password -alias emsdev

Convert certificate in BIN format to X509 format

I have read this good article on running tomcat in https and implemented it.
http://techtracer.com/2007/09/12/setting-up-ssl-on-tomcat-in-3-easy-steps/
It is working fine and my tomcat is running in https mode.
But the problem is i got the certificate in BIN format. I need it in X509 format so that i can use it as an raw resource for my Android project
I have used java keytool to create it.Can i use OpenSSL to convert it into X509 Format or java keytool is sufficient?
I am new to this securities stuff.
Please point me in the right direction and clear my doubts.
I think keytool already handles certificates in X509 format only. You should have generated .keystore file. You can export certificate from it using command:
keytool -export -alias mycert -keystore mykeystore.bin -file certificatefile.cer
Yes of course, you can use OpenSSL to convert the certificate and keys to and from the following formats
Standard PEM
DER / Binary
PKCS#7 (aka P7B)
PKCS#12 (aka PFX)
In your case, given a private key file and digital certificate in standard PEM,
convert them both to pkcs12 format using the following steps:
Step 1: Convert the PEMs to a single PKCS12 file
OpenSSL> pkcs12 -export -in CE_cert.cer -inkey CE_prv_key_PEM.key -out
pkcs12_KeyStore.p12 -name ce_cert_prv_key
Heres the doc for OpenSSL PKCS12 command.
Step 2: Import the PKCS12 file created in step 1 into the new JKS
C:\>keytool -importkeystore -srckeystore pkcs12_KeyStore.p12 -srcstoretype pkcs12 -srcstorepass somepass -srcalias ce_cert_prv_key -destk
eystore path/to/JavaKeyStore_KS.jks -deststoretype jks -deststorepass somepass -destkeypass somepass
Now after having the certificate and private key in the JKS format, you can use this JSK key store in Tomcat.