These notes describe installation of Glassfish 3.1 or 3.1.x — the reference implementation of Java EE — on a Debian or Ubuntu system. The Java SE Development Kit is assumed to be installed already. Users who prefer to download the bundle containing both JavaSE and Glassfish will need to make adjustments to Steps 2 and 3 below.
It is simple and tempting to install Glassfish in your own directory (for convenience), or to switch to superuser and install it in a more public space. Many other tutorials take one of these easy options. However the aim of this tutorial is to implement a (slightly) higher level of security. For this reason we take the more tricky route of installing Glassfish in the home directory of a pseudo-user 'glassfish' with limited rights. We also touch on certificates and administration matters.
This document is the result of performing several installations of Glassfish. It is more of a recipe than a tutorial. Feel free to write to me if you find errors, or if you notice serious omissions.
It is possible to install Glassfish under your own username: the advantage is personal convenience, but the disadvantage occurs when trying to make it accessible to the public. Conversely, it is possible to install Glassfish as root; however the advantages and disadvantages are then reversed. And both approaches are ugly from the perspective of security. Far better to create a user with restricted rights, and use that for running Glassfish. Once you have added such a user (let's say 'glassfish'), you might also want to add a new group (let's called it 'glassfish' too). This group can then be used to facilitate access for all users who will be allowed to administer Glassfish.
Below are the required user- and group-related commands. Customize them
to suit your environment. In particular, choose whether to give
the pseudo-user 'glassfish' a shell. Doing so facilitates administration
— the .bashrc file can contain handy environment
variables and aliases — however this is a security concern.
To allay these concerns, it is possible deny Glassfish automatic access
to any shell; and instead to invoke a shell and environment variables
only if and when necessary. The present instructions have been
tested both ways. Generally, these instructions assume that Glassfish has
no default shell.
# Add a new user called 'glassfish' with group 'glassfish' sudo adduser --system --group --home /home/glassfish [--shell /bin/bash] glassfish # Enable an existing user to be a Glassfish administrator. Repeat # for additional users. sudo usermod -a -G glassfish existingUser # ##### NOTE! ###### # The user will need to login afresh, before this modification takes effect # The user can check their group membership with: groups # List should include 'glassfish' # Undo: # If we want to delete the user and group 'glassfish' (and optionally remove Glassfish too): sudo deluser [--remove-home] glassfish sudo delgroup glassfish
We now have a limited user, who will be the owner of Glassfish. Note that user 'glassfish' has no login ability. But don't worry. As will be seen below, Glassfish maintains its own administration passwords and security realms, so the configuration and content of the server will still be password protected.
See instructions elsewhere for installation of Java SE. (Glassfish 3.1
requires Oracle's JDK 1.6.0_22 or later; Glassfish 3.1.1 requires JDK 1.6.0_26
or later, including 1.7.0.)
One of the consequences of installation should be addition of an
environment variable pointing to its location, e.g.
JAVA_HOME=/usr/java/jdk1.6.0_26, or similar.
Glassfish administrators and developers will need to make some additions to
their .bashrc file in order to be able to perform compilations
and administration tasks. Here is an example of the required additions
— although those users will certainly need to make adjustments to the
following, to suit their own environment.
# Java SE
export JAVA_HOME=/usr/java/jdk1.7.0
export JAVA_BINDIR=${JAVA_HOME}/bin
echo $PATH | /bin/grep -q -v $JAVA_BINDIR
if [ $? -eq 0 ]; then export PATH="${PATH}:$JAVA_BINDIR"; fi
# Ant
export ANT_HOME=/usr/java/apache-ant-1.8.2
echo $PATH | /bin/grep -q -v $ANT_HOME/bin
if [ $? -eq 0 ]; then export PATH="${PATH}:$ANT_HOME/bin"; fi
# Glassfish
export GLASSFISH_PARENT=/home/glassfish
export GLASSFISH_HOME=/home/glassfish/glassfish
echo $PATH | /bin/grep -q -v $GLASSFISH_HOME/bin
if [ $? -eq 0 ]; then export PATH="${PATH}:$GLASSFISH_HOME/bin"; fi
We shall configure Glassfish to be managable by certain favoured users,
logged in as themselves, and so it should never be necessary for anyone to
log in as user 'glassfish'. For this reason the home directory of the
pseudo-user glassfish does not need any .profile
or .bashrc file.
In particular, appending $GLASSFISH_HOME/bin to their
$PATH (as suggested above) will give administrators access
to asadmin and other management and development tools.
[There is just one other location that administrators might want to add
to their $PATH, namely $GLASSFISH_PARENT/bin.
This contains the two update tools, plus an alternative version of
asadmin.]
Choosing amongst the many available versions of Glassfish is very confusing, as the differences are not explained properly. As of June 2011 some of the alternatives are:
What are the distinctions?
It is actually not terribly critical which version you choose: all are free and will quickly get you up and running. But I find the Glassfish zip from dlc.sun.com.edgesuite.net to be more to my taste, as I can manage installation and operation more directly. The zip version is required for this tutorial.
Accordingly we shall download the Glassfish zip installation file.
We shall opt for the 'full' version, rather than the Web Profile. In
the following set of commands we shall download it to
/home/glassfish/downloads/, unzip it there, and finally re-home
everything to /home/glassfish/.
# Switch user to the glassfish user we created (see step 1) # Switch to the user 'glassfish' and to /home/glassfish, but retain the # superuser's environment sudo su --shell /bin/bash glassfish # 'sudo -H -u glassfish -s' has a similar effect, but preserves env variables # Create new download directory, '/home/glassfish/downloads' cd ~ whoami # should say 'glassfish' pwd # should say '/home/glassfish' mkdir downloads cd downloads # Download Glassfish and unzip. The alternative site is download.java.net. # [You may or may not need to set the environment variable http_proxy first.] wget http://dlc.sun.com.edgesuite.net/glassfish/3.1.1/release/glassfish-3.1.1.zip unzip glassfish-3.1.1.zip # This creates /home/glassfish/downloads/glassfish3/* # Move the relevant content up two levels to home directory mv glassfish3/* /home/glassfish/ # One strangely named file needs to be moved explicitly mv glassfish3/.org.opensolaris,pkg /home/glassfish/ # Delete the now-empty directory created by unzip rmdir glassfish3 # Exit from glassfish user. We didn't login, so 'logout' is not appropriate. exit # Ensure owner:group for glassfish is glassfish:glassfish sudo chown -R glassfish:glassfish /home/glassfish # Ensure the owner and group can execute/modify/read bin files, and autodeploy sudo chmod -R ug+rwx /home/glassfish/bin/ sudo chmod -R ug+rwx /home/glassfish/glassfish/bin/ sudo chmod -R ug+rwx /home/glassfish/glassfish/domains/domain1/autodeploy/ # Ensure others are not allowed to execute/modify/read bin files, nor autodeploy sudo chmod -R o-rwx /home/glassfish/bin/ sudo chmod -R o-rwx /home/glassfish/glassfish/bin/ sudo chmod -R o-w /home/glassfish/glassfish/domains/domain1/autodeploy/ # Undo: # In case we want to delete Glassfish: sudo rm -rf /home/glassfish
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 --shell /bin/bash glassfish # Start Glassfish export AS_JAVA=/usr/java/jdk1.7.0 /home/glassfish/bin/asadmin start-domain domain1 /home/glassfish/bin/asadmin start-database #check the output, /home/glassfish/glassfish/domains/domain1/logs/server.log 05/06/2011 5:56:22 PM com.sun.enterprise.admin.launcher.GFLauncherLogger info INFO: JVM invocation command line: /usr/java/jdk1.6.0_26/bin/java -cp /home/glassfish/glassfish/modules/glassfish.jar -XX:+UnlockDiagnosticVMOptions -XX:MaxPermSize=192m -XX:NewRatio=2 -Xmx512m -javaagent:/home/glassfish/glassfish/lib/monitor/btrace-agent.jar=unsafe=true,noServer=true -client -Dosgi.shell.telnet.maxconn=1 -Dfelix.fileinstall.disableConfigSave=false -Djdbc.drivers=org.apache.derby.jdbc.ClientDriver -Dfelix.fileinstall.dir=/home/glassfish/glassfish/modules/autostart/ -Djavax.net.ssl.keyStore=/home/glassfish/glassfish/domains/domain1/config/keystore.jks -Dosgi.shell.telnet.port=6666 -Djava.security.policy=/home/glassfish/glassfish/domains/domain1/config/server.policy -Dfelix.fileinstall.log.level=2 -Dfelix.fileinstall.poll=5000 -Dcom.sun.aas.instanceRoot=/home/glassfish/glassfish/domains/domain1 -Dosgi.shell.telnet.ip=127.0.0.1 -Dcom.sun.enterprise.config.config_environment_factory_class=com.sun.enterprise.config.serverbeans.AppserverConfigEnvironmentFactory -Djava.endorsed.dirs=/home/glassfish/glassfish/modules/endorsed:/home/glassfish/glassfish/lib/endorsed -Dcom.sun.aas.installRoot=/home/glassfish/glassfish -Dfelix.fileinstall.bundles.startTransient=true -Djava.ext.dirs=/usr/java/jdk1.6.0_26/lib/ext:/usr/java/jdk1.6.0_26/jre/lib/ext:/home/glassfish/glassfish/domains/domain1/lib/ext -Dfelix.fileinstall.bundles.new.start=true -Djavax.net.ssl.trustStore=/home/glassfish/glassfish/domains/domain1/config/cacerts.jks -Dorg.glassfish.additionalOSGiBundlesToStart=org.apache.felix.shell,org.apache.felix.gogo.runtime,org.apache.felix.gogo.shell,org.apache.felix.gogo.command -Dcom.sun.enterprise.security.httpsOutboundKeyAlias=s1as -Djava.security.auth.login.config=/home/glassfish/glassfish/domains/domain1/config/login.conf -DANTLR_USE_DIRECT_CLASS_LOADING=true -Dgosh.args=--nointeractive -Djava.library.path=/home/glassfish/glassfish/lib:/usr/java/jdk1.6.0_26/jre/lib/i386/server:/usr/java/jdk1.6.0_26/jre/lib/i386:/usr/java/jdk1.6.0_26/lib/i386:/usr/java/packages/lib/i386:/lib:/usr/libcom.sun.enterprise.glassfish.bootstrap.ASMain -domainname domain1 -asadmin-args --host,,,localhost,,,--port,,,4848,,,--secure=false,,,--terse=false,,,--echo=false,,,--interactive=true,,,start-domain,,,--verbose=false,,,--debug=false,,,--domaindir,,,/home/glassfish/glassfish/domains,,,domain1 -instancename server -verbose false -debug false -asadmin-classpath /home/glassfish/glassfish/modules/admin-cli.jar -asadmin-classname com.sun.enterprise.admin.cli.AsadminMain -upgrade false -type DAS -domaindir /home/glassfish/glassfish/domains/domain1 -read-stdin true 05/06/2011 5:56:22 PM com.sun.enterprise.admin.launcher.GFLauncherLogger info INFO: Successfully launched in 6 msec. 05/06/2011 5:56:24 PM null INFO: Running GlassFish Version: GlassFish Server Open Source Edition 3.1 (build 43) [#|2011-06-05T17:56:24.090+0930|INFO|glassfish3.1|org.glassfish.ha.store.spi.BackingStoreFactoryRegistry|_ThreadID=10;_ThreadName=Thread-1;|Registered org.glassfish.ha.store.adapter.cache.ShoalBackingStoreProxy for persistence-type = replicated in BackingStoreFactoryRegistry|#] [#|2011-06-05T17:56:24.354+0930|INFO|glassfish3.1|javax.enterprise.system.core.com.sun.enterprise.v3.services.impl|_ThreadID=28;_ThreadName=Thread-1;|Grizzly Framework 1.9.31 started in: 136ms - bound to [0.0.0.0:8080]|#] [#|2011-06-05T17:56:24.354+0930|INFO|glassfish3.1|javax.enterprise.system.core.com.sun.enterprise.v3.services.impl|_ThreadID=32;_ThreadName=Thread-1;|Grizzly Framework 1.9.31 started in: 107ms - bound to [0.0.0.0:4848]|#] [#|2011-06-05T17:56:24.354+0930|INFO|glassfish3.1|javax.enterprise.system.core.com.sun.enterprise.v3.services.impl|_ThreadID=29;_ThreadName=Thread-1;|Grizzly Framework 1.9.31 started in: 98ms - bound to [0.0.0.0:3700]|#] [#|2011-06-05T17:56:24.354+0930|INFO|glassfish3.1|javax.enterprise.system.core.com.sun.enterprise.v3.services.impl|_ThreadID=31;_ThreadName=Thread-1;|Grizzly Framework 1.9.31 started in: 92ms - bound to [0.0.0.0:7676]|#] [#|2011-06-05T17:56:24.354+0930|INFO|glassfish3.1|javax.enterprise.system.core.com.sun.enterprise.v3.services.impl|_ThreadID=30;_ThreadName=Thread-1;|Grizzly Framework 1.9.31 started in: 113ms - bound to [0.0.0.0:8181]|#] [#|2011-06-05T17:56:24.426+0930|INFO|glassfish3.1|javax.enterprise.system.core.com.sun.enterprise.v3.server|_ThreadID=1;_ThreadName=Thread-1;|GlassFish Server Open Source Edition 3.1 (43) startup time : Felix (1,579ms), startup services(556ms), total(2,135ms)|#] [#|2011-06-05T17:56:24.651+0930|INFO|glassfish3.1|javax.enterprise.system.tools.admin.org.glassfish.server|_ThreadID=40;_ThreadName=Thread-1;|JMXStartupService: Started JMXConnector, JMXService URL = service:jmx:rmi://dogmatix:8686/jndi/rmi://dogmatix:8686/jmxrmi|#] # Stop glassfish /home/glassfish/bin/asadmin stop-domain domain1 /home/glassfish/bin/asadmin stop-database #check the output, /home/glassfish/glassfish/domains/domain1/logs/server.log [#|2011-06-05T18:04:39.659+0930|INFO|glassfish3.1|javax.enterprise.system.tools.admin.com.sun.enterprise.v3.admin|_ThreadID=60;_ThreadName=Thread-1;|Server shutdown initiated|#] [#|2011-06-05T18:04:42.376+0930|INFO|glassfish3.1|javax.enterprise.system.tools.admin.org.glassfish.server|_ThreadID=60;_ThreadName=Thread-1;|JMXStartupService: Stopped JMXConnectorServer: null|#] [#|2011-06-05T18:04:42.376+0930|INFO|glassfish3.1|javax.enterprise.system.tools.admin.org.glassfish.server|_ThreadID=60;_ThreadName=Thread-1;|JMXStartupService and JMXConnectors have been shut down.|#] [#|2011-06-05T18:04:42.376+0930|INFO|glassfish3.1|javax.enterprise.system.core.com.sun.enterprise.v3.server|_ThreadID=60;_ThreadName=Thread-1;|Shutdown procedure finished|#] # Exit from glassfish user exit
Let's create an init script, to help start, stop and restart Glassfish
easily. It may be called manually, or else automatically during rebooting.
The file we need to create is /etc/init.d/glassfish. We will
take this opportunity to start Derby too, and will use the
asadmin tool for both jobs.
# Create init script sudo vi /etc/init.d/glassfish
Then insert the following:
#! /bin/sh
### BEGIN INIT INFO
# Provides: glassfish
# Required-Start: $remote_fs $network $syslog
# Required-Stop: $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starts Glassfish
# Description: Starts Glassfish application server
### END INIT INFO
# We need this, since NetworkServerControl uses $JAVA_HOME to find java
export JAVA_HOME=/usr/java/jdk1.7.0 # Check!
# We need this, since asadmin contains the line 'JAVA=${AS_JAVA}/bin/java'
export AS_JAVA=$JAVA_HOME
GLASSFISH=/home/glassfish
DERBY_BIN=/home/glassfish/javadb/bin
case "$1" in
start)
echo "Starting Glassfish from ${GLASSFISH}"
sudo -u glassfish -E $GLASSFISH/bin/asadmin start-database
sudo -u glassfish -E $GLASSFISH/bin/asadmin start-domain domain1
;;
stop)
echo "Stopping Glassfish from ${GLASSFISH}"
sudo -u glassfish -E $GLASSFISH/bin/asadmin stop-domain domain1
sudo -u glassfish -E $GLASSFISH/bin/asadmin stop-database
;;
restart)
$0 stop
$0 start
;;
status)
echo "# Glassfish at ${GLASSFISH}:"
sudo -u glassfish -E $GLASSFISH/bin/asadmin list-domains | grep -v Command
sudo -u glassfish -E $GLASSFISH/bin/asadmin list-domains | grep -q "domain1 running"
if [ $? -eq 0 ]; then
sudo -u glassfish -E $GLASSFISH/bin/asadmin uptime | grep -v Command
echo "\n# Deployed applications:"
sudo -u glassfish -E $GLASSFISH/bin/asadmin list-applications --long=true --resources | grep -v Command
echo "\n# JDBC resources:"
sudo -u glassfish -E $GLASSFISH/bin/asadmin list-jdbc-resources | grep "jdbc/"
fi
echo "\n# Derby:"
sudo -u glassfish -E $DERBY_BIN/NetworkServerControl ping | sed "s/^.* : //"
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit 0
Make the script executable. You can now start, stop or restart Glassfish manually via the init.d script:
# Make the init script executable by root
sudo chmod ug+x /etc/init.d/glassfish
# Start
sudo /etc/init.d/glassfish start
# Status
sudo /etc/init.d/glassfish status
# Do some tests (here, 'EXAMPLEDB' is some pre-existing database)
firefox http://localhost:8080/
firefox file:///home/glassfish/javadb/index.html
java -jar $GLASSFISH_PARENT/javadb/lib/derbyrun.jar ij # 'quit;' to exit
java -jar $GLASSFISH_PARENT/javadb/lib/derbyrun.jar sysinfo
java -jar $GLASSFISH_PARENT/javadb/lib/derbyrun.jar dblook -d jdbc:derby://localhost:1527/EXAMPLEDB
# Restart
sudo /etc/init.d/glassfish restart
# Stop
sudo /etc/init.d/glassfish stop
When Glassfish is started with this init.d script, the
process will be owned by the user 'glassfish'. This is a major goal of
our installation procedure, as this user has very limited authorization.
(Indeed, user 'glassfish' is not even able to run the init.d script!)
Now ensure that Glassfish (and Derby) are run whenever the server is restarted.
# Configure Glassfish for autostart on Ubuntu boot sudo update-rc.d glassfish defaults
This is a good time to reboot, and to check that
http://localhost:8080/ is showing up in your browser. You
will also see from ps aux that the processes Glassfish and
Derby are both owned by the pseudo-user 'glassfish'. This user is very
limited: it has no login shell (see /etc/passwd), and
even when you become that user via
sudo su --shell /bin/bash glassfish you will find that you
belong to no groups, other than 'glassfish'. This is as it should
be.
However, we are not done yet. The server is currently running with a widely-known default administration password … Hopefully your firewall is blocking attackers! Fixing this vulnerability is the subject of the next section.
If we want to remove this init script:
# Undo:
sudo /etc/init.d/glassfish stop
sudo update-rc.d -f glassfish remove
sudo rm /etc/init.d/glassfish
We shall now begin the configuration of Glassfish itself. For security, you should always run these steps: change the default passwords, enable https, change the default SSL certificate used for https etc. We shall also give attention to Glassfish obfuscation.
The first step is to switch to user 'glassfish' and set environment variables. This is a pre-requisite for all three of the following subsections.
# Switch user to glassfish (and remain as this user throughout Step 6!) sudo su --shell /bin/bash glassfish # Or 'sudo -H -u glassfish -s' # Set up environment for user 'glassfish' export AS_JAVA=/usr/java/jdk1.7.0 [essential for running asadmin] export PATH=$PATH:$AS_JAVA/bin [essential for running keytool] #export PATH=$PATH:/home/glassfish/bin [optional: facilitates running asadmin]
Our first step is to change the master password with
change-master-password. Glassfish uses the master password
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 —
and for this reason Glassfish needs to be provided with the master password,
either in an intertactive way or in a non-interactive way. We shall choose
the non-interactive way: we want our Glassfish to start up on Ubuntu
reboot as a daemon, and prefer not to have to enter a password each time.
To accomplish this we need to set the --savemasterpassword
option to true. This option causes the master password to be
stored in the file master-password in the parent of
the domain's configuration directory, namely in
$GLASSFISH_HOME/domains/domain1/.
$GLASSFISH_HOME/domains/domain1/master-password,
as well as update three files in
$GLASSFISH_HOME/domains/domain1/config/, namely
domain-passwords, keystore.jks and
cacerts.jks.
If I do this carelessly, I often get a hard-to-recover-from error,
"Keystore was tampered with, or password was incorrect",
so I suggest backing-up these files before updating the master password.
It may save you from a re-installation. [Another tip: If you are
in deep trouble, then setting export AS_DEBUG=true
may help.]# Ensure you are running as user 'glassfish' # Stop Glassfish /home/glassfish/bin/asadmin stop-domain domain1 # Change master password /home/glassfish/bin/asadmin change-master-password --savemasterpassword=true domain1 # Enter the current master password> [By default this is 'changeit'] # Enter the new master password> [e.g. 'myMasterPwd'] # Enter the new master password again> # After entering the new master password twice, there is a pause of several # seconds. Then you will find new versions of 'master-password' # 'domain-passwords' 'keystore.jks' and 'cacerts.jks'. [All initially have # 600 permissions, but after change-master-password the # file 'domain-passwords' has 644 permissions: this is surely a bug.] # Test: # Your chosen master password should unlock both keystores, and reveal # two certificates in keystore.jks, and many additional one in cacerts.jks. keytool -list -v -keystore /home/glassfish/glassfish/domains/domain1/config/keystore.jks [-storepass myMasterPwd] keytool -list -v -keystore /home/glassfish/glassfish/domains/domain1/config/cacerts.jks [-storepass myMasterPwd]
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. Also, we probably want to grant password-less logins
to some users; and so we shall also generate an admin password file
(named .asadminpass).
# Ensure you are running as user 'glassfish' # Start Glassfish /home/glassfish/bin/asadmin start-domain domain1 # Change admin password /home/glassfish/bin/asadmin change-admin-password # Enter admin user name [default: admin]> [Just press Enter] # Enter admin password> [By default this is blank, so just press Enter] # Enter new admin password> [Must contain at least 8 chars (e.g. 'myAdminPwd')] # Enter new admin password again> # There will now be a new version of '$GLASSFISH_HOME/domains/domain1/config/admin-keyfile' # Store admin password, to enable automatic login to localhost:4848 /home/glassfish/bin/asadmin [--host localhost --port 4848] login # Enter admin user name [default: admin]> [Just press Enter] # Enter admin password> [e.g. 'myAdminPwd'] # Login information relevant to admin user name [admin] # for host [localhost] and admin port [4848] stored at # [/home/glassfish/.asadminpass] successfully. # Stop Glassfish /home/glassfish/bin/asadmin stop-domain domain1
The file /home/glassfish/.asadminpass is handy: it may be
copied to the home directory of the GF administrator, who will then be able
to run asadmin without entering the password. After copying the
file to the home directory of some GF administrator, ensure it is owned that
user:
chown gf_admin:glassfish ~gf_admin/.asadminpass.
The group ownership for this file is irrelevant, and its permissions should
obviously be limited to rw-------.
Glassfish comes with two pre-configured server certificates that can be
used for SSL (i.e. for the https: protocol). They are contained in
keystore.jks, and have the aliases s1as
and glassfish-instance. However this means that everybody
knows these two certificates: the public keys, private keys, etc., so
anyone can capture and read data sent to Glassfish even via https.
Accordingly, be sure to replace the pre-configured s1as
and glassfish-instance entries in your keystore.
The following code box shows you the commands needed for modifying
our Glassfish keystores. We first update and extend
keystore.jks. We then generate new certificates for
s1as and glassfish-instance and import
them into cacerts.jks — the 'truststore' used by SSL.
The latter keystore contains a large number of trusted certificates, as
well as our two newly-minted certificates.
See elsewhere for how to obtain certificates from trusted sources, and
add them to cacerts.jks.
# Ensure you are running as user 'glassfish' # Inspect keystore.jks cd /home/glassfish/glassfish/domains/domain1/config/ $AS_JAVA/bin/keytool -list -keystore keystore.jks -storepass myMasterPwd # Update keystore.jks $AS_JAVA/bin/keytool -delete -alias s1as -keystore keystore.jks -storepass myMasterPwd $AS_JAVA/bin/keytool -delete -alias glassfish-instance -keystore keystore.jks -storepass myMasterPwd $AS_JAVA/bin/keytool -genkeypair -alias s1as -dname "CN=someOne,OU=someUnit,O=someOrg,L=someCity,S=someState,C=XX" -keyalg RSA -keysize 2048 -validity 3650 -keystore keystore.jks -keypass myMasterPwd -storepass myMasterPwd $AS_JAVA/bin/keytool -genkeypair -alias glassfish-instance -dname "CN=someOne,OU=someUnit,O=someOrg,L=someCity,S=someState,C=XX" -keyalg RSA -keysize 2048 -validity 3650 -keystore keystore.jks -keypass myMasterPwd -storepass myMasterPwd # Check $AS_JAVA/bin/keytool -list -keystore keystore.jks -storepass myMasterPwd # Export certificates from keystore.jks $AS_JAVA/bin/keytool -export -alias s1as -file s1as.cert -keystore keystore.jks -storepass myMasterPwd $AS_JAVA/bin/keytool -export -alias glassfish-instance -file glassfish-instance.cert -keystore keystore.jks -storepass myMasterPwd # Update cacerts.jks $AS_JAVA/bin/keytool -delete -alias s1as -keystore cacerts.jks -storepass myMasterPwd $AS_JAVA/bin/keytool -delete -alias glassfish-instance -keystore cacerts.jks -storepass myMasterPwd $AS_JAVA/bin/keytool -import -alias s1as -file s1as.cert -keystore cacerts.jks -storepass myMasterPwd $AS_JAVA/bin/keytool -import -alias glassfish-instance -file glassfish-instance.cert -keystore cacerts.jks -storepass myMasterPwd # Check and tidy up $AS_JAVA/bin/keytool -list -keystore cacerts.jks -storepass myMasterPwd rm s1as.cert glassfish-instance.cert
What do these two similar-sounding keystores do? They are indeed similar, but are used in a complementary way:
keystore.jks) is used to provide
credentials. Hence it contains your server's own certificates.cacerts.jks) is used to verify
credentials. Hence it contains certificates from many Certificate
Authorities, and from sources that you trust implicitly.Now we want to enable https for the admin console. Once we have done that we can be sure that nobody can decrypt data sent via https, since nobody else has our certificate. But this is not all we want to do here: we also want to change some of the default JVM Options, and we want to make our Glassfish not reveal too much about itself ('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: -Xmx2048m. Furthermore I have added -Xms1024m. For more information about these options please check the documentation for the java launcher options.
All JVM configuration changes so far are optional. But adding -Dproduct.name= is a good idea for everyone. If you don't, then each http/https response will contain a revealing header like: Server: GlassFish Server Open Source Edition 3.1
Similarly, we also don't want Glassfish to send a header similar to X-Powered-By: Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 3.1 Java/Apple Inc./1.6). We can disable sending 'x-powered-by' in the http/https headers with the last three asadmin commands in the code box below. Now our Glassfish is working in silent mode. Glassfish obfuscation accomplished.
# Ensure you are running as user 'glassfish' # 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 set server-config.network-config.protocols.protocol.admin-listener.security-enabled=true /home/glassfish/bin/asadmin enable-secure-admin # Change JVM Options # List current JVM options /home/glassfish/bin/asadmin list-jvm-options # Now update some important JVM settings. (Adding '--' is a workaround for # bugs #16037 and #16770, which cause certain options to be misinterpreted. # The bug is largely fixed in GlassFish 3.1.1.) /home/glassfish/bin/asadmin delete-jvm-options -- -client /home/glassfish/bin/asadmin create-jvm-options -- -server /home/glassfish/bin/asadmin delete-jvm-options -- -Xmx512m /home/glassfish/bin/asadmin create-jvm-options -- -Xmx2048m /home/glassfish/bin/asadmin create-jvm-options -- -Xms1024m # Get rid of http header field value 'server' (Glassfish obfuscation) /home/glassfish/bin/asadmin create-jvm-options -Dproduct.name= # Restart to take effect. /home/glassfish/bin/asadmin stop-domain domain1 /home/glassfish/bin/asadmin start-domain domain1 # What JVM options are configured now? (Confirm trust.) /home/glassfish/bin/asadmin list-jvm-options # 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 # We are done with user 'glassfish'. exit
The Release Notes for Glassfish 3.1 say that debugging JPA is aided
by adding the line
org.eclipse.persistence.session.level=INFO
to /home/glassfish/glassfish/domains/domain1/config/logging.properties.
This line is included by default in 3.1.1.
If we want to remove these security measures, start Glassfish, become user
'glassfish' (although this is unnecessary if you have the
.asadminpass file), and enter:
# Undo:
# Disable https for remote access to admin console
/home/glassfish/bin/asadmin set server-config.network-config.protocols.protocol.admin-listener.security-enabled=false
/home/glassfish/bin/asadmin disable-secure-admin
# Restore default JVM Options
/home/glassfish/bin/asadmin delete-jvm-options -- -server
/home/glassfish/bin/asadmin create-jvm-options -- -client
/home/glassfish/bin/asadmin delete-jvm-options -- -Xmx2048m
/home/glassfish/bin/asadmin create-jvm-options -- -Xmx512m
/home/glassfish/bin/asadmin delete-jvm-options -- -Xms1024m
/home/glassfish/bin/asadmin delete-jvm-options -Dproduct.name="Glassfish"
# Restore 'x-powered-by' in http header
/home/glassfish/bin/asadmin get server.network-config.protocols.protocol.*.xpowered-by
/home/glassfish/bin/asadmin set server.network-config.protocols.protocol.http-listener-1.http.xpowered-by=true
/home/glassfish/bin/asadmin set server.network-config.protocols.protocol.http-listener-2.http.xpowered-by=true
/home/glassfish/bin/asadmin set server.network-config.protocols.protocol.admin-listener.http.xpowered-by=true
Finally: we have installed, secured and configured our Glassfish installation. Now it has to be managed …
# Manual control of Glassfish and Derby # Any sudoer can do this, and the services will be owned by user 'glassfish' sudo /etc/init.d/glassfish [start | stop | restart | status] # Monitor logs. Any user can view the logs. less +F /home/glassfish/glassfish/domains/domain1/logs/server.log less +F /home/glassfish/glassfish/databases/derby.log # Explore asadmin, doing so here as user 'glassfish' sudo su --shell /bin/bash glassfish export AS_JAVA=/usr/java/jdk1.7.0 /home/glassfish/bin/asadmin list-commands exit # Test of the administrator's group membership, $PATH and copy of .asadminpass asadmin list-commands asadmin list-applications # Updates (preliminary notes only). # If Glassfish was installed from a zip, then updatetool and pkg exist only # as stubs initially -- however the missing bits will be downloaded and # installed when the stubs are first run. If Glassfish was installed # from a self-extracting executable, then updatetool and pkg will already # be fully installed. # See also the Glassfish Runtime Administration Guide at # http://www.oracle.com/technetwork/middleware/glassfish/documentation/index.html # Notes regarding 'pkg' # The man page is accessible via: man -M $GLASSFISH_PARENT/pkg/man/ pkg # With Glassfish 3.1 I was unable to run pkg when behind a proxy. # This problem went away with Glassfish 3.1.1 # Note regarding 'updatetool' # It is hard to manage permissions when we need to be the user 'glassfish' # to create files; yet we must be a regular user to be able to access the # X11 server. A solution is to grant 'glassfish' access to X11 before # running updatetool. This is done with the 'xhost' command. See below # for an example. # Before updating, we must halt GlassFish and Derby sudo /etc/init.d/glassfish stop # 20110808, running 'pkg', the text-based updater sudo su --shell /bin/bash glassfish export AS_JAVA=/usr/java/jdk1.7.0 export PATH=$PATH:$AS_JAVA/bin /home/glassfish/bin/pkg -R /home/glassfish [list | info | history] /home/glassfish/bin/pkg -R /home/glassfish image-update -v exit # 20110808, running 'updatetool', the GUI-based updater xhost +SI:localuser:glassfish # Run this first, as yourself, not as user 'glassfish' sudo su --shell /bin/bash glassfish export AS_JAVA=/usr/java/jdk1.7.0 export PATH=$PATH:$AS_JAVA/bin /home/glassfish/bin/updatetool exit xhost -SI:localuser:glassfish # Run this last, as yourself, not as user 'glassfish' # Restart Glassfish and Derby sudo /etc/init.d/glassfish start
Backing-up can be done crudely by saving everything under
/home/glassfish/ (including raw database files) — or
it could be done more selectively. In the latter case, the crucial
backups are:
$GLASSFISH_HOME/domains/domain1/master-password$GLASSFISH_HOME/domains/domain1/autodeploy/*.war$GLASSFISH_HOME/domains/domain1/config/keystore.jks$GLASSFISH_HOME/domains/domain1/config/cacerts.jks$GLASSFISH_HOME/domains/domain1/config/*.policy$GLASSFISH_HOME/domains/domain1/config/domain.xml$GLASSFISH_HOME/databasesasadmin backup-domain domain1 is the smarter
alternative
Brief instructions for fronting Glassfish with an Apache server are available at http://weblogs.java.net/blog/amyroh/archive/2012/02/15/running-glassfish-312-apache-http-server
Your installation contains more information, such as
$GLASSFISH_HOME/docs/quickstart.html, and there is more at
http://download.oracle.com/javaee/.
Users of Eclipse might like to check this introductory tutorial: http://glassfishplugins.java.net/eclipse36/, which describes how to deploy and debug a servlet from within version 3.6 (aka 'helios') of Eclipse.
| Validate HTML CSS |