0

I am writing a Bash script to manage various JBoss instances across multiple servers.

The script allows users to check the status of each instance as well as stop/start them. The script is situated in /opt and then for the stop/start part, it passes arguments to a child script situated under each /jboss/bin directory.

The users who are allowed to stop/stop already have permissions to run anything as the application user (jbossuser) and that user has ssh keys set up for the other servers. I have had no issues getting this part of the functionality to work.

I would like to allow any user (namely those who don't have the permissions to execute as the application user) to be able to check the status of each instance. For that I have:

status() {
    pid=$(ssh -q -t jbossuser@${server} "ps -ef | grep "$instance" | grep -wv 'grep\|vi\|vim' | awk '{print \$2}'")
    if [ ${#pid} -gt 0 ]
    then
    echo "$name > ${yellow}ONLINE  ${default}PID: $pid"
    else
    echo "$name > ${red}OFFLINE${default}"
    fi  
}

If the script hasn't be run with sudo -u jbossuser ./script.sh, which the standard users are not allowed to do, it prompts for jbossuser's password.

I know I need to add something to the sudoers file to allow those users to run this specific command, but I am not sure what I need to add. I have got as far as:

user ALL=(jbossuser) NOPASSWD: /usr/bin/ssh

But I want to restrict them to only be allowed to ssh to a handful of servers, only as jbossuser and limited to that ps -ef command.


/Edit:

Going by the answers/comments, I guess I need to further clarify what I'm trying to do and what the issue is.

System Admins would be running the script with:

sudo -u jbossuser ./script.sh

Standard Users are not allowed to sudo so would just be running it with:

./script.sh

Those running it as jbossuser have no issues selecting options which call the status() function mentioned earlier, because it uses ssh keys set up for the jbossuser to connect to other servers.

Those two are not running it as jbossuser (the Standard Users) get prompted for their password and then get an error as they aren't allowed to use ssh. Even if they could use ssh, they wouldn't have the ssh keys for jbossuser to connect to the other servers.

I would like to allow the Standard users to only be allowed to:

sudo -u jbossuser ssh -q -t jbossuser@[hostname] ps -ef | grep [process]

I would then update the status() function to include sudo -u jbossuser at the start so it works for both Admin and Standard Users.

  • 1
    If you're running sudo -u jbossuser ./script.sh, then the sudoers line should be user ALL = (jbossuser) NOPASSWD: /path/to/script.sh, with the full path to script.sh. It isn't clear how the server is given to script, so it's not possible to say how you could limit that, and the script is only using the jbossuser and running ps -ef, so those restrictions are already in place. – muru Oct 30 '18 at 1:42
  • I've added more detail to the question, and actually your comment got me thinking... it would be easier to put the status() function into a separate script and allow the Standard Users to execute that as the jbossuser (basically what you wrote above. Its not as tidy but it would probably work. – hshah Oct 30 '18 at 17:37
  • Eh, why bother with modifying the script instead of letting "standard users" run sudo -u jbossuser script.sh? – muru Oct 31 '18 at 4:58
  • It's because the script also allows you to stop, start and restart the instances, which I don't want the standard users to be able to do. – hshah Oct 31 '18 at 9:30
  • Maybe the standard users should have sudo access to a separate status-only script? – Jeff Schaller Oct 31 '18 at 10:06
1

There are a few different problems to be solved here:

  1. How to permit access to only certain hosts?

    This can be done by giving the user on the source host a specific SSH private key. Then, you install the matching public key only on the hosts the user should have access to. Ensure that the user does not know the target account password, or that password authentication is disabled in sshd_config. The user should only be able to authenticate via ssh key.

  2. How to restrict the user to a specific command only?

    This can be solved similarly to #1 above - in the user's ~/.ssh/authorized_keys file on the target server, when adding the key, you can also specify a command that the user will be forced to run. They will not be able to execute anything except for this one command.

An example authorized_keys entry that supports this would look like this, using the example command that you provided:

command="ps -ef | grep \"$SSH_ORIGINAL_COMMAND\" | grep -wv 'grep\|vi\|vim' | awk '{print $2}'",no-pty,no-port-forwarding,no-x11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAkwY/8z8sADor5NmM0rZd3clWIcycSzP1gj1gjZCymuYxXRZX/YFnjphkuCWU7c4KK6AtS4Xv1OFjpqtZ6ucBEws+sJIS7hfdELWuTmmYeO3UKL1p9xt4lJRlv1F8WZkUpy5iUo6VqZbgwywzyiqZj5u100Rcbho4BDFjYbSWOw== jbossuser@source_host

NOTE: This must all be one line in authorized_keys!

The user can pass the name of the process they are trying to grep for on the command line when issuing the ssh command. Here is an example of this in use - in this example, I'm going to grep for the "crond" process in the ps listing:

jbossuser@source_host ~$ ssh -i .ssh/testkey jbossuser@target_host crond
1044
jbossuser@source_host ~$ 

So, this command returned the PID of the "crond" process, "1044".

  1. sudo access for the users on source host

    You have the syntax correct, but the command wrong - you're not giving sudo access to ssh, but to the script you want them to execute as the jbossuser.

If different users should have access to different hosts, then you can give them different versions of the script that point to an SSH private key that is specific only to them.

  • I may not have explained myself too well so apologies for that. I have updated the question to include more detail. – hshah Oct 30 '18 at 17:34
  • Having (unprivileged) users sudo to the jbossuer account, only to then run a command over ssh seems like an unnecessarily complex solution. Why not just let them ssh directly? The method I outlined above would still let you restrict which users can access which target machines, and also limit them to only running the command to check the status of the process. In other words, you only need to set up their accounts following steps 1 and 2 of my answer, and you can ignore 3 altogether because it seems to serve no real purpose. – guzzijason Oct 30 '18 at 22:25
  • Unfortunately I'm trying to cater for ease of use and stupidity all at the same time. By getting this working as I see it in my head, once in the script everything is explained to users, I have the flexibility of adding more if required to the same menus/options, and it covers new users in the future. Whilst this may be complicated for me right now, it will work out for the best in the long run. – hshah Oct 31 '18 at 1:22

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.