Linux/SSH

Secure Shell (SSH)

 * "Secure Shell or SSH is a network protocol that allows data to be exchanged over a secure channel between two computers. Encryption provides confidentiality and integrity of data. SSH uses public-key cryptography to authenticate the remote computer and allow the remote computer to authenticate the user, if necessary.


 * SSH is typically used to log into a remote machine and execute commands, but it also supports tunneling, forwarding arbitrary TCP ports and X11 connections; it can transfer files using the associated SFTP or SCP protocols.


 * An SSH server, by default, listens on the standard TCP port 22." (Wikipedia: SSH)

SSH Server
See sshd

Tunneling
NOTE: Only TCP ports can be tunneled

Allow Tunneling on server: /etc/ssh/sshd_config AllowTcpForwarding yes

Tunnel ssh -L 8000:localhost:5900 kenneth@t0e.org ssh -L 8000:localhost:5900 -L 8001:localhost:5901 kenneth@t0e.org # multiple forwards
 * 1) ssh -L [localport]:[server]:[serverport] [user]@[host]
 * 1) Forward local 8000 to remote VNC port

Options: -L port:host:hostport Specifies that the given port on the local (client) host is to be   forwarded to the given host and port on the remote side. -N Do not execute a remote command. This is useful for just forwarding ports (protocol version 2 only).

To allow other external systems to use the tunnel: ssh -L *:8000:winserver:3389 kenneth@t0e.org

References:
 * SSH Tunneling http://www.linux-mag.com/id/1705

Add Forward to Live Connection
Open the SSH command line, using special SSH key: ~C - open a command line

ssh> help Commands: -Lport:host:hostport   Request local forward -Rport:host:hostport   Request remote forward -KRhostport            Cancel remote forward

List Forwarded Connections
SSH special key: ~# - list forwarded connections

This will list each client connection that is being forwarded (not the actual forward tunnels themselves)

Reverse Tunnel
Tunnel
 * 1) ssh -R [bind_address:]port:host:hostport [user]@[host]

ssh -R *:8000:localhost:80 root@216.119.194.247
 * 1) Reverse forward port 8000 to local HTTP port

Options: -R [bind_address:]port:host:hostport Specifies that the given port on the remote (server) host is to  be forwarded to the given host and port on the local side.

By default, the listening socket on the server will be bound to  the loopback interface only. This may be overriden by specifying a bind_address. An empty bind_address, or the address ‘*’, indi- cates that the remote socket should listen on all interfaces. Specifying a remote bind_address will only succeed if the server’s GatewayPorts option is enabled (see sshd_config(5)).

Allow remote bind to any address: /etc/ssh/sshd_config GatewayPorts yes
 * 1) GatewayPorts no

Tunnel Command Mode
ssh man: ~C     Open command line. Currently this allows the addition of port forwardings using the -L and -R options (see above). It also allows the cancellation of existing remote port-forwardings using -KR hostport. !command allows the user to            execute a local command if the PermitLocalCommand option is enabled in ssh_config(5). Basic help is available, using the -h option.

command mode: ssh> help Commands: -Lport:host:hostport   Request local forward -Rport:host:hostport   Request remote forward -KRhostport            Cancel remote forward

X Forwarding
/etc/ssh/ssh_config or ~/.ssh/config: ForwardX11 yes

/etc/ssh/sshd_config: X11Forwarding yes X11DisplayOffset 10

Client: ssh -o ForwardX11=yes some-user@the-server # or ssh -X some-user@the-server

Ref: https://unix.stackexchange.com/questions/12755/how-to-forward-x-over-ssh-to-run-graphics-applications-remotely

Putty X11 Forwarding
Connection → SSH → X11 → Enable X11 forwarding

Xming
Ref: https://aruljohn.com/info/x11forwarding/

Disconnect
To force a disconnect (Force SSH connection closed): ~.

Escape Characters
man ssh: ESCAPE CHARACTERS When a pseudo-terminal has been requested, ssh supports a number of func- tions through the use of an escape character.

A single tilde character can be sent as or by following the tilde by a     character other than those described below. The escape character must always follow a newline to be interpreted as special. The escape charac- ter can be changed in configuration files using the EscapeChar configura- tion directive or on the command line by the -e option.

The supported escapes (assuming the default '~') are:

~.     Disconnect.

~^Z    Background ssh.

~#     List forwarded connections.

~&     Background ssh at logout when waiting for forwarded connection / X11 sessions to terminate.

~?     Display a list of escape characters.

~B     Send a BREAK to the remote system (only useful for SSH protocol             version 2 and if the peer supports it).

~C     Open command line. Currently this allows the addition of port forwardings using the -L and -R options (see above). It also allows the cancellation of existing remote port-forwardings using -KR hostport. !command allows the user to execute a local com- mand if the PermitLocalCommand option is enabled in            ssh_config(5). Basic help is available, using the -h option.

~R     Request rekeying of the connection (only useful for SSH protocol             version 2 and if the peer supports it).

Note: If you are double connected, you can send. to exit the second connection only.

Escape Characters
man ssh: ESCAPE CHARACTERS When a pseudo-terminal has been requested, ssh supports a number of functions through the use of an escape character.

A single tilde character can be sent as or by following the tilde by a character other than those described below. The escape character must always follow a newline to be interpreted as special. The escape character can be changed in configu- ration files using the EscapeChar configuration directive or on the command line by the -e option.

The supported escapes (assuming the default ‘~’) are:

~.     Disconnect.

~^Z    Background ssh.

~#     List forwarded connections.

~&     Background ssh at logout when waiting for forwarded connection / X11 sessions to terminate.

~?     Display a list of escape characters.

~B     Send a BREAK to the remote system (only useful for SSH protocol version 2 and if the peer supports it).

~C     Open command line. Currently this allows the addition of port forwardings using the -L and -R options (see above). It also allows the cancellation of existing remote port-forwardings using -KR hostport. !command allows the user to            execute a local command if the PermitLocalCommand option is enabled in ssh_config(5). Basic help is available, using the -h option.

~R     Request rekeying of the connection (only useful for SSH protocol version 2 and if the peer supports it).

rsync and SSH
See rsync

User Config
per-user configuration file is ~/.ssh/config

SSH Default User
~/.ssh/config Host myserver user bob Host * user jenkins

Host gh-foo Hostname github.com User git IdentityFile ~/.ssh/foo_github_id Host gh-bar Hostname github.com User git IdentityFile ~/.ssh/bar_github_id

keyscan
Collect host key: (should check first if it is already there) ssh-keyscan -t rsa [HOST] >> /etc/ssh/ssh_known_hosts ssh-keyscan -t rsa [HOST] >> ~/.ssh/known_hosts [HOST]

Types: "Specifies the type of the key to fetch from the scanned hosts. The possible values are “rsa1” for protocol version 1 and “rsa” or “dsa” for protocol version 2. Multiple values may be specified by separating them with commas.  The default is “rsa1”."

Print the rsa1 host key for machine hostname:

$ ssh-keyscan hostname

Print the rsa2 host key for machine hostname:

$ ssh-keyscan -t rsa hostname

Find all hosts from the file ssh_hosts which have new or different keys from those in the sorted file ssh_known_hosts:

$ ssh-keyscan -t rsa,dsa -f ssh_hosts | \ sort -u - ssh_known_hosts | diff ssh_known_hosts -

Remove previous key: ssh-keygen -f /etc/ssh/ssh_known_hosts -R [HOST]

SSH Public Private Keys
Generate key: ssh-keygen

Get public key from private key file: ssh-keygen -y -f id_rsa > id_rsa.pub

Get hash from public key: ssh-keygen -l -f id_rsa.pub

Remote server authenticated keys are stored in: .ssh/authorized_keys

To avoid the No identities error: ln -s id_rsa.pub ~/.ssh/identity.pub
 * 1) /usr/bin/ssh-copy-id: ERROR: No identities found

If you copy keys to a Secure Linux system, you may need to fix the permissions: restorecon -r -v ~/.ssh

ssh-copy-id
Copy key to remote server: ssh-copy-id [USER]@[REMOTE_SERVER] ssh-copy-id -i ~/.ssh/id_rsa.pub [USER]@[REMOTE_SERVER] ssh-copy-id "[USER]@[REMOTE_SERVER] -p [PORT]"  # if on a different port

Extract Public Key from Private Key
ssh-keygen -y # enter private key filename when asked ssh-rsa AAA.....AAA my-key-pair

ssh-keygen -y -f private.pem

References:
 * Amazon EC2 Key Pairs - Amazon Elastic Compute Cloud - http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html

Key Location
Default Location: ~/.ssh/id_rsa   # ver 2 ~/.ssh/id_dsa   # ver 2 ~/.ssh/identity # ver 1

Specify alternate location: ssh -i [PATH_TO_KEY] user@host

Setting the default ssh key location - Stack Overflow - http://stackoverflow.com/questions/84096/setting-the-default-ssh-key-location

Method #1: add the keys from the non-standard location to the agent ssh-agent ssh-add /path/to/where/keys/really/are/id_rsa

Method #2: ~/.ssh/config file (man ssh_config to find other config options) IdentityFile ~/.foo/identity

Host * IdentityFile ~/.foo/identity

Method #3: alias: alias ssh="ssh -i /path/to/private_key"

SSH v1
Generate your skey (on connecting host): ssh-keygen

Append your public key to the ~/.ssh/authorized_keys file in the remote machine: ssh user@remote test -d \~/.ssh \|\| mkdir \~/.ssh \; cat \>\> \~/.ssh/authorized_keys <~/.ssh/id_rsa.pub

You can also use "ssh-copy-id" for this task.

Reference: ssh without password:

Full Reference: with Keys HOWTO

SSH v2
Generate your skey (on connecting host): ssh-keygen -t rsa ssh-keygen -t dsa

Copy public key to server: scp .ssh/id_rsa.pub kenneth@server:~/ scp kenneth@server.com mkdir .ssh ; chmod 700 .ssh touch .ssh/authorized_keys2 ; chmod 600 .ssh/authorized_keys2 cat id_rsa.pub >> .ssh/authorized_keys2 ssh -2 -v kenneth@server
 * 1) copy to server
 * 1) connect to server
 * 1) create and set permissions
 * 1) copy to authorized
 * 1) test force version 2 with verbose

Reference: SSH with Keys in a console window

Full Reference: with Keys HOWTO

SSH Keys Example
ssh-keygen -t rsa1
 * One time only make yourself an SSH1 key with no passphrase.

This command makes two files: ~/.ssh/identity and ~/.ssh/identity.pub. cat ~/.ssh/identity.pub >> ~/.ssh/authorized_keys
 * Append your public identity to your autorized keys list.

chmod go-rwx .ssh chmod go-rwx .ssh/authorized_keys
 * Set permissions so nobody else can access these files (except root)

command="cvs server" 1024 
 * Edit ~/.ssh/authorized_keys by prepending command="cvs server" plus one space at the front of the top line so it looks like:

NOTE: If you trust the superusers, you don't need to do this step, and SSH and all associated commands (sftp, scp, cvs, etc) will never ask you for a password. Your choice. cvs -d :ext: @denali.cse.nau.edu:/research/cvsroot/ checkout 
 * Copy the ~/.ssh/identity file to each client you want to run cvs commands from.

on the client when you want to check out code.
 * You don't need ~/.ssh/identity. Delete it if you don't want to copy it to other computers.

NOTE:As long as ~/.ssh/identity exists on remote computers, SSH uses it by default, and will let you run CVS commands without entering a password.

(Notes from: http://ccl.cens.nau.edu/CCL/Help/cvs.html)

Convert an ssh2 public key to openssh format
Convert SSH2 key to OpenSSH key: ssh-keygen -i -f ~/.ssh/id_dsa_1024_a.pub > ~/.ssh/id_dsa_1024_a_openssh.pub ssh-keygen -i -f [SSH2_KEY_FILE] >> authorized_keys

Convert OpenSSH key to SSH2 key ssh-keygen -e -f ~/.ssh/id_dsa.pub > ~/.ssh/id_dsa_ssh2.pub

—- BEGIN SSH2 PUBLIC KEY —- ... —- END SSH2 PUBLIC KEY — References:
 * Convert an ssh2 public key to openssh format | commandlinefu.com - http://www.commandlinefu.com/commands/view/155/convert-an-ssh2-public-key-to-openssh-format
 * SSH Public-Key Authentication HOWTO - https://hkn.eecs.berkeley.edu/~dhsu/ssh_public_key_howto.html
 * SSH: Convert OpenSSH to SSH2 and vise versa « //burnz.blog - http://burnz.wordpress.com/2007/12/14/ssh-convert-openssh-to-ssh2-and-vise-versa/

ssh_config
Several options can be set as default for a host by placing the host in your .ssh/config file: ~/.ssh/config

To create: touch ~/.ssh/config chmod 600 ~/.ssh/config

Example config: Host server1 HostName example.dyndns.org Port 12022 Host server2 HostName 192.168.1.15

This would allow you to connect using "ssh server1" and "ssh server2".

"These are just a few of the options that you can set in ssh's config file. You can also, for example, specify that X11 forwarding be enabled. You can set up local and remote port forwarding (i.e. ssh's -L and -R command line options, respectively). Take a look at the man page (man ssh_config) for more information on the available options.

One of the added benefits of using ssh's config file is that programs like scp, rsync, and rdiff-backup automatically pick up these options also and work just as you'd expect (hope)."

More information: man ssh_config

Source: Use ssh_config To Simplify Your Life | Linux Journal

SSH Key Forwarding
Start agent: ssh-agent /bin/bash ssh-add

Note: if you don't specify 'ssh-agent /bin/bash' you may get a "Could not open a connection to your authentication agent" error when you try ssh-add. 

Or tricky version: ssh-agent sh -c 'ssh-add < /dev/null && bash'

Forward agent through config /etc/ssh/ssh_config Host * ForwardAgent no

Forward agent through parameter: ssh -A user@server

Note: when you ssh into another server, and then want to ssh into yet another, make sure to forward the agent again if you will need to forward to yet another server.

References:
 * An Illustrated Guide to SSH Agent Forwarding - http://unixwiz.net/techtips/ssh-agent-forwarding.html
 * SSH and ssh-agent | Symantec Connect Community - http://www.symantec.com/connect/articles/ssh-and-ssh-agent
 * SSH public-key forwarding at Xaprb - http://www.xaprb.com/blog/2006/03/30/ssh-public-key-forwarding/

No Host Verification
/etc/ssh/ssh_config: StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel=ERROR
 * 1) to not prompt
 * 1) to not store keys
 * 1) do not display warnings

Via command line: ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no peter@192.168.0.100

Default: StrictHostKeyChecking ask
 * 1) StrictHostKeyChecking
 * 2) If this flag is set to "yes", ssh will never automatically add
 * 3) host keys to the $HOME/.ssh/known_hosts and
 * 4) $HOME/.ssh/known_hosts2 files, and refuses to connect to hosts
 * 5) whose host key has changed. This provides maximum protection
 * 6) against trojan horse attacks. However, it can be somewhat annoy-
 * 7) ing if you don"t have good /etc/ssh_known_hosts and
 * 8) /etc/ssh_known_hosts2 files installed and frequently connect to
 * 9) new hosts. This option forces the user to manually add all new
 * 10) hosts. If this flag is set to "no", ssh will automatically add
 * 11) new host keys to the user known hosts files. If this flag is set
 * 12) to "ask", new host keys will be added to the user known host
 * 13) files only after the user has confirmed that is what they really
 * 14) want to do, and ssh will refuse to connect to hosts whose host
 * 15) key has changed. The host keys of known hosts will be verified
 * 16) automatically in all cases. The argument must be "yes", "no"
 * 17) or "ask". The default is "ask".
 * 1) or "ask". The default is "ask".

If you want to supress all warnings (and errors, including could not resolve hostname): ssh -q ... ssh -o LogLevel=quiet ... alias ssh="ssh -o LogLevel=ERROR" # best

Or add to /etc/ssh/ssh_config: LogLevel=ERROR

For example, the following prints out the gcc version installed on machine.example.org (and no warning): ssh -o UserKnownHostsFile=/dev/null \ -o StrictHostKeyChecking=no \ -o LogLevel=quiet \ -i identity_file \ machine.example.org \ gcc -dumpversion

Or use this tricky wrapper script: remove="^Warning: Permanently added" # message to remove from output
 * 1) !/bin/bash

cmd=${0##*/}

case $cmd in ssh) binary=/usr/bin/ssh ;; *) echo "unsupported binary ($0)" exit ;; esac $binary "$@" 2>&1 | grep -v "$remove"

Keep Alive
ssh -o ServerAliveInterval=30 root@myhost

[--

It's possible that your server closes connections that are idle for too long. You can update either your client (ServerAliveInterval) or your server (ClientAliveInterval)

ServerAliveInterval Sets a timeout interval in seconds after which if no data has been received from the server, ssh(1) will send a message through the encrypted channel to request a response from the server. The default is 0, indicating that these messages will not be sent to        the server. This option applies to protocol version 2 only.

ClientAliveInterval Sets a timeout interval in seconds after which if no data has been received from the client, sshd(8) will send a message through the encrypted channel to request a response from the client. The default is 0, indicating that these messages will not be sent to the client. This option applies to protocol version 2 only.

To update your server (and restart your sshd)

echo "ClientAliveInterval 60" | sudo tee -a /etc/ssh/sshd_config

Or client-side:

echo "ServerAliveInterval 60" >> ~/.ssh/config

--]

Source: What does the Broken pipe message mean in an SSH session? - Unix and Linux - Stack Exchange - http://unix.stackexchange.com/questions/2010/what-does-the-broken-pipe-message-mean-in-an-ssh-session

sshpass
sshpass -p "password" scp -r user@example.com:/some/remote/path /some/local/path
 * 1) password in history:

sshpass -f "/path/to/passwordfile" scp -r user@example.com:/some/remote/path /some/local/path
 * 1) password not in bash history:

ref:

SSH-D Proxy
SSH SOCKS Proxy (DSOCKS)

Keey Proxy Alive
[--

It’s possible that your server closes connections that are idle for too long. You can update either your client (ServerAliveInterval) or your server (ClientAliveInterval).

To update your server (and restart your sshd)

echo "ClientAliveInterval 60" | sudo tee -a /etc/ssh/sshd_config

Or client-side:

echo "ServerAliveInterval 60" >> ~/.ssh/config

I wrote this shell script to automatically restart ssh as soon as it breaks down.


 * 1) !/bin/sh
 * 2) This is an SSH-D proxy with auto-reconnect on disconnect


 * 1) Created by Liang Sun on 28, Sep, 2011
 * 2) Email: i@liangsun.org

i=0 while test 1==1 do exist=`ps aux | grep ENTER.YOUR.IP.HERE | grep 9090` #echo $exist if test -n "$exist" then if test $i -eq 0 then echo "I'm alive since $(date)" fi               i=1 else i=0 echo "I died... God is bringing me back..." ssh p@ENTER.YOUR.IP.HERE -f -N -D 9090 fi       sleep 1 done

--]

Source: How to Solve Broken Pipe Message in SSH Session | Next Spaceship - http://nextspaceship.com/2011/09/how-to-solve-broken-pipe-message-in-ssh-session/

IPv6 is Default
When SSH tries to connect to anything, it will try to resolve the IPv6 address first. This is dumb. To force IPv4 as the default, add the following to /etc/ssh_config and /etc/sshd_config:

AddressFamily inet

You can also do this per connection with:

ssh -4 [HOST] # use IPv4 address ssh -6 [HOST] # use IPv6 address

References:
 * SSH and IPV6 - Keith's Personal Blog - http://keith.chaos-realm.net/archives/173-SSH-and-IPV6.html
 * IPv6-ready client programs (selection) - http://tldp.org/HOWTO/Linux+IPv6-HOWTO/x885.html
 * Disabling SSH Connections over ipv6 | Ubuntu Tutorials - http://ubuntu-tutorials.com/2008/01/12/disabling-ssh-connections-on-ipv6/

reverse mapping checking getaddrinfo for SERVER_NAME failed - POSSIBLE BREAK-IN ATTEMPT!
Solution:
 * Just add the SERVER_NAME and ip address to /etc/hosts
 * OR add host to DNS
 * OR add 'GSSAPIAuthentication no' to each server - painful

See http://www.electrictoolbox.com/reverse-mapping-possible-break-in-ssh/

Pseudo-terminal will not be allocated because stdin is not a terminal
Error:

Pseudo-terminal will not be allocated because stdin is not a terminal.

Solution:

The solution to use ssh command without using the console(tty) is to add -t -t option.

example: ssh -t -t -R 8080:127.0.0.1:80 root@192.168.1.1

The -t -t option is useful to execute ssh script in a crontab without error:

Pseudo-terminal will not be allocated because stdin is not a terminal.

References:
 * Pseudo-terminal will not be allocated because stdin is not a terminal. - The UNIX and Linux Forums - http://www.unix.com/unix-advanced-expert-users/26124-pseudo-terminal-will-not-allocated-because-stdin-not-terminal.html

Public keys not accepted on a Secure Linux server
If you have copied keys using ssh-copy-id, you may need to fix the Secure Linux permissions: restorecon -r -v ~/.ssh

keywords
ssh sshd secure shell