1

Target system can only be logged into using public key authentication using a named user. The password is disabled. We use ssh-agent forwarding in combination with libpam_ssh_agent_auth to allow certain forwarded keys to gain sudo rights on the target system.

However, sometimes a running process may fill the entire disk up, leaving no space for the SSH agent's socket (which is usually in $TMPDIR). This way I cannot gain sudo rights on my box and without sudo rights I also cannot free up any disk space.

I have tried starting the ssh-agent manually in ramdisk (eval $(ssh-agent -a "/dev/shm/socketname")) and then adding the keys (ssh-add -k) but it only adds the key available on the target system, not the one forwarded from the client.

Questions:

  1. Can I add the forwarded key to the ssh-agent after I have logged in? OR
  2. Can I tell SSH to start the target system's ssh-agent in the ramdisk upon login?

1 Answer 1

4

Can I tell SSH to start the target system's ssh-agent in the ramdisk upon login?

Agent forwarding does not start any "target system's ssh-agent". It creates a listening Unix-domain socket on the remote side and relays incoming connections to the local socket where your local agent listens.

You don't need to use ssh -A to let remote processes access your local agent. What ssh -A does, you can do more "by hand" and therefore e.g. you can choose to create the remote socket in /dev/shm/.

Locally the environment variable named SSH_AUTH_SOCK stores the path to the right local socket. Let's create a remote socket connected to the local socket. ssh -R can forward a stream socket like it can forward a TCP port.

# local side
ssh -R /dev/shm/foo:"$SSH_AUTH_SOCK" user@server

In my tests sshd identified as OpenSSH_9.2 gave /dev/shm/foo the right mode: 600. I expect it to have done it safely (i.e. there was no time window when the mode was 666 or so), but if you want to be on the safe side then:

  • create a private directory safely beforehand (mktemp -d -p /dev/shm on the server) and then ask the SSH server to create a socket there;
  • or use an already existing private directory in tmpfs on the server (check $XDG_RUNTIME_DIR).

Next you need to tell your future remote processes (including sudo) where the right socket is:

# remote side
SSH_AUTH_SOCK=/dev/shm/foo
export SSH_AUTH_SOCK

And here you go. From now on processes started from this shell will inherit SSH_AUTH_SOCK that will ultimately lead them to your local agent. It is as if you used ssh -A, but the remote socket is where you wanted.

Note after our ssh -R disconnects, the stale socket will stay. Then you may want to use the same path for the remote socket again. Now the problem is if the remote /dev/shm/foo already exists then it must be removed before our ssh -R can work. An automatic solution exists, it requires StreamLocalBindUnlink to be yes on the server (in sshd_config). If you cannot configure the SSH server this way then locally you should ssh user@server 'rm /dev/shm/foo' first, before ssh -R. StreamLocalBindUnlink exists as an option also for ssh but I think it applies to sockets created by ssh on the client side (we don't use such sockets here); some say it's a bug.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .