4

Is there a possible way that I can execute a script, say abc.sh; as root user on every login to my system via SSH?

I've gone through a similar question which says to add the script execution to .bashrc file. This is not much helpful as I'd have to add it to every users' config file. Also, they'd still have ability to remove it.

Execution as root is not as important as denying the users' the power to stop its execution. The OS is debian, if that helps in any way.

2

This is a late answer, but you can execute it on every login AND have it run as root (or any other user you want), by doing the following:

  1. Write your script, with the commands you want to run as root, and save it e.g. as /path/to/root-script.sh .
  2. Make root (or the desired user) the owner of the script.

    chown root:root /path/to/root-script.sh`
    
  3. Set the setuid bit on the script, with other desired permissions. (make sure it is not universally writable etc.)

    chmod 4755 /path/to/root-script.sh
    

    The 4 means set the setuid bit, which will cause the script to be run as the owner of the script. This is what sudo uses to ensure execution as root.

  4. To ensure it is run on every login, run the sticky-bit-set root-script.sh from within /etc/profile . The /etc/profile should be run regardless of the shell used by the user. Note this will only apply to interactive logins however.

Edit. As noted by Scott in comments, this solution does NOT generally work on any modern system with any shebang script other than Perl < 5.12.0. Modern kernels would ignore scripts with a setuid bit unless they have been patched, which would not be recommended for security reasons.

Rather, setuid only generally works on compiled binaries and [old versions of Perl][https://stackoverflow.com/questions/21597300/can-i-setuid-for-perl-script] that can use (Perl <5.12.0) with suidperl.

This Unix/Linux SE question has thorough answer of why setuid is ignored for shebang scripts, with its summarized TL;DR:

Setuid shebang is insecure but usually ignored. If you run a program with privileges (either through sudo or setuid), write native code or perl, or start the program with a wrapper that sanitizes the environment (such as sudo with the env_reset option).

4
  • I tried this on manjaro 17.x (running linux kernel 4.14.x) and the command didn't get executed. I am trying to run /home/user/bin/script as root. After doing steps 1-3 above, I tried adding a line with /home/user/bin/script to /etc/profile as well as replacing it with sudo /home/user/bin/script. In both cases it didn't have the desired effect. What am I doing wrong ? – koushik Mar 23 '18 at 7:56
  • I just get told I don't have permission to run the script when I try this – jamzsabb Aug 18 '18 at 14:59
  • 1
    (1) Good job on getting the name of the bit correct; the 1000 bit is, indeed, the sticky bit.  However, that is not the same as the setuid bit (that would be 4000) which is the one that causes a program to be run as the owner of the program.  (2) But it doesn’t matter.  The setuid bit hasn’t worked for scripts since the previous millennium, plus or minus. (3) Also, if you chmod a file to 1750 (with root:root ownership), then only root or a user in the root group will be able to execute it. – Scott Oct 9 '18 at 0:24
  • Thanks @Scott, edited to correctly refer to setuid bit instead of sticky bit and correct permissions. Also mentioned that modern kernels won't execute them as root, excepting old Perl. – hilcharge Oct 30 '18 at 11:37
2

You could add the call into /etc/bash.bashrc - this is processed on every Bash login, so assuming your users are using Bash as their shell, it should run the script.

1
  • 3
    .bashrc is only sourced when Bash is run as a non-login shell, so you might want to use /etc/profile? – slhck Jul 14 '13 at 12:23
1

OpenSSH supports the ForceCommand configuration variable which might be set to the pathname of a script which

  1. Does something administrative — see below for details.
  2. Calls

    $(SHELL) -c "$SSH_ORIGINAL_COMMAND"
    

    or

    eval "$SSH_ORIGINAL_COMMAND"
    

    after that to actually perform the task the user intended to carry out.

Now the problem is that the forced command is executed with the credentials of the logged in user. To combat this, it's sufficient to use some sort of IPC to communicate with a daemon process, running as root. Unix-domain sockets appears to be a best bet for me as it actually allows transferring of the credentials before the actual data exchange takes place (by using the getsockopt(SO_PREERCRED) call). The downside is that you'll have to write a pair of tools to do that (well, the client part could be handled by socat).

See also this thread.

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.