# ssh for port forwarding, passwordless key, no cmd

## depontius

I want to use a passwordless key to get ssh port forwarding with no command shell.

I've got an odd little twist on doing something with ssh.  I'm "hiding" or "localizing" a server that I want for my own personal use only.  As such I rebound all of the services to loopback.  To get at those ports from a remote machine, I open port forwarding tunnels with ssh.  They need to be opened by root, because some of them are low (<1024) ports, so it's root on the client ssh'ing to my account on the server.  I'm using the "-fN" flags to forward the ports and not bother opening a shell, along with several "-L" flags to designate the forwarded ports.

This works.  Now I'd like to automate it, either when the client machine (a laptop) sees that it is connected to this particular network, or when it's remote and the VPN tunnel comes up.

There are plenty of examples of public key authentication, and they're all advise great care when using passwordless keys, particularly to restrict what that particular session can do.  Some examples make sure that you can't forward ports - the exact opposite of what I want.  I want no commands, just forwarded ports.  I'd be happier yet to restrict the allowed forwarded ports to the specific ones I want.  Right now I'm using my own account on the ssh target machine, but now that I can think of it, there is merit to using a special-purpose account for this purpose, and restrict the capabilities for that account.

Anyone have any experience with this type of usage?

----------

## timeBandit

I don't use them for port forwarding but I have lots of experience with automated use of passwordless keys.

I have a DAT drive in the server in my basement and use it to back up my workstation. I don't want or need to do it often, but it can take an hour or two so I don't want to stay logged in while the backup runs. I have a cron job that watches for backup requests, creates catalogs and tarballs as needed and streams the whole mess directly to tape via ssh. The job runs as root and uses an unprotected key to connect to the server as a non-root user. (This slightly wacky scheme came about because the server is too massively underpowered for "real" backup software, so the workstation does the heavy lifting. Plus, it was fun.  :Smile: )

```
# ll -R /etc/backup

/etc/backup:

total 6

-rw-r--r-- 1 root root 1181 2006-10-29 13:08 backup.conf

-rw-r--r-- 1 root root  127 2005-11-04 22:22 backup.deny

drwxr-xr-x 2 root root 1024 2006-10-29 13:09 devices/

drwx------ 2 root root 1024 2006-06-26 00:12 hosts/

-rw-r--r-- 1 root root    0 2005-10-31 20:02 paths.exclude

-rw-r--r-- 1 root root   72 2007-12-18 21:40 paths.include

...

/etc/backup/hosts:

total 1

-rw------- 1 root root 887 2005-11-01 22:09 bivouac.id_rsa
```

Note the permissions on /etc/backup/hosts (where the key resides) and the key itself: both readable only by root. The private key is for the server account backup, which has access to almost nothing on the server except the tape drive.

To connect, simply add the -i /path/to/hostkey.id_rsa option to your ssh command. You only need to be root to bind to privileged ports on the client end. That is, suppose Apache is running on port 80 the server and you want to forward it to port 81 on the client. You don't need to connect as root on the server to do that. The point is, create a key for a user who has the bare minimum access needed on the server, to minimize risk.

The dire warnings against this practice are reasonable over the Internet. In a controlled network, it's a different story and there's no harm in the technique if managed with due care.

----------

## Hu

The section AUTHORIZED_KEYS FILE FORMAT in man sshd describes some ways you can limit what an authorized key can do, such as disallowing pty allocation, X11 forwarding, or execution of client-chosen commands.

----------

## depontius

I've been through that - I was hoping to limit the action to port forwarding only, and didn't find that.  I was also hoping to limit/define the ports forwarded at the server rather than just trusting the client invocation.  I have pretty much decided that the client account on the server should be special-purpose with tightly limited access.

----------

## timeBandit

 *depontius wrote:*   

> I was also hoping to limit/define the ports forwarded at the server rather than just trusting the client invocation.

 The permitopen="host:port" option does just that, unless I've missed something. You can further restrict it to allow connections only from your laptop. In conjunction with -N on the client it seems to meet your requirements.

----------

## depontius

I just set up the public keys, etc, and have authentication and port forwarding working.  I've also got "Match User" PermitOpen statements to restrict the ports.

So far I haven't been able to prevent an interactive session.  Anything I try to do to stop an interactive session, including a "Match User" chroot or preset commands prevents the connection from completing, at least so far.  For the moment, I've locked the account that holds the key, and unlock it to experiment.

----------

## Mad Merlin

FWIW, you don't need to forward the port to the same port on the client. Thus, if you wanted to avoid using root on either side, you could forward 80 on the server to 8080 (or any other port) on the local side. Then, connecting to localhost:8080 would send you to server:80, no root necessary!

----------

## depontius

For my purposes, root on the client side is better.  My stuff is hooked into dhcp and vpn clients, which run as root.  When they the connection comes up I'm already doing other stuff, like grabbing my in-company hostname and tweaking configurations and security to match the local environment.  Adding the ssh port-forwarding to the rest is easy.  On the destination machine, it's a minimal-privilege account, and what I'm trying to do here is cut the privileges even more, to where about all it can do is forward the ports.

Actually, this is a company setting, and I run a few servers for myself.  Notably, I keep my email on dovecot imap, run a portage mirror on rsync, and run http-replicator.  All of these servers are for my own use, only.  This setup lets me get at my stuff from my laptop at work or through VPN on laptop my home systems.  But the company has a no-servers rule which hadn't been enforced for less-common (not http or smtp) ports. Recently I got indications that that might be changing, and it feels safest to cut it all the way back to just ssh.  My other option would be port knocking, but that's more involved than I want to get, at the moment.

----------

