I'm looking to set up my sudoers file correctly, but the documentation I've found doesn't seem to help.

I have a user, e.g. user1

I have two Debian servers, server1 and server2.

At present I can connect to either server from my Windows PC using SSH, and when required execute sudo to elevate my privileges.

I now have a need to be able to connect from server1 to server2 in a shell script, and execute a file on server2 as sudo, without entering the password (either in the script or manually).

I understand I can use the sudoers file to allow me to do this.

But how do I do this?

In my sudoers file (on server2 )I have:

# User privilege specification
# Allow members of group sudo to execute any command
%sudo  ALL=(ALL:ALL) ALL
%user1 ALL=(ALL:ALL) ALL

I understand I can do something like:

%user1 ALL = NOPASSWD: /path/to/myscript    

This will then allow user1 to run the script in /path/to/mysqcript without entering the password. But, will that prevent me from doing anything else apart from running my script when I connect from my Windows PC.

Ideally I'd want to limit this NOPASSWD functionality to connections from server1.

Am I missing something here? I'm reluctant to 'test' the changes in case I lock myself out completely.

  • Set up key-based ssh authentication first. If you don't password-protect the key, you can ssh from server1 to server2 without a password. – Jan Oct 29 '15 at 16:41
  • If any of the existing answers solved your problem, please consider accepting it with the checkmark; thank you! – Jeff Schaller Apr 18 '17 at 10:55

One thing to tweak before getting to the real answer. Using "%user1" means "people in the group user1"; you probably just want "user1" to mean user1.

Secondly, sudo has no idea where you are logged in from -- only where you are currently running sudo.

Thirdly, ensure you are using "visudo" to make your changes; it will try to prevent you from making syntax errors.

Fourthly, adding a sudoers line only adds to your current access; it will not not prevent you from running other scripts; if you need sudo for those scripts, then you'll need more sudoers entries.

  • ok cheers (a rookie error there with the % ). So am I right in thinking then that if I add user1 ALL = NOPASSWD: /path/to/myscript I will be able to connect as user1, and run /path/to/myscript without needing to type sudo or typing a password? And then I will be able to do everything else the same as before by typing sudo? – IGGt Oct 29 '15 at 16:57
  • I'm confused -- in your question, you're looking to "execute a file on server2 as sudo, without entering the password". Putting the NOPASSWD flag in the sudoers entry accomplishes that. You (or your script) would still need to prefix /path/to/myscript with sudo. – Jeff Schaller Oct 29 '15 at 17:16

You asked about restricting the functionality to connections from server1. I would do this with ssh. The code for modifying users is for Debian/Ubuntu. The principles and most of the other code should be fairly universal. After making this configuration, to execute the script on server2 from server1, you will issue this command:

$ ssh -i ~/.ssh/script_identity.pub ruser@server2

The above command will connect to server2 and run your script, requiring no further intervention for ssh or sudo authentication. The ssh public key file is the only access to run the script remotely on server2, thus enabling you to decide which machines and/or accounts can access the script over ssh.

The code to accomplish these tasks is exemplified below this description.

This configuration requires a dedicated account on server2. There are many good reasons, one of which you've already mentioned, the possibility of locking yourself out of server2, or worse, inadvertently modifying the wrong files in your working account.

Steps to Configure ssh for Restricted Remote Access

On server1

  1. From the account on server1 where you'll execute the script, create a new ssh key which will be used only to execute the remote script.
  2. Modify the new ssh public key to restrict to execute only one command (see command= in the sshd manpage).
  3. Make a test script that prints the user ids and date.

On server2 (all will be done remotely from server1)

  1. Make a new account on server2.
  2. Copy the modified public identity file to .ssh/authorized_keys in the home directory of the new user on server2.
  3. Copy the test script to the new users home directory on server2.
  4. Check all permissions and ownership on all files in the new user's account.


After saving the following script as ruser.sh on server1, and, after you understand what it will do, issue this command to execute:

$ sh ./ruser.sh ruser server2

Save this script as ruser.sh in your user account on system1:

#!/bin/sh -e

# ruser.sh -- setup user on remote host for secure remote script execution
# This is for first time setup!
# Always use a new user on remote host.

USAGE="ERROR: Usage: sh $0 remote-username remote-hostname"    

# build files that will be transferred to the remote host

# Make the new ssh key, and modify the public key so that
# it can only be used to execute "./rscript.sh"

ssh-keygen -N '' -f ~/.ssh/script_identity
sed -i '1 {
    s,^,command="./rscript.sh" ,
}' ~/.ssh/script_identity.pub

# rscript.sh -- the only script that can be executed
# with the modified public key.

printf '%s' '(id;date) > rscript.out' > /tmp/rscript.sh.$$

# copy the new identity public key and rscript.sh to the remote host

scp ~/.ssh/script_identity.pub "${RHOST}":/tmp/script_identity.pub.${UNIQUE}
scp /tmp/rscript.${UNIQUE} "${RHOST}":/tmp/script_identity.pub.${UNIQUE}

# setup remote user for script execution
# Create new user
# Move identity file and script to new user's home directory.
# Fix ownership and permissions

ssh -t ${RHOST} "sudo /bin/sh -cex '
        adduser --system --shell=/bin/sh ${RUSER};
        mkdir -m0700 ~${RUSER}/.ssh;

        mv /tmp/script_identity.pub.${UNIQUE} ~${RUSER}/.ssh/authorized_keys;
        mv /tmp/rscript.sh.${UNIQUE} ~${RUSER}/rscript.sh

        chmod -R 0600 ~${RUSER}/.ssh/;
        chmod    0700 ~${RUSER}/.ssh/;
        chmod 0700 ~${RUSER}/rscript.sh;
        chown -R ${RUSER}:nogroup ~${RUSER}/;

# remove temp files

rm -rf /tmp/rscript.sh.${UNIQUE}

Test the above configuration from server1 by executing:

$ ssh -i ~/.ssh/script_identity.pub ruser@server2

Then check the home directory of ruser on server2 to see that the file rscript.out was indeed created, indicating that everything is configured correctly.

If so, modify the ruser@server2:rscript.sh to call your /path/to/myscript. Before modifying the sudoers file, issue the ssh command again to run the remote script again to make sure your output and error output are working the way you want.

Now configure server2's sudoers file to allow this new user on server2 to execute only one script as root without a password.

ruser ALL = NOPASSWD: /path/to/myscript

Congratulations, you may now securely run privileged scripts remotely with no ssh, sudo or system passwords.

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.