Home
OpenSSH is a set of
utilities to allow you to connect to a remote machine through an encrypted
tunnel. You can use it as a terminal connection or to tunnel any data through a
VPN interface.
OpenSSH is a FREE version of the SSH suite of network connectivity tools that increasing numbers of people on the Internet are coming to rely on. Many users of telnet, rlogin, ftp, and other such programs might not realize that their password is transmitted across the Internet unencrypted, but it is. OpenSSH encrypts all traffic (including passwords) to effectively eliminate eavesdropping, connection hijacking, and other network-level attacks.OpenSSH FAQ
Most operating systems come with one version or another of OpenSSH. You may want to make sure you have the latest version on your machine. Check the OpenSSH site for the latest source code. You can also look to the package maintainers of your OS revision to see if they make a premade package for you to install.
NOTE: The directives and options listing in the following config files apply to the latest official OpenSSH release from OpenSSH.org .
This config is for the client side options. You can specify directives here and the client will negotiate them with the server. Only if the server allows them will they will take effect.
####################################################### ### Calomel.org CLIENT /etc/ssh/ssh_config ####################################################### Host * AddressFamily inet CheckHostIP yes Ciphers aes128-ctr,aes256-ctr,arcfour256,arcfour,aes128-cbc,aes256-cbc Compression no ConnectionAttempts 1 ConnectTimeout 10 ControlMaster auto ControlPath ~/.ssh/master-%r@%h:%p EscapeChar ~ ForwardAgent no ForwardX11 no ForwardX11Trusted no HashKnownHosts yes IdentityFile ~/.ssh/identity IdentityFile ~/.ssh/id_rsa IdentityFile ~/.ssh/id_dsa IdentitiesOnly yes MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160 PermitLocalCommand no Port 22 Protocol 2 RekeyLimit 1G ServerAliveInterval 15 ServerAliveCountMax 3 StrictHostKeyChecking ask TCPKeepAlive no Tunnel no TunnelDevice any:any VisualHostKey no ####################################################### ### Calomel.org CLIENT /etc/ssh/ssh_config #######################################################
These directives are for sshd. Permissions should be "chmod 755". We want to restrict access with the following options to better protect the server.
####################################################### ### Calomel.org SERVER /etc/ssh/sshd_config ####################################################### # Port 22 Protocol 2 AddressFamily inet #ListenAddress 127.0.0.1 #See the questions section for setting up the gatekeeper #ForceCommand /tools/ssh_gatekeeper.sh AllowUsers calomel@10.10.10.3 calomel@192.168.* AllowGroups calomel AllowTcpForwarding yes AuthorizedKeysFile .ssh/authorized_keys Banner /etc/banner ChallengeResponseAuthentication no Ciphers aes128-ctr,aes256-ctr,arcfour256,arcfour,aes128-cbc,aes256-cbc ClientAliveInterval 15 ClientAliveCountMax 3 Compression no GatewayPorts no LogLevel VERBOSE LoginGraceTime 50s MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160 MaxAuthTries 6 MaxStartups 10 PasswordAuthentication yes PermitEmptyPasswords no #PermitOpen localhost:80 PermitRootLogin no PermitUserEnvironment no PidFile /var/run/sshd.pid PrintLastLog yes PrintMotd no PubkeyAuthentication yes StrictModes yes Subsystem sftp /usr/libexec/sftp-server SyslogFacility AUTH TCPKeepAlive no UseDNS no UseLogin no UsePrivilegeSeparation yes X11DisplayOffset 10 X11Forwarding no X11UseLocalhost yes #Match User anoncvs # X11Forwarding no # AllowTcpForwarding no # ForceCommand cvs server # ####################################################### ### Calomel.org SERVER /etc/ssh/sshd_config #######################################################
In many high security (top secret) or ultra paranoid environments multi factor authentication is required. In order to log into a machine you need to provide many proofs of your identity. An authentication factor is a piece of information and process used to authenticate or verify the identity of a person requesting access under security constraints. For example, two-factor authentication (TFA) is a system wherein two different factors are used in conjunction to authenticate. Using more than one factor (single factor or SFA) is sometimes called strong authentication. However, strength is always bound to secrecy under which the factors are kept and protected against any third party challenge. In order to increase security one can increase the amount of independent authentication methods used.
Multi factor authentication (MFA) is comprised of three(3) or more of the following:
- access control (firewall port limit or server location or user ACL conditions)
- something you know (your password or pass phrase)
- something you have (your ssh key or secure id key-fob hardware)
- something you are (fingerprint or iris scan)
- somebody you know (human authentication through mutual acquaintance)
- something you deduce (logical authentication which the user will need to reason, personal knowledge or life experience)
OpenSSH can help you better secure remote access by adding another authentication layer to the system by using the ForceCommand directive and the ssh_gatekeeper script. By definition true multi-factor authentication requires the use of solutions from two or more of the three categories of factors. Using multiple solutions from the same category would not constitute multi-factor authentication
To practice good security using multi-factor (very strong) authentication through OpenSSH you should at least:
- limit access to ssh by ip address (access control)
- limit access by username with the "AllowUsers" directive (access control)
- use a pre-authorized ssh key (something you have)
- use that ssh key _with_ a pass-phrase (something you know)
- ssh_gatekeeper script (logical authentication of a constantly changing answer)
How does the ssh_gatekeeper script work? How does it help me?
The Gatekeeper script will require the user to enter the correct answer before being allowed a shell and access to the system. This adds another layer of authentication as the string can be constantly changing. If someone steals your ssh key, especially if it is pass phrase-less, or gets a hold of your password they will still need to deduce what the gatekeeper expects as an answer. Lets take a look.
The script will have the client input a string once they have been authenticated through ssh and are just about to be awarded a shell. The user can run any shell they want to including bash, sh, ksh, csh or tcsh. Before the gatekeeper can run the user must provide a valid password for a valid user or connect using a pre-authorized ssh key having supplied a valid or empty pass-phrase. The sshd daemon will run the ssh_gatekeeper.sh script using ForceCommand. The user will not be able to break out of the script and must provide the correct answer to receive shell access according to the $QUERY question. If the script receives anything other than the correct response the connection is closed.
The default question ($QUERY variable) we have setup is a string asking the current minute, day of the month and hour (24-hour format). If the date is "Mon Jan 10 13:25:00 EST 2020" then the answer is "251013". As you can see the answer is only good for 60 seconds per month and only for that exact minute. This is just an example and you can make up any question you want.
You can put anything into the $QUERY variable like a string, an equation or put a logic if-then tree in to make it even more difficult to know. We highly suggest using some logic that changes periodically, but the client can remotely deduce.
How do I setup the "ssh_gatekeeper.sh" script?
First, edit your /etc/ssh/sshd_config and add the following line. The ForceCommand directive will make sshd execute this script when any client tries to log into the machine. The rest is the path and name of the script. Make sure you restart the sshd server so the changes take effect.
ForceCommand /tools/ssh_gatekeeper.shSecond, copy the following script to a location where all users will be able to execute it. When the ForceCommand directive runs the script it will be run as the user attempting log in. For our example we will place it in /tools/ssh_gatekeeper.sh and set the permissions to "chmod 755" with the owner as root (chown root).
# ## Calomel.org ssh_gatekeeper.sh # ## This script is run by the ForceCommand directive in the sshd_config. It expects ## the user SSH'ing to the box to answer the $QUERY question before being allowed ## a shell. Permissions of this script should be owned by root and executable by ## all other users (chmod 755)". Rsync is allowed through, but scp and sftp are ## denied. # ## Disconnect clients who try to quit the script (Ctrl-c) trap jail INT jail() { kill -9 $PPID exit 0 } ## Allow SSH. Clients can ssh to the box and then answer the $QUERY question. if [ -z "$SSH_ORIGINAL_COMMAND" ]; then ## This is the question the client needs to know the answer to. ## Here we are asking for the current minute, day of the month ## and hour (24-hour time). If the date is "Mon Jan 10 13:25:00 EST 2020" ## then the answer is "251013" QUERY=`date +%M%d%H` ### The welcome message. This can be helpful or completely arbitrary ### depending on your user. Here we use a random quote as we are ### expecting the user to already know the question. echo "" echo " All truths are easy to understand once they are" echo " discovered; the point is to discover them." echo " -Galileo Galilei" echo "" ### The Decision ### If the answer is correct give the user their shell. ### If the answer is wrong, log the attempt and kill the connection. while read -s inputline do answer="$inputline" if [ $QUERY = "${answer}" ]; then $SHELL -l exit 0 else logger "ssh_gatekeeper $USER login failed from $SSH_CLIENT" kill -9 $PPID exit 0 fi done fi ## Allow RSYNC. Rsync can not be used with the question above. ## We need to let the command though so our shell environment is clean. if [ `echo $SSH_ORIGINAL_COMMAND | awk '{print $1}'` = rsync ]; then $SHELL -c "$SSH_ORIGINAL_COMMAND" exit 0 fi ## Default deny. This is the last command to catch all other command ## input. If the client tries to use anything other than ssh or rsync ## the connection is dropped. SCP and SFTP are not allowed on our server ## so they are denied as well. kill -9 $PPID exit 0
Testing the ssh_gatekeeper.sh script
Now, ssh to the machine as a valid user. You should first have to enter your password or use your ssh key. Then the "welcome message" will print out from the script. If you kept the same $QUERY from the example you will need to enter in the current minute, day of the month and hour (24-hour format). Make sure the time on all of your machines is in sync otherwise you will never figure out the answer. Your input will _not_ be echoed. If the entry is correct you will be given a shell. If the input is wrong the connection will be closed and the attempt will be logged.
If you have many machines to take care of you can setup ssh keys on each of them from a central ssh key server. This way you can ssh to the key server and then ssh to any other machine with the key without a password. Working with one machine at a time is fine, but what if you need to work on many machines doing the same task over and over again?
This is a simple shell script you can use to connect to many machines and execute the same commands on all of them from your centralized key server.
#!/usr/local/bin/bash # ## Calomel.org Distributed SSH ## sh batch_ssh.sh "machine1 machine2" 'uptime' ## sh batch_ssh.sh "`cat servers.txt`" 'uptime' # ## global options TIMEOUT=3 OUTLOG=/tmp/remote-out-$$.log ## command line options MACHINES=$1;shift COMMAND=$1;shift ## distribute commands to machines for machine in $MACHINES do echo $machine >>$OUTLOG.$machine ssh -q -oStrictHostKeyChecking=no -oBatchMode=yes -oCompression=yes \ -oConnectTimeout=$TIMEOUT -l root $machine $COMMAND >>$OUTLOG.$machine \ 2>>$OUTLOG.$machine & done # wait for all processes to finish wait ## print logs and delete tmp files cat $OUTLOG.* rm -f $OUTLOG.*
This is a companion script to the distributed SSH script above. The is for scp'ing a local file on your key server to a list of servers. Just provide three arguments in the form of the list of machines, the name of the local file to distribute and the location on the remote server you want the file to be placed.
#!/usr/local/bin/bash # ## Calomel.org Distributed SCP ## sh batch_scp.sh "machine1 machine2" 'local_file' 'remote_directory' ## sh batch_scp.sh "`cat servers.txt`" 'myfile.txt' '/root/' # ## global options TIMEOUT=3 OUTLOG=/tmp/remote-out-$$.log ## command line options MACHINES=$1;shift LOCAL=$1;shift REMOTE=$1;shift ## distribute commands to machines for machine in $MACHINES do echo $machine >>$OUTLOG.$machine scp -q -oStrictHostKeyChecking=no -oBatchMode=yes -oCompression=yes \ -oConnectTimeout=$TIMEOUT $LOCAL root@$machine:$REMOTE \ >>$OUTLOG.$machine 2>>$OUTLOG.$machine & done # wait for all processes to finish wait ## print logs and delete tmp files cat $OUTLOG.* rm -f $OUTLOG.*
A reverse ssh connection will allow you to use an existing ssh connection from work, through their restrictive firewall (port 443 is open), to your machine at home. Then you can initiate a reverse ssh connection from your home machine, back through the established ssh tunnel to your work machine. This is what we are tying to accomplish:
Initial Tunnel: 1.1.1.1:443 --> NAT FIREWALL --> 2.2.2.2:443 [localhost:12345] (work) (home) Reverse SSH: localhost:22 <-- SSH TUNNEL <-- localhost:12345Lets say work only allows port 80 (http) and port 443 (https) out through the firewall. Since ssh and https are both encrypted no one should notice ssh traffic going out the https port on the firewall.
First, you need to execute the following on your work machine. It will setup a ssh tunnel to your home machine (sshd at home is listening on port 443) going out port 443 (hidden on the https port). On your home machine, port 12345 on localhost will the the end of the tunnel that starts on your machine at work.
calomel@WORK: ssh -R 12345:localhost:22 usernamer@2.2.2.2Now, on your home machine you can use the ssh tunnel you just setup to ssh back though to the target machine at work.
calomel@HOME: ssh localhost -p 12345Anyone with access to the home machine can now access the work machine through the tunnel. To keep the tunnel active you can run "top" on the home machine. Just imagine the security implications and how difficult a reverse tunnel would be to stop if you are the admin of the work machine.
Instead of using a special program to encrypt and decrypt files, like password or financial data, you can just use OpenSSL. You can pass any file into OpenSSL and using a password as a key you can encrypt it. The best part is that any OS, be it Linux OpenBSD, NetBSD, MacOSX or even windows and use this method as long as OpenSSL is installed. For example, we have some random file called "calomel". Use the following commands to encrypt and then decrypt this file.
to encrypt (-e): openssl aes-256-cbc -a -e -salt -in calomel -out calomel.aes to decrypt (-d): openssl aes-256-cbc -a -d -salt -in calomel.aes -out calomel
Questions, comments, or suggestions? Contact Calomel.org