Tuesday, August 5, 2014

Private servers on EC2

Build all the servers (or, how to setup a secure-ish private minecraft server on EC2)

At the time of writing, Amazon EC2 gives you a free virtual machine for the first 12 months of a new account. It's not huge, but it has a CPU and 1GB of RAM, and that gives you a few possibilities. A VM in the cloud is cool, but there's an obvious downside to not having it in your own house/office/parents' basement

Open servers on the internet

If you want to do anything cool with your VM, chance are you'll end up opening ports, and introducing security holes. You may say that you're not worried about this, that your server isn't super important, but if someone can own your VM, then they're one step closer to breaking into your own computer, and that's a bad thing.

In short, you need a way to lock things down, and that's what we're going to do here. But first, let's spin up an EC2 VM

Ubuntu VMs on EC2


Go to the Compute menu, and click on Launch Instance



Check the Free tier only box, and click on the Ubuntu 64 bit VM


You'll see the green highlighted free tier eligible text next to the smallest VM, select that and click Next: Configure Instance Details


Leave as is and click next


Nothing to see here, click next


You can add tags if you want, but we don't need them for anything in particular right now


You'll want to make some adjustments to the security groups - click Add Rule and make a custom TCP rule opening up port 1723 - this will allow PPTP VPN connections.


Your config should look like mine here


And now you're good to go, click Launch and head to the final step


Make a name for your keypair and download it



Annnnnnnd you're all good to go!

To log in (instructions for OSX/Linux, windows users can figure out how to do this in PuTTY themselves), use the -i switch to load the private key (make sure you chmod it to 600), and log in with the user ubuntu. On the "compute" screen you'll be able to see the IP for your server, log in as follows:

ssh -i keyfile.pem ubuntu@IP

And you're in! Feel free to have a play with this as is, or move onto the next step - setting up containers.

Linux containers (LXC)

Making them work

LXCs are the secret sauce that'll let you make faux-VMs to put things in. Install LXC with the following:

sudo apt-get update
sudo apt-get install lxc

This will load up everything you need to build an LXC. To build your LXC, use the following. We'll call our container "minecraft", for no particular reason:

sudo lxc-create -t ubuntu -n minecraft

This will take a long time, so get yourself a coffee or three. This only happens the first time, as it sets up the template - subsequent LXCs will take seconds when you make them.

Once this finishes, start it up and log in (CTRL+A followed by the Q key will get you out of the console)

sudo lxc-start -d -n minecraft
sudo lxc-console -n minecraft

Here's your container! If for some reason, you were wanting to install minecraft, you would install the JDK and download the minecraft JAR file from the appropriate website. The below lines will install version 1.7.10, you'll probably want whatever the latest version is.

sudo apt-get install default-jdk
wget https://s3.amazonaws.com/Minecraft.Download/versions/1.7.10/minecraft_server.1.7.10.jar

Making things a little nicer

Your LXCs will use DHCP when you spin them up, which is great for getting things going at first, but we want a little bit more control. Go back to the host machine (CTRL+A, then Q, if you aren't in it already) and open up /etc/default/lxc-net.conf and change the DHCP settings so we can open up some space - change the settings in there to the following:

LXC_BRIDGE="lxcbr0"
LXC_ADDR="10.0.3.1"
LXC_NETMASK="255.255.255.0"
LXC_NETWORK="10.0.3.0/24"
LXC_DHCP_RANGE="10.0.3.200,10.0.3.240"
LXC_DHCP_MAX="40"

We'll also want to give our LXC a static IP, so get back into your LXC

sudo lxc-console -n minecraft

and edit /etc/network/interfaces (if you're still in the host you can edit this at /var/lib/lxc/minecraft/rootfs/etc/network/interfaces if you like). Remove the line

iface eth0 inet dhcp

and replace with the following

iface eth0 inet static
        address 10.0.3.250
        netmask 255.255.255.0
        gateway 10.0.3.1

Save and close, and power off your container for now

sudo poweroff

This is all we need from the LXC for now, let's set up the VPN.

PPTP VPNs

We're using PPTP today because you can get it working in minutes, and it has native clients in Ubuntu and OSX. As per the instructions on the Ubuntu website, we'll install as follows:

sudo apt-get install pptpd

Then edit /etc/pptpd.conf, scroll to the bottom, and set up addresses for clients. I've done this as follows:

localip 10.0.3.1
remoteip 10.0.3.2-22

Open /etc/ppp/pptpd-options, and add DNS

ms-dns 8.8.8.8
ms-dns 8.8.4.4

Then edit /etc/ppp/chap-secrets and set up accounts. This shouldn't need to be said, but just in case security isn't clear, DO NOT USE THESE LOGINS AS EVERYONE ON THE INTERNET KNOWS WHAT THEY ARE NOW

user1 * password1 *
user2 * password2 *

Now restart the PPTP server

/etc/init.d/pptpd restart

And give it a shot!

Putting it all together

Weird stuff can happen if you haven't shut everything down, so the safest way to apply your LXC settings is reboot the whole VM

reboot

Now log back in, start up your LXC, and then try to log in from the outside. Connect to your server with your PPTP account, then once the VPN is up, try to ping your LXC on 10.0.3.250. If you've installed a minecraft server on it, log into the LXC and fire it up with the following:

java -Xms512M -Xmx1G -jar minecraft_server.1.7.10.jar nogui

Edit the newly-generated eula.txt to say true, start up again, and test it out... remember to use the LXC's internal IP (10.0.3.250) when connecting though!

Troubleshooting


  • Try turning it off and on again. I am not joking.
  • Make sure you're fully upgraded (apt-get upgrade/apt-get dist-upgrade) - LXC has dependencies on newer versions of certain code, but doesn't automatically upgrade them for you.

What have we done?!

What's the point in putting a VM inside a VM in the cloud? The reason you might consider this, is because while cloud resources are cheap and plentiful, they're also hard to configure properly to allow full access to you, but completely lock out everyone else. I can't make any guarantees on the security of this - LXC is still new, and there are further things we can do to lock down the internal bridge - but I hope this has been a useful start to get people thinking about bridging out into private servers in public clouds such as EC2.