Linux/SSH

From Omnia
Jump to: navigation, search

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 [localport]:[server]:[serverport] [user]@[host]

# Forward local 8000 to remote VNC port
ssh -L 8000:localhost:5900 kenneth@t0e.org
ssh -L 8000:localhost:5900 -L 8001:localhost:5901 kenneth@t0e.org  # multiple forwards

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:

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

# ssh -R [bind_address:]port:host:hostport [user]@[host]
# Reverse forward port 8000 to local HTTP port
ssh -R *:8000:localhost:80 root@216.119.194.247

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 no
GatewayPorts yes

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

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).

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#SSH

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:

# /usr/bin/ssh-copy-id: ERROR: No identities found
ln -s id_rsa.pub ~/.ssh/identity.pub

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:

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"

Notes

"As there exists two version of the SSH protocol, version 1 and 2, the identities are tied to the protocol version. Most SSH-servers use version 2 of the protocol due to the limitations of version 1." [1]

Key Protocols:

Protocol	Type	Commandline
Version 1	RSA1	-t rsa1
Version 2	RSA	-t rsa
Version 2	DSA	-t dsa

Key Generation:

ssh-keygen -t dsa

Generated files: (~/.ssh/)

-rw-------   1 bob users   668 Jun 17 23:52 id_dsa
-rw-r--r--   1 bob users   602 Jun 17 23:52 id_dsa.pub

Copy public key to remote server:

ssh-copy-id -i ~/.ssh/id_dsa.pub username@remotebox

Alternate copy method: [2]

ssh server "mkdir .ssh; chmod 0700 .ssh"
$ scp .ssh/id_dsa.pub server:.ssh/authorized_keys2

Server configuration (/etc/ssh/sshd_config):

# Allow Identity Auth for SSH1?
RSAAuthentication yes

# Allow Identity Auth for SSH2?
PubkeyAuthentication yes

Change password on private key:

ssh-keygen -p -f ~/.ssh/id_dsa

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:

# copy to server
scp .ssh/id_rsa.pub kenneth@server:~/
# connect to server
scp kenneth@server.com

# create and set permissions
mkdir .ssh ; chmod 700 .ssh
touch .ssh/authorized_keys2 ; chmod 600 .ssh/authorized_keys2
# copy to authorized
cat id_rsa.pub >> .ssh/authorized_keys2

# test force version 2 with verbose
ssh -2 -v kenneth@server

Reference: SSH with Keys in a console window

Full Reference: with Keys HOWTO

SSH Keys Example

  • One time only make yourself an SSH1 key with no passphrase.
ssh-keygen -t rsa1

This command makes two files: ~/.ssh/identity and ~/.ssh/identity.pub.

  • Append your public identity to your autorized keys list.
cat ~/.ssh/identity.pub >> ~/.ssh/authorized_keys
  • Set permissions so nobody else can access these files (except root)
chmod go-rwx .ssh
chmod go-rwx .ssh/authorized_keys
  • Edit ~/.ssh/authorized_keys by prepending command="cvs server" plus one space at the front of the top line so it looks like:
command="cvs server" 1024 <rest-of-key>

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.

  • Copy the ~/.ssh/identity file to each client you want to run cvs commands from.
cvs -d :ext:<username>@denali.cse.nau.edu:/research/cvsroot/ checkout <repository-name>

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:

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. [3]

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:


No Host Verification

/etc/ssh/ssh_config:

# to not prompt
StrictHostKeyChecking no
# to not store keys
UserKnownHostsFile /dev/null
# do not display warnings
LogLevel=ERROR

Via command line:

ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no peter@192.168.0.100

Default:

####### StrictHostKeyChecking
#
# If this flag is set to "yes", ssh will never automatically add
# host keys to the $HOME/.ssh/known_hosts and
# $HOME/.ssh/known_hosts2 files, and refuses to connect to hosts
# whose host key has changed. This provides maximum protection
# against trojan horse attacks. However, it can be somewhat annoy-
# ing if you don"t have good /etc/ssh_known_hosts and
# /etc/ssh_known_hosts2 files installed and frequently connect to
# new hosts. This option forces the user to manually add all new
# hosts. If this flag is set to "no", ssh will automatically add
# new host keys to the user known hosts files. If this flag is set
# to "ask", new host keys will be added to the user known host
# files only after the user has confirmed that is what they really
# want to do, and ssh will refuse to connect to hosts whose host
# key has changed. The host keys of known hosts will be verified
# automatically in all cases. The argument must be "yes", "no"
# or "ask". The default is "ask".
#
StrictHostKeyChecking 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: [4] [5]

LogLevel=ERROR

For example, the following prints out the gcc version installed on machine.example.org (and no warning): [6]

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: [7]

#!/bin/bash
remove="^Warning: Permanently added" # message to remove from output

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

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.

#!/bin/sh
#This is an SSH-D proxy with auto-reconnect on disconnect

#Created by Liang Sun on 28, Sep, 2011
#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:

Issues

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:

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