Total Pageviews

Friday 31 July 2015

SSH tunnel以及ssh的16条技巧



Contents

simple port forwarding (SSH tunneling)

This example creates a tunnel for HTTP. This will forward port 80 of your localhost to port 80 of www.example.com.
ssh -f -N -q -L 80:localhost:80 username@www.example.com
This example creates a tunnel for IMAP. Here we forward port 1143 on localhost to 143 (IMAP) on imap.example.com.
ssh -f -N -q -L 1143:localhost:143 username@imap.example.com
  • -f tells ssh to go into the background (daemonize).
  • -N tells ssh that you don't want to run a remote command. That is, you only want to forward ports.
  • -q tells ssh to be quiet
  • -L specifies the port forwarding

port forwarding through an intermediary

You can have the remote machine forward ports to a third machine. This is useful where your have your local machine outside a firewall; a visible machine on the DMZ; and a third machine invisible to the outside.
This creates a tunnel from your localhost port 81 to 192.168.1.69 port 80 through dmz.example.com. This lets you see the web server from outside a LAN.
ssh -f -N -q -L 81:192.168.1.69:80 username@dmz.example.com
This example creates a tunnel for IMAP. Here we forward port 1143 on localhost to 143 (IMAP) on 192.168.1.100 through dmz.example.com.
ssh -f -N -q -L 1143:192.168.1.100:143 username@dmz.example.com

reverse port forwarding

This is used in the following situation:
  • You have a server inside a private LAN that you want to connect to from the WAN outside.
  • You can't create a NAT and port forwarding on your firewall to map the machine to the outside.
  • You have a server outside that you can connect to from the server inside the LAN.
What this does is creates a connection from the server in the LAN to the server outside. Once that connection is established the server outside starts listening on port 2222. All connections to port 2222 are sent back to port 22 of the server in the LAN. Now you can leave this connection running in your office; go home and ssh to your proxy server at port 2222 and you will be connecting to your server inside the LAN on port 22.
ssh -f -N -q -R 2222:localhost:22 my_name@remote.example.com

tricky reverse forwarding

This allows a server on an internal LAN expose a service to the outside WAN. For example, I have a database server that will only accept connections from a specific development box. That dev box is inside the firewall. I want to connect to the database from outside the firewall.
ssh -t -L 5432:localhost:1999 my_name@firewall.example.com ssh -t db_server ssh -t -R 1999:127.0.0.1:5432 my_name@firewall

Using scp through a DMZ gateway to a machine behind a firewall using a tunnel

First you setup port forwarding through an intermediary. This forwards your localhost port 2222 to port 22 on 192.168.1.100. Remember, that 192.168.1.100 is not on your local network; 192.168.1.100 is on the LAN network shared with 208.77.188.166.
ssh -f -N -q -L 2222:192.168.1.100:22 user@208.77.188.166
scp -P 2222 transformers.avi user@localhost:.
A diagram might help. Remember, port 22 is the SSH server port on the 192.168.1.100 machine.
+---------------+        +----------------+        +----------------------+
|     your      |        |  remote DMZ    |        | server on remote LAN |
| local machine |        |    server      |        |    192.168.1.100     |
|               |        | 208.77.188.166 |        |                      |
|         2222:  >-------|                |-------> :22                   |
|               |        |\______________/|        |                      |
|               |        |                |        |                      |
+---------------+        +----------------+        +----------------------+

SOCKS5 with Firefox

Simple and secure web browsing. You can setup a tunnel as described above or you can use the following technique. This starts SSH on your localhost acting as a SOCKS proxy. Once you start SSH this way you can point any application that supports a SOCKS5 interface to this port. But these instructions will show what you need to do to get Firefox to proxy through SOCKS. Firefox supports SOCKS with no extra add-ons.
Start ssh an connection to a host that you want to proxy through. Use the -D option to specify a SOCKS5 port on your localhost. The port doesn't really matter. You just need to use the same port in your SOCKS client application.
ssh -D 9999 username@proxy.example.com
In Firefox select "Edit | Preferences | Advanced Tab | Connection Settings button". Then select "Manual proxy configuration". All you need to fill out is "SOCKS Host: Localhost", "Port: 9999", then select "SOCKS v5". It's easy.
Image:Firefox_socks_settings.png
This tool can also help in switching the proxy settings on and off: SwitchProxy Tool
from http://www.noah.org/wiki/SSH_tunnel
---------------------------------------------------------------------------------------------------------

Getting started with SSH

The following sections hope to provide enough information to setup a user new to ssh with the appropriate files necessary for accessing remote hosts in a secure manner. Improvements to and comments about this document are welcome.
Updated: The examples now show ssh version 2 commands, using OpenSSH. There are several security vulnerabilities in protocol version 1. Everyone should have already migrated to version 2 by now, so it was about time for me to also reflect best practises in this document. I also updated the link section at the end of the document to better reflect today’s software selection.
(21.7.2004)

Contents


About public key cryptography

Public key cryptography uses a public key to encrypt data and a private key to decrypt it. The name public keycomes from the fact that you can make the encryption key public without compromising the secrecy of the data or the decryption key.
What this means is that it is safe to send your public key (i.e. the contents of the ~/.ssh/id_rsa.pub file) in electronic mail or by other means e.g. to have a system administrator of a remote site install that key into your~/.ssh/authorized_keys file. For anyone to actually gain access they need the corresponding private key (i.e. the decrypted contents of ~/.ssh/id_rsa) to identify themselves.
To further protect your private key you should enter a passphrase to encrypt the key when it is stored in the filesystem. This will prevent people from using it even if they gain access to your files.

Creating your authentication key

The very first step is to use ssh-keygen to create an authentication key for yourself. In most cases the defaults for this command are what you want.
Always, always, type in a good pass-phrase when prompted for one. It can be multiple words (i.e. spaces are just fine within the phrase), so you could choose a sentence that you can remember. Changing some of the words by misspelling them or by changing some of the letters into digits is highly recommended to increase the strength of your pass phrase.
Here is a sample session, your input is in bold. Note that the pass-phrase is not echoed back as you type it.
  beowulf% ssh-keygen -t rsa
  Generating public/private rsa key pair.
  Enter file in which to save the key (/u/kim/.ssh/id_rsa): [RETURN]
  Enter passphrase (empty for no passphrase): 1amp jumb3d
  Enter same passphrase again: 1amp jumb3d
  Your identification has been saved in /u/kim/.ssh/id_rsa.
  Your public key has been saved in /u/kim/.ssh/id_rsa.pub.
  The key fingerprint is:
  b7:18:ad:3b:0b:50:5c:e1:da:2d:6f:5b:65:82:94:c5 kim@beowulf.gw.com
If you have multiple accounts you might want to create a separate key on each of them. I have separate keys for
  • my office environment
  • my private systems
  • my Internet service provider (ISP) systems
  • my university account
This allows me to limit access between these organizations, e.g. not allowing the university account to access my ISP account or the machines in the office. This enhances the overall security in case any of the authentication keys are compromised for some reason.

Changing your pass-phrase

You can change the pass-phrase at any time by using the -p option of ssh-keygen.
  beowulf% ssh-keygen -p
  Enter file in which the key is (/u/kim/.ssh/id_rsa): [RETURN]
  Enter old passphrase: 1amp jumb3d
  Key has comment '/u/kim/.ssh/id_rsa'
  Enter new passphrase (empty for no passphrase): cow 3ats grass
  Enter same passphrase again: cow 3ats grass
  Your identification has been saved with the new passphrase.
The pass-phrases are not echoed as you type them.

Authorizing access

To allow access to a system for a given identity place the public key in your ~/.ssh/authorized_keys file on that system. All keys listed in that file are allowed access.
Usually you will want to authorize access to the local system using the local key (especially in an environment where multiple systems share the same home directory e.g. using NFS). Thus a good start is to copy the public key for your default identity into the ~/.ssh/authorized_keys file.
  beowulf% cd ~/.ssh
  beowulf% cp id_rsa.pub authorized_keys
You could now copy the ~/.ssh/authorized_keys file to other systems to allow access from the local system. One way to copy the file is to use the scp command, like this:
  beowulf% scp -p ~/.ssh/authorized_keys hrothgar:.ssh/
  kim@hrothgar's password: YourPasswordHere
  authorized_keys               100% 1839     1.2MB/s   00:00
As no identities have been authorized yet on the remote system, you will be asked for your regular login password as seen above. It will not be echoed as you type it. The Copying files between systems section has more information about scp.
Use a text editor to add more keys to the file. If you use cut and paste to copy the key make sure each key entry isa single line in the file. The keys to add are always the public keys (from files with the .pub extension).
NOTE: To gain access to restricted systems you might need to send your public key in electronic mail to the administrator of the system. Just include the contents of the ~/.ssh/id_rsa.pub file in the message.

Directory and file permissions

If access to the remote system is still denied you should check the permissions of the following files on it:
  • the home directory itself
  • the ~/.ssh directory
  • the ~/.ssh/authorized_keys file
The permissions should allow writing only by you (the owner). This example shows the most relaxed permissions you could use.
  hrothgar% cd
  hrothgar% ls -ld . .ssh .ssh/authorized_keys
  drwxr-xr-x 36 kim kim 4096 Jul 25 02:24 .
  drwxr-xr-x  2 kim kim  512 Apr 10 02:30 .ssh
  -rw-r--r--  1 kim kim 1674 Apr 10 02:29 .ssh/authorized_keys
To make the remote system allow access you must change the permissions to disallow writing by others than the owner.
  hrothgar% cd
  hrothgar% chmod go-w . .ssh .ssh/authorized_keys
Remember to do this on all the systems you want to have access to.

Logging into remote systems

To establish an interactive connection to a remote system you would use either the slogin or the ssh command. The only parameter is the name of the remote system. The pass-phrase is not echoed back to you when you type it.
  beowulf% slogin hrothgar
  Enter passphrase for key '/u/kim/.ssh/id_rsa': 1amp jumb3d
  Last login: Wed Jul 21 00:00:49 2004 from beowulf.gw.com
  [more output from the remote machine]
  hrothgar%
You can avoid the pass-phrase prompts by keeping the authentication keys in memory. You only need to type the pass-phrase when you add a key into memory.
If your account name on the remote system differs from the one on the local system (the system you are connecting from) you can use the -l switch to specify the remote account name.
  beowulf% slogin -l suominen panix.com
  Last login: Sun Jun 13 14:55:17 2004 from beowulf.gw.com
  [more output from the remote machine]
  panix%
You can change the default remote account name by creating a configuration file entry for the host.

Keeping authentication keys in memory

If you frequently open connections to remote systems you can run your session under the ssh-agent. The agent will provide decrypted authentication keys to all the commands when new connections are created.
When you start ssh-agent you need to provide it a command to spawn. This is usually either your shell or a command to start a windowing environment. When you exit the command all keys will be removed from memory.
  beowulf% ssh-agent $SHELL
  beowulf%
You will now need to add keys into memory to have them available for other commands.

Running X on a local display

If you have workstation where you start the X window system after logging in you can have the whole windowing environment benefit from the keys in memory. The X window system is normally started with startx and the initial clients are in your ~/.xinitrc file.
  beowulf% ssh-agent startx &
If your workstation has virtual consoles it is good to put the X window system in the background so the current virtual console can still be used for more commands if necessary. It won’t hurt to background the command even without virtual consoles.
NOTE: Your system might have a non-standard way of starting the X window system. Replace startx with the appropriate command if necessary. Please ask your system administrator for the exact command to use.

Running X with an xdm session

If you use an X-terminal or your workstation is running xdm you need to arrange for the clients to run under ssh-agent. The easiest way (which is conveniently compatible with the method used without xdm) is to put all initial clients into the ~/.xinitrc file which in turn is called from the ~/.xsession file.
An example ~/.xsession file is below. It runs ssh-agent only if you have a ~/.ssh directory.
  #!/bin/sh
  if [ -d $HOME/.ssh ]
  then EXEC="exec ssh-agent"
  else EXEC="exec"
  fi
  if [ -x $HOME/.xinitrc ]
  then $EXEC $HOME/.xinitrc
  else $EXEC xterm -geometry 80x24+0-60 -ls
  fi
Make sure the files are executable. The following command will change the permissions suitably.
  beowulf% chmod a+x ~/.xinitrc ~/.xsession
NOTE: If you are using an X-terminal keep in mind that your session is most likely not secure. Usually anything you type can be captured on the local area network you are connected to.

Managing keys in memory

Before your connections can be authenticated without prompts for a pass-phrase you have to use ssh-add to add the necessary keys to memory. To add the default key on the current system to memory no options are needed. The pass-phrase is prompted for to decrypt the key. It is not echoed back as you type it.
  beowulf% ssh-add
  Enter passphrase for /u/kim/.ssh/id_rsa: 1amp jumb3d
  Identity added: /u/kim/.ssh/id_rsa (/u/kim/.ssh/id_rsa)
You can specify the file that contains the key if you have other identities than the default. You must use the privatekey file (the one that does not have the .pub extension).
The -d option will have the key deleted from memory. There is no ssh-delete command.
  beowulf% ssh-add -d ~/.ssh/isp
To list all keys currently in memory use the -l option.
  beowulf% ssh-add -l
  1024 [hex numbers] /u/kim/.ssh/id_rsa (RSA)
  1024 [hex numbers] /u/kim/.ssh/isp (RSA)
You can delete all keys from memory at once with the -D option.
  beowulf% ssh-add -D
This is useful if you have added keys into memory on remote systems and don’t want to reconnect just to delete the keys.

Running commands on remote systems

The ssh command can also be used to run commands on remote systems without logging in. The output of the command is displayed and control returns to the local system. Here is an example which will display all the users logged in on the remote system.
  beowulf% ssh hrothgar who
  christos ttyp8    Oct 17 20:42  (milou)
  beowulf%
If you are using the X Window System you can use this capability to start a terminal window to start an interactive session on the remote system.
  beowulf% ssh -n hrothgar xterm &
  [1] 15866
  beowulf%
Use the -n to prevent the remote system from trying to read from the terminal starting the xterm and put the processin the background. A new window from the remote system should appear shortly on your display.

Copying files between systems

You can copy files from the local system to a remote system or vice versa, or even between two remote systems using the scp command. To specify a file on a remote system simply prefix it with the name of the remote host followed by a colon.
If you leave off the filename of the copy or specify a directory only the name of the source file will be used. An easy way of retrieving a copy of a remote file into the current directory while keeping the name of the source file is to use a single dot as the destination.
  beowulf% scp -p hrothgar:aliases .
  beowulf%
The -p option is not required. It indicates that the modification and access times as well as modes of the source file should be preserved on the copy. This is usually desirable.
You can copy several files in a single command if the destination is a directory.
  beowulf% scp -p hrothgar:.login hrothgar:.logout panix.com:.
  beowulf%
Relative filenames resolve differently on the local system than on the remote system. On the local system the current directory is assumed (as usual with all commands). On the remote system the command runs in the home directory! Thus relative filenames will be relative to the home directory of the remote account.
NOTE: When you specify remote machines in both the source and the destination the connection to copy the files is made directly between those hosts. The files are not copied through the local system. Sometimes this makes a difference in a firewalled or otherwise restricted environment.

Changing default settings

The defaults for the ssh-related commands can be altered for each account in a configuration file ~/.ssh/config(there is also a system-wide file, usually /etc/ssh/ssh_config). Each entry starts with a Host keyword. You can use wildcards to match all the appropriate systems:
  • ? matches any single character
  • * matches any sequence of zero or more characters
Usual keywords include (defaults in parenthesis):
Compression yes/no (no)
Controls whether compression is used on the connection.
CompressionLevel 1-9 (6)
Level of compression: 1 is fastest, 9 is slowest (achieves best compression). Compression is good for slow links (saves bandwidth) and fast machines.
FallBackToRsh yes/no (yes)
If a secure connection to the remote system cannot be established the commands can try unsecure connections (a warning will be displayed if this happens). On highly secure systems this could be disabled in the system-wide configuration.
KeepAlive yes/no (yes)
Controls whether TCP keepalive messages are used. When enabled it is possible to detect network outages and automatically close your connections (which is good). However, if you are connected over a dialup link that automatically dials when there is traffic, you will want to turn this off to avoid unnecessarily bringing up the line.
User account (local account)
Specify the remote account name. Add this to avoid having to use the -l option when issuing commands.
Here is an example ~/.ssh/config file.
  Host *panix.com
    User suominen
    Compression no

  Host *gw.com
    FallBackToRsh no

  Host *
    Compression yes
    CompressionLevel 9
    FallBackToRsh yes
    KeepAlive no
Options are accumulated over entries, but a more specific entry will override a less specific one. E.g. in the above compression will not be used for hosts that match *panix.com but will be used for hosts that match *gw.com (and all other hosts since the * entry matches all hosts).
For a complete list of options please refer to the manual pages of both ssh and sshd.

Sources of more information

  • OpenSSH is a free ssh suite implementation for Unix-like systems, under a BSD license.
  • The OpenSSH FAQ answers common questions on obtaining and using the OpenSSH suite.
  • LSH is a free ssh suite implementation under a GNU license (protocol version 2 only).
  • PuTTY is a free ssh client suite for 32-bit Windows platforms, under an MIT-license (BSD-like).
  • WinSCP is an open source sftp and scp client for Windows with a drag-and-drop interface.
  • NiftyTelnet SSH is a free ssh terminal client for MacOS. It also supports scp.
  • SSH Communications Security offers commercial implementations of ssh.
  • The Secure Shell FAQ anwers questions on obtaining and using the commercial version.
from http://kimmo.suominen.com/docs/ssh/


Proxy through SSH

Accessing an HTTP proxy using SSH tunneling
Accessing resources on an intranet can sometimes be problematic. Using SSH tunneling to access an HTTP proxy server is a simple and quick solution. The connection over the Internet will be secured by the SSH encryption, and the proxy will be able to access servers on your behalf and deliver the content to your browser, or other software that can use an HTTP proxy.
In this example we are using the following software:

PuTTY Configuration

Enter the name of the host that you connect to normally (e.g. beowulf.gw.com) and select the SSH protocol. Go through the settings and choose your preferences. You probably want to pay attention at least to the following:
  • Window: number of rows, scrollback size
  • Appearance: cursor type, font
  • Colours: text and background colors
I find the defaults in PuTTY well chosen, so if you are in a hurry you can probably ignore most of the categories right now. If a particular behaviour is getting to you later, you can always return to the configuration options and chances are that you can adjust everything to your liking.
If you make many changes and plan to add multiple sessions (hosts) then you should first save all your choices in the Default Settings without a host name. After the defaults are set you can continue with adding sessions to specific hosts.

SSH Settings

There is one very important setting to adjust: you should choose SSH protocol version 2. The default is still version 1, which unfortunately is insecure. Even more unfortunate is that there is no fix to make version 1 secure, so you should just never use it.
You should also disable the Blowfish encryption cipher. It is buggy on some SSH server versions, and can cause strange misbehaviour if it ever gets selected in the negotiation between PuTTY and your server.
Select the SSH category, then find Blowfish in the list of ciphers. By default it is the second best choice PuTTY will pick. Click on it, and then click Down until it is below the warning indicator.
You should make sure you save these two changes in the Default Settings so they will be used for all new sessions. All settings up to this point can be used in all sessions without the sessions interfering with each other.

Proxy Tunnel

The connection to the proxy is realized using SSH port forwarding. PuTTY will listen to the local port that is forwarded. When it accepts an incoming connection, it will ask the remote SSH server to open an outgoing connection to the proxy. It will then forward all traffic from these connections inside the encrypted SSH connection between PuTTY and the SSH server.
Only one program can listen to each local port simultaneously. What this means is:
  • You can only forward the same port number to one proxy, and from a single instance of PuTTY at the same time.
  • You can only forward port numbers that are not used by other programs on your computer (e.g. by Windows).
To avoid ports important to the operating system, select a port number above 1023. Common choices are ports used by proxy servers:
  • 3128: the default port for Squid proxy servers
  • 8080: the default port for Microsoft ISA proxy servers
Enter the selected port (e.g. 3128) in the Source port field. This is the port number you will use later in the browser configuration. (Make a note!)
The proxy server name and its port number are entered in the Destination field, separated by a colon (e.g.proxy:3128). Make sure to leave the Local button selected, to indicate that the source port is on your machine.
Once you click on Add the setting will be displayed in the Forwarded ports listbox. Don’t forget to go back to theSession settings to Save your changes, including the forwarded port.

Internet Options

Whenever you are connected using a session with the port forwarding enabled, you can configure your web browser to use the forwarded port as its proxy.
A forwarded connection will work just like a normal proxy server connection. If your proxy asks for a password, it will ask for it using the forwarded connection as well. The proxy server will see all proxy requests as originating from the SSH server, as opposed to the client machine. Therefore the SSH server must be allowed to use the proxy for you to be able to use a forwarded connection through it.
The proxy configuration is done in the Internet Options applet. It can be started from the Control Panel, or from theTools menu of an already running browser. Select the Connections tab and click on LAN Settings.

LAN Settings

Clear all check boxes in the Automatic configuration section to make sure the manual settings are used.
Fill in the Proxy server section. The address is 127.0.0.1 (usually also known as localhost — the numeric form is always guaranteed to work). The port is the local port number selected earlier as the forwarded port (e.g. 3128 —check that note you made).
Click OK twice (once on each open dialogue) and you are ready to browse using the forwarded proxy connection!
If there are servers that the proxy cannot access, the LAN Settings dialogue provides two quick fixes that may help:
  • Bypass proxy server for local addresses: This means the proxy won’t be used for addresses where the server name does not have a dot (e.g. http://www/).
  • Exceptions: You can list exceptions in the Advanced settings to avoid using the proxy for selected domains or IP addresses (e.g. *.mydomain.com; 10.*.*.*; 192.168.*.*)
from http://kimmo.suominen.com/docs/proxy-through-ssh/
--------------------------------------------------------
SSH的 Port Forwarding —— Remote Forwarding

简介
SSH的的Port Forward,中文可以称为端口转发,是SSH的一项非常重要的功能。它可以建立一条安全的SSH通道,并把任意的TCP连接放到这条通道中。本文仔细 讨论SSH的这种非常有用的功能, 上文已经介绍了Port Forward的Local Forward功能,这篇将要介绍是的Remote Forward功能。
Remote Forward
所谓的Remote Forward,也就是远程转发,意思就转化Remote端,也就SSH服务器上的端口。首先我们要搞清楚,Remote Forward与Local Forward的区别在在哪里。什么时候用Remote Forward,什么时候用Local Forward,如果搞清楚这两个问题,你就可以说了解了SSH的Port Forward了。


机器A与SSH服务器B可以互相访问,SSH服务器与目标服器C可以互相访问,但是A不能与C互想访问。在机器A上把 一个本地端口,比如:2202,通过SSH服务器转发(Forward)到服务器C的21号端口。整个过程,相当于在原来并不相通的A和C之间建立了一个 从A机器2202端口到C机器21端口可以互相讯问的通道,所以SSH的Port Forward也叫做SSH Port Tunnels,非常形象。
接着来看看Remote Forward的情况:

办公室本地(local) 机器A,一般都在防火墙后面,防火墙一般让出不让进,所以机器A可以访问SSH服务器B,如果家里的机器C,开着的话,也可以访问机器C。但是服务器B和 机器C都没有办法直接访问机器A。而我们在家里有时希望能够SSH到办公室机器A。这种情况下,就要使用SSH的Remote Forward功能了。
机器A是本地(local)机器,也就是说在机器A运行SSH程序进行Port Remote Forward。

    方法1. 在机器A的~/.ssh/config文件中加入: Host home-with-tunnel
       Hostname ssh.b.com
       RemoteForward 2002:a:22
       User tom 然后运行: tom@a ]$ ssh home-with-tunnel
    tom@ssh.b.com's password: ********
    方法2. 使用SSH命令行参数: sptom@a ]$ ssh -N -f -R 2202:a:22 ssh.b.com -f使得SSH到服务器B后,就转入后台运行。
    -N使得连到SSH服务器B后,一直维持这个连接。
    -R是Remote Forward的参数选项
    2202是Remote服务器上,要被Forward的端口,这个端口将会被SSH程序绑定到这个连接上。
    a:22是我们希望联到的目标机器的名字或者IP,冒号后是希望连到目标机器的端口。端口22一般是SSH服务用的。

当我们完成上面任意一种方法以后,回到家中,当我们希望能从家里机器C,连到机器A时,我们只要先连到SSH服务器B上: tom@c ]$ ssh ssh.b.com
tom@ssh.b.com's password: ********
tom@ssh.b.com ]$ 因为SSH服务器上的端口2202已经被Remote Forward到a:22上了。所以 tom@ssh.b.com ]$ ssh -p 2202 localhost
tom@localhost's password:***********
tom@a] 可见,在机器A上运行SSH的Remote Forward,建立了一条,从机器C通向机器A的通道。正如图2中红线标示的一样。正是因为存在这样单向访问的网格,所以需要Remote Forward的功能存在。 机器C,通过访问服务器B的上已经被Forward的端口2202,与机器A进行交流。


具体流程如图所示:
    机器A,运行Remote Forward命令,建一个条机器A与SSH服务器的安全加密通道。
    然后,SSH程序在SSH服务器B上,绑定个端口,如:2202,并监听它。
    机器C,登陆到服务器B上,连接localhost的端口2202。 tom@c ]$ ssh ssh.b.com
    tom@ssh.b.com's password: *********
    tom@bssh.b.com ]$ ssh -p 2202 localhost 如图3,箭头2。
    SSH程序把端口2202监听到的数据经由,第一步建立的加密通道(图3中红色管道)传给机器A,如箭头3,4。
    最后由机器A,把数据转到目标机器上的指定端口,这里就是机器A本身的SSH端口22。

Remote Forward 端口的安全问题
当你在服务器B,打开一个监听端口,同样问题来了,这个端口,允许哪些机器来联接。SSH程序的默认设置是不允许除了本机外的IP使用这个端口。如果你想让别的机器也能连接这个端口,你需要在/etc/sshd_config文件中打开:GatewayPorts yes 选项。这是唯一的办法。
参考文献
    SSH Port Forwarding http://www.securityfocus.com/infocus/1816
-----------------------------------------------------------------------------------------------------------------

Port Forwarding Cheat Sheet

Remembering how to specify the kind of SSH Forward you want is sometimes tricky. Hopefully, the following table will make it a bit easier.

LocalForwards
Command Line Option-L local_listen_port:destination_host:destination_port
Configuration file entryLocalForward local_listen_port:destination_host:destination_port
local_listen_port is onSSH client loopback interface
destination_host is contacted fromSSH server host

RemoteForwards
Command Line Option-R remote_listen_port:destination_host:destination_port
Configuration file entryRemoteForward remote_listen_port:destination_host:destination_port
remote_listen_port is onSSH server loopback interface
destination_host is contacted fromSSH client host
Forwards can be confusing - we typically think of connections as being made up of four things - the local IP and port, and the remote IP and port. In the forward definition you create, you only have three things because the first port is always either the SSH client or server machine, and thus isn't specified.

Port Forward Security

Port forwards bind a port on either the ssh client (Local Forwards) or ssh server (Remote Forwards). With a default installation, the port will only be bound on the localhost interface, 127.0.0.1. This means that the tunnel is only available to someone on the machine where that port is listening.
In general, you don't want to allow other machines to contact your SSH tunnel so this is the correct setting. If you want to allow these ports to be available to any machine, then use one of the following:

 Command line optionConfiguration file option
LocalForwards-gGatewayPorts yes
(in ~/.ssh/config or /etc/ssh/ssh_config)
RemoteForwards(none available)GatewayPorts yes
(in /etc/sshd_config)
The other important thing you must remember is that the data connection is only encrypted inside the SSH connection. If your destination_host you specify is not localhost[6] then the portion of the connection that extends out of the tunnel is not encrypted.
We'll see how you can put further limits on port forwards in a future article, such as rejecting or limiting them based on the SSH Pubkeys/Identity that is used for authentication.

NOTES:
[4] Some POP server software offers SSL-encrypted POP, by negotiating SSL using STARTTLS on port 110, or wrapped entirely in SSL on port 995. For this example, however, let's assume you have a non-SSL aware POP server.
[5] Some POP servers support alternate authentication methods, such as S/Key or challenge response, which can keep your password from going across the network.
[6] Unsniffable options would be localhost, 127.0.0.1 (or any 127/8 address on most unix-like systems) or any local IP address - these should all go through the local machine's TCP/IP stack without hitting the network card at all, and thus would be as secure as the network stack itself.
View more articles by Brian Hatch on SecurityFocus.co

-------------------------------------------------------------------------------------

16条技巧让你更高效使用SSH


SSH有很多非常酷的特性,如何它是你每天的工作伴侣,那么我想你有必要了解以下16条高效使用SSH的秘籍,它们帮你节省的时间肯定会远远大于你用来配置它们的时间。
1. 多条连接共享
如果你需要在多个窗口中打开到同一个服务器的连接,而不想每次都输入用户名,密码,或是等待连接建立,那么你可以配置SSH的连接共享选项,在本地打开你的SSH配置文件,通常它们位于~/.ssh/config,然后添加下面2行:
ControlMaster auto
ControlPath /tmp/ssh_mux_%h_%p_%r
现在试试断开你与服务器的连接,并建立一条新连接,然后打开一个新窗口,再创建一条连接,你会发现,第二条连接几乎是在瞬间就建立好了。
Windows用户
如果你是Windows用户,很不幸,最流行的开源SSH客户端Putty并不支持这个特性,但是Windows上也有OpenSSH的实现,比如这个Copssh,如果你觉得下面的一些技巧对你很有帮助,或许你应该试试Copssh。
文件传输
连接共享不止可以帮助你共享多个SSH连接,如果你需要通过SFTP与服务器传输文件,你会发现,它们使用的依然是同一条连接,如果你使用的 Bash,你会发现,你甚至SSH甚至支持Tab对服务器端文件进行自动补全,共享连接选项对于那些需要借助SSH的工具,比如rsync,git等等也 同样有效。
2. 长连接
如果你发现自己每条需要连接同一个服务器无数次,那么长连接选项就是为你准备的:
ControlPersist 4h
现在你每次通过SSH与服务器建立连接之后,这条连接将被保持4个小时,即使在你退出服务器之后,这条连接依然可以重用,因此,在你下一次(4小时 之内)登录服务器时,你会发现连接以闪电般的速度建立完成,这个选项对于通过scp拷贝多个文件提速尤其明显,因为你不在需要为每个文件做单独的认证了。
3. 别再输入密码
如果你还在通过密码方式登录SSH,那么你或许应该试试SSH Keys,首先使用OpenSSH为自己声称一对密钥:
$ ssh-keygen
跟随指示,完成之后,你应该可以在你的.ssh目录下看到两个文件,id_rsa就是你的私钥,而id_ras.pub则是你的公钥,现在你需要将你的公钥拷贝到服务器上,如果你的系统有ssh-copy-id命令,拷贝会很简单:
$ ssh-copy-id smylers@compo.example.org
否则,你需要手动将你的公钥拷贝到服务器上的~/.ssh/authorized_keys文件中:
$ < ~/.ssh/id_rsa.pub ssh clegg.example.org 'mkdir -p .ssh; cat >> .ssh/authorized_keys; chmod go-w .ssh .ssh/authorized_keys'
现在试试重新连接到SSH服务器,或是拷贝文件,是不是已经不需要再输入密码了?
为Putty配置SSH Key
Putty也可以使用SSH Key,从Putty网站下载PuttyGen和Pageant,然后使用PuttyGen生成你的密钥,将公钥拷贝到服务器的'.ssh/authorized_keys'目录,然后运行Pageant,导入你的私钥,让它在后台运行,险隘你就可以使用Putty通过公钥直接登录服务器了,你可以在Putty手册的第8,9章了解关于这一特性的详细介绍。
4. 连接中转
有时候你可能需要从一个服务器连接另外一个服务器,比如在两个服务器之间直接传输数据,而不用通过本地电脑中转:
www1 $ scp -pr templates www2:$PWD
(顺便说一下,当你需要在两台服务器间拷贝文件时,$PWD变量时非常有用的),因为即使你已经在两台服务器上添加了你本地电脑的公钥,scp默认 仍然会提示你输入密码:这是因为你用来作为跳板的那台服务器上并没有你的私钥,所以,第二胎服务器会拒绝你的公钥,但是一定不要通过将你的私钥拷贝到中转 服务器上来解决这个问题,你可以使用agent forwarding来解决这个问题,只要在你的.ssh/config文件中加入下面这行代码就可以了:
ForwardAgent yes
或者是在Putty中勾上“Allow agent forwarding”选项,现在你的本地SSH就变成了第一台服务器的SSH代理,从第一台服务器在连接其它服务器就变和和在你本地一样简单,注意,如果要开启这个选项,前提是这个中间服务器值得你信任。
5. 省略主机名
输入服务器的完整主机名来建立一个新的SSH连接实在是太乏味无聊了,尤其是当你有一组拥有相同域名但是子域名不同的服务器需要管理时,比如下面这样:
* www1.example.com
* www2.example.com
* mail.example.com
* intranet.internal.example.com
* backup.internal.example.com
* dev.internal.example.com
或许你的网络已经配置了可以直接使用短域名,比如intranet,但是如果你的网络不支持,实际上你可以自己搞定这个问题,而不用求助网络管理员。
解决办法根据你用的操作系统而略有差异,下面是我的Ubuntu系统的配置:
prepend domain-search "internal.example.com", "example.com";
然后你需要重启网络:$ sudo restart network-manager
不同的系统,这两条命令可能会略有差异。
5. 主机别名
你也可以在你的SSH配置中直接定义主机别名,就像下面这样:
Host dev
    HostName dev.internal.example.com
你还可以使用通配符来进行分组:
Host dev intranet backup
    HostName %h.internal.example.com
Host www* mail
    HostName %h.example.com
在Putty中你可以为每个主机名保存单独的session,然后双击建立连接(但是它可能没办法支持通配符)。
7. 省去用户名
如果你在远程服务器上的用户名和你本地的用户名不同,你同样可以在SSH配置中进行设置:
Host www* mail
    HostName %h.example.com
    User simon
现在就算我的本地用户名是 smylers,我仍然可以这样连接我的服务器:
$ ssh www2
SSH会使用simon账户连接你的服务器,同样,Putty可以保存这个信息在你的session中。
8. 在服务器间跳转
有些时候,你可能没法直接连接到某台服务器,而需要使用一台中间服务器进行中转,这个过程也可以自动化。首先确保你已经为服务器配置了公钥访问,并开启了agent forwarding,现在你就可以通过2条命令来连接目标服务器,不会有任何提示输入:
$ ssh gateway
gateway $ ssh db
然后在你的本地SSH配置中,添加下面这条配置:
Host db
    HostName db.internal.example.com
    ProxyCommand ssh gateway netcat -q 600 %h %p
现在你就可以通过一条命令来直接连接目标服务器了:
$ ssh db
这里你可能会需要等待长一点的时间,因为SSH需要进行两次认证,,注意netcat也有可能被写成nc或者ncat或者前面还需要加上g,你需要检查你的中间服务器来确定实际的参数。
9. 突破网络封锁
有些时候,你使用的网络可能只开放了80端口,或者它们封锁了SSH端口(默认的22端口),这种情况下,你可以通过配置SSH服务器在80或者443端口进行监听来突破封锁,只需要编辑你的服务器的/etc/ssh/sshd_config文件:
Port 443
然后重启SSH服务器:
$ sudo reload ssh
当然这样做的前提是你的服务器没有使用HTTS服务,但是实际上你只需要设置一台服务器使用https端口就够了,你但你可以访问这台服务器,你就 可以使用我们前面提到的技术利用它作为跳板来访问其它服务器,但是记住,你需要提前配置好这台服务器(现在怎么样?),这样万一当你身处一个只能访问 Web的网络环境时,就可以省掉打电话让其他人帮你配置中间服务器的麻烦了。
10. 穿越Web代理
有些时候,你所在的网络不止封锁SSH端口,它们有可能更进一步,只让你通过Web代理来访问网络,幸运的是我们有一个叫做Corkscrew的程序可以通过Web代理在发送SSH数据。Corkscrew的使用非常简单,一般我都是在需要时搜索,然后直接下载,跟随网站上的指示,然后就搞定了,一般你需要这样一条配置:
ProxyCommand corkscrew proxy.example.org 8080 %h %p
11. 远程GUI
有时候通过本地的GUI程序来访问远程服务器的文件会非常有用,比如,编辑一副图片,或者查看一个PDF文件,或者只是简单的通过一个非命令行的编 辑器来修改代码,我发现GVim要比终端里的Vim更有用,因为我可以通过gvimopens打开一个新窗口来编辑文件,而用当前的SSH窗口继续执行其 它操作,不要要这样做,你需要先在你的SSH配置中开启一个叫做X forwarding的选项:
ForwardX11 yes
这个选项需要服务器配置才能起作用,服务器也需要开启X forwarding,你可以在服务器的/etc/ssh/sshd_config中添加下面这个命令:
X11Forwarding yes
同时你还需要确保安装了xauth,编辑器,图片查看器以及其它的你需要运行的图形化程序,这种方式只有在支持本地X服务器的操作提供才可以工 作,mac和Windows上都有免费的X Server,你可能需要花些时间配置它们,相比之下,切换到Linux相对会更容易一下。
12.本地操作远程文件
另一种让远程GUI程序显示在本地的替代方案就是让本地的GUI程序可以直接操作远程文件,你可以通过SSHFS来实现,只需要创建一个空目录,然后使用SSHFS将一个远程目录mount到这个目录就可以了:
$ mkdir gallery_src
$ sshfs dev:projects/gallery/src gallery_src
$ cd gallery_src
$ ls
现在你就可以使用任何你喜欢的本地程序来便捷这个目录中的文件了,它们看起来是在你的本地,但其实时远程服务器上的文件,你可以使用fusermount命令来unmount这些文件,不要担心记不住,它们就在sshfs手册的顶上:
$ cd ..
$ fusermount -u gallery_src
SSHFS可以在Linux和OSX上工作,Windows用户我目前还没找到什么好办法。
13. 通过Vim访问远程文件
Vim有一个内置的功能可以直接编辑远程文件,需要借助SCP URL:
$ gvim scp://dev/projects/gallery/src/templates/search.html.tt
这中方式明显不如SSHFS灵活,但是如果你只需要对远程服务器的1,2个文件进行编辑时,这条命令就要更灵活一些了,并且可以在Windows上你也可以这样做:
:help netrw-problems
14. 使用本地App连接远程服务器
有时可能有些服务,比如数据库或是Web服务器,它们运行在远程服务器上,但是如果有用方式可以直接从本地程序连接它们,那会非常有用,要做到这一 点,你需要用到端口转发(port forwarding),举个例子,如果你的服务器运行Postgres(并且只允许本地访问),那么你就可以在你的SSH配置中加入:
Host db
    LocalForward 5433 localhost:5432
现在当你连接你的SSH服务器时,它会在你本地电脑打开一个5433端口(我随便挑的),并将所有发送到这个端口的数据转发到服务器的5432端口 (Postgres的默认端口),然后,只要你和服务器建立了连接,你就可以通过5433端口来访问服务器的Postgres了。
$ ssh db
现在打开另外一个窗口,你就可以通过下面这条命令在本地连接你的Postgres数据库了:
$ psql -h localhost -p 5443 orders
如果你想要使用服务器不支持的图形化Postgres客户端时,这条命令会显得尤其有用:
$ pgadmin3 &
或者你有一个后台的Web服务器,你不希望直接通过Internet访问它,你也可以通过端口转发来访问它:
Host api
    LocalForward 8080 localhost:80
现在连接到服务器:
$ ssh api
然后将浏览器指向你选择的端口号:
$ firefox http://localhost:8080/
15. 减少延迟
如果每次连接服务器都意味着你需要等待几十秒而无所事事,那么你或许应该试试在你的SSH配置中加入下面这条:
GSSAPIAuthentication no
如果这条命令有效的话,你应该通知你的系统管理员让他在服务器上禁用这个选项,这样其他人就不用再分别添加这条配置到它们的本地配置了。
16. 加速连接
如果你确保你和某个服务器之间的连接是安全的(比如通过公司内网连接),那么你就可以通过选择arcfourencryption算法来让数据传输更快一些:
Host dev
    Ciphers arcfour
注意这个加速是以牺牲数据的“加密"性为代价的,所以如果你连接的是位于网上的服务器,千万不要打开这个选项,并且确保你是通过VPN建立的连接。
开始行动吧!
以上就是我收集的高效使用SSH的技巧合集了,如果你还有更多技巧想要分享,记得通过Smylers@cpan.org或是通过@Smylers2来和我联系。
现在就赶紧行动试试通过这些技巧来让你的SSH更有效率吧!

本文来自:SSH Can Do That? Productivity Tips for Working with Remote Servers
---------------------------------------------------------------------------------------------------------------

SSH Can Do That? Productivity Tips for Working with Remote Servers

SSH has many features which are helpful when working regularly with files on remote servers; together they can give a vast increase in productivity over the bare use of SSH. If you regularly use SSH, it’s worth spending a little time learning about these and configuring your environment to make your life easier.

This has been presented at presented at Yapc Europe 2011 in Riga and the Floss UK Spring 2012 Conference in Edinburgh. If you’d like me to come and talk about this at your user group or workplace, please get in touch.

Multiple Connections

Often it’s useful to have multiple connections to the same server, for example to edit a file, run some file-system commands, and view a log file all in different terminal windows. Except sometimes that can seem too much hassle, so we compromise and end up repeatedly cycling through quitting and restarting a few different commands in one window.

Fortunately OpenSSH has a feature which makes it much snappier to get another terminal on a server you’re already connected to: connection sharing. OpenSSH is the implementation of SSH that comes with many Unix-liked operating systems, including all the common Linux distributions and Mac OSX.

To enable connection sharing, edit (or create) your personal SSH config, which is stored in the file ~/.ssh/config, and add these lines:

ControlMaster auto
ControlPath /tmp/ssh_mux_%h_%p_%r
Then exit any existing SSH connections, and make a new connection to a server. Now in a second window, SSH to that same server. The second terminal prompt should appear almost instantaneously, and if you were prompted for a password on the first connection (which we need to sort out anyway ‒ keep reading ‒ but it's a convenient way of verifying this shared connection stuff) you won’t be on the second. An issue with connection sharing is that sometimes if the connection is abnormally terminated the ControlPath file doesn’t get deleted. Then when reconnecting OpenSSH spots the previous file, realizes that it isn’t current, so ignores it and makes a non-shared connection instead. A warning message like this is displayed:
ControlSocket /tmp/ssh_mux_dev_22_smylers already exists, disabling multiplexing
In such circumstances the only remedy I’ve found on seeing such a message is to exit the connection, rm the file, then connect again. Any tips for making this less tedious would be gratefully received.

What About Windows Users?

Some of these productivity features are specific to OpenSSH, so don’t work with other SSH clients, such as Putty. However, OpenSSH is available for Windows. If some of these OpenSSH tips sound useful to you, it may be worth giving OpenSSH for Windows a try (or indeed switching to a different operating system ...).

Copying Files

Shared connections aren’t just a boon with multiple terminal windows; they also make copying files to and from remote servers a breeze. If you SSH to a server and then use the scp command to copy a file to it, scp will make use of your existing SSH connection ‒ and in Bash you can even have Tab filename completion on remote files, with the Bash Completion package. Connections are also shared with rsync, git, and any other command which uses SSH for connection.

Repeated Connections

If you find yourself making multiple consecutive connections to the same server (you do something on a server, log out, and then a little later connect to it again) then enable persistent connections. This is simply one more line in your config (in addition to the two above for shared connections):
ControlPersist 4h
That will cause connections to hang around for 4 hours (or whatever time you specify) after you log out, ready to spring back into life if you request another connection to the same server during that time. Again, it really speeds up copying multiple files; a series of git push or scp commands doesn’t require authenticating with the server each time. ControlPersist requires OpenSSH 5.6 or newer.

Don’t Type Passwords

If currently you type a password when making an SSH connection, you can make connecting much more pleasant by setting up SSH keys. With keys you do get prompted for a pass phrase, but this happens only once per booting your computer, rather than on every connection. With OpenSSH generate yourself a private key with:
$ ssh-keygen
and follow the prompts. Do provide a pass phrase, so your private key is encrypted on disk. Then you need to copy the public part of your key to servers you wish to connect to. If your system has ssh-copy-id then it’s as simple as:
$ ssh-copy-id smylers@compo.example.org
Otherwise you need to do it manually:
  1. Find the public key. The output of ssh-keygen should say where this is, probably ~/.ssh/id_rsa.pub.
  2. On each of your remote servers insert the contents of that file into ~/.ssh/authorized_keys.
  3. Make sure that only your user can write to both the directory and file.
Something like this should work:
$ < ~/.ssh/id_rsa.pub ssh clegg.example.org 'mkdir -p .ssh; cat >> .ssh/authorized_keys; chmod go-w .ssh .ssh/authorized_keys'
Then you can SSH to servers, copy files, and commit code all without being hassled for passwords.

SSH Keys with Putty

Putty can do SSH keys too. Download PuttyGen and Pageant from the Putty website, use PuttyGen to generate a key, copy it to remote servers’ .ssh/authorized_keys as above, and then run Pageant. Introduce Pageant to your private key, and it will keep running in the background. Putty will spot this, and automatically use the key provided by Pageant instead of prompting you for a password. Full details are in chapters 8 and 9 of the Putty manual.

Don’t Type Full Hostnames

It’s tedious to have to type out full hostnames for servers. Typically a group of servers have hostnames which are subdomains of a particular domain name. For example you might have these servers:
  • www1.example.com
  • www2.example.com
  • mail.example.com
  • intranet.internal.example.com
  • backup.internal.example.com
  • dev.internal.example.com
Your network may be set up so that short names, such as intranet can be used to refer to them. If not, you may be able to do this yourself even without the co-operation of your local network admins. Exactly how to do this depends on your OS. Here’s what worked for me on a recent Ubuntu installation: editing /etc/dhcp/dhclient.conf, adding a line like this:
prepend domain-search "internal.example.com", "example.com";
and restarting networking:
$ sudo restart network-manager
The exact file to be tweaked and command for restarting networking seems to change with alarming frequency on OS upgrades, so you may need to do something slightly different.

Hostname Aliases

You can also define hostname aliases in your SSH config, though this can involve listing each hostname. For example:
Host dev
  HostName dev.internal.example.com
You can use wildcards to group similar hostnames, using %h in the fully qualified domain name:
Host dev intranet backup
  HostName %h.internal.example.com

Host www* mail
  HostName %h.example.com

In Putty you can save a separate session for each hostname, then double-click on it to start a connection to that server. (I don’t think there’s a way of using wildcards to specify hostname transformations though.)

Don’t Type Usernames

If your username on a remote server is different from your local username, specify this in your SSH config as well:

Host www* mail
  HostName %h.example.com
  User simon

Now even though my local username is smylers, I can just do:

$ ssh www2
and SSH will connect to the simon account on the server. Again, Putty users can save usernames in their session config to avoid being prompted on each connection.

Onward Connections

Sometimes it’s useful to connect from one remote server to another, particularly to transfer files between them without having to make a local copy and do the transfer in two stages, such as:
www1 $ scp -pr templates www2:$PWD
(Aside: note how useful $PWD is when copying between servers with common directory layouts.) Even if you have your public key installed on both servers, this will still prompt for a password by default: the connection is starting from the first remote server, which doesn’t have your private key to authenticate against the public key on the second server. Do not ‘fix’ this by copying your private key to remote servers; you don’t want to have copies of that stored on servers’ disks, and anyway it doesn’t help much cos you still need to provide a pass phrase to decrypt it. Instead use agent forwarding, with this line in your .ssh/config:
ForwardAgent yes
Or in Putty check the box ‘Allow agent forwarding’. Then your local SSH agent (which has prompted for your pass phrase and decoded the private key) is forwarded to the first server and can be used when making onward connections to other servers. Note you should only use agent forwarding if you trust the sys-admins of the intermediate server.

Resilient Connections

It can be irritating if a network blip terminates your SSH connections. OpenSSH can be told to ignore short outages (though this also means it takes longer to notice permanent outages). The precise numbers to use are a matter of preference, but putting something like this in your SSH config seems to work quite well:
TCPKeepAlive no
ServerAliveInterval 60
ServerAliveCountMax 10
If the network disappears your connection will hang, but if it then re-appears with 10 minutes it will resume working.

Restarting Connections

Sometimes your connection will completely end, for example if you suspend your computer overnight or take it somewhere there isn’t internet access. When you have connectivity again the connection needs to be restarted. AutoSSH can spot when connections have failed, and automatically restart them; it doesn’t do this if a connection has been closed by user request. The AutoSSH works as a drop-in replacement for ssh. This requires ServerAliveInterval and ServerAliveCountMax to be set in your SSH config, and (somewhat irritatingly) this environment variable in your shell config:
export AUTOSSH_PORT=0
Then you can type autossh instead of ssh to make a connection that will restart on failure. If you want this for all your connections you can avoid the extra typing by making AutoSSH be your ssh command. For example if you have a ~/bin/ directory in your path (and before the system-wide directories) you can do:
$ ln -s /usr/bin/autossh ~/bin/ssh
$ hash -r
Now simply typing ssh will give you AutoSSH behaviour. If you’re using a Debian-based system, including Ubuntu, you should probably instead link to this file, just in case you ever wish to use ssh’s -M option:
$ ln -s /usr/lib/autossh/autossh ~/bin/ssh
AutoSSH doesn’t cure the the issue mentioned above with stale ControlPath files (though it doesn’t make it any worse either).

Persistent Remote Processes

Sometimes you wish for a remote process to continue running even if the SSH connection is closed, and then to reconnect to the process later with another SSH connection. This could be to set off a task which will take a long time to run and where you’d like to log out and check back on it later. Or it could be to provide resilience against a flaky connection (or laptop battery), so if you get abruptly cut off in the middle of something you can pick it up later once you’ve regained access. Screen and Tmux provide such functionality along with their ability to switch between multiple shells in a single terminal. If you already like working with Screen or Tmux as a way of managing multiple local shells then obviously it makes sense to do that for remote shells too. But if you’re somebody who prefers to have a separate window or tab for each shell, then it makes sense to do that as well for remote shells (with connection sharing, of course). In which case Dtach may be of use; it provides the persistent detached processes feature from Screen, and only that feature. You can use it like this:
$ dtach -A tmp/mutt.dtach mutt
The first time you run that it will start up a new mutt process. If your connection dies (type Enter ~. to cause that to happen) Mutt will keep running. Reconnect to the server and run the above command a second time; it will spot that it’s already running, and switch to it. If you were partway through replying to an e-mail, you’ll be restored to precisely that point.

Jumping Through Servers

Sometimes you can’t make a network connection directly to the server you wish to access; you have to first SSH to an intermediate server and then on to the server you want. This can also be automated. First make sure that you have keys and agent forwarding set up so that you can SSH to the intermediate server in one command and from there to the target server in a second command, each without any prompting:
$ ssh gateway
gateway $ ssh db
Then in your local SSH config, specify that a connection to the target server should be proxied through the intermediate server, using the -W option:
Host db
  HostName db.internal.example.com
  ProxyCommand ssh gateway -W %h:%p

Then you can just do:

$ ssh db
And, after a brief pause while SSH chugs through authenticating twice, you’ll have a shell on the second server. The -W option was introduced in OpenSSH 5.4. If you have an older version you can achieve the same result with Netcat instead.

Escaping from Networks

Sometimes the problem is that you can’t SSH out of a network; you’ve been provided with web access but SSH is blocked. Or rather port 22, the default SSH port, is blocked. You can allow for this by configuring your SSH server to listen on port 80 or 443, which being web ports will be accessible from any network that provides web access. Edit /etc/ssh/sshd_config on a server, add this line:
Port 443
and restart the SSH server:
$ sudo reload ssh
Then when connecting from the restricted network specify the port number with -p, such as:
$ ssh -p 443 sid@cafe.example.net
If you need your server to be serving HTTPS web pages on port 443, you can have incoming SSH connections on that port as well: use sslh, a cunning piece of software which works out whether an incoming connection is HTTPS or SSH then forwards it appropriately. You only need to set up one server with SSH on port 443 on the internet; once you have SSHed there, you can make onward connections to port 22 on other servers as normal. And remember you need to set this up in advance: once you’ve found yourself on a network with only web access, you’re stuck unless you can contact somebody else with access to your SSH server to reconfigure it for you. So how about doing it right now?

Defeating Web Proxies

Sometimes not only does a network provide just web access, but to get even that you have to use a web proxy. Fortunately a program called Corkscrew can send SSH traffic through a web proxy. Corkscrew is really simple to use. Whenever I’ve needed it, I've searched the web for it, downloaded it, followed the instructions on its website, and it’s just worked. You (temporarily) use configuration like this:
ProxyCommand corkscrew proxy.example.com 8080 %h %p

Gui Applications and Remote Windows

It can be useful to run gui programs on files on remote servers. For example, to edit an image, or view a PDF file, or simply for editing code if your text editor of choice isn’t terminal based; I find GVim more usable than terminal Vim, and also like that running gvim opens a new window and frees up the shell prompt for typing further commands. This can be made to work over SSH too, using a feature call X forwarding. Enable it in your config:
ForwardX11 yes
This also requires the server to co-operate. It needs to allow X forwarding, enabled with this line in /etc/ssh/sshd_config (and a restart):
X11Forwarding yes
It also requires the xauth command installing, as well as the editor, image viewer, gui debugger, or any other graphical applications you wish to run. This works on Linux and any other operating systems with a local X server. X servers for Mac and Windows are available; Xming has been recommended to me for Windows (but I haven’t tried it). You may find that switching to using Linux is easier.

Operating on Remote Files Locally

An alternative to having remote gui applications display locally is to have local gui applications operate on remote files. This can be done with SSHFS. Simply create an empty directory then use sshfs to mount a remote directory there; specify a server and directory on that server, and your empty directory:
$ mkdir gallery_src
$ sshfs dev:projects/gallery/src gallery_src
$ cd gallery_src
$ ls
Then you can run any local applications on files in that directory. Well, files that appear to be in that directory; magic happens which makes them appear there whenever requested, but actually stored on the server. To unmount you need to use the fusermount command. Don’t worry if you find this hard to remember; the sshfs manual page includes it in the synopsis at the top.
$ cd ..
$ fusermount -u gallery_src
SSHFS works on Linux and OSX. Some Windows users have reported success with Dokan SSHFS, while others reckon ExpanDrive is worth paying for; I haven’t tried either of them personally.

Editing Remote Files with Vim

Vim has a built-in feature for editing remote files, using rsync URLs:
$ gvim rsync://dev/projects/gallery/src/templates/search.html.tt
If you only wish to edit a remote file or two this may be easier than setting up SSHFS. And it can be made to work on Windows. In Vim see:
:help netrw-problems

Editing Remote Files with Emacs

For Emacs users, the equivalent functionality is called Tramp. (I haven’t used it. (I know even less about Emacs than I do about Windows.))

Connecting to Remote Services with Local Apps

Sometimes there is a service, such as a database or a website, which is available on a remote server but it would be handy to connect to it from a local application. This can be achieved with port forwarding. You can either configure individual ports yourself, or use Sshuttle to forward all traffic on particular IP addresses. Each approach has advantages and disadvantages.

Forwarding Specific Ports

If you have a server called db which is running Postgres (and only allows access from the server itself), you can get access from your local computer with something like this in your SSH config:
Host db
  LocalForward 5433 localhost:5432

Then when you SSH to that server it sets up port 5433 (a number I just plucked out of thin air — there’s nothing special about it) on your computer to forward all traffic to port 5432 (the standard Postgres port) on the server, and that, so far as the server is concerned, the connection comes from localhost.

$ ssh db
So in another window (or after immediately exiting the shell created by the above command if you’re using persistent connections) you can connect to the DB with a local Postgres client:
$ psql -h localhost -p 5433 orders
This is especially handy if you wish to use a graphical DB client which isn’t available on the server:
$ pgadmin3 &
Or if you have a ‘back-end’ web server which isn’t directly accessible on the internet, you can forward it traffic from a local port:
Host api
  LocalForward 8080 localhost:80

Then SSH to the server:

$ ssh api

And point a local web browser at the port number you picked to view the server’s output:

$ firefox http://localhost:8080/

Setting Hostnames for Forwarded Connections

If a website is using name-based virtual hosting then simply forwarding traffic to the correct server and port will not be sufficient to view the site. You also need your browser to send the correct HTTP request for the domain name that the server knows the site as.

You could fake this in /etc/hosts, pretending that the site’s domain name is an alias of localhost. Then you can put the site’s real domain name (but still with your local port number) into your browser’s URL bar, and the correct HTTP header will be sent.

Doing this can be a little tedious; you may find using Sshuttle is less hassle for you.

Using Sshuttle to Forward Connections

Sshuttle provides VPN functionality, by forwarding traffic over SSH. For example, suppose there is a server called dev which you can SSH to, and which is on a private network which your local computer isn’t. You can set up the VPN connection with a command like this; you need local sudo privileges, and will be prompted for your password:

sshuttle -DHr dev 192.168.42.0/24

192.168.42.0/24 is the private network. Your computer can now make connections to an IP address in that range, and Sshuttle will forward them over the SSH connection to the dev server. You don’t have to think of every service which you might want forwarding and configure them all individually, then remember which port numbers you’ve used for what.

The -H flag tells Sshuttle tp configure hostnames for you too, automatically putting entries in /etc/hosts for hostnames that the remote server knows. This means you connect to a service using the same name as you would from the remote server, for example:

$ firefox http://api/

api will resolve to an address on the 192.168.42.* network, which will then get forwarded to the remote server.

Unfortunately this feature is limited to unqualified hostnames. If you need api.example.net in full to resolve, you still have to mess around with /etc/hosts yourself. (If you know of a way of making fully qualified domain names work automatically, I would be interested to hear from you.) In practice I often find myself configuring Apache at the far end to recognize both the short and long names.

The -D flag turns Sshuttle into a dæmon. This has the advantage of it not hogging a shell prompt, but does mean that closing the connection involves hunting around with ps to kill it if you ever wish to close the connection. (killall isn’t much use, because the process name is python, not sshuttle.) An alternative is not to use -D but simply to put the process in the background with &, so it can be listed with jobs and terminated with kill %sshut:

$ sudo -v && { sshuttle --syslog -Hr dev 192.168.42.0/24 & }

Well, perhaps not that simply. A background process can’t prompt for a sudo password, so it’s necessary to ensure sudo authentication has been performed (in a foreground process) before starting sshuttle in the background. And --syslog prevents warnings from littering your terminal. Together they make the full command rather unwieldy, but for servers you wish to do this with frequently you can hide that by saving it in a script or defining an alias.

Whether to use Sshuttle or forward individual ports depends on your circumstances and preferences. Sshuttle is often more convenient. Port forwarding defined in your SSH config has the advantage of being set up automatically whenever you make any SSH connection to the server; if you want a shell on a server and a Sshuttle VPN then you have to enter both ssh and sshuttle commands. And Sshuttle requires local root access, which may not be available or something you would prefer to avoid.

Avoiding Delays

If connecting to a server seems to sit there for a few seconds not doing anything, try adding this line to your config:

GSSAPIAuthentication no

GSSAPI is an authentication method related to Kerberos. If you don’t know what it is, you almost certainly aren’t using it. But some servers are configured to attempt GSSAPI authentication, and only try other methods after a 2-second time-out. By instructing your client never to use this authentication method, the attempt, and therefore the time-out, is skipped.

And if that speeds up connecting for you, ask the server’s sys-admin to disable it in the server config, for the benefit of all users ‒ exactly the same line as above, but in /etc/ssh/sshd_config.

Faster Connections

If you’re on a low-bandwidth internet connection then you can make SSH access faster by compressing the traffic: simply use the -C flag when connecting:

$ ssh -C wainwright

That will use gzip compression, reducing the number of bytes which are sent over the network. (But don’t do this all the time: on fast connections the overhead of zipping and unzipping costs more time than is saved.)

If you are connecting to a server across a network which is already secure (such as your internal office network) then you can make data transfer faster by choosing the arcfour encryption algorithm:

Host dev
  Ciphers arcfour

Note this speed-up is achieved by using less secure ‘encryption’, so do not do this for connections over the internet. Make sure you only specify it for particular hosts, not as the default. And only use it on a laptop (which of course can be used on multiple networks) for connections that go over a VPN.

Go and Do It!

The above are a collection of productivity tips for using SSH. If you have any more to share, please do get in touch on Smylers@cpan.org or to @Smylers2 on Twitter. (And this hasn’t been proofread yet, so corrections also welcome.)

Now go and use these features. Take a little bit of time now to get SSH set up nicely, and make working with remote servers easier for yourself.

Acknowledgements

Thank you to Aaron Crane, who as well as being my keyboard monkey during the talk also taught me much of what I know about SSH, some of which came from his Speeding up SSH Logins article; to Paul Knight for the tips about Vim’s remote editing feature and persistent connections; to Aristotle (@apag on Twitter) for telling me about the arcfour, ExpanDrive, Vim rsync URLs, Tramp, and Sshuttle; to Damien Miller for pointing out -W; to Roland Schmitz for telling me about sslh; to Joanathan Cormier for suggestion Dokan SSHFS; and to JS Vaughan for mentioning -C. Many small improvements have been made to this article in response to feedback, so thank you also to everybody else who has given feedback.

Thank you to Webfusion, my employer, for support in attending the conferences (and letting me practice this talk on colleagues).

And thank you to search engine DuckDuckGo for the T-shirt I wore when presenting this talk in Riga. If you haven’t tried DuckDuckGo, I recommend giving it a go as your first-choice search engine. It happens to be written in Perl, and the customer service (responding to requests and fixing reported bugs) is fantastic.

35 Comments

ControlPersist seems to be fairly recent. It's in Fedora 15 and Ubuntu 11.04 (OpenSSH_5.6p1), but not Fedora 14 (OpenSSH_5.5p1) or Ubuntu 10.04 LTS (OpenSSH_5.3p1).

Very useful list, thanks! But don't forget about SSH's tunneling capabilities. You can tunnel any number of services on various ports with the -L option, or use -R for reverse tunnels. Together with something like autossh, you have some very powerful options.

I like using autossh to persist and share ssh connections. see http://aaroncrane.co.uk/2008/04/ssh_faster/ for a good writeup.

I am running OpenSSH_5.8p2, OpenSSL 1.0.0d 8 Feb 2011 and it seems that the option AgentForwarding is called ForwardAgent there. but nice talk at YAPC::EU anyway!

When “jumping through servers”, instead of using netcat in your ProxyCommand, you can use ssh’s new “netcat” mode that connects a remote host:port to standard IO:

ProxyCommand ssh -W %h:%p gateway

I’d recommend arcfour256 instead of arcfour as the fast cipher, as the former has better cryptographic properties. The MAC that is used also contributes to speed, and the fastest MAC that OpenSSH supports is UMAC-64. The “fast” settings I’d recommend are therefore:

Host foo
  Ciphers arcfour256
  MACs umac-64@openssh.com

Note that UMAC-64 is AFAIK only supported by OpenSSH

  • For jumping through servers, a very nice solution where applicable is sshuttle.

  • For a SSHFS alternative on Windows, see ExpanDrive. Payware, and not terribly cheap, but at least it’s very nice. (There are some libre offerings, but they are all horribly half-baked.)

  • For remote Vim editing, try rsync:// instead of scp://. Drop-in replacement, much nicer with large files.

  • Emacs users, of course, have TRAMP.

Very useful tips. Its going to help a lot in improving productivity. Thanks for sharing!!

For multiple connection use screen utility - it is make many window in one ssh connection and (main feature) all your windows stay live after connections is broken, connect again, run screen -d -RR and see all your shell windows (this feature make possible run slow scripts and be sure that it is not crash after connection broke).

For user name and host use .ssh/config, for example if you add:

Host ex
HostName example.com
IdentityFile ~/.ssh/mykey
IdentitiesOnly yes
User mylongusername
Port 22

you can run ssh ex

Multiple connections is handy, but I can't seem to figure out how the remote server tab-completion works with SCP (OpenSSH on a mac).

Anybody have an idea?

Better than corkscrew, I highly recommend "socat" as my new favorite tool, completely replacing uses of "netcat" for me. You wouldn't believe the sideways connections I've set up with socat. I have many ssh recipes involving that.

And yes, I have an ssh on 443... works great, and never gets the traditional dictionary attacks that I had when I was on 22.

Thanks for this! Now pushing to github is much faster.

+1 on socat.

Great blog post.

Did you want to have a go at explaining the Subsystem sftp stuff? The traditional documentation is a bit turgid.

@Derek: Do you have bash running on both locations with tab completion?

For a very simple local x server, try xming.

For remote vim connections I prefer:

ssh -t remote vim /path/to/file

Just a matter of getting a tty (or pseudo-tty).

Being a Windows user at work, I renamed putty.exe to ssh.exe and copied it into the system32 directory. Then install pageant, make sure your domainname(s) are prepended, and that putty automatically uses your username, and you can access your servers by typing: Start-> Run-> ssh

Hi,

Nice post. I wrote a few ssh tricks on my own http://diogomelo.net/blog/10/ssh-tricks

you could add a brief (technically not ssh directly) usage of keychain, and potentially askpass to allow key authentication with pass-phrases to become easier. If you want.

Fantastic tricks. Efficiency of command line console and ssh made my work much much more productive and very well justifies my switch from Windows to Linux about a year ago. Age of this article does not harm it's validity, in fact, it shows, that some great stuff was burned into Linux DNA already some time ago. Thanks a lot for this article it.

thanks alot for this great resource! didnt know quite a few things listed here :)

Great article, so many useful tips for.

One small suggestion. I wouldn't recommend enabling ForwardAgent in your .ssh/config, since that could be a security risk if you connect to a malicious host. I would suggest that you use ssh -A when you need it, or enable ForwardAgent just for specific hosts.

I actually use WebDrive to do this, if anyone still happens to be looking for a reasonably-priced option. It is a bit less expensive than Expandrive (which I will admit I have never tried). But I've always had success with Webdrive and have been using it for years. www.webdrive.com

For persistent connections I find it better to use the %C token in ControlPath. It produces a shorter string, so will help get around some path length restrictions. Also, that really ought not to be a path in a world-readable place like /tmp!

How to bypass a proxy server with SSH

These steps will guide you on how to bypass a proxy server that may be blocking you from accessing that interesting web-site at work, school or wherever.

Please note that I do not make myself responsible for the usage of this. Use it at your own risk of getting fired or expelled from school. Main thing, use it with responsibility.

The steps of bypassing a web proxy are actually simple. This how to will enable you to even bypass socks proxies that need username and password, as long as they allow encrypted traffic over port 443 and/or 80.

You are going to need:
- A SSH server at the remote side (Windows or *nix)
- A proxy server at the remote side (I’m using squid, which can be installed either on a *nix or Windows box) which can be the same as the SSH server
- Port forwarding on you remote router (if applicable)
- Address for the local (blocking) proxy server (can be easily discovered by opening a web browser, running “netstat -a” and looking for a established connection on port 8080)
- Putty

I’ll lay it out in steps to make it easier:

1- Install Squid on the remote PC
Download and install squid (either the Windows version or *nix). Make sure you know what port is open and change if necessary (default is 3128).

Test it from another computer in the LAN or using 127.0.0.1:3128.

2- Install SSH server on the remote PC. Configure the listening port and configure a user if required. Test it to confirm that it’s working.

3- Configure port forwarding on your remote router to forward port we will use at your work (443 or 80) to the port the SSH server is listening to.

4- Download 
Putty.exe.
Now we need to configure it with all the required information for the connection.

4.1 Open putty and fill out the “Host name” with your remote IP (home) and the port you will be connecting to your router or directly to the PC with SSH installed (port 80, 443…)


4.2 On “Connection => Proxy” we need to enter the Proxy type, Proxy, Port, Username and Password. Remember that this information is for the proxy that we are trying to bypass
- Proxy type - Could be HTTP, SOCKS 4, SOCKS 5
- Proxy hostname - IP or hostname of the proxy
- Port - Port used to connect to the proxy (remember the netstat command)
- Username - Username that you usually input into IE when accessing the web
- Password - Password you usually input into IE when accessing the web


4.3 Open “Connection => SSH => Tunnels” and enter the following rules.


- Source port - Port you are going to use on your browser (I use 80)
- Destination:port - LAN IP address of the Squid server and port that is listening to. If you are using one server as SSH and another as Squid, this must be the IP of the Squid server. Now if you are using the Squid server and the SSH in one PC, you need to do a loopback into the port that squid is listening to. Eg: 127.0.0.1:80


5 Configure your web-browser to send requests to the source port we configured on the previous step. I have downloaded a different browser (Opera) that I use to bypass the proxy.


That’s it. You should now be able to access the blocked pages when putty is open and connected.

Process Explanation:
1- Browser sends a request to 127.0.0.1:80 (your PC)
2- Putty listens to the request and binds local port 80 to remote address 127.0.0.1 on port 80
3- Putty connects to the proxy and authenticates using username and password
4- Proxy connects to address and port we configured on step 4.1 (your remote address)
5- Your router accepts the request and forwards it to the port the SSH server is listening to
6- A putty terminal window opens and asks for username and password for SSH server
7- SSH server authenticates username and password and binds configuration from step 2
8- Squid sends requests to the Internet and replies back to tunnel


All this process is encrypted starting from step 2, so local proxy is not aware of any of the information sent over the tunnel.

There are also another 2 things that you might want to add for security and flexibility.

=> Security
- Use a USB pen to store an RSA key, which can be used for authentication with your SSH server. You can them configure your SSH server to only accept connections if the key is provided.

There are many how to’s on the Internet that show you how to do this. 
This one is a good tutorial for RSA and putty.

- You can also CHROOT you SSH user. 
This is a good tutorial for Ubuntu.

- If you decide to use CHROOT you can also limit WAN connections only for that limited CHROOT user. Take a look 
here.

=> Flexibility
- As you are using a USB pen, your configurations will be saved to the registry, and not your pen. You will have to reconfigure putty every time you connect to a different computer.

A good idea would be to use a batch file that loads your configuration when you open putty, and deletes it when you close the connection, so no one has access to it. Check 
this link.

from http://wazem.blogspot.com/2007/06/how-to-bypass-proxy-server-with-ssh.html