Replacement for rexec/Bastion?

Colin Coghill (SFive) mugginsm at under-the-fridge.com
Wed Aug 27 20:13:15 EDT 2003


In article <mailman.1061992484.17157.python-list at python.org>, 
Michael Chermside wrote:
> 
> Great! If you are willing to run the untrusted code in a separate
> process and fall back on the OS to do the restricting, it _is_ 
> actually capable of restricting what code can perform, in a way that
> Python simply can't match. You can use ulimit and chroot to restrict
> what the untrusted code may do. Then there's no particular need to
> use ANY special restricted execution support in Python. 

The reason I haven't just done this is that there are two problems
I haven't solved yet, for which I appear to need help from Python itself.

Zope's restricted python *does* look like it can solve both of these,
I'm still figuring it out though :)

A) Network connections
   You can't afford for the untrusted code to open an uncontrolled network 
   connection, unless you're happy running a spam-repeater.
   This *could* be solved with a more secure operating system - I'm sure
   SELinux or OpenBSD could be configured to do this, but that's probably
   too large a penalty for most uses.
   I suppose if the chrooted environment provided a cut-down version of
   Python with all the dangerous stuff stripped, that could do it. But I
   suspect that'd be more work than reimplementing rexec safely.

B) Clean sandbox
   You can't afford to restart the untrusted process between every piece
   of code its given unless you're not doing all that much processing. Only
   restarting it when something goes wrong is the ideal.
   There needs to be a way to stop one piece of code from messing up the
   environment for the next one (by creating new versions of __builtins__,
   for example.
   
Ideas?


I currently have three pieces of code:

server.py
    sits in the main application. Provides an API, currently by xmlrpc.
    provides a "fetchNextSnippet()" which returns the next piece of code to
    be run. If it has not been called for N seconds, will kill the untrusted
    process and restart it. 
linux-safe.py  
    does a chroot(), could probably do more, like setting ulimits, 
    quotas,  setuid?
unsafe.py
    fetches a piece of code to run from server using the xmlrpc API.
    Runs it. That code can call methods in server.py via xmlrpc. Repeat.

If I can solve the above two problems, I'm happy to release this code. 

The interesting thing is that linux-safe.py is the only OS-dependent part. 
Perhaps equivalents could be made for other systems. There's also no reason 
unsafe.py needs to be python, this could quite happily be a java, ruby, or
whatever environment, if you want to use one of those as your scripting 
language.

Using xmlrpc was only a placeholder because it was easy. This should probably 
be replaced with something pythonic, over a UNIX Domain socket or the like. 

- Colin




More information about the Python-list mailing list