Glassfish Installation
Introduction
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 upcoming Glassfish 4.0 is not considered. 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.
Table of contents:
- Setting up users
- Setting up environment variables
- Downloading and installing Glassfish
- Setting up an init script
- Autostart: adding init script
- Security configuration
- Maintaining Glassfish
- Programming for Glassfish
- Appendix: Private Glassfish installation
1. Setting up users
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.
2. Setting up environment variables
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, Glassfish 3.1.2 requires JDK 1.6.0_31+
or 1.7.0_03+.)
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.
Ant is Glassfish's other dependency. There is said to be a version of Ant built-in to Glassfish, but I expect everyone will want to install the latest version themselves.
Once these two dependencies are satisfied we must ensure that Glassfish
administrators and developers can access Java SE+EE and Ant. This will
enable them to complete the installation of Glassfish, and subsequently
to perform compilations and administration tasks. Here is an example of
the required additions to their .bashrc — 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_15 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.4 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.]
3. Downloading and installing Glassfish
Choosing amongst the many available versions of Glassfish is very confusing, as the differences are not explained properly. Also, the naming and numbering of Java products is annoyingly volatile. However the alternatives are, roughly, as follows:
- Six versions of 'Java EE 6' are offered at http://www.oracle.com/technetwork/middleware/glassfish/downloads/index.html. The six versions are 'Oracle Glassfish Server', 'Java EE 6 plus Java JDK', and 'Java EE 6 without Java JDK'; and each can supply Java EE in either the full form or in the simpler 'Web Profile' form. Subversions cater for different platforms (Linux, Mac OSX, Solaris SPARC, Solaris x86, Windows), and for English or Multilingual versions. Sub-subversions offer the choice between an executable 'self-extracting bundle' and a zip file. Oracle hosts the industry face of the app server.
- Twelve versions of 'GlassFish Server' are offered at http://dlc.sun.com.edgesuite.net/glassfish/3.1.1/release/*, and at http://glassfish.java.net/downloads/3.1.1-final.html. These present a more sparse set of choices, but they are easier to navigate, and this is where pros go for the most up-to-date version. There are generic zip, Unix .sh and Windows .exe versions; English or Multilingual; full or Web Profile. In addition to these twelve, there are two files named 'javaee-*' (but these are probably identical the generic glassfish zips) and one bundle of documentation. Glassfish.java.net is the community face of the app server.
- The embeddable version was initially distinct from Java EE/Glassfish.
That was case for
version 3.1, and up to version 3.2_b06. By the time you read this
it may be time to use version 4.
Version 3.1 (and all others) can be found at Maven repositories like
The Central Respository as
org.glassfish.extras:glassfish-embedded-all:3.1, ororg.glassfish.extras:glassfish-embedded-web:3.1. The newer – absorbed – version is intended for use with Glassfish 4.0, and has coordinatesorg.glassfish.main.extras:glassfish-embedded-all:4.0and similar.
What are the distinctions?
- The distinction between 'Oracle Glassfish Server' and 'Java EE 6 SDK'
lies just in various augmentations to the 'Glassfish Open Source Edition'.
- The 'Oracle' version bundles MySQL and Oracle JDBC drivers along with certain backup and monitoring features, whereas 'Java EE' bundles sample code, API documentation, and the Java EE tutorial.
- There is a legal difference between the two versions: the Oracle version requires a licence when used in a production environment, whereas the 'Java EE' is free.
- The style of support differs.
- There are branding differences.
- The distinction between the full version and the Web Profile is that the latter lacks some more obscure features. There is a handy comparison at http://glassfish.java.net/downloads/3.1.1-final.html.
- The distinction between the self-extracting executables and zip bundle is that the executable assists in installing the update tool, and offers a friendly GUI — while the downside is that it is platform-specific, and installing the update utilities may introduce some extra fuss when proxy servers get in the way. The zip version has the advantage of simplicity (there is only an 'unzip' command required), and is certainly preferable for installation on a headless server — and installing the update utilites can easily be done later.
- The embeddable version is used for unit testing of EJB modules. It is also useful if you need to add EJB functionality to a stand-alone application.
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 set of instructions.
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 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. # [You may or may not need to set the environment variable http_proxy first.] wget http://dlc.sun.com.edgesuite.net/glassfish/3.1.2/release/glassfish-3.1.2.zip unzip glassfish-3.1.2.zip # This creates /home/glassfish/downloads/glassfish3/* Move the relevant content up two levels to home directory mv glassfish3/* /home/glassfish/ # One strangely named directory 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 already start your 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_15 /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
4. Setting up an init script
Let's create an init script, to help start, stop and restart Glassfish
easily. (I know that init is a bit old-fashioned, but upstart is still
unfamiliar to me.) This script may be called manually, or else automatically
during reboots and shutdowns.
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_15 # 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!)
5. Autostart: adding init 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
6. Security configuration
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_15 [essential for running asadmin] export PATH=$PATH:$AS_JAVA/bin [essential for running keytool] #export PATH=$PATH:/home/glassfish/bin [optional: facilitates running asadmin]
Passwords
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 Backup default passwords. # In addition to the three shown: # - add domains/domain1/master-password, if this exists # - add domains/domain1/local-password, just for completeness cd /home/glassfish/glassfish tar cf passwords.orig.tar domains/domain1/config/domain-passwords domains/domain1/config/keystore.jks domains/domain1/config/cacerts.jks 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 664 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 ones 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-------.
Certificates
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 keystore.jks $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:
- The 'keystore' (
keystore.jks) is used to provide credentials. Hence it contains your server's own certificates. - The 'truststore' (
cacerts.jks) is used to verify credentials. Hence it contains certificates from many Certificate Authorities, and from sources that you trust implicitly.
JVM Options and Obfuscations
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 List current JVM options /home/glassfish/bin/asadmin list-jvm-options Change JVM Options # Glassfish 3.1.1 and earlier.... # 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 # Glassfish 3.1.2 and later.... # Now update some important JVM settings. (Inclusion of '--secure=false' # is due to lingering issues when interpreting the string '-server'.) /home/glassfish/bin/asadmin delete-jvm-options -client /home/glassfish/bin/asadmin --secure=false 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, when prompted.) /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 # Show something other than default error pages (which tend to # be rather too revealing....). In the case of wrong URLs: # 1 It is possible to create 404 error pages that are application-specific # by editing that application's web.xml file, and adding a # element like # <error-page> # <error-code>404</error-code> # <location>/404.html</location> # </error-page> # # 2a It is possible to create 404 error pages that are global to the server # by editing the server's domain.xml file, and adding a property having # name="send-error_1" # value="code=404 path=/tmp/404.html reason=Resource_not_found" # 2b Or by executing a command like # asadmin set server.http-service.virtual-server.server.property.send-error_1="code=404 path=/tmp/404.html reason=Resource_not_found" # 2c Or by using the admin console to add a new property 'send-error_1' # with a value "code=404 path=/tmp/404.html reason=Resource_not_found" We are done with user 'glassfish'. exit
Here is a telnet session that shows that the line "Server: GlassFish Server 3.1.1" has been successfully eliminated from the HTTP response header
$ telnet localhost 8080 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. HEAD /index.html HTTP/1.1 Host: localhost Connection: close HTTP/1.1 200 OK Content-Type: text/html Content-Length: 4759 Date: Fri, 01 Jun 2012 13:44:05 GMT Connection: close Connection closed by foreign host. $
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=
# 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
7. Maintaining Glassfish
Finally: we have installed, secured and configured our Glassfish installation. Now it has to be managed …
Starting and stopping 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_15 /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 asadmin list-jvm-options To see all system properties: sudo jinfo PID_of_GF 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_15 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_15 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- Dump of any databases in
$GLASSFISH_HOME/databases - And probably more …
- Probably
asadmin backup-domain domain1is 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/.
8. Programming for Glassfish
There are several options for progamming environments: Eclipse, NetBeans, and Emacs (of course). 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.
Fancy environments have their appeal, however programming web apps is not so very different from desktop apps. Indeed there are only two configuration-related things that a programmer needs to know in order to build and deploy Java EE web apps:
/home/glassfish/glassfish/modules/This is where all the Java EE jar files are located./home/glassfish/glassfish/domains/domain1/autodeploy/This is the place to drop your.warfile.
Appendix: Private Glassfish installation
Here is a sketch of what to do for a private installation. This may be preferable for program developers, as it simplifies some testing mechanisms. You don't want authenication problems when Maven is managing integration tests.
The general plan is to unpack the Glassfish distro in your personal
directory space, and to start and stop the server manually. In this
example we choose to place Glassfish in $HOME/glassfish,
and to advertise this by setting environment variables appropriately.
Glassfish
export GLASSFISH_PARENT=$HOME/glassfish3
export GLASSFISH_HOME=$HOME/glassfish3/glassfish
echo $PATH | /bin/grep -q -v $GLASSFISH_HOME/bin
if [ $? -eq 0 ]; then export PATH="${PATH}:$GLASSFISH_HOME/bin"; fi
To download and install Glassfish, follow the instructions above in 3. Downloading and installing Glassfish. The difference is the base directory, and everything to do with user names.
cd ~/Downloads wget http://dlc.sun.com.edgesuite.net/glassfish/3.1.2.2/release/glassfish-3.1.2.2.zip unzip glassfish-3.1.2.2.zip mv glassfish3 ~
Now you can start and stop the server by
asadmin start-domain domain1 asadmin stop-domain domain1