When managing multi-user Linux systems, administrators often face the dilemma of needing to restrict potentially dangerous system commands (like rm
, chmod
, or dd
) while still allowing users to execute approved shell scripts. This creates a security paradox where we need to balance functionality with safety.
Role-Based Access Control provides the most comprehensive solution:
# Create restricted role
sudo groupadd restricted_shell_users
# Set directory permissions
sudo chmod 750 /usr/local/bin/approved_scripts
# Configure sudoers
echo "%restricted_shell_users ALL=(ALL) NOPASSWD: /usr/local/bin/approved_scripts/*" | sudo tee -a /etc/sudoers
Several specialized shells can enforce command restrictions:
- rbash (Restricted Bash): Prevents changing directories and restricts command execution
- scponly: Limits users to SCP/SFTP operations
- git-shell: For Git-only access
Here's how to set up a restricted environment that allows script execution but blocks system commands:
# Create restricted user
sudo useradd -s /bin/rbash restricted_user
# Create restricted PATH
sudo mkdir -p /home/restricted_user/bin
sudo ln -s /path/to/approved/script1 /home/restricted_user/bin/
sudo ln -s /path/to/approved/script2 /home/restricted_user/bin/
# Set PATH in .bashrc
echo "PATH=$HOME/bin" | sudo tee -a /home/restricted_user/.bashrc
sudo chattr +i /home/restricted_user/.bashrc
For enterprise environments, consider:
- SELinux/AppArmor: Create custom security policies
- Linux Containers: Isolate users in controlled environments
- Command Filters: Use
pam_exec
to intercept and validate commands
Always test your restrictions thoroughly:
# Test as restricted user
sudo -u restricted_user -i
script1 # Should work
ls # Should fail
cd / # Should fail
Remember that security is an ongoing process - regularly audit your restrictions and update them as needed.
System administrators often face the dilemma of needing to restrict potentially dangerous shell commands (like rm
, chmod
, or dd
) while still allowing users to execute approved shell scripts. This is particularly common in shared hosting environments or multi-user systems.
The most straightforward approach is using the restricted bash shell:
# Create a restricted shell user
sudo useradd -s /bin/rbash restricted_user
Then configure PATH restrictions in /home/restricted_user/.bash_profile
:
PATH=$HOME/bin
export PATH
For more granular control, create sudo rules that only allow specific commands:
# /etc/sudoers.d/restricted_commands
User_Alias RESTRICTED_USERS = user1, user2
Cmnd_Alias SAFE_CMDS = /usr/bin/ls, /usr/bin/cat, /home/scripts/*
RESTRICTED_USERS ALL=(ALL) SAFE_CMDS
Use kernel capabilities to limit system calls:
# Install libcap2-bin
sudo apt install libcap2-bin
# Create capability-limited script execution
sudo setcap cap_dac_override,cap_kill=ep /path/to/safe_script.sh
Here's a complete setup for a script-execution-only environment:
#!/bin/bash
# create_restricted_user.sh
USERNAME="app_user"
SCRIPT_DIR="/home/$USERNAME/approved_scripts"
# Create user with restricted shell
sudo useradd -m -s /bin/rbash $USERNAME
# Set up restricted environment
sudo mkdir -p $SCRIPT_DIR
sudo chown $USERNAME: $SCRIPT_DIR
# Configure PATH restriction
echo 'PATH=$HOME/approved_scripts' | sudo tee /home/$USERNAME/.bash_profile
sudo chmod 644 /home/$USERNAME/.bash_profile
Remember these critical points when implementing restrictions:
- Always test restrictions thoroughly before deployment
- Monitor for privilege escalation attempts
- Keep regular backups of critical system files
- Consider using containers for stronger isolation
Implement logging to track restricted user activities:
# Add to /etc/bash.bashrc
export PROMPT_COMMAND='history -a >(tee -a ~/.bash_history | logger -t "$USER[$$]")'