Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Is there a way to prevent all commands from being defined as an alias?

For example a user shouldn't be able to define rm or any other command (Ubuntu default commands) as an alias name.

share|improve this question
    
What do you mean exactly? Are you looking for something like a "soft block" to prevent yourself from doing that accidentally? – kos Jan 9 at 17:25
4  
I'm not sure what's the point of doing so, even if it were possible. – muru Jan 9 at 17:30
4  
what would be the logic for this? It does not prevent a user from typing the actual command ... so I see no reason for anyone to need to block aliases? – Rinzwind Jan 9 at 17:35
2  
Like muru and Rinzwind said, what's the point? Aliases can't do nastier things than the things a user is allowed to do already, blocking aliases just makes the user's life harder. Also whatever the solution would be (e.g. using an alias / function to override the built-in) I can't think of a way to make it non-circumventable by the users themselves, unless by locking their ~/.bashrc. – kos Jan 9 at 17:35
    
Not blocking all alias, only prevent him/her to do not use default commands name as an alias name. I know we can escape aliases with many ways such as using \ with same aliased command to run actual command. That is all – Afshin Hamedi Jan 9 at 17:41
up vote 23 down vote accepted

There is no way you can prevent a user from defining whatever aliases they prefer. Consider:

  1. You disable aliases in /etc/bash.bashrc. They enable it wherever they chose to.
  2. You delete all mentions of aliases in /etc/bash.bashrc, and all ~/.bashrc and ~/.bash_aliases via a script. They put their aliases in another file and source it.
  3. You run a command in PROMPT_COMMAND that disables certain aliases. They redefine or undefine PROMPT_COMMAND.
  4. You trap DEBUG and undefine aliases. They remove the trap.
  5. You chown all files sourced at invocation to root. They use another file and source it manually as the first command they run.
  6. You disable the builtins unset, builtin and enable; make alias a function; declare -rf alias to prevent users from modifying the function; and export the function. They run /bin/bash with --rcfile and --init-file to start a new shell, where said builtins are now enabled.
  7. ...

You could disable aliases at compile time, then it would be up to you to keep bash up-to-date and make sure you aren't affected by the next Shellshock. Of course, the users could build their own bash.

share|improve this answer
4  
I had a bit of a funny idea though: you can alias alias :=) – Rinzwind Jan 9 at 17:51
4  
And they unalias alias. – muru Jan 9 at 17:52
4  
@muru sure but you can also alias unalias :+ – Rinzwind Jan 9 at 17:54
7  
@Rinzwind and they run \unalias unalias. – muru Jan 9 at 17:54

TL;DR

The only way to prevent a user from creating aliases is to provide them with a shell that doesn't support aliasing. This is generally an X/Y problem, where X is really a threat model that should be solved with appropriate controls or architectures rather than trying to solve the problem post-facto after a user is given a shell on a shared system.

Below, I provide a technically-correct answer, as well as some guidance on what problems this will and won't solve. I also provide some additional guidance on alternative controls.

Using the Bash Restricted Shell

You can use Bash's restricted shell by assigning rbash as the user's login shell. For example:

foo:x:2001:2001:restricted user:/home/foo:/bin/rbash

You must then disable the alias built-in for the user, preferably without breaking everyone else's shell too. As an example, you could add the following to a file such as /etc/profile.d/rbash.sh:

# Limit effect to users in a specific UID range.
if ((UID >= 2000)) && ((UID < 3000)); then
    # Check shell options; disable alias builtins when shell is restricted.
    if [[ $- =~ r ]]; then
        enable -n alias
        enable -n unalias
    fi
fi

Caveats

Unless you've placed the user into a chroot jail or provided them with a modified PATH that doesn't include access to other shells, there's nothing stopping the user from simply typing bash at the prompt and getting an unrestricted shell.

In addition, by design the restricted shell prevents many common activities such as changing directories:

$ cd /tmp
rbash: cd: restricted

but doesn't prevent other scripts or programs in the PATH from doing so. This means you have to carefully craft the user's environment, and specifically that you need to prevent them from being able to modify the PATH in their startup files, because even though rbash makes PATH read-only it does so after initialization.

Better Choices

Even if you use rbash, you need to do so as part of a broader set of controls. Some examples may include:

  • Prevent non-technical users from accidentally invoking dangerous commands by providing default aliases such as rm -i, mv -i, and cp -i in the /etc/bash.bashrc file.

    • Given your original example, this is probably the most sensible solution.
    • You can combine this with enable -n alias if you like.
    • This won't prevent knowledgable users from changing the aliases, but it may be sufficient to prevent non-technical users from doing whatever it is you're concerned about.
  • Traditional Unix permissions or POSIX ACLs to protect files and directories.

  • Logins that perform a single non-interactive command. For example:

    foo:x:2001:2001:run foo.sh:/home/foo:/usr/local/bin/foo.sh
    
  • Use per-key SSH forced commands. For example:

    # ~foo/.ssh/authorized_keys
    command="/usr/local/bin/foo.sh" [remainder of line]
    
  • Use the OpenSSH ForceCommand option with a conditional Match block.

  • Use special tools like gitolite or scponly designed for your specific use case.

  • Use a chroot jail.

  • Use virtualization such as Xen, OpenVZ, LXC, VMware, VirtualBox, or other technologies to provide a segregated environment.

Once you have accurately defined your threat model, you can identify the most appropriate controls for your use case. Without a more meaningful understanding of why you want to prevent aliasing (e.g. what real-world problem does it solve?) you can't select the most appropriate controls.

share|improve this answer
    
+1 in general, but also specifically for classifying this as an X/Y problem. – Joe Jan 14 at 3:43

This is quite a pointless endeavor, as muru's answer shows. But there are some options, but they are not perfect.

According to bash manual, functions always take precedence over aliases, thus we could do the following:

xieerqi@eagle:~$ function alias { echo "Aliases are no-no" ; }
xieerqi@eagle:~$ alias TEST='rm'
Aliases are no-no

You could place function definition into the systemwide .bashrc , however as muru pointed out, smart users will find way to get aliases by sourcing a different bashrc file for example.

Another idea I've played with is enable built-in. alias is a shell built in, and bash has nice enable command that allows enabling or disabling builtins. For instance, here's me disabling alias.

xieerqi@eagle:~$ enable -n alias
xieerqi@eagle:~$ alias
No command 'alias' found, did you mean:
 Command '0alias' from package 'zeroinstall-injector' (universe)
alias: command not found
xieerqi@eagle:~$ alias TEST='rm'
No command 'alias' found, did you mean:
 Command '0alias' from package 'zeroinstall-injector' (universe)
alias: command not found
xieerqi@eagle:~$ enable alias
xieerqi@eagle:~$ alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'
xieerqi@eagle:~$ 

Again, using systemwide bashrc is an option here.

share|improve this answer
    
Not blocking all alias, only built-in commands not alias itself :) – Afshin Hamedi Jan 9 at 18:04
    
@Afshin.Hamedi Well, what is a default command ? The one that comes with ubuntu ? That means you'd have to have a list of all the commands (binary files) that came with default installation. Then every time user loads shell or tries to alias something to rm , it checks the list. Considering that the lists would be pretty large, it would take long time to start, your users will complain to you a lot and hate you as system admin :) – Serg Jan 9 at 18:08
    
It's a fun , awesome question you have, I like it ! Selective aliasing would be nice. But I doubt it's achievable , unless shell developers find a need for it to be implemented :) – Serg Jan 9 at 18:10
    
The function idea was nice. It came closest. – muru Jan 9 at 18:11

You could define (in /etc/profile) a function called alias which does the validation you want (probably using type -p) (after all "Ubuntu default commands" are "executables in $PATH") before calling the builtin alias, BUT, as others have pointed out, your users could get around that. Why not get a different set of users, or educate them ("Defining an alias that overrides a command is a Very Good Way of Shooting Oneself in the Foot, and causing confusion (e.g, Why does ls prompt for my password?))?

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.