Setup Server

Sep 16th, 2021

This user manual is to help you maintain, update and use the relevant application easily and quickly. You’ll find detailed screenshots, explanations and instructions on how to manage it.

Prerequisites

Depending on your runtime infrastructure, you may have to change the technologies below. We are going to follow them.

Connecting to the server

Digital Ocean

Create a droplet from Digital Ocean first.

Get the IP address of the droplet and create A record (subdomain.domain.com) from domain name registrar.

To connect the droplet, remove domain from ssh known hosts if you already have

$ nano ~/.ssh/known_hosts

Then connect to the server

$ ssh root@subdomain.domain.com

AWS

Create a Lightsail Instance from Amazon Lightsail first.

Download your default private key from the Account page.

Change permission to 400 due to security.

chmod 400 LightsailDefaultKey-eu-central-1.pem

Then connect to the server using private key

$ ssh -i LightsailDefaultKey-eu-central-1.pem admin@subdomain.domain.com

Installation

Debian operating system is pre-installed. To update and upgrade it

# update the list of available packages and their versions, it does not install or upgrade any packages.
$ apt-get update
# install newer versions of the installed packages
$ apt-get upgrade
# or combine both
$ apt-get update && apt-get upgrade

To Set server time, Check out World Clock / Converter

Current default time zone is ‘Etc/UTC’. Run dpkg-reconfigure tzdata if you wish to change it.

To change time zone, run

$ dpkg-reconfigure tzdata

To change locale

$ nano /etc/locale.gen

Uncomment tr_TR.UTF-8 UTF-8 line, and run below to activate locale

$ locale-gen

To install Java

# install jdk
$ apt-get install default-jdk
# check version
$ java -version

To download and install Glassfish application server

# Download Glassfish on Maven Central
$ wget https://repo1.maven.org/maven2/org/glassfish/main/distributions/glassfish/5.1.0/glassfish-5.1.0.zip
# Install unzip and then unzip Glassfish
$ apt-get install unzip
$ unzip glassfish-5.1.0.zip -d /opt

For MySQL JDBC connection you need to install MySQL Connector/J. In order to download and install MySQL Connector/J to Glassfish external libraries directory.

# Download MySQL Connector/J and copy it to Glassfish external libraries directory
$ wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.21/mysql-connector-java-8.0.21.jar -P /opt/glassfish5/glassfish/domains/domain1/lib/
# or
$ curl -o ${GLASSFISH_HOME}/domains/domain1/lib/mysql-connector-java-8.0.21.jar -L https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.21/mysql-connector-java-8.0.21.jar

For PostgreSQL JDBC connection you need to install PostgreSQL JDBC Driver. In order to download and install PostgreSQL JDBC Driver to Glassfish external libraries directory.

# Download PostgreSQL JDBC Driver and copy it to Glassfish external libraries directory
$ wget https://jdbc.postgresql.org/download/postgresql-42.2.14.jar -P /opt/glassfish5/glassfish/domains/domain1/lib/
# or
$ curl -o ${GLASSFISH_HOME}/domains/domain1/lib/postgresql-42.2.14.jar -L https://jdbc.postgresql.org/download/postgresql-42.2.14.jar

Edit domain.xml to change ports from 8080 to 80 for HTTPS and 8181 to 443 for HTTPS and application context root

$ nano /opt/glassfish5/glassfish/domains/domain1/config/domain.xml

Find http-listener-1 and http-listener-2

<network-listener protocol="http-listener-1" port="8080"
<network-listener protocol="http-listener-2" port="8181"

Find context-root and change the value to “/”

<application context-root="/"

You can now start Glassfish

$ asadmin start-domain domain1

Creating SSL certificates

To enable the Stretch backports repo, create sources.list file if you have not already.

$ nano /etc/apt/sources.list.d/sources.list

Add this line to your sources.list

deb http://ftp.debian.org/debian stretch-backports main

exit from the file and run update.

$ apt-get update

You are now ready to download and install certbot. To install Certbot

$ sudo apt-get install certbot -t stretch-backports

Options to know

$ sudo certbot certonly --webroot --webroot-path=/var/www/html --email sammy@example.com --agree-tos --no-eff-email --staging -d example.com  -d www.example.com
  • --webroot: This tells Certbot to use the webroot plugin to place files in the webroot folder for authentication.
  • --webroot-path: This specifies the path of the webroot directory.
  • --email: Your preferred email for registration and recovery.
  • --agree-tos: This specifies that you agree to ACME’s Subscriber Agreement.
  • --no-eff-email: This tells Certbot that you do not wish to share your email with the Electronic Frontier Foundation (EFF). Feel free to omit this if you would prefer.
  • --staging: This tells Certbot that you would like to use Let’s Encrypt’s staging environment to obtain test certificates. Using this option allows you to test your configuration options and avoid possible domain request limits. For more information about these limits, please see Let’s Encrypt’s rate limits documentation.
  • --force-renewal: Replace the --staging flag in the command option with the --force-renewal flag, which will tell Certbot that you want to request a new certificate with the same domains as an existing certificate.
  • -d: This allows you to specify domain names you would like to apply to your request. In this case, we’ve included example.com and www.example.com. Be sure to replace these with your own domain preferences.

Using certbot webroot

If you already have a webserver running, we recommend choosing the “webroot” plugin. To obtain a cert using the “webroot” plugin, which can work with the webroot directory of any webserver software:

$ sudo certbot certonly --webroot -w /opt/glassfish5/glassfish/domains/domain1/docroot -d subdomain.domain.com

Using certbot manual

$ sudo certbot certonly --manual --preferred-challenges dns -d domain.tld -d subdomain.domain.tld
#change permission to access files
$ sudo chmod -R 755 /etc/letsencrypt/*
#use pbcopy to copy data from STDIN to the clipboard
$ pbcopy < /etc/letsencrypt/live/domain.tld/fullchain.pem
$ pbcopy < /etc/letsencrypt/live/domain.tld/privkey.pem

Using certbot standalone

$ sudo certbot certonly --standalone -d example.com -d www.example.com

Using certbot step by step

$ sudo certbot certonly

How would you like to authenticate with the ACME CA?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Spin up a temporary webserver (standalone)
2: Place files in webroot directory (webroot)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Plugins selected: Authenticator webroot, Installer None
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel): subdomain.domain.com
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for subdomain.domain.com
Input the webroot for subdomain.domain.com: (Enter 'c' to cancel): /opt/glassfish5/glassfish/domains/domain1/docroot
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/subdomain.domain.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/subdomain.domain.com/privkey.pem
   Your cert will expire on 2019-03-12. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"

Backup certificates

$ tar -zcvf letsencrypt_subdomain_domain_com.tgz /etc/letsencrypt/

And copy file from the remote host to local host using scp

$ scp root@subdomain.domain.com:/root/letsencrypt_api_aripd_com.tgz ~/Desktop/

The certificate you have contains two certificates, each certificate starts with -----BEGIN CERTIFICATE----- and finish with -----END CERTIFICATE-----. The first one is the certificate for your domain and the second one is the Let’s Encrypt Intermediate certificate.

  • cert.pem is certificate for your domain, public key
  • chain.pem is intermediate certificate
  • fullchain.pem is the chain of trust, certificate chain. CA Bundle (Your Certificate + Intermediate Certificate) is to complete the chain of trust.
  • privkey.pem is the private key

All files are PEM-encoded. If you need other format, such as DER or PFX, then you could convert using openssl. You can automate that with --deploy-hook if you’re using automatic renewal.

Automating renewal SSL certificates

Since Let’s Encrypt certificates last for 90 days, it’s highly advisable to take advantage of this feature. You can test automatic renewal for your certificates by running this command:

$ sudo certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/subdomain.domain.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator webroot, Installer None
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for subdomain.domain.com
Waiting for verification...
Cleaning up challenges

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/subdomain.domain.com/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/subdomain.domain.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.

Creating keystore using certificates

Glassfish has a file called keystore.jks, where you need to add the certificate and key which were previously created. The file should be located at <GLASSFISH_HOME>/domains/domain1/config/keystore.jks and the default password for it is changeit.

Adding the two files (fullchain.pem and privkey.pem) to the keystore.jks is a 2-step process:

Change directory to glassfish config directory

cd <GLASSFISH_HOME>/domains/domain1/config/

Create a keystore from the two files

Create a .pkcs12 file containing full chain and private key

openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out pkcs.p12 -name letsencryptcrt

You will set a password for this file, which you will need to specify at the next step STORE_PASS.

You may also see what is inside the new bundle, using keytool:

$ keytool -list -keystore pkcs.p12

Convert the PKCS12 bundle (pkcs.p12) to the keystore (letsencrypt.jks)

$ keytool -importkeystore -deststorepass PASSWORD_STORE -destkeypass PASSWORD_KEYPASS -destkeystore letsencrypt.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -srcstorepass STORE_PASS -alias letsencryptcrt

I would recommend setting all these passwords (PASSWORD_STORE, PASSWORD_KEYPASS and STORE_PASS) the same as the original keystore.jks password since, at the next point, the passwords of the source and destination keystores’ have to be the same.

Importing the created keystore into Glassfish’s keystore

$ keytool -importkeystore -srckeystore letsencrypt.jks -destkeystore keystore.jks

Of course, make sure the paths to all the referenced files are correct, taking into account the current directory, when you are running all these commands.

To verify the contents of the JKS, you can use this command:

$ keytool -list -v -keystore keystore.jks

Configuring the Glassfish HTTPS listener

Set the port to 443 (HTTPS port)

In the SSL tab, enable SSL3 and TLS, set the Certificate NickName to letsencryptcrt and the Key Store to keystore.jks. This will change domain.xml as below.

<ssl classname="com.sun.enterprise.security.ssl.GlassfishSSLImpl" cert-nickname="letsencryptcrt"></ssl>

or

<ssl ssl3-enabled="true" classname="com.sun.enterprise.security.ssl.GlassfishSSLImpl" cert-nickname="letsencryptcrt" key-store="keystore.jks"></ssl>

If configuration is correct, run below command in order to check ssl

$ openssl s_client -connect host:port

Changing the keystore password

$ cd /opt/glassfish5/glassfish/domains/domain1/config
keytool -storepasswd -keystore keystore.jks
Enter keystore password:  changeit
New keystore password:  new-password
Re-enter new keystore password:  new-password

Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.jks -deststoretype pkcs12".
$ keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.jks -deststoretype pkcs12
Enter source keystore password: P@ssword1
Enter key password for <glassfish-instance> changeit
New key password for <glassfish-instance>: P@ssword1
Re-enter new key password for <glassfish-instance>: P@ssword1

Installing MySQL

# Install MySQL
$ apt-get install mysql-server
# Improve MySQL installation security
$ mysql_secure_installation
# check version
$ mysql --version

To create a database with the new privilege, run

$ mysql -uroot -p

then enter below lines respectively

CREATE DATABASE dbname CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER dbname@localhost IDENTIFIED BY 'P@ssword1';
GRANT ALL PRIVILEGES ON dbname.* TO dbname@localhost;
FLUSH PRIVILEGES;

To import a mysql database

$ mysql -u root -p newdatabase < /path/to/newdatabase.sql

To backup a mysql database

$ mysqldump -u root -p --opt [database name] > [database name].sql

Setup

Define resources to Glassfish using asadmin tool

  • Create a JDBC resource with the specified JNDI name

    $ asadmin> help create-jdbc-resource for help

      $ asadmin> create-jdbc-resource --connectionpoolid aripd_pool --enabled=true jdbc/aripd
      Command create-jdbc-resource executed successfully.
    
  • Register a JDBC connection pool

    $ asadmin> help create-jdbc-connection-pool for help

      $ asadmin> create-jdbc-connection-pool
      --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlXADataSource --restype javax.sql.XADataSource
      --property portNumber=3306:password=P@ssword1:user=aripd:serverName=localhost:databaseName=aripd:connectionAttributes=\;create\\=true aripd_pool
      Command create-jdbc-connection-pool executed successfully.
    

Add the named authentication realm to Glassfish using asadmin tool

$ asadmin> help create-auth-realm for help

$ asadmin> create-auth-realm --classname com.sun.enterprise.security.auth.realm.jdbc.JDBCRealm --property jaas-context="jdbcRealm":datasource-jndi="jdbc/aripd":user-table="USERENTITY":user-name-column="EMAIL":password-column="PASSWORD":group-table="USERENTITY":group-name-column="USERGROUP":digest-algorithm="none":digestrealm-password-enc-algorithm="none" "jdbcaripd"