Difference between revisions of "SSH - Client and Server"

From Blue-IT.org Wiki

(Download)
(ssh tunnel with port redirection)
 
(32 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
== clusterssh or tmux ==
 +
A way to update multiple clients in your network is clusterssh. Clusterssh normally uses an Xserver, a graphical UI to interact as a user. Ita usage is very intuitive and not further dicussed here, just use it.
 +
 +
Thankes to this [[https://www.christoph-egger.org/weblog/entry/33 article about using clusterssh in the shell]], the author user spawning the ssh sessions in separate "tmux" panes and using simple ssh. I altered the script using '''bash''', using variables with '''brackets''' (standard) and '''autossh''' instead of ssh (you also can use [[mosh]]).
 +
 +
'''Tmux''' is a terminal multiplexer - hey is'nt it fantastic, what marveless shell tools exist out there ;-)
 +
 +
Let's start:
 +
 +
1. Open a tmux session:
 +
tmux
 +
 +
2. Now you can execute the script shown in the next section INSIDE of tmux, it will open your serverlist
 +
ssh-tmux
 +
 +
The '''script''' attaching multiple server:
 +
#/bin/bash
 +
# ssh-tmux - need tmux
 +
#
 +
#######################################################################
 +
## EDIT HERE ##########################################################
 +
myHostList="hostname_or_ip_1 hostname_or_ip_2 hostname_or_ip_n"
 +
mySSH="autossh"
 +
mySession="ssh-tmux"
 +
 +
#######################################################################
 +
which tmux > /dev/null || echo "Please install tmux first! Exiting ..."
 +
which tmux > /dev/null || exit 1
 +
 +
if tmux has-session
 +
then
 +
echo "ssh-tmux session already opended"
 +
else
 +
TMUX= tmux new-session -d -s ssh-tmux
 +
tmux switch-client -t ssh-tmux
 +
fi
 +
 +
for myHost in ${myHostList}
 +
do
 +
  tmux splitw "$mySSH $myHost"
 +
  tmux select-layout tiled
 +
done
 +
tmux set-window-option synchronize-panes on
 +
 +
 +
The author updated his post:
 +
If you want to type in just one pane (on one host) you can do that as well:
 +
C-b : set-window-option synchronize-panes off and moving to the right pane (C-b + Arrow keys)
 +
 +
== ssh tunnel with port redirection ==
 +
 +
ssh -L 9000:IP_OF_SERVER:8443 loginname@IP_OF_SERVER
 +
 +
or
 +
autossh -L 9000:IP_OF_SERVER:8443 loginname@IP_OF_REMOTE_SERVER
 +
 +
... makes the port 8443 of a remote server with IP_OF_REMOTE_SERVER accessible on port 9000 on the local pc. This works with any kind of connection: console, webinterface and so on.
 +
 +
This often can be used to secure administration ports on a server, that should only be reached via a secure tunnel like e.g. VPN, but VPN is not avaiable everywhere.
 +
 +
If you also secure your ssh server only accepting certificate authentification, you will be almost secure:
 +
 +
#> vim /etc/ssh/sshd_config
 +
[...]
 +
PasswordAuthentication no
 +
[...]
 +
UsePAM no
 +
 +
== ssh tunnel over two servers ==
 +
* Source: http://dev.firegate.de/projects/public/wiki/SSH_Tunnel_%C3%BCber_zwei_Server
 +
Goal: From a local pc you like to access local-server on port 22000 via SFTP.
 +
 +
Problem: But local-server is only accessible from public-gateway.tld.
 +
 +
Solution:
 +
ssh username@public-gateway.tld -L localhost:22000:local-server:22 -l localusername -i /path/to/.ssh/gatewaykeyfile
 +
 +
== rsync ==
 +
=== Use rsync with special ssh port ===
 +
 +
You can add certain '''ssh-parameters''' with the ''-vraze'' option to rsync:
 +
 +
-vraze 'ssh -p xxxxx'
 +
 +
The  complete command then looks like this:
 +
rsync [ -av --delete ] -vraze 'ssh -p xxxxx' \
 +
      /local/source/. username@ssh-server:/target/.
 +
 +
Another method is to edit or create a '''ssh-config''' file in the ''.ssh'' directory and add the port and e.g. username there:
 +
 +
#> vim ~/.ssh/config
 +
 +
Host hostname_as_in_etc_hosts
 +
        port    4444
 +
        User    user_to_connect
 +
 +
=== Rsync "trick" for mirroring a certain location to server ===
 +
cd /to/the/very/long/path/on/localhost
 +
rsync -av . user@server:$(pwd)/.
 +
 +
where $(pwd) automacically expands to the correct path on the remote host.
 +
 +
If the path on the server does not exist, an error will occur - so you should care for this ;-)
 +
 +
=== Reduce bandwidth ===
 +
 +
To reduce the overall traffic bandwitch AND the system load, I start the rsync process on the server with '''ionice (perl based)''' and the rsync option '''--bwlimit=<KByteSec>'''. The ionice parameter '''-c3'''
 +
 +
sudo apt-get install liblinux-io-prio-perl
 +
 +
ionice -c 3 rsync -av --progress --bwlimit=5000 . teneriffa:/local_slow/mythtv/.
 +
 +
man ionice: -c
 +
The scheduling class. 0 for none, 1 for real time, 2 for best-effort, 3 for idle.
 +
 +
== SSH with unstable network access ==
 +
 +
* source: [http://www.linux-community.de/Internal/Artikel/Print-Artikel/LinuxUser/2012/08/SSH-ueber-unzuverlaessige-Leitungen SSH über unzuverlässige Leitung - LinuxUser Magazine]
 +
TCP/IP connections are reliable, but if there is an unstable od changing IP, it will break! Concerning a ssh connections a breaking wlan - e.g. when travelling in the train - will render your ssh session useless.
 +
 +
There are two programs which can help solve this problem:
 +
 +
* '''autossh''' in conjunction with '''screen'''
 +
* '''mosh'''
 +
 +
The following commandline will connect via ssh to ''remote-pc'' an starts  a screen-session. When the connection is lost, the ssh-tunnel will be build up by ''autossh''.
 +
autossh remote-pc -t 'screen -RD'
 +
 +
''Mosh'' works different. Why: three letters [http://web.mit.edu MIT] - from the best of the best IT-stuff ;-)
 +
* http://mosh.mit.edu/
 +
 +
It is more robust and trys to keep up the connection. Therefore ''mosh'' must be installed on the client AND the server.
 +
mosh [-p NUM] [user@]remote-pc
 +
 +
 +
=== mosh --ssh ===
 +
I had some problems connecting to some special ssh port. Using the following syntax made it run.
 +
mosh --ssh="ssh -pPORT" your_user@your_ip ***
 +
 +
In Ubuntu 12.04 to be able to use the "--ssh" paramater, please use the newer mosh version from the follwing ppa:
 +
 +
https://launchpad.net/~keithw/+archive/mosh
 +
 +
Ubuntu 13.04 and up are using the correct versions.
 +
 +
=== Working with .ssh/config ===
 +
If you don't like to always type in the credentials for a well known pc, you can simply add these to the file:
 +
 +
~/.ssh/config
 +
 +
Simply enter something like this:
 +
 +
Host IP_OF_YOUR_PC
 +
        port    <YOUR_SSH_PORT>
 +
        User    <USERNAME>
 +
 +
and the command
 +
ssh IP_OF_YOUR_PC
 +
 +
will simply login with the right connection credentials.
 +
 +
 +
 
== A little script to enable passwordless login==
 
== A little script to enable passwordless login==
 +
The same can be achieved using ''ssh-copy-id''!. But sometimes you need control over the process.
 +
 
Needless to say, that using this script you should '''exactly''' know what you are doing.
 
Needless to say, that using this script you should '''exactly''' know what you are doing.
  
Line 5: Line 170:
  
 
=== Download ===
 
=== Download ===
* [https://wiki.blue-it.org/images/Ssh_export_pub_key_for_passwordless_login.sh.zip /Ssh_export_pub_key_for_passwordless_login.sh.zip]
+
* [https://wiki.blue-it.org/images/Ssh_export_pub_key_for_passwordless_login.sh.zip Ssh_export_pub_key_for_passwordless_login.sh.zip]
  
 
=== Source Code ===
 
=== Source Code ===
Line 11: Line 176:
 
  #!/bin/bash
 
  #!/bin/bash
 
  #
 
  #
  cat <<EOF
+
  # This scripts exports THIS computers public ssh key to
---------------------------------------------------------------------
+
  # a clients's ~/.ssh/authorized_keys2 file.
This scripts exports THIS computers public ssh key to
+
  #
  a clients's ~/.ssh/authorized_keys2 file.
+
  # This will enable passworless login from THIS pc to the client.
   
+
  #
  This will enable passworless login from THIS pc to the client.
+
  # You need to have the password, username and IP/alias of the other pc.
   
 
  You need to specify at least the IP/alias of the other pc!
 
You optionally can specify another username than the actual one.
 
 
Usage: ssh_export ip_of_remote_client  [alternate_username]
 
---------------------------------------------------------------------
 
 
EOF
 
 
   
 
   
 
  client="$1"
 
  client="$1"
 
  NAME="$2"
 
  NAME="$2"
THIS_HOSTNAME="$HOSTNAME"
 
 
   
 
   
 
  [ "$NAME" ] || NAME="${USER}"
 
  [ "$NAME" ] || NAME="${USER}"
Line 36: Line 192:
 
  cd ~/.ssh
 
  cd ~/.ssh
 
   
 
   
  echo -n "* Check connection to client ... "
+
  echo "Create ssh dir on client ... "
if ping -c 1 $client > /dev/null
 
then
 
echo OK.
 
else
 
echo Please check the connection.
 
echo  - Aborting here.
 
exit 1
 
fi
 
 
echo "* Create ssh dir on client, if it not already exists ... "
 
 
  ssh ${NAME}@$client "mkdir -p ~/.ssh; chmod 700 ~/.ssh"
 
  ssh ${NAME}@$client "mkdir -p ~/.ssh; chmod 700 ~/.ssh"
 
   
 
   
  echo "* Check if a local pub key exist and/or create one ... "
+
  echo "Check if pub key exist and/or create one ... "
  PUB_KEY="id_dsa.pub"
+
  [ -e id_dsa.pub ] || ssh-keygen -t dsa  
if test -e $PUB_KEY
 
then
 
echo "  - A file named $PUB_KEY exists."
 
else
 
echo "  - Creating a new one."
 
ssh-keygen -t dsa  
 
fi
 
 
   
 
   
  echo "* Check, if an older key was exported already in former time to the client."
+
  echo "Copy the public key of THIS pc to the client ... "
if
 
        ssh ${client} "if (cat ~/.ssh/authorized_keys2 | grep ${NAME}@${THIS_HOSTNAME});\
 
                then echo  - WARNING: An older key was exported before to $client. \
 
\n  - Please fix manually.; exit 1; \
 
                fi";
 
then
 
        echo "  - Authorized keys file is clean."
 
else
 
echo "  - Aborting here."
 
exit 1
 
fi
 
 
echo "* Copy the public key of THIS pc to the client ... "
 
 
  scp id_dsa.pub ${NAME}@$client:~/.ssh/id_dsa.pub_${HOSTNAME}
 
  scp id_dsa.pub ${NAME}@$client:~/.ssh/id_dsa.pub_${HOSTNAME}
 
   
 
   
  echo "* We make an entry into the authorized_keys file on the client ... "
+
  echo "We make an entry into the authorized_keys file on the client ... "
  ssh ${NAME}@$client "cat ~/.ssh/id_dsa.pub_${HOSTNAME} >> ~/.ssh/authorized_keys2; \
+
  ssh ${NAME}@$client "cat ~/.ssh/id_dsa.pub_${HOSTNAME} \
     rm ~/.ssh/id_dsa.pub_${HOSTNAME};"
+
    >> ~/.ssh/authorized_keys2; \
 +
     rm ~/.ssh/id_dsa.pub_${HOSTNAME}"
 
   
 
   
  echo "* Secure the local public key ... "
+
  echo "Secure the local public key ... "
 
  chmod 600 id_dsa.pub
 
  chmod 600 id_dsa.pub
 
   
 
   
 +
echo TEST:
 +
echo Now we test with running the following terminal command:
 +
echo "  ssh ${NAME}@$client echo Congratulation: You can login passwordless to your client $client."
 
  echo ;
 
  echo ;
  echo "* LET'S TEST IT:"
+
  ssh ${NAME}@$client "echo Congratulation: You can login passwordless to your client $client."
echo "  Now we test with running the following terminal command."
 
echo "  You should NOT be prompted by a password."
 
echo ;
 
 
if
 
        ssh ${NAME}@$client "echo   - This is a message on $client."
 
then
 
        echo "  - Congratulation: If you was NOT promptd for a password,"
 
echo "    you can login passwordless to your client $client."
 
else
 
echo "  - WARNING: There was an error with the passwordless login to $client."
 
        exit 1
 
fi
 
 
   
 
   
 
  echo ;
 
  echo ;
 
  echo ;
 
  echo ;
  echo "** Program ended."
+
  echo Program ended.
 
  echo ;
 
  echo ;
 
  echo If you like to remove the automatic login, you have to  
 
  echo If you like to remove the automatic login, you have to  
 
  echo remove the public key in the file /home/${NAME}/.ssh/authorized_keys2
 
  echo remove the public key in the file /home/${NAME}/.ssh/authorized_keys2
 
  echo on your clients - $client - computer.
 
  echo on your clients - $client - computer.
 +
 +
 +
== Troubleshooting ==
 +
=== Authentification error 'authenticity ... can't be established' ===
 +
When connecting you get the following error:
 +
 +
$ ssh server
 +
The authenticity of host 'server (xxx.xxx.xxx.xxx)' can't be established.
 +
'''ECDSA key fingerprint is SHA256:hjlfaskdfadfah+lofadfgahjewzwetrewtrqwert/F.'''
 +
Are you sure you want to continue connecting (yes/no)? yes
 +
Failed to add the host to the list of known hosts (/home/USERNAME/.ssh/known_hosts).
 +
username@server's password:
 +
 +
Solution:
 +
ssh-keyscan -H server >> ~/.ssh/known_hosts
 +
 +
[[Category:Security]]
 +
[[Category:Network]]

Latest revision as of 15:55, 29 April 2017

clusterssh or tmux

A way to update multiple clients in your network is clusterssh. Clusterssh normally uses an Xserver, a graphical UI to interact as a user. Ita usage is very intuitive and not further dicussed here, just use it.

Thankes to this [article about using clusterssh in the shell], the author user spawning the ssh sessions in separate "tmux" panes and using simple ssh. I altered the script using bash, using variables with brackets (standard) and autossh instead of ssh (you also can use mosh).

Tmux is a terminal multiplexer - hey is'nt it fantastic, what marveless shell tools exist out there ;-)

Let's start:

1. Open a tmux session:

tmux

2. Now you can execute the script shown in the next section INSIDE of tmux, it will open your serverlist

ssh-tmux

The script attaching multiple server:

#/bin/bash
# ssh-tmux - need tmux
#
#######################################################################
## EDIT HERE ##########################################################
myHostList="hostname_or_ip_1 hostname_or_ip_2 hostname_or_ip_n"
mySSH="autossh"
mySession="ssh-tmux"

#######################################################################
which tmux > /dev/null || echo "Please install tmux first! Exiting ..."
which tmux > /dev/null || exit 1

if tmux has-session
then
	echo "ssh-tmux session already opended"
else
	TMUX= tmux new-session -d -s ssh-tmux
	tmux switch-client -t ssh-tmux
fi

for myHost in ${myHostList}
do
  tmux splitw "$mySSH $myHost"
  tmux select-layout tiled
done
tmux set-window-option synchronize-panes on


The author updated his post:

If you want to type in just one pane (on one host) you can do that as well: 
C-b : set-window-option synchronize-panes off and moving to the right pane (C-b + Arrow keys)

ssh tunnel with port redirection

ssh -L 9000:IP_OF_SERVER:8443 loginname@IP_OF_SERVER

or

autossh -L 9000:IP_OF_SERVER:8443 loginname@IP_OF_REMOTE_SERVER

... makes the port 8443 of a remote server with IP_OF_REMOTE_SERVER accessible on port 9000 on the local pc. This works with any kind of connection: console, webinterface and so on.

This often can be used to secure administration ports on a server, that should only be reached via a secure tunnel like e.g. VPN, but VPN is not avaiable everywhere.

If you also secure your ssh server only accepting certificate authentification, you will be almost secure:

#> vim /etc/ssh/sshd_config
[...]
PasswordAuthentication no
[...]
UsePAM no

ssh tunnel over two servers

Goal: From a local pc you like to access local-server on port 22000 via SFTP.

Problem: But local-server is only accessible from public-gateway.tld.

Solution:

ssh username@public-gateway.tld -L localhost:22000:local-server:22 -l localusername -i /path/to/.ssh/gatewaykeyfile

rsync

Use rsync with special ssh port

You can add certain ssh-parameters with the -vraze option to rsync:

-vraze 'ssh -p xxxxx'

The complete command then looks like this:

rsync [ -av --delete ] -vraze 'ssh -p xxxxx' \
     /local/source/. username@ssh-server:/target/.

Another method is to edit or create a ssh-config file in the .ssh directory and add the port and e.g. username there:

#> vim ~/.ssh/config

Host hostname_as_in_etc_hosts
       port    4444
       User    user_to_connect

Rsync "trick" for mirroring a certain location to server

cd /to/the/very/long/path/on/localhost
rsync -av . user@server:$(pwd)/.

where $(pwd) automacically expands to the correct path on the remote host.

If the path on the server does not exist, an error will occur - so you should care for this ;-)

Reduce bandwidth

To reduce the overall traffic bandwitch AND the system load, I start the rsync process on the server with ionice (perl based) and the rsync option --bwlimit=<KByteSec>. The ionice parameter -c3

sudo apt-get install liblinux-io-prio-perl
ionice -c 3 rsync -av --progress --bwlimit=5000 . teneriffa:/local_slow/mythtv/.
man ionice: -c
The scheduling class. 0 for none, 1 for real time, 2 for best-effort, 3 for idle.

SSH with unstable network access

TCP/IP connections are reliable, but if there is an unstable od changing IP, it will break! Concerning a ssh connections a breaking wlan - e.g. when travelling in the train - will render your ssh session useless.

There are two programs which can help solve this problem:

  • autossh in conjunction with screen
  • mosh

The following commandline will connect via ssh to remote-pc an starts a screen-session. When the connection is lost, the ssh-tunnel will be build up by autossh.

autossh remote-pc -t 'screen -RD'

Mosh works different. Why: three letters MIT - from the best of the best IT-stuff ;-)

It is more robust and trys to keep up the connection. Therefore mosh must be installed on the client AND the server.

mosh [-p NUM] [user@]remote-pc


mosh --ssh

I had some problems connecting to some special ssh port. Using the following syntax made it run.

mosh --ssh="ssh -pPORT" your_user@your_ip ***

In Ubuntu 12.04 to be able to use the "--ssh" paramater, please use the newer mosh version from the follwing ppa:

https://launchpad.net/~keithw/+archive/mosh

Ubuntu 13.04 and up are using the correct versions.

Working with .ssh/config

If you don't like to always type in the credentials for a well known pc, you can simply add these to the file:

~/.ssh/config

Simply enter something like this:

Host IP_OF_YOUR_PC
       port    <YOUR_SSH_PORT>
       User    <USERNAME>

and the command

ssh IP_OF_YOUR_PC

will simply login with the right connection credentials.


A little script to enable passwordless login

The same can be achieved using ssh-copy-id!. But sometimes you need control over the process.

Needless to say, that using this script you should exactly know what you are doing.

!! The author takes NO response for all kinds of damage and security issues that could happen using this script !!

Download

Source Code

#!/bin/bash
#
# This scripts exports THIS computers public ssh key to
# a clients's ~/.ssh/authorized_keys2 file.
#
# This will enable passworless login from THIS pc to the client.
#
# You need to have the password, username and IP/alias of the other pc.

client="$1"
NAME="$2"

[ "$NAME" ] || NAME="${USER}"
[ "$client" ]  || echo "ERROR: You have to specify at least a client IP or alias."
[ "$client" ]  || exit 1

cd ~/.ssh

echo "Create ssh dir on client ... "
ssh ${NAME}@$client "mkdir -p ~/.ssh; chmod 700 ~/.ssh"

echo "Check if pub key exist and/or create one ... "
[ -e id_dsa.pub ] || ssh-keygen -t dsa 

echo "Copy the public key of THIS pc to the client ... "
scp id_dsa.pub ${NAME}@$client:~/.ssh/id_dsa.pub_${HOSTNAME}

echo "We make an entry into the authorized_keys file on the client ... "
ssh ${NAME}@$client "cat ~/.ssh/id_dsa.pub_${HOSTNAME} \
   >> ~/.ssh/authorized_keys2; \
   rm ~/.ssh/id_dsa.pub_${HOSTNAME}"

echo "Secure the local public key ... "
chmod 600 id_dsa.pub

echo TEST:
echo Now we test with running the following terminal command:
echo "  ssh ${NAME}@$client echo Congratulation: You can login passwordless to your client $client."
echo ;
ssh ${NAME}@$client "echo Congratulation: You can login passwordless to your client $client."

echo ;
echo ;
echo Program ended.
echo ;
echo If you like to remove the automatic login, you have to 
echo remove the public key in the file /home/${NAME}/.ssh/authorized_keys2
echo on your clients - $client - computer.


Troubleshooting

Authentification error 'authenticity ... can't be established'

When connecting you get the following error:

$ ssh server
The authenticity of host 'server (xxx.xxx.xxx.xxx)' can't be established.
ECDSA key fingerprint is SHA256:hjlfaskdfadfah+lofadfgahjewzwetrewtrqwert/F.
Are you sure you want to continue connecting (yes/no)? yes
Failed to add the host to the list of known hosts (/home/USERNAME/.ssh/known_hosts).
username@server's password:

Solution:

ssh-keyscan -H server >> ~/.ssh/known_hosts