Created Tuesday 22/8/2006
To hop over a firewall you can setup a redirection via ssh like so: (assumes that you have ssh access on port 22 from a machine inside the firewall to a machine outside, see proxy piercing in proxy):
bash $ ssh -R 2222:localhost:22 user@outside.com
bash $ ssh -p 2222 user@localhost
The first ssh configures the redirected tunnel on port 2222 and the second uses that tunnel to login back into the machine with behind the firewall
Many proxy firewalls restrict outbound traffic to http. Proxy piercing software like corkscrew can be used to drill straight through the proxy firewall (See #2.A in proxy)
Note: inside $ means a host inside a proxy firewall outside $ means a host outside a proxy firewall
Warning: It is important to set the local-side ssh port number as the number on which the local-side ssh daemon is listening (e.g., -R2225:localhost:22) if sshd is listing on 22 on the host from where the reverse tunnel is being created.
Warning: It is important to clear out the ~/.ssh/known_hosts if port forwarding back to localhost
First create a reverse tunnel so that it becomes possible to loop back in (pick any non-privileged port, e.g., 2225):
inside $ ssh -R2225:localhost:22 user@outside
After creating the reverse tunnel, it becomes possible to locally forward (on outside) any (non privileged) port back to inside (in addition to simply being able to ssh). In this example, i'm forwarding 8008 on localhost (which will be outside) back to port 80 on inside, we have to ssh over the reverse tunnelling port we chose before (i.e., over 2225):
outside $ ssh -p 2225 -L 8008:localhost:80 user@localhost
Two things have happened here:
inside (we can tell ssh not to open a shell if that's important)localhost:8008 on outside will tunnel back over port 2225 and on to port 80 on inside
Warning: Forwarding to a privileged port requires relevant privileges on the final host
Imagine that inside is a host sitting behind a proxy firewall. Imagine also that outsideserver is a host serving, perhaps http, via apache. Further imagine that outsideserver is only accessible via outsideintermediate. In this case we can tunnel from inside through to outsideserver via a series of ssh tunnels:
inside to outsideintermediate. This will be the port that we connect to on inside. We choose port 9999outsideintermediate to outsideserver over the same port as chosen in the preceeding step (i.e., 9999).outsideserver to localhost from 9999 to port 80
E.g.,
inside $ ssh -L9999:localhost:9999 user@outsideintermediate outsideintermediate $ ssh -L9999:localhost:9999 foo@outsideserver outsideserver $ sudo ssh -L9999:localhost:80 foo@localhost
Then on inside, executing something like
wget http://localhost:9999/index.html
The preceeding wget(1) will hop the firewall over 9999 to outsideintermediate and then bounce on over to outsideserver on 9999 to be punted to port 80 (on outsideserver)
The tcpd server uses /etc/hosts.allow and /etc/hosts.deny to decide which hosts are allowed access to local INET services. The format of the file is pretty simple, with one record per line. Each line specifies a service keyword like "in.tftpd:" or "ALL:" and a list of allowed hosts. The allowed hosts entry can include the "EXCEPT" keyword (self explanatory) and the "LOCAL" keyword (matches any host on the local network). Netgroups can be specified with the syntax such as @my_netgroup
This is a simple policy that defaults to denying all hosts except those explicitly listed in hosts.alow. For example, to deny all servces to all hosts except ok.host.com
bash $ cat /etc/hosts.deny
ALL: ALL
bash $ cat /etc/hosts.allow
ALL: ok.host.com
This is the reverse of the mostly closed policy (2.B) above. In this case, services are open to all hosts, except those stated in the deny file. For example, to prohibit all services to evil.com
bash $ cat /etc/hosts.deny ALL: evil.com
bash $ cat /etc/hosts.allow ALL: ALL
An entry like this, for example, will allow connections to sshd from any source address:
bash $ cat /etc/hosts.allow sshd sshd1 sshd2 : ALL : ALLOW
A nice way to debug ssh connections is to start the ssh daemon (sshd) in single connect mode, with debug turned on. This starts up the ssh daemon and starts it listening for connections, printing debug and connect info to stderr as it goes. After a single ssh connection is attempted, the daemon exits, regardless of the success or not of the connection. Make sure any currenly active ssh daemons are terminated and then exec the full path to sshd(1), like so:
bash # /etc/init.d/sshd stop bash # /usr/sbin/sshd -d -d
SSH works well with a certificate with private key and the ssh-agent running. In this configuration, the ssh daemon will authenticate with the agent when the connection is established. If the agent holds a valid certificate (for which the user is already authenticated) then connection is established without bothering the user for their passphrase. SSH can use different certificates types such as dsa, however an rsa is preferred.
See public key authentication with ssh tutorial
Creating an rsa certificate can be done in a number of ways. The simplest is to use the ssh-keygen script provided with openssh. In it's default form, the ssh-keygen creates the RSA certificate with private key in id_rsa and the RSA public key in id_rsa.pub. The keygen script will ask for an output directory, which defaults to ~/.ssh.
bash $ ssh-keygen
The ssh-agent is the certificate management component of openssh. The agent is typically started by many xwindowing environments but is not necessarily running. The agent must be running in order for ssh to operate in authenticated mode. In this mode, ssh connections are established without asking the user for a passphrase, if the required certificate is already authenticate and being held with the agent.
To start the agent, eval(1) the ssh-agent script provided with openssh:
bash $ eval $(ssh-agent) SSH_AUTH_SOCK=/tmp/ssh-kkDkb20895/agent.20895 SSH_AGENT_PID=20896 Agent pid 20896
This process is typically done on login. In an xorg environment the .Xclients file can be used to start the agent and add the certificate. To do this , add the following to ~/.Xclients
eval `ssh-agent` # some environments start the agent for you.
rt=1
while [ $rt == 1 ]
do
# return codes from ssh-add: 0=success, 1=failed to add, 130=ctrl+c
xterm -e 'cat <<< "Type ssh passphrase, or type ctrl+c to cancel"; ssh-add'
rt=$?
done
Gnome provides the utility gnome-ssh-askpass (see /usr/libexec/openssh/gnome-ssh-askpass) however this has been problematic in the past and the simple ssh-add scriptlet works fine.
SSH can be used to mount a filesystem by installing fuse-sshfs. The sshfs rpm is a derivative the SSHFS filesystem distributed with LUFS. The main difference is that sshfs is based on FUSE (the userspace filesystem framework for Linux). Refer to 6. Mounting a filesystem with SSH.
Stuart Moorfoot 22 Aug 2006 mailto:foo@bund.com.au