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 [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:
- 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
# 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
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
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#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:
- 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"
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:
- 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. [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:
- 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:
# 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
sshpass
# password in history: sshpass -p "password" scp -r user@example.com:/some/remote/path /some/local/path
# password not in bash history: sshpass -f "/path/to/passwordfile" scp -r user@example.com:/some/remote/path /some/local/path
ref: [8]
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:
- 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/
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:
- 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