How to Configure Sudoers File for Passwordless Execution of Specific Scripts in Linux


1 views

When managing Linux servers, you often need to grant limited sudo privileges for specific scripts while maintaining system security. The common pitfall is assuming directory-level permissions will work, when sudo actually requires explicit file paths.

The entry jsmith ALL=(ALL) NOPASSWD: /usr/local/tomcat7/bin doesn't work because:

  1. Sudo validates exact file paths, not directories
  2. Wildcards have special requirements in sudoers
  3. Directory permissions don't imply execution rights

For Tomcat scripts, use this format in /etc/sudoers:

# Grant passwordless access to specific scripts
jsmith ALL=(root) NOPASSWD: /usr/local/tomcat7/bin/startup.sh
jsmith ALL=(root) NOPASSWD: /usr/local/tomcat7/bin/shutdown.sh
jsmith ALL=(root) NOPASSWD: /usr/local/tomcat7/bin/catalina.sh

If you need to match multiple scripts safely:

# Allow all scripts in bin/ but with strict naming
jsmith ALL=(root) NOPASSWD: /usr/local/tomcat7/bin/[a-z]*.sh

Important: Avoid broad wildcards like * or .* which create security holes.

After editing sudoers, always verify with:

sudo visudo -c
sudo -u jsmith sudo -l
  • Use full absolute paths
  • Restrict scripts to read-only locations
  • Audit scripts for potential privilege escalation
  • Consider creating a dedicated system group instead

For complex cases, create a C wrapper:

#include <unistd.h>
int main() {
    setuid(0);
    system("/usr/local/tomcat7/bin/your_script.sh");
    return 0;
}

Compile with: gcc wrapper.c -o wrapper then chmod u+s wrapper


When you need to grant passwordless sudo access to specific scripts while maintaining system security, the sudoers file provides the most reliable solution. Here's the proper syntax:

# Allow user 'jsmith' to run all scripts in /usr/local/tomcat7/bin without password
jsmith ALL=(root) NOPASSWD: /usr/local/tomcat7/bin/*.sh

Several important considerations when implementing this:

  • Wildcards must be explicit (like *.sh) - directory paths alone won't work
  • Specify the target user (root in this case) for security
  • Test with sudo -l before implementation

For a concrete example with Tomcat control scripts:

# /etc/sudoers.d/tomcat-user
jsmith ALL=(root) NOPASSWD: /usr/local/tomcat7/bin/startup.sh
jsmith ALL=(root) NOPASSWD: /usr/local/tomcat7/bin/shutdown.sh
jsmith ALL=(root) NOPASSWD: /usr/local/tomcat7/bin/catalina.sh

To enhance security while maintaining convenience:

# Create a dedicated group
sudo groupadd tomcatadmins

# Set script ownership
sudo chown root:tomcatadmins /usr/local/tomcat7/bin/*.sh
sudo chmod 750 /usr/local/tomcat7/bin/*.sh

# Group-based sudo rule
%tomcatadmins ALL=(root) NOPASSWD: /usr/local/tomcat7/bin/*.sh

If your configuration isn't working:

  1. Check syntax with visudo -c
  2. Ensure no conflicting rules exist
  3. Verify file permissions on both scripts and sudoers file
  4. Check SELinux/AppArmor contexts if applicable

For more complex scenarios, consider wrapper scripts:

#!/bin/bash
# /usr/local/bin/tomcat-control
case "$1" in
    start)
        sudo /usr/local/tomcat7/bin/startup.sh
        ;;
    stop)
        sudo /usr/local/tomcat7/bin/shutdown.sh
        ;;
    *)
        echo "Usage: $0 {start|stop}"
        exit 1
esac

Then grant sudo only to the wrapper:

jsmith ALL=(root) NOPASSWD: /usr/local/bin/tomcat-control