Personal Programming Notes

To err is human; to debug, divine.

SSH Cookbook: Ssh

This blog lists some recipes that is related to ssh commands.

Quick recipes

Recipe 1: link

Recipe 1: Generate public key from private key
1
ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub

Recipe 2: link

Recipe 2: Show fingerprint of the private key in MD5 format (used by Github, AWS)
1
openssl rsa -in ~/.ssh/id_rsa -pubout -outform DER | openssl md5 -c

Recipe 3: link.

Recipe 3: Add new hosts to known_hosts file
1
2
ssh-keyscan -H [ip_address] >> ~/.ssh/known_hosts
ssh-keyscan -H [hostname] >> ~/.ssh/known_hosts

Recipe 4: link

Recipe 4: Add self-signed certificates into cacerts
1
2
3
4
5
6
7
openssl s_client -connect nexus.company.com:443 < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > public.crt
/opt/jdk-latest/jre/bin/keytool -import -alias nexus.company.com  -keystore /opt/jdk-latest/jre/lib/security/cacerts -file public.crt

# Typical error in Java
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

Recipe 4: Java keystore

Recipe 4: Java keystore related commands
1
2
3
4
5
6
7
8
9
10
11
12
13
# Generate Root CA
keytool -genkey -v -alias rootca -keyalg RSA -keystore kstore
# Generate Intermediate CA
keytool -genkey -v -alias CA -keyalg RSA -keystore kstore
# Export certificate
keytool -export -alias CAsigned -keystore kstore -file CAsigned.crt
# Import cert
keytool -import -alias CA -keystore kstore -file CAsigned.crt
# List keystore
keytool -list -v -keystore kstore

# Import internal root CA with default path
keytool -import -alias "sfdc root" -keystore $JAVA_HOME/jre/lib/security/cacerts -file ~/Downloads/sfdc_root.cert 

Recipe 5: How to check if a private key file matches a public key file (both in PEM format).

Recipe 5: Check if public and private key match
1
2
3
4
5
6
# openssl x509 -noout -modulus -in chain.pem | openssl md5
(stdin)= c416781461f0c1c5c59489e658e4b4c5

# openssl rsa -noout -modulus -in key.pem | openssl md5
Enter pass phrase for key.pem:
(stdin)= c416781461f0c1c5c59489e658e4b4c5

-R and -L of ssh

Those options stands for remote and local port forwarding. There are blog posts explain these options better than this. The awesome answer and sketches are reproduced here for occasional review:

Example 1
1
ssh -L 80:localhost:80 SUPERSERVER

In Example 1, you specify that a connection made to the local port 80 is to be forwarded to port 80 on SUPERSERVER. That means if someone connects to your computer with a webbrowser, he gets the response of the webserver running on SUPERSERVER. You, on your local machine, have no webserver running.

Example 2
1
ssh -R 80:localhost:80 tinyserver

In Example 2, you specify, that a connection made to the port 80 of tinyserver is to be forwarded to port 80 on your local machine. That means if someone connects to the small and slow server with a webbrowser, he gets the response of the webserver running on your local machine. The tinyserver, which has not enough diskspace for the big website, has no webserver running. But people connecting to tinyserver think so.

Other things could be: The powerful machine has five webservers running on five different ports. If a user connects to one of the five tinyservers at port 80 with his webbrowser, the request is redirected to the corresponding webserver running on the powerful machine. That would be

Example 3 (before)
1
2
3
ssh -R 80:localhost:30180 tinyserver1
ssh -R 80:localhost:30280 tinyserver2
etc.

Or maybe your machine is only the connection between the powerful and the small servers. Then it would be (for one of the tinyservers that play to have their own webservers):

Example 3 (after)
1
2
3
ssh -R 80:SUPERSERVER:30180 tinyserver1
ssh -R 80:SUPERSERVER:30280 tinyserver2
etc