0

To process tasks for a web application, I have a background "task runner" that's managed with systemd:

[Unit]
Description=Background Job Runner
After=network.target mariadb.service

[Service]
Type=simple
Restart=always
User=sitesdb
ExecStart=/bin/scl enable rh-git29 rh-php71 "/var/www/sitesdb/current/bin/console --env=prod jms-job-queue:run -v"

[Install]
WantedBy=multi-user.target

The web application queues jobs for the task runner to execute, which is constantly looking for new jobs to run.

One of these jobs runs a remote SSH command on another server and needs to forward the SSH keys of the "sitesdb" user to that server.

Since systemd is starting the job runner, how can this work? I need to ensure that an SSH agent is running, and then need to add the SSH keys of the sitesdb user to it, since that's the user that owns the process.

One idea is to change the startup command to this:

eval `ssh-agent -s` && ssh-add && /bin/scl enable rh-git29 rh-php71 "/var/www/sitesdb/current/bin/console --env=prod jms-job-queue:run -v"

But is this appropriate? I think this would start multiple SSH agents every time my job runner command died and must be started again (and it's configured to auto kill every 15 min).

1
+50

There are some security risks associated with agent forwarding and in many cases there are better ways to solve a problem than through the use of agent forwarding. I recommend you carefully look at the requirements to find out if they can possibly be addressed without the need for agent forwarding.

Sometimes the best solution really is to use agent forwarding. So let's assume your scenario is one of those.

I recommend against using eval `ssh-agent -s` for an agent only needed for the duration of a single command. Instead you can use ssh-agent command in which case ssh-agent will run command and once command exits ssh-agent will exit as well. This is often a bit simpler but more importantly it will automatically clean up the ssh-agent once it's no longer needed. For an interactive use case you could be using a command like:

ssh-agent bash

Now your case isn't interactive so your command would need to look a bit different from that. The following command would not work:

ssh-agent ssh-add && /bin/scl enable rh-git29 rh-php71 "/var/www/sitesdb/current/bin/console --env=prod jms-job-queue:run -v"

This is because ssh-agent will only be starting the ssh-add command. Once keys have been added to the agent it will shut down and the scl command will be run without an agent. Instead you could use:

ssh-agent sh -c 'ssh-add && /bin/scl enable rh-git29 rh-php71 "/var/www/sitesdb/current/bin/console --env=prod jms-job-queue:run -v"'

If you find this command too complex you could use a shell script to make it more clear. For example:

ssh-agent /usr/local/bin/scl-wrapper-script enable rh-git29 rh-php71 "/var/www/sitesdb/current/bin/console --env=prod jms-job-queue:run -v"

And /usr/local/bin/scl-wrapper-script could contain:

#!/bin/bash -e
ssh-add
exec /bin/scl "$@"

Obviously there are endless opportunities for variations. For example you might not want to pass all the scl arguments to the wrapper script. Instead the wrapper script could contain some or all of those arguments itself.

0
0

When user (sitesdb) runs ssh (or scp, sftp) it automatically loads ssh keys from user (sitesdb, probable location /home/sitesdb/.ssh/) and offers them to remote server for authentication.

Remote server checks .ssh/authorized_keys for public part of ssh key. If they match, session is open.

For this to work you need to create ssh keys for sitesdb user without passphrase. Without passphrase you don't need ssh-agent.

Configure public part of ssh keys on remote servers, under user with which you are logging in (also sitesdb?). Use command ssh-copy-id.

If you set it up manually in .ssh/authorized_keys on remote server, file mode bits for directory .ssh should be 700 and for file authorized_keys 600

Test it manually with ssh, it should log you in remote server. If not, ssh keys are not set up correctly.

Edited:

You have 3 servers:

  • A: local
  • B: remote hop server, has ssh public keys
  • C: remote cmd server

SSH keys auth works between A and B.

To "forward" ssh keys for it to work on C server you have to do interactive login on C and prepare ssh keys same as for B.

You can use tool expect to automate ssh login from B to C, eg. execute ssh-copy-id with expect.

There are various implementations of expect, in different languages.

https://core.tcl.tk/expect/index

https://pexpect.readthedocs.io/en/stable/

2
  • Yes I can get this part working fine, but I need to enable SSH forwarding as well. I detail that in my question. – Brian Jan 3 '19 at 17:39
  • I'll update answer – dario Jan 4 '19 at 8:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.