Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

evaluating perl code securely in a virtual machine online

update 2: I got this working and it's live :)

update: Please check the comments, @ikegami answer is working but with a slight problem. I may be doing something pretty simple wrong.


I recently decided I had to learn Linux/Perl really well, and then I started building this www.tryperl.com as a learning project. It's a Cloud IDE of sorts.

(It's only been a few months since I first laid hands on perl, linux, bash, osx, so please go easy on me)

Currently I eval code with Safe.pm, but my game plan is :

A separate Amazon EC2 VM that will eval unsafe perl code and return the result. The VM will be blocked from the internet and load balanced. I can then reset this machine from a snapshot every now and then.

This is mostly the code I will use to eval perl code on the server, I use Time::Out for timeout management:

my $code = ..
my $arg = ..

#create a file with random name
my $filename = rand().".pl";
open(FILE,">$filename")
print FILE $code;
close(FILE);

#use Time::Out to timeout after 10 secs

my $ret = timeout 10 => sub {
  #run the file just created with $arg as an argument. << This is IMP 
  my $r = `perl $filename $arg`;
  return $r;
};
if ($@){
    return $@;
}   
return $ret;

My Issues

  1. Can I somehow avoid physical file creation and pipe the $code with the $arg? Like open(FILE,"perl <some_magic> | "). Might sound stupid but I had to ask :(. This has been solved by @ikegami in the comments.

  2. I can't seem to use Capture::Tiny. I tried doing this inside the timeout block:
    my ($stdout, $stderr, $count) = capture { system('echo Hello') };
    But I kept getting empty strings! :( Is it because it's inside the timeout? (I don't care too much about this though)

  3. Are there any other security flaws I'm not seeing? Should I be doing a fork limit? How should I begin doing that? (Links and some pointers would be nice)

  4. The author of http://www.perltuts.com says in this article he uses qemu and a debian image to run his code. Apart from fork limiting, Is his approach semantically similar to mine ? (Forgive my ignorance here again, Remember I touched a linux box only a few months ago)

My dev box is OSX 10.8, Production server is RHEL for front-end and Ubuntu for the Perl eval Machine. I run on EC2. See the full stack details here.

Any detailed answer will be will appreciated and rewarded with rep and unicorn dust :)

like image 405
gideon Avatar asked Feb 13 '13 19:02

gideon


1 Answers

After 13 days of hard work, I finally did it!!

I explored FreeBSD Jails, my lack of networking experience and the fact that I had to rebuild the OS many times drove me away. FreeBSD is really cool though!! I'll get back to it soon.

I looked bleakly at OpenVZ and then thanks to @ewwhite I revisited Linux Containers and gave it a proper shot.

The docs aren't great but this article really helped with everything.

  • I setup multiple containers under a load balancer : HAProxy.
  • I have a perl installation inside each container with the cpan modules I need.
  • My PerlExecutor application is a Dancer app that runs on Starman, it runs under owned by a limited user which has less privileges and has limits in limits.conf
  • The container is blocked from the internet.

One Limitation : I don't know much about networking so I blocked the jails from the internet by disabling port forwarding on the host. However, the jails still need to be on the network for the host to communicate to it, as a result, you can still do a ping inside the jail which will resolve the domain but it won't respond. So any web requests inside fail. I also do a string scan for Ping and block it.

Any suggestions or improvements will be very welcome!

I'd like to thank @JakeFeasel @ikegami @ewwhite @chris-s and the guys at ubuntu.SE and unix.SE for their help :

This is what it looks like:

TryPerl Architecture Diagram

like image 188
gideon Avatar answered Oct 12 '22 15:10

gideon