1

For deploying code to a server I run a script which scp's the deployment file onto the server using my private key . But after scp I have to manually ssh to the machine sudo to a superuser account and run a deployment script .

I would like to automate the second step too , but cannot figure out how to .

Any other alternatives to this two step process ?

6 Answers 6

4

If whomever controls the sudoers file will change it so that you can run certain commands without a password, it will be as simple as running:

$ ssh other-host sudo /path/to/deployment.script

If not, then you can have sudo take its input from a file:

$ ssh other-host 'sudo -S /path/to/deployment.script < password.file'

But, don't do that as that means you're putting your password into a file. And the server admin should kick your ass for that.

A better option than all of the above is to have the server admin set up an entry in root's authorized_keys file that is only allowed to run the deployment script. This way, to run the script you only need to ssh into the server as root with a special key.

2
  • thanks ..deployment script cannot be runwith a password even though its a qa machine ..out of my control :( ..but this 2 step process is killing lot of my time :(
    – user5967
    Jul 14, 2009 at 18:50
  • Added another option for you.
    – MikeyB
    Jul 14, 2009 at 19:16
2

Create a key pair on the remote host just for this purpose add it to root's authorized keys file on the server your are deploying to. In front of the key add 'command="cat - >> file.name;deploy_script.sh" ,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty' On the remote host run "cat /path/to/file|ssh -i /path/to/key"

You can also set this up with scp using the following in the authorized keys file

command="scp -t /destination/directory/;deploy_script.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-dss xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx user@remote_server

If you can't get access to root's authorized_keys2 file combine it with password less sudo. If that is not allowed use ssh,scp and expect.

1
  • I'd think that keeping a password in an expect script would violate some kind of policy...
    – freiheit
    Jul 14, 2009 at 19:05
1

You could do this fairly easily with some kind of cron based solution

#!/bin/bash

if [ -f /path/to/deployment.script ]; then
    mv /path/to/deployment.script /path/to/somewhere/else
    do_deployment
fi

Running a script like that every few minutes from cron as root should do what you need. There's probably a more elegant way to do this, but this is the simplest/quickest that came to mind.

3
  • 1
    If tampering is an issue, you can combine this with md5sum to take the digest of the file before transfer, then use gpg to sign the digest file and transfer it alongside the target file. On the other end, your cron job can verify the gpg signature using the public side of the key you used to sign the digest, then verify the digest before copying the file.
    – James F
    Jul 14, 2009 at 18:48
  • 1
    Running unconfirmed scripts as root automatically though opens up an attack vector, so I'd second the need for this.
    – Zenham
    Jul 14, 2009 at 19:04
  • Yep. I got the impression from the question that the file copied over wasn't the actual script that was ran. If the file copied over is executed than I'd totally agree with the argument for some kind of verification Jul 14, 2009 at 19:47
1

I think your best solution is to discuss the matter with whomever actually controls the server. The solutions all potentially violate some kind of security policy or require changes you may not be authorized to make. Basically, sounds like policy is that to run something as root you need to type in your password every time.

However, here's a local shell function that could work:

deploy_bypassing_security () {
  if [ -z "$REMOTEPASSWORD" ]; then
    read -s -p "Password: " REMOTEPASSWORD
  fi
  scp deployment_file username@remotehost
  echo $REMOTEPASSWORD | ssh -t username@remotehost sudo -S deployment_script
}

That will ask you for the password if it doesn't have one (so you have to get it right the first time!) and then echo that password to sudo, telling sudo to read the password from stdin instead of via tty.

Then just run deploy_bypassing_security on the CLI. The first time it runs it asks for a password before doing anything else, then next time it just runs without prompt. You might need to add a "ssh username@remotehost sudo -k" after the scp.

0

I'd suggest using something like Chef or Puppet to handle this, as they're probably going o be more secure than methods you handroll.

0

You can do something like the following to copy a file, and then run commands after copying the file, all within one ssh command:

cat testfile | ssh root@superServer 'dd of=/home/testcopy; chown root/home/testcopy; chmod o+rx /home/testcopy; sudo /home/testcopy'

I do think you might need the password-less sudo for this though... not sure.

You must log in to answer this question.

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