DevOps Zone is brought to you in partnership with:

Nikhil primarily works as a Ruby application developer with ThoughtWorks. He enjoys writing fast web-apps as much as he likes writing Chef cookbooks. He also digs everything that is GNU/Linux/Emacs. Professionally, he's worked on several offshore development projects and knows the challenges of working with distributed agile teams and enterprise data centers. He blogs at and tweets using @hyfather. Nikhil has posted 4 posts at DZone. You can read more from them at their website. View Full User Profile

Restricted Bash

  • submit to reddit

While working on deploying a web-application recently, I needed to transfer a 'build artifact' (fancy name for a .tgz) from a Continuous Integration server to an RPM repository server.

We already have an existing RPM repository server that uses Apache, and once my tarball was in the correct location, it would be available over HTTP for all to consume.

Cutting to the chase, what is the simplest way by which I could automatically transfer a ~20 MiB file from one CentOS host to another?
I didn't want to install an FTP server or any extra Apache module on the existing RPM host that would then support multi-part file uploads.

The quickest solution, it seemed was an scp or an rsync.

So, how would this CI host be authorized to open an SSH tunnel to the web-server?
Where would the identity key reside? There is no elaborate keyserver in this ecosystem.

I decided to the transfer the responsibility of protecting the system from the identity key to the remote host's operating system.

A new user called tarballs on the RPM repository host with its HOME set to /var/www/html/tarballs, and set its SHELL to rbash.

What is rbash?
When the bash is started with the name rbash (ln -s /bin/bash /bin/rbash) or by passing a -r to bash, it starts up in a restricted way, which is handy while setting up more controlled environments. I know of it thanks to Saurabh 'Rob' Mookherjee, a sysadmin whom I work with.
When in bash's restricted mode, one cannot change directories, use commands with a '/' in them, neither can one change the PATH or the SHELL variables. A more comprehensive list of contraints can be found in the manpage for bash.

So, all is good except the tarballs user still has access to all executables that exist in its PATH that the system assigns by default.
A quick hack in the /etc/profile.d to unset the PATH for the tarballs user and there is hardly anything the tarballs user can do once logged in.
The only required executble binary was /usr/bin/ln to make a symlink called 'latest' to the most recent tarball that was SCP'ed over.
I copied this binary to tarballs' HOME. A kludge, I admit.

Now, from my Continuous Integration agent, I can script these two commands to be run everytime a new build artifact is to be uploaded to the repository.

scp -v -i tarball_identity tmp/build7f3cd88.tar.gz  
ssh -v -i tarball_identity "ln -sf build7f3cd88.tar.gz latest"

For reference, here is what I have on the repository host:

[ ~]# cat /etc/profile.d/ 
if [ `whoami` = 'tarballs' ]; then unset PATH; fi

In larger, more complicated systems that support different products and web-apps, I have seen the occasional file that is rsync'ed to another host, or a larger script residing remotely being invoked over SSH. While such things usually happen inside of a VPN or a DMZ, it is still a risky proposition to have an identity file being checked into the codebase or lying on an arbitrary host.
While having a more robust security solution should certainly be on the list, creating a separate user on the remote host that has only enough privileges to perform a said task is a great idea.
Once such a user exists, we have effectively moved that responsibility from the SSH identity keyfile to the remote host's operating system.

Bear in mind that this infrastructure lies in a secure corporate datacenter with access to the machines restricted to trusted co-workers. Also, while the RPM repository host is important, all the data it holds can be easily mirrored and reproduced.
Solely relying on an rbash is by no means a solution for any mission-critical host that is directly exposed to the internet or any untrusted zone.


Published at DZone with permission of its author, Nikhil Mungel.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)



Afandi Merathi replied on Sun, 2012/03/18 - 7:48am

BTW, about the profile.d hack, you want to be careful about what sequence those scripts are run. I believe it's alphabetical and if you have something that runs after and uses PATH or exposes other binaries/shell vars you could be in trouble.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.