Installing Glassfish 4.1 on Ubuntu 14.04 LTS

This tutorial will explain how to install a Glassfish 4.1 Server on an Ubuntu 14.04 LTS Server. It will also cover some but not all security concerns. The steps have been executed successfully on Ubuntu 14.04 LTS Server edition (64-bit). I have tested everything by using Parallels Virtual Machines - you might want to use Virtual Machines as well. You can use this tutorial for setting up a Glassfish server which is reachable via internet for everybody. Both Ubuntu root servers and Ubuntu virtual servers should be fine for this tutorial, so you can choose any hosting package offered by the provider of your choice. In all cases you need to make sure to have root access to your server. You should also be familiar with the Unix/Linux command line because you will have to execute lots of commands on the shell. After having this tutorial completed you can use your new Glassfish installation to host your own Java EE 7 compliant applications.

In my previous tutorials I described how to install Glassfish 3.0.1/3.1/3.1.1 on Ubuntu. I have received plenty of feedback directly posted on the corresponding page and even much more feedback from people who directly contacted me. It seems that my tutorials are quite helpful for many of my readers - thank you for reading my tutorials!

I would like to take this chance to thank everybody who left comments and hints on my previous tutorials. Some of the hints have been incorporated into this tutorial. Keep posting your information and ideas here to improve this tutorial for others! Share your knowledge here!


Table of contents:


Creating this tutorial meant a lot of effort - although I could reuse a lot of the work I invested into my previous tutorial. I hope it will help others. If you have any questions do not hesitate to contact me. Any feedback is welcome! Also feel free to leave a comment (see below). For helping me to maintain my tutorials any donation is welcome.


1. Setting up the OS environment

Before you start doing anything you should think about a security concept. A detailed security concept is out of scope for this tutorial. Very important from security point of view is not to run your Glassfish server as root. This means you need to create a user with restricted rights which you can use for running Glassfish. Once you have added a new user, let's say 'glassfish', you might also want to add a new group called 'glassfishadm'. You can use this group for all users that shall be allowed to "administer" your Glassfish in full depth. In full depth means also modifying different files in the Glassfish home directory. Below you find user and group related commands that you might want to use.

#Add a new user called glassfish
sudo adduser --home /home/glassfish --system --shell /bin/bash glassfish

#add a new group for glassfish administration
sudo groupadd glassfishadm

#add your users that shall be Glassfish adminstrators
sudo usermod -a -G glassfishadm $myAdminUser

#in case you want to delete a group some time later (ignore warnings):
#delgroup glassfishadm

Glassfish allows some of the configuration tasks to be managed via a web based Administration GUI. We will simply call it AdminGUI from now on. You can reach the AdminGUI by visiting http://www.yourserver.com:4848/ in your browser (please replace www.yourserver.com with localhost or where ever your Glassfish server is). As you can see port 4848 is used. Of course, we don't want anyone to access our AdminGUI. Therefore we have to restrict access to the AdimnGUI. A way do this is to block port 4848 via the firewall. Anything you can do via AdminGUI is also available via the asadmin tool that ships with Glassfish. So you don't have to worry about not being able to configure Glassfish if you block the AdminGUI.

Usually you want to run Glassfish on port 80 (everything below port 1024 has to run as root). But since we don't suggest to run Glassfish as root we cannot run Glassfish on port 80. But there are still ways to run Glassfish as a non-root user and still receive http requests on port 80. One option could be mod_jk, but this would only be another component that needs to be managed. An easy way is to use a simple iptables redirection rule, that redirects requests on port 80 to port 8080 (http) and requests on port 443 to port 8181 (https).

You should make sure that you do not block other important ports, for example your ssh port which usually runs on port 22 (else you will be locked out). Changing the default ssh port to some other is actually a good idea, but for now we will simply assume your ssh port is 22. Another helpfull iptables rule related to your ssh port 22 is to slow down connection tries from an ip if they fail 3 times. I found a rule for that on the web and added it below. Although I will not mention it here you should also use other techniques and tools to secure your ssh port. Unfortunately, I did not get the time to post a tutorial about that.

Now we have created a lot of rules. You could enter them always one by one, but we don't want this kind of effort. I suggest to enter the following iptables rules in a separate file which contains all of our iptables related ideas we discussed so far:

#!/bin/bash

# ATTENTION: flush/delete all existing rules
iptables -F

################################################################
# set the default policy for each of the pre-defined chains
################################################################
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP

# allow establishment of connections initialised by my outgoing packets
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# accept anything on localhost
iptables -A INPUT -i lo -j ACCEPT

################################################################
#individual ports tcp
################################################################
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
iptables -A INPUT -p tcp --dport 8181 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
#uncomment next line to enable AdminGUI on port 4848:
#iptables -A INPUT -p tcp --dport 4848 -j ACCEPT

################################################################
#slow down the amount of ssh connections by the same ip address:
#wait 60 seconds if 3 times failed to connect
################################################################
iptables -I INPUT -p tcp -i eth0 --dport 22 -m state --state NEW -m recent --name sshprobe --set -j ACCEPT
iptables -I INPUT -p tcp -i eth0 --dport 22 -m state --state NEW -m recent --name sshprobe --update --seconds 60 --hitcount 3 --rttl -j DROP

#drop everything else
iptables -A INPUT -j DROP

################################################################
#Redirection Rules
################################################################
#1. redirection rules (allowing forwarding from localhost)
iptables -t nat -A OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -A OUTPUT -o lo -p tcp --dport 443 -j REDIRECT --to-port 8181

#2. redirection http
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080

#3. redirection https
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8181


################################################################
#save the rules somewhere and make sure
#our rules get loaded if the ubuntu server is restarted
################################################################
iptables-save > /etc/my-iptables.rules
iptables-restore < /etc/my-iptables.rules

#List Rules to see what we have now
iptables -L

I suggest to create a file called iptables.DISABLE_4848.rules which contains exactly everything from the code box above. Then you could also create a file called iptables.ENABLE_4848.rules which has line 28 uncommented (everything else is just the same). Of course, you have to make both files executable with the command chmod +x $filename (see below). Then you can simply run one of the scripts when ever you want to disable or enable the AdminGUI on port 4848, i.e. sudo ./iptables.DISABLE_4848.rules

chmod +x iptables.DISABLE_4848.rules
chmod +x iptables.ENABLE_4848.rules

Please also do not forget that all your iptables rules should also be activated if your Ubuntu server is restarted. Otherwise you would have to remember to run your iptables rules manually after each restart. If you forget to run them all manually, or if you have simply forgotten that your server has been restarted, then your firewall is open for everyone. If you are lucky nothing will happen, if not you might get some successful instrusion attacks. Lines 58 and 59 will help you to make sure your rules are automatically loaded after each restart. But this is not everything for iptables configuration on startup. You also need to create a file at /etc/network/if-pre-up.d/iptablesload and one at /etc/network/if-post-down.d/iptablessave. For more information please have a look at the official Ubuntu help sites for iptables. The following code boxes show the content of our two files and where they have to be created. As you can see in both the latter two code boxes, line 2 is refering to the file /etc/my-iptables.rules, which we have defined in line 58 and 59 of our files iptables.DISABLE_4848.rules and iptables.ENABLE_4848.rules respectively. I have added /sbin/ in front of the iptables commands (see below) because I was facing the problem that iptables commands without /sbin/ could not be found at the time when the files iptablesload or iptablessave were executed during the Ubuntu server startup process.

# first we have to create these two files:
sudo touch /etc/network/if-pre-up.d/iptablesload
sudo touch /etc/network/if-post-down.d/iptablessave
#!/bin/sh
/sbin/iptables-restore < /etc/my-iptables.rules
exit 0
#!/bin/sh
/sbin/iptables-save -c > /etc/my-iptables.rules
if [ -f /etc/iptables.downrules ]; then
   /sbin/iptables-restore < /etc/iptables.downrules
fi
exit 0

Finally you have to make sure that both files are executable. For that you only need to execute the following commands once.

sudo chmod +x /etc/network/if-post-down.d/iptablessave
sudo chmod +x /etc/network/if-pre-up.d/iptablesload

At this point you can try what happens if you reboot your Ubuntu server (sudo reboot). After Ubuntu has restarted just try sudo iptables -L on the shell. It should show you the rules we have defined. You should see something like this if you hit sudo ./iptables.DISABLE_4848.rules before rebooting:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       tcp  --  anywhere             anywhere            tcp dpt:ssh state NEW recent: UPDATE seconds: 60 hit_count: 3 TTL-Match name: sshprobe side: source
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh state NEW recent: SET name: sshprobe side: source
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:http-alt
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:8181
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:https
DROP       all  --  anywhere             anywhere

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Your firewall settings are loaded automatically whenever Ubuntu is starting up. We can continue with the next steps. Please do not forget that these are only some minimum firewall settings. For maximum security you might need to add your own iptables rules.


2. Setting up Java

The next step is to set up Java. As you can see on the official Oracle Glassfish 4.1 download site it is recommended to use the latest Oracle JDK 8 for GlassFish 4.1. On the other hand you can see that Java EE 7 requires at least JDK 7 or above. That means these are the minimum versions you want to use! I suggest to remove the ObenJDK first if you have it installed and install the Oracle JDK and JRE. I also suggest to remove any previous Sun/Oracle JDK and JRE already installed on your system. On a production system I don't suggest to use the ObenJDK because it is not certified (but that's another story...).

So what we want now is to install the latest JDK 8 from Oracle. Unfortunately Oracle's JDK 8 is not available via Ubuntu's aptitude. So if you want to install Oracles's JDK 8 you will have to download the Linux distribution from Oracle's JDK 8 Download site and install it manually. Installing Oracle's JDK 8 manually means downloading it manually, uploading it manually to your Ubuntu server and the executing the actual installation process. See How can I install Sun/Oracle's proprietary Java JDK 6/7/8 or JRE? on askubuntu.com for more information. The following commands expect that you have already downloaded Oracle's JDK 8 (i.e. jdk-8u31-linux-x64.tar.gz) manually to your local machine (i.e. by the browser of your choice) and that the same file has been uploaded to ~/downloads on your Ubuntu server (i.e. via scp).

#remove OpenJDK if installed - this is how you would remove OpenJDK :
sudo apt-get remove openjdk-6-jre openjdk-6-jdk
sudo apt-get remove openjdk-7-jre openjdk-7-jdk
#OpenJDK 8 packages not yet in the official 14.04 LTS repos 
#sudo apt-get remove openjdk-8-jre openjdk-8-jdk

#remove sun's jdk if you have it (I am sure you don't have it):
#sudo apt-get remove sun-java6-jdk sun-java6-jre

#get rid of several automatically-installed packages that are not needed anymore...
sudo apt-get autoremove
sudo apt-get autoclean

#extract oracle's jdk
cd ~/downloads
tar -xvf jdk-8u31-linux-x64.tar.gz

#remove previous installations if available
sudo rm -rf /usr/lib/jvm/jdk1.8.0

#make sure our destination folder exists
sudo mkdir /usr/lib/jvm

#move extracted files
sudo mv ./jdk1.8.0_31 /usr/lib/jvm/jdk1.8.0
sudo chgrp -R root /usr/lib/jvm/jdk1.8.0
sudo chown -R root /usr/lib/jvm/jdk1.8.0

#update alternatives - make sure environment points to a valid install if you are replacing...
sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk1.8.0/bin/java" 1
sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/lib/jvm/jdk1.8.0/bin/javac" 1
sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/lib/jvm/jdk1.8.0/bin/javaws" 1
sudo update-alternatives --config java

#check JDK by looking in the /etc/alternatives/ directory
cd /etc/alternatives
ls -lrt java*

#this is optionally since we will add everything to the PATH variable (i usually don't use this):
sudo update-alternatives --install "/usr/bin/apt" "apt" "/usr/lib/jvm/jdk1.8.0/bin/apt" 1
sudo update-alternatives --install "/usr/bin/idlj" "idlj" "/usr/lib/jvm/jdk1.8.0/bin/idlj" 1
sudo update-alternatives --install "/usr/bin/jarsigner" "jarsigner" "/usr/lib/jvm/jdk1.8.0/bin/jarsigner" 1
sudo update-alternatives --install "/usr/bin/java-rmi.cgi" "java-rmi.cgi" "/usr/lib/jvm/jdk1.8.0/bin/java-rmi.cgi" 1
sudo update-alternatives --install "/usr/bin/javadoc" "javadoc" "/usr/lib/jvm/jdk1.8.0/bin/javadoc" 1
sudo update-alternatives --install "/usr/bin/javah" "javah" "/usr/lib/jvm/jdk1.8.0/bin/javah" 1
sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/lib/jvm/jdk1.8.0/bin/javaws" 1
sudo update-alternatives --install "/usr/bin/jconsole" "jconsole" "/usr/lib/jvm/jdk1.8.0/bin/jconsole" 1
sudo update-alternatives --install "/usr/bin/jdb" "jdb" "/usr/lib/jvm/jdk1.8.0/bin/jdb" 1
sudo update-alternatives --install "/usr/bin/jinfo" "jinfo" "/usr/lib/jvm/jdk1.8.0/bin/jinfo" 1
sudo update-alternatives --install "/usr/bin/jps" "jps" "/usr/lib/jvm/jdk1.8.0/bin/jps" 1
sudo update-alternatives --install "/usr/bin/jsadebugd" "jsadebugd" "/usr/lib/jvm/jdk1.8.0/bin/jsadebugd" 1
sudo update-alternatives --install "/usr/bin/jstat" "jstat" "/usr/lib/jvm/jdk1.8.0/bin/jstat" 1
sudo update-alternatives --install "/usr/bin/jvisualvm" "jvisualvm" "/usr/lib/jvm/jdk1.8.0/bin/jvisualvm" 1
sudo update-alternatives --install "/usr/bin/native2ascii" "native2ascii" "/usr/lib/jvm/jdk1.8.0/bin/native2ascii" 1
sudo update-alternatives --install "/usr/bin/pack200" "pack200" "/usr/lib/jvm/jdk1.8.0/bin/pack200" 1
sudo update-alternatives --install "/usr/bin/rmic" "rmic" "/usr/lib/jvm/jdk1.8.0/bin/rmic" 1
sudo update-alternatives --install "/usr/bin/rmiregistry" "rmiregistry" "/usr/lib/jvm/jdk1.8.0/bin/rmiregistry" 1
sudo update-alternatives --install "/usr/bin/serialver" "serialver" "/usr/lib/jvm/jdk1.8.0/bin/serialver" 1
sudo update-alternatives --install "/usr/bin/tnameserv" "tnameserv" "/usr/lib/jvm/jdk1.8.0/bin/tnameserv" 1
sudo update-alternatives --install "/usr/bin/wsgen" "wsgen" "/usr/lib/jvm/jdk1.8.0/bin/wsgen" 1
sudo update-alternatives --install "/usr/bin/xjc" "xjc" "/usr/lib/jvm/jdk1.8.0/bin/xjc" 1
sudo update-alternatives --install "/usr/bin/appletviewer" "appletviewer" "/usr/lib/jvm/jdk1.8.0/bin/appletviewer" 1
sudo update-alternatives --install "/usr/bin/extcheck" "extcheck" "/usr/lib/jvm/jdk1.8.0/bin/extcheck" 1
sudo update-alternatives --install "/usr/bin/jar" "jar" "/usr/lib/jvm/jdk1.8.0/bin/jar" 1
sudo update-alternatives --install "/usr/bin/javafxpackager" "javafxpackager" "/usr/lib/jvm/jdk1.8.0/bin/javafxpackager" 1
sudo update-alternatives --install "/usr/bin/javap" "javap" "/usr/lib/jvm/jdk1.8.0/bin/javap" 1
sudo update-alternatives --install "/usr/bin/jcmd" "jcmd" "/usr/lib/jvm/jdk1.8.0/bin/jcmd" 1
sudo update-alternatives --install "/usr/bin/jcontrol" "jcontrol" "/usr/lib/jvm/jdk1.8.0/bin/jcontrol" 1
sudo update-alternatives --install "/usr/bin/jhat" "jhat" "/usr/lib/jvm/jdk1.8.0/bin/jhat" 1
sudo update-alternatives --install "/usr/bin/jmap" "jmap" "/usr/lib/jvm/jdk1.8.0/bin/jmap" 1
sudo update-alternatives --install "/usr/bin/jrunscript" "jrunscript" "/usr/lib/jvm/jdk1.8.0/bin/jrunscript" 1
sudo update-alternatives --install "/usr/bin/jstack" "jstack" "/usr/lib/jvm/jdk1.8.0/bin/jstack" 1
sudo update-alternatives --install "/usr/bin/jstatd" "jstatd" "/usr/lib/jvm/jdk1.8.0/bin/jstatd" 1
sudo update-alternatives --install "/usr/bin/keytool" "keytool" "/usr/lib/jvm/jdk1.8.0/bin/keytool" 1
sudo update-alternatives --install "/usr/bin/orbd" "orbd" "/usr/lib/jvm/jdk1.8.0/bin/orbd" 1
sudo update-alternatives --install "/usr/bin/policytool" "policytool" "/usr/lib/jvm/jdk1.8.0/bin/policytool" 1
sudo update-alternatives --install "/usr/bin/rmid" "rmid" "/usr/lib/jvm/jdk1.8.0/bin/rmid" 1
sudo update-alternatives --install "/usr/bin/schemagen" "schemagen" "/usr/lib/jvm/jdk1.8.0/bin/schemagen" 1
sudo update-alternatives --install "/usr/bin/servertool" "servertool" "/usr/lib/jvm/jdk1.8.0/bin/servertool" 1
sudo update-alternatives --install "/usr/bin/unpack200" "unpack200" "/usr/lib/jvm/jdk1.8.0/bin/unpack200" 1
sudo update-alternatives --install "/usr/bin/wsimport" "wsimport" "/usr/lib/jvm/jdk1.8.0/bin/wsimport" 1
sudo update-alternatives --config java

#setting JAVA_HOME and AS_JAVA globally for all users (only for bash)
sudo vim /etc/bash.bashrc
#append the following lines:
export GLASSFISH_HOME=/home/glassfish
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0
export PATH=$PATH:$JAVA_HOME/bin:$GLASSFISH_HOME/bin

#setting JAVA_HOME ans AS_JAVA for everyone (best place for setting env vars globally)
#see https://help.ubuntu.com/community/EnvironmentVariables for details
sudo vim /etc/environment
#append the following lines:
JAVA_HOME=/usr/lib/jvm/jdk1.8.0
#we will set this here because it might prevent problems later
AS_JAVA=/usr/lib/jvm/jdk1.8.0

#check JDK by looking in the /etc/alternatives/ directory...
cd /etc/alternatives
ls -lrt java*

SSL (Secure Sockets Layer) and TLS (Transport Layer Security) are protocols designed to help protect the privacy and integrity of data while it is being transferred across a network. SSLv3 (or simply SSL 3) is not safe anymore, that's why we will disable SSL in step 6. Security configuration before first startup (see below). However, if you run Glassfish with a standard JRE you will realize soon that only 128-bit ciphers suites are supported in your Glassfish. It is quite easy to enable cipher suites with more than 128-bit encryption, i.e. 256-bit AES. The restriction in Glassfish comes from the fact that Glassfish uses what ever is supported by the underlying JSSE. To enable 256-bit cipher suites we need to download the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 and copy them to /usr/lib/jvm/jdk1.8.0/jre/lib/security/ (all Java gurus should know that step very well). The following commands assume that you have downloaded the JCE archive with a browser to your local machine and saved it to ~/Downloads:

#upload jce to ubuntu server via scp (assuming you have scp, else upload somehow else...)
#(replace myuser with your ubuntu user and ipAddressOfUbuntuServer with the ip address of you ubuntu server)
scp ~/Downloads/jce_policy-8.zip myuser@ipAddressOfUbuntuServer:downloads
#now the archive is on the ubuntu server at /home/myuser/downloads

#now we execute the next commands on the ubuntu server
#first, backup old files
sudo mv /usr/lib/jvm/jdk1.8.0/jre/lib/security/local_policy.jar /usr/lib/jvm/jdk1.8.0/jre/lib/security/local_policy.jar.bak
sudo mv /usr/lib/jvm/jdk1.8.0/jre/lib/security/US_export_policy.jar /usr/lib/jvm/jdk1.8.0/jre/lib/security/US_export_policy.jar.bak

#now copy local_policy.jar and US_export_policy.jar to /usr/lib/jvm/jdk1.8.0/jre/lib/security/
cd ~/downloads
sudo unzip ./jce_policy-8.zip
sudo cp ./UnlimitedJCEPolicyJDK8/local_policy.jar /usr/lib/jvm/jdk1.8.0/jre/lib/security/
sudo cp ./UnlimitedJCEPolicyJDK8/US_export_policy.jar /usr/lib/jvm/jdk1.8.0/jre/lib/security/
sudo chgrp -R root /usr/lib/jvm/jdk1.8.0/jre/lib/security
sudo chown -R root /usr/lib/jvm/jdk1.8.0/jre/lib/security

Now Glassfish will be allowed to offer even AES-256. You could also allow only a certain set of cipher suites by changing the settings of your Http Listeners and IIOP Listeners in the admin console or via asadmin later, once Glassfish is installed. If you are interested to learn more about security I suggest to read 256-bit AES Encryption for SSL and TLS: Maximal Security. This paper also tells you how to force certain ciphers in different browsers. However, to be very sure in risky environments, it's a good decision to force a certain set of allowed ciphers directly on your Glassfish server (we will not focus too much on that).

A few days ago the Internet Engineering Task Force (IETF) has announced with Request for Comment 7465 to prohibit RC4 Cipher Suites in TLS. RC4 is considered to be very weak and insecure, so let's follow RFC 7465 and disable RC4. You could do this directly in Glassfish via the admin console or asadmin CLI. However, I believe it's a better idea to do this globally in your JRE. The following configuration will make sure that your Glassfish server will not use any RC4-based cipher suites (not disabling RC4 is a risk these days):

sudo vim /usr/lib/jvm/jdk1.8.0/jre/lib/security/java.security
#then add RC4 to jdk.tls.disabledAlgorithms, i.e. (SSLv3 is the only default in java 1.8.0_31):
jdk.tls.disabledAlgorithms=SSLv3, RC4
# for higher security add maybe this:
# jdk.tls.disabledAlgorithms=MD5, SSLv3, SHA1, DSA, RC4, RSA keySize < 2048, DH keySize < 768
#also add this because of Logjam attack:
jdk.tls.ephemeralDHKeySize=2048

3. Downloading and Installing Glassfish

Now we can download Glassfish. I suggest to switch the user now to glassfish, which we have created in the first step. We want to download the Glassfish zip installation file to /home/glassfish/downloads/. Afterwards the zip file has to be extracted and the content can be moved to /home/glassfish/ - this is everything needed for installing Glassfish. Usually the zip file is extracted to a directory called ./glassfish4/. Make sure to move the content of ./glassfish4/ and not ./glassfish4 itself to /home/glassfish/.

#if you dont't have "unzip" installed run this here first
sudo apt-get install unzip

#now switch user to the glassfish user we created (see step 1)
sudo su glassfish

#change to home dir of glassfish
cd /home/glassfish/

#create new directory if not already available
mkdir downloads

#go to the directory we created
cd /home/glassfish/downloads/

#download Glassfish and unzip
#Hint: get the correct link from  https://glassfish.java.net/download.html if wget fails
wget http://download.java.net/glassfish/4.1/release/glassfish-4.1.zip
unzip glassfish-4.1.zip


#move the relevant content to home directory
mv /home/glassfish/downloads/glassfish4/* /home/glassfish/
#if something has not been moved, then move it manually, i.e.:
mv /home/glassfish/downloads/glassfish4/.org.opensolaris,pkg /home/glassfish/.org.opensolaris,pkg

#exit from glassfish user
exit

#change group of glassfish home directory to glassfishadm
sudo chgrp -R glassfishadm /home/glassfish

#just to make sure: change owner of glassfish home directory to glassfish
sudo chown -R glassfish /home/glassfish

#make sure the relevant files are executable/modifyable/readable for owner and group
sudo chmod -R ug+rwx /home/glassfish/bin/
sudo chmod -R ug+rwx /home/glassfish/glassfish/bin/

#others are not allowed to execute/modify/read them
sudo chmod -R o-rwx /home/glassfish/bin/
sudo chmod -R o-rwx /home/glassfish/glassfish/bin/

At this point you can give it a try and start you Glassfish server. But do not forget to stop it again before you continue with the next steps. Here are the commands for starting and stopping Glassfish:

#now switch user to the glassfish user
sudo su glassfish

#start glassfish
/home/glassfish/bin/asadmin start-domain domain1
#check the output...

#stop glassfish
/home/glassfish/bin/asadmin stop-domain domain1
#check the output...

#exit from glassfish user
exit

4. Setting up an init script

Let's create an init script now. It helps you to start, stop and restart your Glassfish easily. We also need this to make Glassfish start up automatically whenever Ubuntu is rebooting. The file we need to create is /etc/init.d/glassfish. For starting and stopping Glassfish we will use the asadmin tool that ships with Glassfish (we used it a little in the previous step).

#create and edit file
sudo vi /etc/init.d/glassfish

#(paste the lines below into the file and save it...):

#! /bin/sh

#to prevent some possible problems
export AS_JAVA=/usr/lib/jvm/jdk1.8.0

GLASSFISHPATH=/home/glassfish/bin

case "$1" in
start)
echo "starting glassfish from $GLASSFISHPATH"
sudo -u glassfish $GLASSFISHPATH/asadmin start-domain domain1
;;
restart)
$0 stop
$0 start
;;
stop)
echo "stopping glassfish from $GLASSFISHPATH"
sudo -u glassfish $GLASSFISHPATH/asadmin stop-domain domain1
;;
*)
echo $"usage: $0 {start|stop|restart}"
exit 3
;;
esac
:

As you can see Glassfish is started with the user glassfish. It's always a bad idea to run a webserver with root. You should always use a restricted user - in our case this will be the user glassfish. You will learn how to use the script we just created in the next steps.


5. Glassfish autostart: adding init script to default runlevels

The init script is set up. Now we can add it to the default run levels. This way our Glassfish will startup whenever Ubuntu is restarted.

#make the init script file executable
sudo chmod a+x /etc/init.d/glassfish

#configure Glassfish for autostart on ubuntu boot
sudo update-rc.d glassfish defaults

#if apache2 is installed:
#stopping apache2
sudo /etc/init.d/apache2 stop
#removing apache2 from autostart
update-rc.d -f apache2 remove

From now on you can start, stop or restart your Glassfish like this (Ubuntu will also do it this way):

#start
/etc/init.d/glassfish start

#stop
/etc/init.d/glassfish stop

#restart
/etc/init.d/glassfish restart

6. Security configuration before first startup

Even now we should not really use Glassfish in production. We will now begin the configuration of Glassfish itself. You should always run these steps, for example changing the default passwords, enabling https, changing the default ssl certificate to be used for https etc. We will also put our attention on Glassfish obfuscation.

Our first step is to change the master password. Glassfish uses it to protect the domain-encrypted files from unauthorized access, i.e. the certificate store which contains the certificates for https communication. When Glassfish is starting up it tries to read such "secured" files - for exactly this purpose Glassfish needs to be provided with the master password either in an intertactive way or in a non-interactive way. I will choose the non-interactive way because we want our Glassfish to start up on Ubuntu reboot as a deamon (in the Windows world this would be called a service). This is necessary so that the start-domain command can start the server without having to prompt the user. To accomplish this we need to set the savemasterpassword option to true. This option indicates whether the master password should be written to the file system. The file is called master-password and can be found at /home/glassfish/glassfish/domains/domain1/master-password. To change the master password you have to ensure that Glassfish is not running - only then you can call the command change-master-password which will interactivly ask you for the new password.

#switch user to glassfish (stay with this user for complete Step 6!)
sudo su glassfish

#change master password, default=changeit
/home/glassfish/bin/asadmin change-master-password --savemasterpassword=true
#prompt: choose your new master password ==> myMasterPwd
# ==> stores file to /home/glassfish/glassfish/domains/domain1/master-password

The next step is to change the administration password with change-admin-password. Because this command is a remote command we need to ensure that Glassfish is running before we can execute the command. Since we want "automatic login" we will create an admin password file allowing us to login without being asked for credetials (it will be stored at /home/glassfish/.gfclient/pass).

#change admin password
/home/glassfish/bin/asadmin change-admin-password
#1. enter "admin" for user (default)
#2. hit enter because default pwd is empty
#3. choose you new pwd ==> myAdminPwd

#now we have to start Glassfish
/home/glassfish/bin/asadmin start-domain domain1

#login for automatic login...
/home/glassfish/bin/asadmin login
#prompt:
#user = admin
#password = myAdminPwd
#==> stores file to /home/glassfish/.gfclient/pass

#now stop Glassfish
/home/glassfish/bin/asadmin stop-domain domain1

Glassfish is coming with a pre-configured certificate which is used for ssl (https). You can see it in the keystore.jks file if you check for the alias s1as. Since Glassfish 3.1 there is even another preconfigured certificate available: glassfish-instance. But that also means that everybody else can get these two certificates, the public keys, private keys, etc. With that information you could never be safe because "others" could "read" your data sent to Glassfish via https. That means you should always make sure to replace the pre-configured s1as and glassfish-instance entries in your keystore. But you should not delete them as long as the alias "s1as" and "glassfish-instance" are still in use (and it is by default in use for https...). I faced some strange behaviour as I did not think of that at the beginning when I simply deleted s1as - learn from my mistake and do not delete it for now... But we can help us with generating a new alias first (myAlias) and when ever needed or wanted we could change each occurrence of s1as to myAlias (i.e. via admin console) and then we could finally delete that s1as. The same has to be done also for glassfish-instance.

The following code box shows you the commands we need for modifying our Glassfish keystore. As you can see we first delete our pre-configured s1as entry (Glassfish mustn't be running!). Later a new s1as entry is generated - it is now unique for us! Similar steps have to be executed also for our second certificate (glassfish-instance).

#create new certs
cd /home/glassfish/glassfish/domains/domain1/config/
keytool -list -keystore keystore.jks -storepass myMasterPwd
keytool -delete -alias s1as -keystore keystore.jks -storepass myMasterPwd
keytool -delete -alias glassfish-instance -keystore keystore.jks -storepass myMasterPwd
keytool -keysize 4096 -genkey -alias myAlias -keyalg RSA -dname "CN=nabisoft,O=nabisoft,L=Mannheim,S=Germany,C=DE" -validity 3650 -keypass myMasterPwd -storepass myMasterPwd -keystore keystore.jks
keytool -keysize 4096 -genkey -alias s1as -keyalg RSA -dname "CN=nabisoft,O=nabisoft,L=Mannheim,S=Germany,C=DE" -validity 3650 -keypass myMasterPwd -storepass myMasterPwd -keystore keystore.jks
keytool -keysize 4096 -genkey -alias glassfish-instance -keyalg RSA -dname "CN=nabisoft,O=nabisoft,L=Mannheim,S=Germany,C=DE" -validity 3650 -keypass myMasterPwd -storepass myMasterPwd -keystore keystore.jks
keytool -list -keystore keystore.jks -storepass myMasterPwd

#make sure that keystore.jks and cacerts.jks stay in sync, so let's update cacerts.jks:
#1. export the two certificates we just created to files: 
keytool -export -alias glassfish-instance -file glassfish-instance.cert -keystore keystore.jks -storepass myMasterPwd
keytool -export -alias s1as -file s1as.cert -keystore keystore.jks -storepass myMasterPwd
#2. now delete the old/existing aliases initially shipped with glassfish:
keytool -delete -alias glassfish-instance -keystore cacerts.jks -storepass myMasterPwd
keytool -delete -alias s1as -keystore cacerts.jks -storepass myMasterPwd
#3. now import the two certificates we stored into files:
keytool -import -alias glassfish-instance -file glassfish-instance.cert -keystore cacerts.jks -storepass myMasterPwd
keytool -import -alias s1as -file s1as.cert -keystore cacerts.jks -storepass myMasterPwd

#we can delete the two cert files now
rm glassfish-instance.cert s1as.cert

Now we want to enable https for the admin console. Once we have done that we can be sure that nobody can listen to our data sent via https because nobody else has our certificates, i.e. nobody can decrypt our password used for entering the admin console via browser (in case someone cought our data packages). However, sometimes clients want to connect via https using SSLv3, which is considered to be vulnerable nowadays (ever heard about "Poodle"?). In other words: disable SSLv3 completely where ever you find it - no discussion about that allowed! Here is a great post about different ways of disabling SSLv3 in Glassfish 4.1. I typically use the command line version (asadmin). Furthermore, it seems that Glassfish 4.1 does not disable TLS client-initiated renegotiation by default, which is considered to open some doors for DoS attacks. The article TLS Renegotiation and Denial of Service Attacks by Ivan Ristic is a good read. For us this means we need to disable client-initiated renegotiation somehow. But this is not all we want to do here. We want to change some of the default JVM Options and we want to make our Glassfish not telling too much ("obfuscation").

The first JVM Option we will change is replacing the -client option with the -server option. I expect the java option -server to be the better choice when it comes to performance. I have also decided to change -Xmx512m (Glassfish default) to a higher value: -Xmx4096m. Additionally, I have added -Xms4096m. Furthermore, we will remove -XX:MaxPermSize=192m and replace it with -XX:MaxMetaspaceSize=512m because -XX:MaxPermSize was deprecated in JDK 8. If you want to find out more about it then have a look at this InfoQ article. For more information about JVM options please check the Oracle's official documentation.
All JVM Options so far are optional. But at least adding -Dproduct.name="" is a good idea for everyone. If you would not add this then each http/https response will contain a header field like this: Server: GlassFish Server Open Source Edition 4.1
This is some great piece of information for hackers - that's why you should disable it. We don't want Glassfish to talk too much for security reasons!

We also don't want Glassfish to send a header similar to X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.1 Java/Oracle Corporation/1.8) because this is telling everyone we are using a Servlet 3.1 container and that we are (of course) using Java etc. So we have to disable sending x-powered-by in the http/https headers. After executing the commands below our Glassfish will run in silent mode - it is not telling too much any more. Glassfish obfuscation accomplished. SSLv3 and cient-initiated renegotiation will also be disabled, which reduces the surface for attacks.

# the commands here change the file at
# /home/glassfish/glassfish/domains/domain1/config/domain.xml

#first we have to start Glassfish
/home/glassfish/bin/asadmin start-domain domain1

# enable https for remote access to admin console
# requests to http://xxx:4848 are redirected to https://xxx:4848
/home/glassfish/bin/asadmin enable-secure-admin

#change JVM Options
#list current jvm options
/home/glassfish/bin/asadmin list-jvm-options
#now start setting some important jvm settings (change this as you wish)
/home/glassfish/bin/asadmin delete-jvm-options -- -client
/home/glassfish/bin/asadmin create-jvm-options -- -server
#For server deployments, -Xms and -Xmx are often set to the same value
/home/glassfish/bin/asadmin delete-jvm-options -- -Xmx512m
/home/glassfish/bin/asadmin create-jvm-options -- -Xms4096m
/home/glassfish/bin/asadmin create-jvm-options -- -Xmx4096m

#-XX:MaxPermSize was deprecated in JDK 8, and superseded by the -XX:MaxMetaspaceSize option, see http://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
# see also this good article: http://www.infoq.com/articles/Java-PERMGEN-Removed
/home/glassfish/bin/asadmin delete-jvm-options '-XX\:MaxPermSize=192m'
/home/glassfish/bin/asadmin create-jvm-options -- '-XX\:MaxMetaspaceSize=512m'
/home/glassfish/bin/asadmin create-jvm-options -- '-XX\:MetaspaceSize=512m'

#disable client-initiated renegotiation (to decrease the surface for DoS attacks)
/home/glassfish/bin/asadmin create-jvm-options -Djdk.tls.rejectClientInitiatedRenegotiation=true

#get rid of http header field value "server" (Glassfish obfuscation)
/home/glassfish/bin/asadmin create-jvm-options -Dproduct.name=""

#disable sending x-powered-by in http header (Glassfish obfuscation)
/home/glassfish/bin/asadmin set server.network-config.protocols.protocol.http-listener-1.http.xpowered-by=false
/home/glassfish/bin/asadmin set server.network-config.protocols.protocol.http-listener-2.http.xpowered-by=false
/home/glassfish/bin/asadmin set server.network-config.protocols.protocol.admin-listener.http.xpowered-by=false
/home/glassfish/bin/asadmin set server.network-config.protocols.protocol.sec-admin-listener.http.xpowered-by=false

#optional: let's disable autodeploy (via autodeploy folder)
/home/glassfish/bin/asadmin set server.admin-service.das-config.autodeploy-enabled=false

#disable SSLv3
/home/glassfish/bin/asadmin set server.network-config.protocols.protocol.http-listener-2.ssl.ssl3-enabled=false
/home/glassfish/bin/asadmin set server.network-config.protocols.protocol.sec-admin-listener.ssl.ssl3-enabled=false
/home/glassfish/bin/asadmin set server.iiop-service.iiop-listener.SSL.ssl.ssl3-enabled=false
/home/glassfish/bin/asadmin set server.iiop-service.iiop-listener.SSL_MUTUALAUTH.ssl.ssl3-enabled=false

#restart to take effect
/home/glassfish/bin/asadmin stop-domain domain1
/home/glassfish/bin/asadmin start-domain domain1
#what jvm options are configured now?
/home/glassfish/bin/asadmin list-jvm-options

#we are done with user glassfish
exit

7. Run Glassfish

Finally we have come to where we wanted. We have installed, secured and configured our Glassfish installation.

#starting glassfish
sudo /etc/init.d/glassfish start

#remove glassfish from autostart
#update-rc.d -f glassfish remove

If you want a quick and free ssl security audit for your Glassfish server then go to Qualys SSL Labs and check your server configuration (the server must be accessible from the internet). I suggest every server available on the internet should use and even force HTTPS because it makes the web much safer. Even Google has announced to take HTTPS as a ranking signal. The "bad performance" argument is not really relevant anymore: TLS has exactly one performance problem: it is not used widely enough. Google gives you some good hints to Secure your site with HTTPS. Another good read is Ivan Ristić's paper: SSL/TLS Deployment Best Practices.

Comments
  • If you like this tutorial help us to maintain it:
  • And don't forget to let others know about it:
I can not get the master password changed
posted by Larry C Robinson
Thu Apr 20 20:51:56 UTC 2017
sudo su glassfish
glassfish@server2:/home/larry$ /home/glassfish/bin/asadmin change-master-password --savemasterpassword=true
Enter the current master password>
Enter the new master password> 
Enter the new master password again> 
Error changing master password( Error changing password for password alias store /home/glassfish/glassfish/domains/domain1/config/domain-passwords( java.io.EOFException ) )
Command change-master-password failed.

I have tried several different passwords using just characters, numbers and characters, and special characters numbers and characters, variations of each of these always having more than 6 places...Help
jdbcRealm
posted by francis mwariri
Sat Oct 08 15:02:10 UTC 2016
Hello. I followed the tutorial and everything seems to work as expected. However, jdbcRealm security authentication now fails.
SSLHandshakeException
posted by Phil
Sun Sep 18 15:30:32 UTC 2016
I followed your tutorial step by step but if I open https://[IPOfGlassfishMachine]:4848 and enter admin User and PW, it results in HTTP Status 500 - Internal Server Error.

The server.log shows:

[2016-09-18T13:26:15.697+0000] [glassfish 4.1] [SEVERE] [] [org.glassfish.admingui] [tid: _ThreadID=108 _ThreadName=admin-listener(9)] [timeMillis: 1474205175697] [levelValue: 1000] [[
  javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: signature check failed;
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: signature check failed;
restRequest: endpoint=https://localhost:4848/management/domain/anonymous-user-enabled
attrs={}
method=GET]]

Glassfish 4.1.1 in the Ubuntu 16.04 with Java 8
posted by Aecio Pires
Thu Jul 21 15:37:34 UTC 2016
Hello, Nabi!

Congratulations on your tutorial! He was very últil in my work here in Brazil.

I wrote a tutorial video of Ubuntu 16.04 and Glassfish 4.1.1 with Java 8.

Follow the link: http://blog.aeciopires.com/customizando-o-glassfish-4-no-ubuntu-16-04/

Hug and is with God.
SSL server test
posted by Roland
Tue Mar 29 11:55:15 UTC 2016
Nabi, thanks this great article. I followed the instructions step by step. By the end of your post you mentioned  Qualys SSL Labs as a good testing tool. After running the test I get the following report:

Authentication section:
Subject: common names, Nabisoft mismatch

Trusted: Not Trusted

This report states that if the Certificate hostnames don't match the site hostname it can be a reason for being not trusted. I am newbie in Ubuntu and security. So can you please tell me which part of your script should be replaced by my domain name?

Cheers,
Roland
Reg - Step 6: Security configuration before first startup
posted by Surendra Ganne
Mon Mar 28 15:46:20 UTC 2016
I have certificates from godaddy. How to use them instead the one's from the documentation. I am new to glassfish and I don't like to mess up things. Need help with keytool commands. 

EC2 t2.micro insufficient memory
posted by Axel
Tue Mar 22 14:46:06 UTC 2016
Dear all,
If you wanna try to install Glassfish on a EC2 t2.nano instance, remember that:
/home/glassfish/bin/asadmin create-jvm-options -- -Xms4096m
/home/glassfish/bin/asadmin create-jvm-options -- -Xmx4096m
are too big. Trying to restart the server you will get an error message and you cannot change these values if the server is not running. You can change these value editing the file: /home/glassfish/glassfish/domains/domain1/config/domain.xml

From
<jvm-options>-Xms4096m</jvm-options>
<jvm-options>-Xmx4096m</jvm-options>

To
<jvm-options>-Xms512m</jvm-options>
<jvm-options>-Xmx512m</jvm-options>

then the server should restart.
Import Letsencrypt certificates (Part 2)
posted by Grandt
Fri Jan 29 14:34:31 UTC 2016
The message was cut off. Ignore the last line in the previous dump, and use this as the rest of the script:
----
keytool -importkeystore -destkeystore $KEYSTORE -srckeystore s1as_pkcs.p12 -srcstoretype PKCS12 -alias s1as $STOREPASS

keytool -list -keystore $KEYSTORE -storepass $KEYSTOREPW

echo ""
echo "- Cleaning up"

cd ..
rm -rf LEtemp

echo ""
echo "- Restarting Glassfish Service"
echo ""

service glassfish stop
echo ""
service glassfish start
Import Letsencrypt certificates
posted by Grandt
Fri Jan 29 14:33:10 UTC 2016
Here's a script I cooked up to import the Letsencrypt generated certificates into Glassfish.
-----
#!/bin/sh
me="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")"

if [ `id -u` -ne 0 ]
then
        echo "This script requires administrator privileges. Run with sudo."
        echo ""
        echo "Usage: sudo ./$me"
        echo ""
        exit 1
fi

DOMAIN=<domain.tld> # your domain name
KEYSTOREPW=<passwprd> # The password given tot he Glassfish Keystore. The same as the GF Admin password.
KEYSTORE=<Path to the Glassfish domains Keystore> # ie. ...glassfish/domains/domain1/config/keystore.jks

LIVE=/etc/letsencrypt/live/$DOMAIN

mkdir LEtemp
cd LEtemp

cp -f $KEYSTORE $KEYSTORE.old

STOREPASS="-srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW"

echo "- Removing old keys"
keytool -delete -alias myalias -keystore $KEYSTORE -storepass $KEYSTOREPW
keytool -delete -alias root -keystore $KEYSTORE -storepass $KEYSTOREPW
keytool -delete -alias glassfish-instance -keystore $KEYSTORE -storepass $KEYSTOREPW
keytool -delete -alias s1as -keystore $KEYSTORE -storepass $KEYSTOREPW

keytool -list -keystore $KEYSTORE -storepass $KEYSTOREPW

echo "- Importing new keys"
openssl pkcs12 -export -in $LIVE/cert.pem -inkey $LIVE/privkey.pem -out cert_and_key.p12 -name myalias -CAfile $LIVE/chain.pem -caname root -password pass:$KEYSTOREPW
keytool -importkeystore -destkeystore $KEYSTORE -srckeystore cert_and_key.p12 -srcstoretype PKCS12 -alias myalias $STOREPASS
keytool -import -noprompt -trustcacerts -alias root -file $LIVE/chain.pem -keystore $KEYSTORE $STOREPASS

echo "- Importing new certs"
openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out glassfish-instance_pkcs.p12 -name glassfish-instance -password pass:$KEYSTOREPW
keytool -importkeystore -destkeystore $KEYSTORE -srckeystore glassfish-instance_pkcs.p12 -srcstoretype PKCS12 -alias glassfish-instance $STOREPASS

openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out s1as_pkcs.p12 -name s1as -pass
This is the tutorial I'm looking for
posted by Grandt
Tue Jan 26 17:38:28 UTC 2016
Hands down the best, and most easily understandable tutorial on setting up a SECURED Glassfish 4 server.

After you wrote it though, a few things have changed in the world of security. Namely the addition of https://letsencrypt.org/ 

Now, I haven't figured out how to get their certificated into my keychain. I'm a rank novice at this and would rather get some correct pointers from someone who obviously know what they are doing, rather than attempting it myself anding up erroneously thinking I did it right, and therefore inadvertently created a vulnerability.

Thanks
RE: Awesome article
posted by Nabi
Tue Nov 24 17:09:08 UTC 2015
Thank you, Matt! You made my day :-)
Awesome article
posted by Matt
Tue Nov 24 16:08:39 UTC 2015
This has to be the best tutorial I've seen in a long time... thank you
Stopping glassfish
posted by Crock
Thu Sep 10 10:05:29 UTC 2015
Thanks for this.  I had a heck of a time getting glassfish to start and stop - which meant that I couldn't get through most of the second half of the tutorial.  All the asadmin commands would just error out or hang.  (Granted - this was my error from not following the instructions closely enough.)  Ubuntu told me that 'something' was using port 4848 and it was probably glassfish.  However, i couldn't reach anything at localhost:4848.  Also, "/home/glassfish/bin/asadmin stop-domain domain1" would just hang.  Same with the bash script.
Finally, I found the command "sudo service glassfish stop"!  This was extremely helpful in stopping glassfish so I could correct and continue.  While this might be obvious to experienced ubuntu users, I would request that you include it in the section where you try to start & stop at the end of step 3.
Lastly, I didn't have vim in my ubuntu install and used gedit - you might want to mention that as an alternate.
Thanks again!
-C
glassfish download location changed
posted by freeman
Tue Aug 18 09:55:16 UTC 2015
oracle changed the way you can download glassfish:

http://download.oracle.com/glassfish/4.1/release/

greets and thx
keytool
posted by Gerald Gray
Fri Aug 14 23:44:52 UTC 2015
Great tutorial - it has been very helpful. However, when I attempt to run line 7 to generate a key

keytool -keysize 4096 -genkey -alias myAlias -keyalg RSA -dname "CN=nabisoft,O=nabisoft,L=Mannheim,S=Germany,C=DE" -validity 3650 -keypass myMasterPwd -storepass myMasterPwd -keystore keystore.jks

(using my Master password of course)

I get an error java.io.IOException: ObjectIdentifier() -- Must be at least two oid components

Your help is greatly appreciated!
Too Verbose
posted by Agul
Wed Jul 29 15:57:05 UTC 2015
Thanks for this tutorial but I fill that is too verbose you need to write an optimized version :).
error
posted by gasper
Tue Jul 28 22:52:36 UTC 2015
I got this error when trying to change master password. System is Ubuntu 14.04, with java 1.8.0_51

xception in thread "main" java.lang.ExceptionInInitializerError
        at javax.crypto.JceSecurityManager.<clinit>(JceSecurityManager.java:65)
        at javax.crypto.Cipher.<init>(Cipher.java:268)
        at com.sun.crypto.provider.CipherForKeyProtector.<init>(KeyProtector.java:362)
        at com.sun.crypto.provider.KeyProtector.seal(KeyProtector.java:300)
        at com.sun.crypto.provider.JceKeyStore.engineSetKeyEntry(JceKeyStore.java:276)
        at java.security.KeyStore.setKeyEntry(KeyStore.java:1140)
        at com.sun.enterprise.security.store.PasswordAdapter.setPasswordForAlias(PasswordAdapter.java:308)
        at com.sun.enterprise.admin.servermgmt.MasterPasswordFileManager.createMasterPasswordFile(MasterPasswordFileManager.java:113)
        at com.sun.enterprise.admin.servermgmt.MasterPasswordFileManager.changeMasterPasswordInMasterPasswordFile(MasterPasswordFileManager.java:158)
        at com.sun.enterprise.admin.servermgmt.pe.PEDomainsManager.changeMasterPassword(PEDomainsManager.java:266)
        at com.sun.enterprise.admin.servermgmt.cli.ChangeMasterPasswordCommandDAS.executeCommand(ChangeMasterPasswordCommandDAS.java:123)
        at com.sun.enterprise.admin.cli.CLICommand.execute(CLICommand.java:322)
        at com.sun.enterprise.admin.servermgmt.cli.ChangeMasterPasswordCommandDAS.execute(ChangeMasterPasswordCommandDAS.java:91)
        at com.sun.enterprise.admin.servermgmt.cli.ChangeMasterPasswordCommand.executeCommand(ChangeMasterPasswordCommand.java:123)
        at com.sun.enterprise.admin.cli.CLICommand.execute(CLICommand.java:322)
        at com.sun.enterprise.admin.servermgmt.cli.ChangeMasterPasswordCommand.execute(ChangeMasterPasswordCommand.java:155)
        at com.sun.enterprise.admin.cli.AdminMain.executeCommand(AdminMain.java:366)
        at com.sun.enterprise.admin.cli.AdminMain.doMain(AdminMain.java:300)
        at org.glassfish.admin.cli.AsadminMain.main(AsadminMain.java:56)
Cause
Flawless instruction
posted by faisal dirie
Mon Jun 22 09:39:00 UTC 2015
Thank you. I followed all the steps. This worked well. Once again thank you.
Never allow user "glassfish" to sudo
posted by Nabi
Fri May 08 07:14:08 UTC 2015
Ray, do not add glassfish to the sudoers list! This is not needed if you follow this tutorial and you should always avoid this! Please make sure to read the complete tutorial, especially the text! Make sure you understand everything and each line of code. Also, make sure to learn some of the linux basics/fundamentals. The init script is basically for automatic startup of Glassfish when Ubuntu is rebooted. Hence, it is executed by root; and root can sudo. If you want to start Glassfish from the console with any other user who is not allowed to sudo please use "/home/glassfish/bin/asadmin stop-domain domain1".
note
posted by Ray Renaldi
Thu May 07 23:05:06 UTC 2015
To anyone that failed to access https://domain-or-ip:4848 

what happened in my case could be the case that you'd be failing to access the admin GUI 

I followed the instructions blindly without understanding what each line is doing(i know better now) BTW. 
my failure was caused by this line 
/home/glassfish/bin/asadmin create-jvm-options -- -Xms4096m

My server only has 1024m, I havent completely figured out yet but from my quick research that line right there set the initial memory allocation for JVM and set it to above your memory capacity will caused JVM to crash -> this is the reason why my server would need to be restarted everytime I try to access the admin GUI

now ...
/home/glassfish/bin/asadmin create-jvm-options -- -Xmx4096m
if you set above line to 4096 it would be fine since its the max value not the initial, in other words Glassfish MAY not reach that value(even in my case more often than not once you start using JPA and all the fancy library it will go up north of 1GB)

just thought id share what i've experienced with everyone. cheers!
good point
posted by Ray Renaldi
Thu May 07 22:56:07 UTC 2015
I failed to notice that, but this is implying that the user: glassfish has to be in sudoer group also and that's the part i missed. I created user glassfish but didn't add glassfish to the sudoer group  It was my fault I'm sorry, everything works flawlessly now, it's just really slow deploying from my local Netbeans to the remote Glassfish, it's not helping that my VPS only has 1GB ram, again awesome tutorial, i'll hit up that paypal once get off work!
got it figured out
posted by Ray Renaldi
Thu May 07 08:03:03 UTC 2015
Last comment, again i want to say thank you and i figured it out. I am able to connect to https://my-vps-ip:4848

ich bedanke mich nach dir!
RE: question
posted by Nabi
Thu May 07 07:54:56 UTC 2015
In the code box of step 4 you can see this:

sudo -u glassfish $GLASSFISHPATH/asadmin start-domain domain1
sudo -u glassfish $GLASSFISHPATH/asadmin stop-domain domain1

That means the commands are executed with user "glassfish" and never with the root user; this is on purpose! Always use sudo to start/stop/restart glassfish with the script, i.e. "sudo /etc/init.d/glassfish start" (see step 7). The start/stop/restart commands from Step 5 will fail if the user is not allowed to sudo; a corresponding error message tells linux guys what to do...
question
posted by Ray Renaldi
Thu May 07 06:40:27 UTC 2015
I decided to re-do everything all over again since the first attempt failed to have access to my admin through https://my-vps-ip:4848

I noticed something contradicting each other between step 4 and 5

This is where it started - STEP 4
#change group of glassfish home directory to glassfishadm
sudo chgrp -R glassfishadm /home/glassfish
 
#just to make sure: change owner of glassfish home directory to glassfish
sudo chown -R glassfish /home/glassfish
 
#make sure the relevant files are executable/modifyable/readable for owner and group
sudo chmod -R ug+rwx /home/glassfish/bin/
sudo chmod -R ug+rwx /home/glassfish/glassfish/bin/
 
#others are not allowed to execute/modify/read them
sudo chmod -R o-rwx /home/glassfish/bin/
sudo chmod -R o-rwx /home/glassfish/glassfish/bin/

I assume there's no other user (Not even ROOT?) allowed to rwx the files in those directory.

Now here's the init.d from STEP 5
From now on you can start, stop or restart your Glassfish like this (Ubuntu will also do it this way):

Bash commands:
#start
/etc/init.d/glassfish start ----------- I assume you installed glassfish with ROOT access? unless the user that you are using to install glassfish have root access there's no way you can execute this command not even with glassfish user.

Now I installed glassfish with ROOT access and when I ran above command it failed since there's NO other users (not even ROOT i assume??) can rwx anything in that directory. 

I apologize if i'm mistaken, i'm new with Ubuntu and trying to understand which part does what while installing an App server can be challenging


 
#stop
/etc/init.d/glassfish stop
 
#restart
/etc/init.d/glassfish restart
Thank you for very details Tutorials
posted by Ray
Mon May 04 20:43:18 UTC 2015
First I'd like to thank you for a very thorough tutorial i was able to get GF 4 up and running in less than two hours and it's my first time setting up GF in ubuntu.

However I haven't been able to access the Web Admin GUI, i changed admin password as you mentioned above and enable-secure-admin but everytime i type https://my-host:4848 it load the Web Admin GUI but it just shows load and get stuck there

On Chrome I opened the developer tools(F12) and checked the log it got stuck on testifbackendisready.html on line 135 which is xhttp.send() command and timed out. 

I have already removed my firewall setting on ubuntu by clearing up the iptable but the problem remains. I have also checked the server.log and nothing suspicious in there except for the warning "Context path from ServletContext:  differs from path from bundle:" 

If you could suggest anything else I can try to solve this problem I would really appreciate as I'm very new with GF installation on *NIX platform
Thanks
posted by Nick
Thu Apr 30 09:12:47 UTC 2015
Thanks, so usefull post!!!
RE: Enter the current master password
posted by Nabi
Wed Apr 29 07:56:47 UTC 2015
From line 4 of the first code box in step 6 you can see that the default master password is "changeit".
oops !
posted by payman
Wed Apr 29 07:55:27 UTC 2015
Dear Nabi, I am sorry, it appears I consistently underestimate the completeness of this document, and ignore the comments. you have already said what the current master password is. 
Enter the current master password
posted by payman
Wed Apr 29 07:21:12 UTC 2015
Dear Nabi, first let me thank you again and also apologize, I didn't read the entire instructions and assumed once I install glassfish I am done. I know better now !! 

So I am trying to carefully implement all your instructions, but I am stuck. every time I want to change the master password, it says Enter the current master password, I hit enter because I assume that the current master password is an empty string, but then it says Incorrect, you will not be able to change the master password.  Help !! Please !!  http://goo.gl/Olupr8

I was able to donate ! so I hope you have received my donation. 
 
RE: http to https redirect on glassfish server
posted by Nabi
Tue Apr 28 17:47:09 UTC 2015
Payman, thank you for your warm words! Hm, for me Paypal works just fine - that's strange...

This tutorial actually gives you all you need and there is actually no need to use any apache modules. If you have followed this tutorial then you can easily access your server even via https. The certificate that is used for https is the one created in this tutorial. As you can see, there is absolutely no need to modify the iptables rules to make https work; it's already in the tutorial! The only thing you need to do is creating a CSR and get a real signed certificate which you would then configure inside your Glassfish. Like I said: there is no apache needed for this at all! This is standard java keystore configuration and you can find many links explaining how to configure a certificate for Glassfish. Basically, you need to add the certificate to /home/glassfish/glassfish/domains/domain1/config/keystore.jks and maybe also updating cacerts.jks and that's it. NO APACHE at all :-)

For the redirect you don't have to use iptables or apache. Instead you can simply handle the redirect inside your Java EE application, i.e. by using a simple filter in your web.xml file of your project/application (or even via JAAS). I think you are also a little confused about how a "redirect" works. If someone connects via http then the browser should simply receive an "HTTP 301 - Moved Permanently" response including the new location which is the initial URL but prefixed with https. This behavior is not a port forwarding, make sure you understand this!

I hope this helps :-)
http to https redirect on glassfish server
posted by payman
Tue Apr 28 16:32:13 UTC 2015
Hi, 
  your tutorial was tremendously useful and I even tried to donate but there seems to be something wrong with your paypal portal. 
 
  It's great that your included iptables are comprehensive and bugfree, I previously tried to use mod-jk to do this, but my mod_jk was incompatible with openjdk and as hard as I tried I was never able to compile and produce a mod_jk that would work on my vps server. 

  But now that I have accomplished this much, thanks to your clear and lucid exposition here, I ache to do more. 

  currently port 80 requests go to port 8080 and port 443 requests go to port 8181.  

  But what if I want to force the user to do all of his communications through HTTPS, I tried to modify the iptables rules, to get the requests to port 80 to go to port 8181, but nothing changed. Then I tried to modify apache2 conf files, to do the same, but it was to no avail. No matter what I do, when I type the http address, it goes straight to http, and no redirect happens. 

 Can you help me here? 

 Also right now, I really haven't set up https, I just want to type the url of my domain http and get redirected to https, 
 But what if I get a security certificate, (either self-signed or signed by a certificate authority)? what do I do then? 

 I spent a lot of time and effort to learn how to configure apache to set up a bona fide https, but now it looks like, it's a whole different deal with glassfish server. Can you give me any pointer on that? 

once again I am immensely thankful. 
Excellent tutorial!
posted by Sander IJpma
Sat Apr 25 17:02:57 UTC 2015
Excellent tutorial! Glassfish securely up and running in less then an hour! I used your previous version as well with great pleasure. One tiny detail; to do a stop-domain before commencing point 7.
Good work --add disclaimer
posted by Kenn
Sun Apr 19 00:28:13 UTC 2015
I found your tutorial really useful. however add a disclaimer to the lines changing the memory requirement -Xmx. I was using t1 micro from amazon and glassfish failed to restart due to memory constraint. I had to update domain.xml using vi