SSH: Difference between revisions
Line 188: | Line 188: | ||
AcceptEnv LANG |
AcceptEnv LANG |
||
</source> |
</source> |
||
=== VPN over SSH === |
|||
SSH allows to setup a full VPN connection over SSH, although it requires some manipulations, and is slower than regular VPN solutions using UDP packets (VPN uses TCP packets, which are slower) . |
|||
References — with ''PermitRootLogin='''no''''': |
|||
* [http://nick.zoic.org/art/etc/ssh_tricks/ More Trickiness With SSH |
|||
** [http://nick.zoic.org/art/etc/ssh_tricks/comments.html] More Trickiness With SSH — Comments] |
|||
References — with ''PermitRootLogin='''yes''''': |
|||
* [https://help.ubuntu.com/community/SSH_VPN SSH_VPN] (rules to make the process automatic) |
|||
Other references: |
|||
* [http://ubuntuforums.org/showthread.php?t=12088 tun/tap on ubuntu] (creating tun device using OpenVPN) |
|||
* [http://manpages.ubuntu.com/manpages/precise/man8/tunctl.8.html tunctl manual pages] |
|||
* [http://manpages.ubuntu.com/manpages/precise/man1/ssh.1.html ssh manual pages] |
|||
'''Preliminary Setup''': |
|||
* First on the server side, ssh daemon must allow creating of tunnels. For this setup however you '''don't''' need to enable ''PermitRootLogin''. Edit <tt>/etc/ssh/sshd_config</tt>: |
|||
<source lang=diff> |
|||
+PermitTunnel yes |
|||
</source> |
|||
* Then install '''uml-utilities''' on both the client and the server: |
|||
<source lang=bash> |
|||
sudo apt-get install uml-utilities |
|||
</source> |
|||
'''Setting up the VPN''': |
|||
* Log on the server, and create the '''tap0''' interface with ''tunctl'', and configure the interface (note that we use interface name '''tap0''', and '''*not* tun0''' as indicated in ssh manpage): |
|||
<source lang=bash> |
|||
sudo tunctl -u $USER # Use '-t tap0' to set device name if needed |
|||
sudo ifconfig tap0 10.1.1.2 10.1.1.1 netmask 255.255.255.252 # This set 10.1.1.1 (client tap0 itf) as our gateway |
|||
sudo route add 10.0.50.0/24 10.1.1.1 # This will route all packets to 10.0.50.0/24 network through |
|||
# ... our tap0 interface directly to the client |
|||
</source> |
|||
* On the client, create the '''tap0''' interface, and setup the tunnel and route table: |
|||
<source lang=bash> |
|||
sudo tunctl -u $USER # Use '-t tap0' to set device name if needed |
|||
ssh -f -w 0:0 -o Tunnel=Ethernet $SSHSERVER true # SSH in backgroup, tunnel from tap0:tap0 |
|||
sudo ifconfig tap0 10.1.1.1 10.1.1.2 netmask 255.255.255.252 # This set 10.1.1.2 (server tap0 itf) as our gateway |
|||
sudo route add 10.0.99.0/24 10.1.1.2 # This will route all packets to 10.0.50.0/24 network through |
|||
# ... our tap0 interface directly to the server |
|||
</source> |
|||
Remarks: |
|||
* SSH manpage creates tun device with different ID, but this is only needed if ssh'ing to localhost. |
|||
* Use <code>-w any:any</code> to let ssh uses any available tun devices |
|||
* Using <code>-o Tunnel=Ethernet</code> is mandatory, or get a <tt>tunnel device open failed</tt> error. |
|||
* Enabling <code>PermitRootLogin</code> offers more flexibility. Security impact can be greatly reduced by restricting root ssh access to execute a forced command (see [http://bodhizazen.net/Tutorials/VPN-Over-SSH] as an example) |
Revision as of 21:56, 18 June 2012
Reference
On this Wiki:
Tips
On ssh command:
ssh -F hostname # Find hostname in ~/.ssh/known_hosts (useful if HashKnowHosts enabled)
ssh -l -f ~/.ssh/known_hosts # Print fingerprint of known host keys
ssh -Lport:host:hostport hostname sleep 60 # Forward port, and exit after 60s if no connection is made
ssh -f -N -n -q -L ${BINDADDR}:port:host:hostport hostname # Idem, with 'go backg', 'no remote cmd', 'redir stdin from /dev/nul', 'quiet'
If a script is to be called as a ssh command, use 1>&2 instead of >/dev/stderr to redirect a message to stderr (if not, you'll get an error undefined /dev/stderr):
#! /bin/bash
# This script is called as an ssh command with
# ssh hostname thisscript.sh
echo "This will go to stdin"
echo "This will go to stderr" 1>&2
Install
After installing ssh (client & server), you have to create an ssh-key:
ssh-keygen
Configuration
SSH can be configured through file ~/.ssh/config. See man ssh_config for more information. The format is as follows:
# Specific configuration options for host host1
Host host1
Option1 parameter
Option2 parameter
# General configuration options for all hosts.
# Options in this section applies if same option was *not already specified* in a relevant host section above.
Host *
Option1 parameter
Option2 parameter
The value to use for each option is given by the first section that matches the host specification and that provides a value for that option. So section Host * should always be at the end of the file, since any subsequent section will be ignored.
Connect through a Proxy
SSH can be said to establish the connection to the server through a proxy by using the option ProxyCommand
. Example of ProxyCommand in the SSH config file:
# none
ProxyCommand none # No proxy
# using nc
ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p # Example in ssh_config manpage but DOES NOT WORK
# using connect (or connect-proxy)
ProxyCommand /usr/bin/connect %h %p # No proxy as well
ProxyCommand /usr/bin/connect -H proxyserver:8080 %h %p # Using HTTP proxy proxyserver:8080
ProxyCommand /usr/bin/connect -h %h %p # Using HTTP proxy defined in env. var HTTP_PROXY
ProxyCommand /usr/bin/connect -S socks5server:1080 %h %p # Using SOCKS5 proxy server socks5server:1080
ProxyCommand /usr/bin/connect -s %h %p # Using SOCKS5 proxy defined in env. var SOCKS5_SERVER
ProxyCommand /usr/bin/connect -S socks4server:1080 -4 %h %p # Using SOCKS4 proxy server socks4server:1080
# Using socat
ProxyCommand socat -ly - PROXY:proxy:%h:%p,proxyport=8080,proxyauth=user:pass
# HTTP Proxy
ProxyCommand socat -ly - SOCKS4A:socksserver:%h:%p,socksport=1080,socksuser=user
# SOCKS4A proxy (%h is resolved by proxy)
# Using ssh-tunnel
ProxyCommand /usr/local/bin/ssh-tunnel.pl -f - - %h %p
If a hostname matches several sections, first match found is used. Use ProxyCommand none to override a default proxy configuration:
Host 192.*
ProxyCommand none # Otherwise setting in Host * would be taken
Host *
ProxyCommand /usr/local/bin/ssh-tunnel.pl -f - - %h %p # Default proxy settings
Dealing with Proxy Time-Out
In some case, the proxy might wait for the client (ie. local pc) to send an authentication string as it is the case in the SSL protocol. A solution for this is described in Yobi. It consists in sending immediately the client SSH banner, and strip it when it is sent by the client. The solution described uses a custom Perl script as ProxyCommand
: ssh-tunnel.pl.
ssh-tunnel
First install the following packages:
- ssh, libssl-dev (cygwin: openssh, openssl, openssl-devel)
Launch CPAN:
sudo cpan
# on first run, autoconfig starts - see wiki for more details
# Also if proxy must be set, run:
# o conf init urllist
# o conf commit
reload cpan
install Getopt::Long
install MIME::Base64
install Net::SSLeay
install IO::Socket::SSL
install Authen::NTLM
Then install ssh-tunnel (if needed, create ~/bin first and don't forget to add ~/bin in the path in .bashrc before /usr/bin and /usr/local/bin):
tar -xvzf ssh-tunnel-2.26.tgz
make install
#Create an empty ssh banner (will be updated at the first connection)
touch ~/.ssh/clbanner.txt
#Create the links
ln -s /usr/local/bin/ssh.pl ~/bin/ssh
Edit ~/.ssh/config and ~/.ssh/proxy.conf as needed.
Command-Line
Remote Command Execution
- SSH allows to execute any command on remote SSH host. The syntax is
ssh -t SSH_HOST COMMAND
- To execute a remote command on remote host and stay connected afterwards, use ssh -t, along with bash rcfile, like:
ssh -t SSH_HOST "bash --rcfile PATH_TO_RC_FILE"
Don't miss the quotes around the command. Bash will execute the commands in the rc file, and will open a session. Connection remains open because stdin/stdout is not closed. Option -t allows for connecting with current terminal. Without this option, there will be no terminal connection, so bash would run in batch mode (no prompt), and terminal features like tab completion or color would be missing.
- Another solution is to force bash interactive mode:
ssh SSH_HOST "bash --rcfile PATH_TO_RC_FILE -i"
Since there is no terminal, bash goes by default in non-interactive mode. Interactive mode is forced with option -i, and so prompt will be printed, etc. But this is only a partial solution because there is still no terminal, ie. no color, no TAB auto-completion.
Port Forwarding
Here two drawings that illustrate very clearly the mechanisms of port forwarding in SSH.
First the case of direct port forwarding, where a port is opened for listening on the (local) SSH Client, and forwarded to the given host and port on the remote side (i.e. accessible from SSH server).
Then the case of reverse port forwarding, where a port is opened for listening on the (remote) SSH Server, and forwarded to the given host and port locally (i.e. accessible from SSH client).
SSHFS
SSH FileSystem using FUSE.
References:
Install
sudo apt-get install sshfs
sudo gpasswd -a $USER fuse
Mount / Unmount
mkdir ~/far_projects
sshfs -o idmap=user $USER@far:/projects ~/far_projects
fusermount -u ~/far_projects
The idmap=user
option ensures that files owned by the remote user are owned by the local user. This is to deal with situations where these users have different UID. This option does not translate UIDs for other users.
/etc/fstab
Line to add to /etc/fstab:
sshfs#$USER@far:/projects /home/$USER/far_projects fuse defaults,idmap=user 0 0
Troubleshooting
Slow SSH connection setup
- DNS time-out on the server
Whenever a new client connects, the server does a reverse-DNS look-up. If the client IP can't be reversed, the SSH connection is suspended until DNS request times out.
FIX: Adds client IP and name in /etc/hosts
Missing Locale in Perl
When logging in from a client with different locale from the server, perl returns a warning about missing locale:
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = (unset),
LC_ALL = (unset),
LC_PAPER = "fr_BE.UTF-8",
...
LC_NAME = "fr_BE.UTF-8",
LANG = "en_US.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
- This is fixed by telling sshd not to accept locale env var. from the client. Edit /etc/ssh/sshd_config:
# AcceptEnv LANG LC_*
AcceptEnv LANG
VPN over SSH
SSH allows to setup a full VPN connection over SSH, although it requires some manipulations, and is slower than regular VPN solutions using UDP packets (VPN uses TCP packets, which are slower) .
References — with PermitRootLogin=no:
- [http://nick.zoic.org/art/etc/ssh_tricks/ More Trickiness With SSH
- [1] More Trickiness With SSH — Comments]
References — with PermitRootLogin=yes:
- SSH_VPN (rules to make the process automatic)
Other references:
- tun/tap on ubuntu (creating tun device using OpenVPN)
- tunctl manual pages
- ssh manual pages
Preliminary Setup:
- First on the server side, ssh daemon must allow creating of tunnels. For this setup however you don't need to enable PermitRootLogin. Edit /etc/ssh/sshd_config:
+PermitTunnel yes
- Then install uml-utilities on both the client and the server:
sudo apt-get install uml-utilities
Setting up the VPN:
- Log on the server, and create the tap0 interface with tunctl, and configure the interface (note that we use interface name tap0, and *not* tun0 as indicated in ssh manpage):
sudo tunctl -u $USER # Use '-t tap0' to set device name if needed
sudo ifconfig tap0 10.1.1.2 10.1.1.1 netmask 255.255.255.252 # This set 10.1.1.1 (client tap0 itf) as our gateway
sudo route add 10.0.50.0/24 10.1.1.1 # This will route all packets to 10.0.50.0/24 network through
# ... our tap0 interface directly to the client
- On the client, create the tap0 interface, and setup the tunnel and route table:
sudo tunctl -u $USER # Use '-t tap0' to set device name if needed
ssh -f -w 0:0 -o Tunnel=Ethernet $SSHSERVER true # SSH in backgroup, tunnel from tap0:tap0
sudo ifconfig tap0 10.1.1.1 10.1.1.2 netmask 255.255.255.252 # This set 10.1.1.2 (server tap0 itf) as our gateway
sudo route add 10.0.99.0/24 10.1.1.2 # This will route all packets to 10.0.50.0/24 network through
# ... our tap0 interface directly to the server
Remarks:
- SSH manpage creates tun device with different ID, but this is only needed if ssh'ing to localhost.
- Use
-w any:any
to let ssh uses any available tun devices - Using
-o Tunnel=Ethernet
is mandatory, or get a tunnel device open failed error. - Enabling
PermitRootLogin
offers more flexibility. Security impact can be greatly reduced by restricting root ssh access to execute a forced command (see [2] as an example)