Tuesday, February 20, 2018

Nginx Reverse Proxy

I deployed a web application at Azure and one of the modules creates an e-mail with a link redirecting to one of the pages in the website. It works great (I mean the e-mail module) but I have a problem: The links are written as http://localhost:8080/something.

This is because the web application sees all remote addresses as localhost when it is served publicly with a host name. To solve this problem, we configure Nginx to reverse proxy - a way to trick the web application that all access to it or the remote addresses accessing it is from the IP of the host or the host name instead.

Here's the configuration from https://www.digitalocean.com/community/tutorials/understanding-nginx-http-proxying-load-balancing-buffering-and-caching

location /match/here {
    proxy_set_header HOST $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_pass http://example.com/new/prefix;
}
For more information, please visit https://www.nginx.com/.

Saturday, August 27, 2016

Keystore and Public Key Generation for Spring OAuth2 JWT


If you are going to implement Gateway Pattern (involving an Auth Server, UI Server and Resource Server) using Spring Boot OAuth2, you may want to look on to the sample at Github. The sample clearly illustrates how to implement the pattern. But, if you want to create your own Keystore and Public Key, the following instruction will be useful.

The instructions are taken from http://www.baeldung.com/spring-security-oauth-jwt. First, execute the following command:

keytool -genkeypair -alias myalias -keyalg RSA -keystore mykeystore.jks 

Enter keystore password:  
Re-enter new password: 
What is your first and last name?
  [Unknown]:  Juan Dela Cruz
What is the name of your organizational unit?
  [Unknown]:  My Company
What is the name of your organization?
  [Unknown]:  My Organization
What is the name of your City or Locality?
  [Unknown]:  Antipolo
What is the name of your State or Province?
  [Unknown]:  Rizal
What is the two-letter country code for this unit?
  [Unknown]:  PH
Is CN=Juan Dela Cruz, OU=My Company, O=My Organization, L=Antipolo, ST=Rizal, C=PH correct?
  [no]:  yes

Enter key password for <myalias>
(RETURN if same as keystore password):

The command will produce mykeystore.jks file. Then, we export the public key through Java:

    public static void main(String[] args) {
        KeyPair keyPair = new KeyStoreKeyFactory(new ClassPathResource("keystore.jks"), "10qpalzm".toCharArray())
                .getKeyPair("safesatcentral", "10qpalzm".toCharArray());
        System.out.println(new String(Base64.encode(keyPair.getPublic().getEncoded())));
    }

After all of these, you may now apply your custom Keystore and Public Key to your Spring OAuth2 project using JWT.


Friday, July 22, 2016

Creating CSR with modern cryptography

I had a post regarding SSL installation at http://jettyapplicationserver.blogspot.com/2015/04/applying-ssl-certificate-to-nginx.html but the procedure on CSR generation is outdated. If you want to protect your website with modern cryptography, you may find this post useful.

By the way, in Chrome you may click the pad lock icon at the address bar to know about a website's SSL connection details.


In this example we will generate a private key named sudo2016.key and CSR file named sudo2016.csr. For your purpose, rename the file names with the names you desire.


Generate an RSA Key

openssl genrsa -out sudo2016.key 4096


Generate CSR

openssl req -out sudo2016.csr -key sudo2016.key -new -sha256


Pre-SSL Certificate Generation

The contents of the CSR will be supplied to the SSL provider. The SSL Provider will generate a number of certificates for you. 

In Name.com, they provide three certificates: Server Certificate, CA Certificate and the Root Certificate.

Different Web Servers have different ways of installing SSL certificates. Usually, the SSL Providers give instruction for every Web Servers.





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.

Thursday, June 12, 2014

Problem with Java System Prefs and User Prefs

If you are running on Linux and you find any of the following WARNING messages at your Java Application logs or Web Application logs:

  • FileSystemPreferences syncWorld Couldn't flush user prefs: java.util.prefs
  • Could not create system preferences directory. System preferences are unusable
  • Could not lock system prefs. Unix error code 0
or anything regarding Java System Prefs and User Prefs, the reason is you have installed JDK in your machine but the installer wasn't able to set-up the System Prefs and User Prefs directories properly.

Here's the solution suggested by a guy at this link: https://groups.google.com/forum/#!topic/xnat_discussion/uOd-YyuBhCQ

chmod 755 /etc/.java
chmod 755 /etc/.systemPrefs
touch /etc/.java/.systemPrefs/.system.lock
touch /etc/.java/.systemPrefs/.systemRootModFile
chmod 544 /etc/.java/.systemPrefs/.system*


Everything went well for me after. To be particular, I'm running a web application in Jetty at my IDEA workspace.

I hope this can be useful in the future.

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"