Monday, October 08, 2018

Enable gc log

When your Java app is running very slow there's a chance that it is caused by some pauses in your app which in turn caused by the diligent garbage collector who loves to take its time cleaning up the memory for you way too often and too long :)

These two steps you might want to do to make sure that it was GC doing its job:
1. Extract the GC log from your app
2. Analyze the log

Extracting GC Log

For extracting the gc log, here's my preferred settings:

-XX:+PrintGCDetails
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCApplicationConcurrentTime
-XX:+PrintGCDateStamps
-Xloggc:gc.log
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=5
-XX:GCLogFileSize=2000k


Add those parameters above on your java runtime parameters, for tomcat you could edit catalina.sh (or catalina.bat), find JAVA_OPTS and add them there.

Restart your Java app or app server and find gc.log on the current directory where you run your java app.

Analyzing GC Log

Refer to the reference 1 below on how to learn to interpret the gc log.
For the tools, choices are you do it using offline tool or online tool.
1. Offline
I'm using GC Viewer (see reference 3 below), simple and easy tool

2. Online
Try gceasy.io, it analyzes your gc log quite awesome :)


Reference:

1. https://dzone.com/articles/enabling-and-analysing-the-garbage-collection-log
2. http://gceasy.io
3. https://github.com/chewiebug/GCViewer

Thursday, October 04, 2018

Updating /etc/hosts in Android emulator

Why? think of it like when all you want is to redirect the target server to another server and you cannot or should not update the dns server and all you need is just one or two lines on the right place ;)

Isn't it as simple as going in and change one or two things? Yes, if it's allowed :)
Anyway here's how we can do it in five simple steps:

1. Assuming emulator is already set up, open the shell and go to the emulator directory under the sdk directory. Start the emulator with this command:

emulator -writable-system -netdelay none -netspeed full -avd {emulator_name}
e.g.
emulator -writable-system -netdelay none -netspeed full -avd Nexus_5X_API_25

2. Go to root mode
Open the shell and run the command:
adb root
3. Remount system partition
adb remount
4. Pull hosts file, edit it as needed
adb pull /etc/hosts hosts
5. Push it back
adb push hosts /etc/hosts

And... we're done, enjoy!

Friday, August 10, 2018

Certificate check and installation (Java)

Been dealing with self signed certificate quite sometimes and found myself always googled around for the how-tos, guess it's time to write it down here (for checking back later on which I guess I will... ;)

And here's the famous security exception:
PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target;
nested exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Goal is to install a self signed certificate in Java keystore so that Java app can open https connection to the server without raising any security error or trying to skip the security checking at all.


How to:

Step 1. Extracting the certificate
Using openssl:
1. Grab the target certificate from the server
openssl s_client -showcerts -verify 5 -connect {HOST:PORT} | tee thecert.txt
Type QUIT and press enter/return, certificate will be captured in thecert.txt
 2. Generate cert file
openssl x509 -inform PEM -in thecert.txt -out thecert.crt
3. Verify cert
openssl x509 -in thecert.crt -text -noout

In case you are dealing with a development environment, you might want to install the root and intermediate cert in your keystore so that you don't have to import each and every certificate that belongs to another system integrated. See below on how to extract the root and intermediate cert.

Step 2. Installing the certificate
Next is to install the extracted certificate in the keystore, one way is to install it right on the jre's keystore and the more secure way is to setup a local truststore and pass it as JVM parameter (e.g. -Djavax.net.ssl.trustStore=./LocalTrustStore)
1. Import the certificate
     keytool -import -alias {THE_ALIAS} -keystore {PATH_TO_KEYSTORE} -file {CERTIFICATE FILE}
    Default jre keystore can be found under jre/lib/security directory.
2. Verify it
   keytool -list -keystore {PATH_TO_KEYSTORE} -alias {THE_ALIAS}

Step 3. Testing using SSLPoke
Get SSLPoke here, it's one nice utility to check whether you have successfully import the certificate or not.
java SSLPoke {URL} {PORT}
e.g. java SSLPoke myserver 1234



Reference:

1. https://operational.io/openssl-commonly-used-commands/
2. https://gist.github.com/4ndrej/4547029
2. Extract root and intermediate
  1. openssl x509 -in cert.x509 -text Find the URL of the signing certificate.
  2. curl (url) >signer.der Download the signing certificate to a file (DER format in my case).
  3. openssl x509 -inform der -in signer.der -out signer.pem Convert signing certificate to PEM (X.509) format.
  4. openssl x509 -in signer.pem -text Confirm your results. Repeat procedure as necessary all the way up the certificate chain.

Tuesday, April 24, 2018

Nginx Reverse Proxy Formulae

It should be simple but it's just not that simple, that's the reason I'm writing down some example for the proxy pass configuration here.

The reference link can be found here.

Theory:

The keyword is "If the URI is specified along with the address, it replaces the part of the request URI that matches the location parameter.....  If the address is specified without a URI, or it is not possible to determine the part of URI to be replaced, the full request URI is passed (possibly, modified)."

Note:
1.If you specify any URI along with the server address it will replace the request URI part on the location
2. If you don't specify any URI, the full request URI on the location is appended to the target URL


Without further ado, here's some examples:
Assume nginx is setup on localhost and will redirect to www.example.com.

Configuration #1
location /some/path {
      proxy_pass http://www.example.com/link;
}
URL: http://localhost/some/path
Passed to: http://www.example.com/link
URL: http://localhost/some/path/hello
Passed to: http://www.example.com/link/hello
URL: http://localhost/some/path/
Passed to: http://www.example.com/link/


Configuration #2
location /some/path {
      proxy_pass http://www.example.com/;
}
URL: http://localhost/some/path
Passed to: http://www.example.com/
URL: http://localhost/some/path/hello
Passed to: http://www.example.com/hello
URL: http://localhost/some/path/
Passed to: http://www.example.com/


Configuration #3
location /some/path {
      proxy_pass http://www.example.com;
}
URL: http://localhost/some/path
Passed to: http://www.example.com/some/path
URL: http://localhost/some/path/hello
Passed to: http://www.example.com/some/path/hello
URL: http://localhost/some/path/
Passed to: http://www.example.com/some/path/


Configuration #4
location /some {
      proxy_pass http://www.example.com/;
}
URL: http://localhost/some
Passed to: http://www.example.com/
URL: http://localhost/some/path/hello
Passed to: http://www.example.com/path/hello
URL: http://localhost/some/
Passed to: http://www.example.com/
URL: http://localhost/some/hello?name=me
Passed to: http://www.example.com/hello?name=me