Showing posts with label Ubuntu. Show all posts
Showing posts with label Ubuntu. Show all posts

Sunday, June 26, 2016

Creating Start-up Script in Ubuntu

I installed Redmine in an Ubuntu Server at Windows Azure and was successful in doing so. However, Azure did some maintenance in my server and has to restart it. So, when I accessed Redmine again, Nginx redirected me to its Error 502 page. Upon checking, I realized that  there was really a restart that happened and I thought I have to create a start-up script to avoid this since it was not only me who is using the Redmine which I installed but also my clients' testers and BA's.

Here's how my script look like.

#!/bin/sh

REDMINE_START=/home/tsiminiya/redmine-3.3.0/run.sh
REDMINE_STOP=/home/tsiminiya/redmine-3.3.0/stop.sh
REDMINE_USER=tsiminiya
REDMINE_COMMAND=

executeCommand() {
    start-stop-daemon -S -u $REDMINE_USER -c $REDMINE_USER -o -x $REDMINE_COMMAND
}

case $1 in
    start)
        REDMINE_COMMAND=$REDMINE_START
        executeCommand
        ;;
    stop)
        REDMINE_COMMAND=$REDMINE_STOP
        executeCommand
        ;;
    *)
        echo "Usage: $(basename $0) (start | stop)"
        ;;
esac


You may modify the variables above to point to your start and stop scripts. I didn't put here the contents of my run.sh and stop.sh. What is important here is the start-stop-daemon line. And, also after constructing your start-up script:

1. Save the file at /etc/init.d/<filename-of-your-choice>.
2. sudo chmod +x /etc/init.d/<filename-of-your-choice>
3. sudo update-rc.d <filename-of-your-choice> defaults

Note: at #3, we don't specify the full path but just the script name.

Restart the server after Step 3 to test whether your start-up script is working.






Thursday, April 23, 2015

Applying SSL Certificate to Nginx

I. Requirements


This procedure is applicable only to Nginx on Ubuntu (or other Linux servers). For my own purpose, I had the following:
  • Ubuntu Server with Nginx installed
  • SSH Client to access the server
Also, to be able to apply SSL Certificate to your server you should already have purchased a domain and has an access to your domain records via your domain provider's control panel.

II. Procedure

1. Generate Server's Private Key and Certificate Signing Request (CSR)

To generate a private key and CSR, you need to be on your server's SSH terminal and logged-in as a sudoer user to be able to execute the following command:


sudo openssl req -new -newkey rsa:2048 -nodes -keyout sudocode.key -out sudocode.crt


The above command would create sudocode.key and sudocode.crt.

The command will ask you to provide the following information. Please change the values with your own.

Country Name (2 letter code) [AU]:PH
State or Province Name (full name) [Some-State]:Rizal
Locality Name (eg, city) []:Antipolo
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Happy Birthday Company
Organizational Unit Name (eg, section) []:R&D
Common Name (e.g. server FQDN or YOUR name) []:sudocodesystems.com
Email Address []:rmaranan@sudocodesystems.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

You may skip inputting values on the challenge password field and optional company name field by pressing enter key.

Copy sudocode.crt and sudocode.key to /etc/nginx/ssl.

Warning: Make sure you secure a copy of your private key and CSR somewhere safe. Losing one of two means you have to create them again. I don't know how much that will cost to re-upload a CSR to the CA Provider. But, probably it will be very inconvenient for you to talk to your CA Provider for re-issuance of CA cert.

2. Upload CSR to CA Provider

My CA Provider is Comodo. They are providing free trial SSL Certificate for 90-days - not bad for a first timer in SSL Certification. Most CA Providers offer only 30 to 60 days of free trial.

The CSR is the one we generate at Step 1 - /etc/nginx/ssl/sudocode.crt.
We need to upload its content to our provider.

On the terminal, we may display the contents of the CSR by using cat command.


cat /etc/nginx/ssl/sudocode.crt


The contents of the CSR should look like the following:


-----BEGIN CERTIFICATE REQUEST-----
MIIDUDCCArkCAQAwdTEWMBQGA1UEAxMNdGVzdC50ZXN0LmNvbTESMBAGA1UECxMJ
TWFya2V0aW5nMREwDwYDVQQKEwhUZXN0IE9yZzESMBAGA1UEBxMJVGVzdCBDaXR5
(more encoded data).......
Rq+blLr5X5iQdzyF1pLqP1Mck5Ve1eCz0R9/OekGSRno7ow4TVyxAF6J6ozDaw7e
GisfZw40VLT0/6IGvK2jX0i+t58RFQ8WYTOcTRlPnkG8B/uV
-----END CERTIFICATE REQUEST-----

We paste the CSR file contents to the Free SSL Certificate request form at Comodo.




3. Domain Validation


Domain Validation in Comdo can be done in several ways.


The easiest and most convenient for me is through CSR Hash which will be configured at the domain provider's control panel. My domain provider is EApps.

We add a CNAME DNS entry.

Comodo gives two hash values: one is created through MD5 and the other through SHA-1. The CNAME DNS entry should look like as shown below:

<Value of MD5 hash of CSR>.yourdomain.com. CNAME <value of SHA1 hash of CSR>.comodoca.com



4. Set-up SSL Certificate at Nginx

4.1. Create Certificate Bundle File

Comodo (or your own CA Provider) will send you the certificates you need to verify your server's identity. 

Here are the sample certificates sent by Comodo:

  • Root CA Certificate - AddTrustExternalCARoot.crt
  • Intermediate CA Certificate - COMODORSAAddTrustCA.crt
  • Intermediate CA Certificate - COMODORSADomainValidationSecureServerCA.crt
  • Your Free SSL Certificate - sudocodesystems_com.crt
We need to create a certificate bundle by putting all contents of the given certs in one file. Note that the contents must be put in a reverse order as listed above. The last cert to include is the Root CA Certificate and the first one is your SSL Certificate. We may use the cat command again for this.


cat sudocodesystems_com.crt COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > /etc/nginx/ssl/sudocode.crt


No that you might have to log-in as root to execute the command above.


4.2. Configure Nginx

Your nginx server configuration may look like the following:

server {
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;

        root /usr/share/nginx/html;
        index index.html index.htm;

        server_name your_domain.com;

        location / {
                try_files $uri $uri/ =404;
        }
}
By applying SSL, it should look like the following:

server {
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;

        listen 443 ssl;

        root /usr/share/nginx/html;
        index index.html index.htm;

        server_name sudocodesystems.com;
        ssl_certificate /etc/nginx/ssl/sudocode.crt;
        ssl_certificate_key /etc/nginx/ssl/sudocode.key;

        location / {
                try_files $uri $uri/ =404;
        }
}
Notice we added the following above:

listen 443 ssl;
server_name sudocodesystems.com
ssl_certificate /etc/nginx/ssl/sudocode.crt
ssl_certificate_key /etc/nginx/ssl/sudocode.key


When configuration is done, restart Nginx and access your website at your favorite browser.

Tuesday, December 10, 2013

Changing Native Jenkins Root Context

I recently had a requirement to change our Jenkins URL from http://our.webdomain:8080 to http://our.webdomain:8080/jenkins. The application is installed in Ubuntu. I tried to read the script at /etc/init.d/jenkins and was able to find out that this can be easily done by modifying /etc/default/jenkins.

The solution is just to add --prefix=$PREFIX or --prefix=/jenkins to JENKINS_ARGS.

# servlet context, important if you want to use apache proxying  
PREFIX=/jenkins

# arguments to pass to jenkins.
# --javahome=$JAVA_HOME
# --httpPort=$HTTP_PORT (default 8080; disable with -1)
# --httpsPort=$HTTP_PORT
# --ajp13Port=$AJP_PORT
# --argumentsRealm.passwd.$ADMIN_USER=[password]
# --argumentsRealm.roles.$ADMIN_USER=admin
# --webroot=~/.jenkins/war
# --prefix=$PREFIX

JENKINS_ARGS="--webroot=/var/cache/jenkins/war --httpPort=$HTTP_PORT --ajp13Port=$AJP_PORT --prefix=$PREFIX"

Tuesday, November 12, 2013

Deploying Java Web Applications in Separate Jetty Instances

I recently have a requirement to deploy GitBlit and Nexus in separate Jetty Application Server instances. It sounds easy right? I could place a package of Jetty on our Linux box and just duplicate so I could have two Jetty instances. But, it was not so straight forward. There were a lot of stuff need to customize, like separate PID of each instance, separate web application directories, etc. I had to read the shell script to start Jetty and find out how to arrive at the set-up required for me to do.

Here's to save you time to research and do experimentation. I documented what to do and how to do things in deploying two web applications (or more than) in separate Jetty instances.

Requirements

Download Jetty package at http://download.eclipse.org/jetty/. Try to download the latest stable version. It's currently 9.0.6 when I wrote this post.

Prepare your Web Archive (WAR) files. For this post, I deploy GitBlit and Nexus WAR files.

Note: I deployed these WARs at a Linux box so if you are using other OS like Windows, you might need to do some stuff differently.

Procedure

Extract Jetty Package

In this procedure, you don't need to duplicate the Jetty package. You just need one package and I recommend the following directory structure for Linux systems.

drwxr-xr-x  3 root     root     4096 Nov 11 23:46 ./
drwxr-xr-x  3 root     root     4096 Nov 12 06:56 ../
lrwxrwxrwx  1 root     root        6 Nov 11 23:46 default -> latest/
drwxrwxr-x 14 rmaranan rmaranan 4096 Nov 13 07:32 jetty-distribution-9.0.6.v20130930/
lrwxrwxrwx  1 root     root       34 Nov 11 23:45 latest -> jetty-distribution-9.0.6.v20130930/

I based this install folder structure from the Java installation in Fedora. Basically in my work, I created two soft links latest and default. The latest links to the latest Jetty package and the default links to the latest soft link. With this set-up, I could easily switch between different Jetty packages in the future.

For those who are not familiar yet, here's how I extracted my Jetty package. Assuming you have root access to your Linux box.

cp jetty-distribution-9.0.7.v20130930.tar.gz /opt

cd /opt

tar xvf jetty-distribution-9.0.7.v20130930.tar.gz

ln -s jetty-distribution-9.0.7.v20130930 latest

ln -s latest default

Set-up Web Application Directories

I know advance Jetty users and Java programmers have already figured this out. The secret for having one package for two Jetty instances is having two separate web application directories. So here, we create directories gitblit-apps and nexus-apps for Gitblit and Nexus applications respectively.

cd /opt/jetty/default
mkdir gitblit-apps
mkdir nexus-apps

Then, we copy the WAR files for each respective directories.

cp ~/war-files/gitblit.war gitblit-apps
cp ~/war-files/nexus.war nexus-apps

Finally, we open to modify the Jetty deployment configuration. This is to make the web application directory configurable.

nano etc/jetty-deploy.xml

Inside jetty-deploy.xml, look for the webappprovider Jetty call. And, add the highlighted text below.

<Call id="webappprovider" name="addAppProvider">
    <Arg>
        <New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
            <Set name="monitoredDirName">
                <Property name="jetty.home" default="." />
                <Property name="jetty.sudocode.webapps" default="/webapps" />
            </Set>
            <Set name="defaultsDescriptor">
                <Property name="jetty.home" default="."/>/etc/webdefault.xml
            </Set>
            <Set name="scanInterval">1</Set>
            <Set name="extractWars">true</Set>
            <Set name="configurationManager">
                <New class="org.eclipse.jetty.deploy.PropertiesConfigurationManager">
                <!-- file of context configuration properties
                    <Set name="file"><SystemProperty name="jetty.home"/>/etc/some.properties</Set>
                  -->
                  <!-- set a context configuration property
                  <Call name="put"><Arg>name</Arg><Arg>value</Arg></Call>
                  -->
                </New>
            </Set>
        </New>
    </Arg>
</Call>

The property jetty.sudocode.webapps will hold the web application directory path when we run each instances of Jetty for Gitblit and Nexus.

Create Customized Start-up Script

To make it more organized, We put the start-up scripts at the /etc/jetty/default/bin. And, we create sub-directories for Gitblit and Nexus start-up scripts.

mkdir bin/gitblit
mkdir bin/nexus

Then on each sub-directory we create separate start-up scripts but these scripts should contain same code except for the values of the parameters (which holds our Jetty run-time properties).

nano bin/gitblit/gitblit-starter

Notice that I have been using nano. If you are not so familiar with Linux, you could actually use any text editor which you are comfortable.

Inside the gitblit-starter script file, we write the following. Notice all the configurable parameters are at the top of the script.

#!/bin/sh

JETTY_BASE_DIR=/opt/jetty/default                                               # Jetty Installation folder
JAVA_EXEC=java                                                                  # java executable
JETTY_PORT=18080                                                                # HTTP Port
JETTY_HTTPS_PORT=18081                                                          # HTTPS Port
JETTY_STOP_PORT=18082                                                           # STOP Port
JETTY_STOP_KEY=ilovejetty                                                       # STOP Key
JETTY_SUDOCODE_WEBAPPS=/gitblit-apps                                            # Location of WAR under ${jetty.home}
JETTY_START_JAR=start.jar                                                       # Location of start.jar
JETTY_HOST=localhost                                                            # Jetty Host
JETTY_JVM_OPTS="-Xms192m -Xmx256m -XX:MaxPermSize=64m"                          # JVM Options

####################################################################################################################
# Don't touch the rest as much as possible
# This file must reside at ${jetty.home}
# Romeo H. Maranan Jr.
# Sudocode Systems Solutions, Inc.
JAVA_EXEC_PARAMS=""
JETTY_COMMAND=$1
JETTY_STOP=""
EXECUTOR_PWD=$(pwd)

changeDirToJettyHome() {
        cd $JETTY_BASE_DIR
}

changeDirBack() {
        cd $EXECUTOR_PWD
}
executeJetty() {
        JAVA_EXEC_PARAMS=" $JETTY_JVM_OPTS"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS -DSTOP.PORT=$JETTY_STOP_PORT"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS -DSTOP.KEY=$JETTY_STOP_KEY"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS -jar $JETTY_START_JAR"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS --module=http"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS jetty.port=$JETTY_PORT"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS jetty.https.port=$JETTY_HTTPS_PORT"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS jetty.sudocode.webapps=$JETTY_SUDOCODE_WEBAPPS"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS jetty.host=$JETTY_HOST"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS $JETTY_STOP"
        COMMAND="$JAVA_EXEC $JAVA_EXEC_PARAMS "
        $COMMAND &
}


case $JETTY_COMMAND in
        start)
                changeDirToJettyHome
                executeJetty
                changeDirBack
                ;;
        stop)
                changeDirToJettyHome
                JETTY_STOP="--stop"
                executeJetty
                changeDirBack
                ;;
        restart)
                changeDirToJettyHome
                executeJetty
                JETTY_STOP="--stop"
                executeJetty
                changeDirBack
                ;;
        *)
                echo "Usage: $(basename $0) (start | stop | restart)"
                ;;
esac

I'm not a "pro" in scripting so forgive me if you notice something awkward in my script. Here's the other one for the nexus-starter.

#!/bin/sh

JETTY_BASE_DIR=/opt/jetty/default                                               # Jetty Installation folder
JAVA_EXEC=java                                                                  # java executable
JETTY_PORT=18090                                                                # HTTP Port
JETTY_HTTPS_PORT=18091                                                          # HTTPS Port
JETTY_STOP_PORT=18092                                                           # STOP Port
JETTY_STOP_KEY=ilovejetty                                                       # STOP Key
JETTY_SUDOCODE_WEBAPPS=/nexus-apps                                              # Location of WAR under ${jetty.home}
JETTY_START_JAR=start.jar                                                       # Location of start.jar
JETTY_HOST=localhost                                                            # Jetty Host
JETTY_JVM_OPTS="-Xms256m -Xmx384m -XX:MaxPermSize=128m"                         # JVM Options

####################################################################################################################
# Don't touch the rest as much as possible
# This file must reside at ${jetty.home}
# Romeo H. Maranan Jr.
# Sudocode Systems Solutions, Inc.
JAVA_EXEC_PARAMS=""
JETTY_COMMAND=$1
JETTY_STOP=""
EXECUTOR_PWD=$(pwd)

changeDirToJettyHome() {
        cd $JETTY_BASE_DIR
}

changeDirBack() {
        cd $EXECUTOR_PWD
}

executeJetty() {
        JAVA_EXEC_PARAMS=" $JETTY_JVM_OPTS"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS -DSTOP.PORT=$JETTY_STOP_PORT"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS -DSTOP.KEY=$JETTY_STOP_KEY"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS -jar $JETTY_START_JAR"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS --module=http"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS jetty.port=$JETTY_PORT"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS jetty.https.port=$JETTY_HTTPS_PORT"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS jetty.sudocode.webapps=$JETTY_SUDOCODE_WEBAPPS"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS jetty.host=$JETTY_HOST"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS $JETTY_STOP"
        COMMAND="$JAVA_EXEC $JAVA_EXEC_PARAMS "
        $COMMAND &
}


case $JETTY_COMMAND in
        start)
                changeDirToJettyHome
                executeJetty
                changeDirBack
                ;;
        stop)
                changeDirToJettyHome
                JETTY_STOP="--stop"
                executeJetty
                changeDirBack
                ;;
        restart)
                changeDirToJettyHome
                executeJetty
                JETTY_STOP="--stop"
                executeJetty
                changeDirBack
                ;;
        *)
                echo "Usage: $(basename $0) (start | stop | restart)"
                ;;
esac

You will notice that we set different ports for properties JETTY_PORT, JETTY_HTTPS_PORT, JETTY_STOP_PORT and JETTY_SUDOCODE_WEBAPPS for each start-up script.

The JETTY_PORT will be set to jetty.port or the HTTP Port to be assigned to the Jetty instance. The JETTY_HTTPS_PORT will be set to the property jetty.https.port. The JETTY_STOP_PORT is for the STOP.PORT property which holds the value for the stop port - the port that will listen for stop commands. JETTY_SUDOCODE_WEBAPPS, finally, is for the property jetty.sudocode.webapps. This is a customized property that we set-up for our web directories.

Feel free to read the scripts so you may understand how things worked here. Also feel free to criticize. I'm very open to them since I'm not really a "pro" Linux user. That will be okay.

Now in able for these scripts to be executable, execute the chmod commands.

chmod +x bin/giblit/gitblit-starter
chmod +x bin/nexus/nexus-starter

Create Daemon Services

You could actually run the Jetty instances if you have finished the previous step.

bin/gitblit/gitblit-starter
bin/nexus/nexus-starter

But, if you are installing in an actual Linux server. You might need to create daemon services that will start-up your Jetty instances when the machine is booting up and will stop them when the machine is shutting down.

For this purpose, I created two more scripts. Using nano again:

nano bin/gitblit/gitblit-daemon

The script contains the following:

#!/bin/sh

JETTY_STARTER=/opt/jetty/default/bin/gitblit/gitblit-starter
JETTY_USER=rmaranan
JETTY_STARTER_COMMAND=

executeCommand() {
        start-stop-daemon -S -u $JETTY_USER -c $JETTY_USER -o -x $JETTY_STARTER $JETTY_STARTER_COMMAND
}

startCommand() {
        JETTY_STARTER_COMMAND=start
        executeCommand
}

stopCommand() {
        JETTY_STARTER_COMMAND=stop
        executeCommand
}

case $1 in
        start)
                startCommand
                ;;
        stop)
                stopCommand
                ;;
        restart)
                stopCommand
                startCommand
                ;;
        *)
                echo "Usage: $(basename $0) (start | stop | restart)"
                ;;
esac

Again, forgive my scripting. I hope you can see it here very straight forward.

The JETTY_STARTER parameter should be set to the respective start-up script. For gitblit-daemon, it should be /opt/jetty/default/gitblit/gitblit-starter.

For the nexus-daemon, it should look like the following:

#!/bin/sh

JETTY_STARTER=/opt/jetty/default/bin/nexus/nexus-starter
JETTY_USER=rmaranan
JETTY_STARTER_COMMAND=

executeCommand() {
        start-stop-daemon -S -u $JETTY_USER -c $JETTY_USER -o -x $JETTY_STARTER $JETTY_STARTER_COMMAND
}

startCommand() {
        JETTY_STARTER_COMMAND=start
        executeCommand
}

stopCommand() {
        JETTY_STARTER_COMMAND=stop
        executeCommand
}

case $1 in
        start)
                startCommand
                ;;
        stop)
                stopCommand
                ;;
        restart)
                stopCommand
                startCommand
                ;;
        *)
                echo "Usage: $(basename $0) (start | stop | restart)"
                ;;
esac

This time, the JETTY_STARTER points to /opt/jetty/default/nexus/nexus-starter.

Next step is to copy both daemon files at /etc/init.d.

Note that I'm using Ubuntu when I created the scripts. So start-stop-daemon command should have a counterpart at other Linux Distros. 

Anyway, let's move on. I leave the minor things to your research and development prowess.

We copy the daemon scripts to /etc/init.d

cp bin/gitblit/gitblit-daemon /etc/init.d
cp bin/nexus/nexus-daemon /etc/init.d

Then we execute the following commands:

update-rc.d gitblit-daemon defaults
update-rc.d nexus-daemon defaults

These commands will make our daemon scripts automatically started and stopped on boot-up and shutdown respectively.

Also, you could execute commands like start, stop and restart the following ways:

/etc/init.d/gitblit-daemon start

/etc/init.d/nexus-daemon start

/etc/init.d/gitblit-daemon stop

/etc/init.d/nexus-daemon stop

/etc/init.d/gitblit-daemon restart

/etc/init.d/nexus-daemon restart

That's all, blog readers!

Thank you for spending some time to read this blog. I hope you learned something. Also if you have comments or inquiries, I'll try my best as possible to answer them. I hope I could learn from you too.