Introduction and A Quick Primer on Amazon VPC
Another job another set of crazy home lab activity! I recently moved from the VMware world (leaving behind many great friends at VCE) into the deep end of the cloud as part of the newly formed Amazon Web Services Professional Services Group. It has been a wild and hectic first couple of months just getting my arms around the entire Amazon ecosystem, brushing up on Linux and even some (gasp!) coding, and attempting to build some mental bridges between public and private “cloud” so I can properly guide my large enterprise customers.
Speaking of which… I have now started having the kinds of conversations I love: discussing infrastructure and application architecture, and more importantly service creation, with corporate technology decision makers and thought leaders. One thing I noticed right away is that Amazon has an incredibly deep and powerful base of “web ecosystem” knowledge. Not a surprise given their DNA! The enterprise space, however, is still in its early maturity stages for AWS which is why they have been courting folks like myself.
Amazon has this brilliant construct within AWS known as “VPC” or “Virtual Private Cloud”. Most traditional AWS customers (read web startups) can’t even spell VPC, nor do they really need to. In the enterprise, however, its an entirely different story; here, VPC is pretty much a pre-requisite to any real adoption in most cases. With this in mind, I dove into the deep end figuring the more pain I took up front, the more value I could provide to my customers down the road.
A ton of great content on AWS in general, and VPC in particular, is already out there in the blogosphere, so I’ll keep the general overview brief. Essentially, the Virtual Private Cloud facility provides AWS customers the capability of defining their own private address space within the AWS network. A customer can define 10 VPCs per account and each VPC can contain 20 subnets (as with most AWS limits, these are negotiable). At the top level, a CIDR block is declared for the VPC. Simply put this is an IP Address block expressed by a subnet mask. So, for example, the entire 10 net would be 10.0.0.0/8 in CIDR notation.
One thing I learned immediately is that it is important to get this initial declaration right for two reasons:
- once the VPC is created, the initial CIDR declaration cannot be changed. Re-numbering would require destroying the VPC and rebuilding which would require taking instances down, snapshotting them, terminating them and then bringing them up in the new VPC. This can be onerous for a large, heavily populated, production network so upfront planning is key.
- overlapping IP ranges will cause lots of trouble for the Customer Gateway. If direct connect (a dedicated circuit to AWS) is being used this isn’t an issue, but for the lower cost Customer Gateway (IPSEC VPN) option, it’s a big deal. So in the above example, declaring a 10.0.0.0/8 for VPC would mean you cant use any 10 net address in your enterprise. Clearly that would be a problem. It is critical then to “right size” the initial CIDR allocation. Like Goldilocks, “not too big” and “not too small” is super important.
As with all things AWS, we start with the extremely intuitive management console (or for veterans, the incredible API, or CloudFormation, but those are topics for another day 😉 ):
Life in the dashboard is pretty straightforward. To begin, simply go ahead and “Create a VPC”, or if you’ve been here before, “Create another VPC”. Suddenly things get interesting. There are a number of options here that bear further explanation:
- VPC with a single public subnet: this is a fairly simple use case. Essentially, we are creating a large DMZ. VPC rules and capabilities will apply (out of scope, but the main page is a great reference for what VPC provides and why it is interesting: http://aws.amazon.com/vpc/), but the instances will be internet direct attached and a combination of subnet ACLs and security groups (more on these later) will be required to secure them. Ingress and egress is internet only, so this architecture has fairly narrow applicability for the enterprise, but nevertheless it is an option
- VPC with public and private subnets: this option is the first of the three “enterprise in the cloud” architectures for VPC. A private IP block is defined and a corresponding public address space is allocated by Amazon. The public space is the traditional DMZ, the private space is the traditional intranet, and a gateway will be required for egress and ingress. Any connectivity back to the home office is purely the responsibility of the site admin. In other words, if you want a VPN with this option, you will be rolling your own endpoint within EC2 (using a pre-built AMI appliance or making one) and attaching it to the on premises end point.
- VPC with public and private subnets and hardware VPN access: now things are getting interesting! this option adds the Amazon VPN end point to the above scenario. This architecture will be the focus of the article. There is a list of supported VPN end points, and it is the usual suspect list of popular edge routers, but Amazon will also provide config files for Astaro and even a “generic” config. What we’re going to be doing here is setting up an IPSEC tunnel, but there are some gotchas (dual tunnels, dependency on BGP routing) that make things a bit more complex. That said, there are also some concessions (pre-shared key) to ease of setup that make things a bit less complex.
- VPC with private subnet only and hardware VPN: this option basically just drops public access from the above architecture. What this means is that there is no “DMZ” and all instances will run in private address space. Ingress and egress will need to either go through the tunnel or a gateway will have to be installed (more on this later as well)
If either of the two “hardware VPN” options are selected, VPC setup will now proceed to the gateway configuration section. What should be entered here is the IP address of the VPN end point appliance that will be used to form the IPSEC tunnel connection to AWS:
The next step is the last chance to make any changes. A summary dialog is presented and if everything is in order, we can go ahead and create the new VPC:
Amazing! With just a few basic questions we now have a private working slice of the Amazon cloud ready to host production workloads. For now, however, it is an isolated slice. The next step is to connect this new network to our on premises infrastructure and establish bi-directional traffic flow. For this step, the first resource we want to create is a “Customer Gateway”. If this sounds familiar, it should! We are creating an AWS reference entry that will allow the Amazon hardware VPN end point service to locate the network edge referenced during VPC creation:
The dialog box is straightforward with just two entries; IP address and BGP ASN. Here we enter the public address of the VPN end point on the corporate LAN (same address entered when creating the VPC) and enter the BGP ASN if there is one. If not, and this is a new BGP path, the default is acceptable and will always be 65000.
The next pre-requisite that needs to be created is the “Virtual Private Gateway”. The VPG is basically an AWS configuration request where we are telling the service to deploy a VPN end point on the AWS side that will ultimately be used to connect to the Customer Gateway created in the prior step:
There is nothing else to this step, but it will take a few minutes since a gateway instance on the backend is being deployed and configured. With both endpoints of the tunnel defined we can now go ahead and instruct AWS to bring up their side. To do this, we navigate to “VPN Connections” and “Create a VPN Connection”. This will invoke the following dialog:
All that is required here is to enter the two end points defined in the prior steps. Once created, a canned configuration script will be provided. This is enormously valuable and required for setting up the IPSEC tunnel correctly. Canned configurations are offered for Juniper, Cisco and Astaro or, if none of those options apply, a super handy generic “catch all” config is also provided. The generic config file looks like this:
This file should be familiar territory for the most part for anyone familiar with IPSEC. For those new to IPSEC, a good primer (http://www.unixwiz.net/techtips/iguide-ipsec.html) should definitely be considered a mandatory first step before continuing. Even for IPSEC veterans, two things do jump out as a bit unique:
- BGP must be configured and will be used to advertise end point routes into the tunnel
- Two tunnels are created for fault tolerance so this is a highly available IPSEC design prescribed by Amazon
It is worth noting, at this point, that for the vast majority of real enterprise customers, things are very straightforward from here from the networking perspective. If you are operating a Cisco or Juniper device, you can utilize the canned config file, with possibly some minor adjustments required, and have the tunnel up and running. As always the devil is in the details, but it shouldn’t be anything an experienced network administrator can’t work out. Later in the entry I will walk through configuration of the instance and the AWS subnet ACL and route tables, as well as provide some notes on joining AD that will be of interest so feel free to skip down to those sections.
Anyone still reading at this point is very likely looking for solutions that work that are either cheap or free 🙂 This was my primary objective since my goal was to build something in my home lab with no additional expenditure using what I had on hand. For reference, this is my home network:
The key callouts here are the following:
- my home LAN consists of two private subnets connected by a Netgear WNR3500 running the Kong mod of DD-WRT (v24SP2)
- my normal default gateway is a standard issue Netgear WNDR4500 which is useless for our purposes here, so I deployed pfSense on some old Compaq hardware I had around to do IPSEC duty
- my lab infrastructure is hosted on a 2 node vCenter 5 cluster (two ESXi 4.1 hosts)
- an active directory implementation is hosted on ESX and the plan is to join a Windows EC2 instance to it
The First Challenge – DD-WRT multi-subnet Routing
DD-WRT obviously needs no introduction for the home network hacker. There are plenty of tutorials and a great Wiki, but in tackling this project things got complex enough, and resources were hard enough to find, that I decided another one out there on the blogosphere wouldn’t hurt. The key is that in this case the DD-WRT is being used as an intranet router only. In my case I need DD-WRT to route between 192.168.1.0 and 192.168.2.0. The reason I segmented my home network this way is that the .2 network hosts vCenter and a number of guest virtual machines. This infrastructure hangs off a Cisco managed switch with 802.1Q VLAN tagging defined. I often do extensive testing in this sandbox and don’t want anything I may do disrupting the normal flow (and internal bandwidth) of my regular home network as this could lead to marital and familial strife 🙂
The key to getting intranet routing working on DD-WRT is VLAN support. In this case my chosen hardware, the Netgear WNR3500, does in fact support VLANs on eth0 (the 1Gbps switch). It is always a good idea, when tackling a DD-WRT project, to refamiliarize oneself with this most excellent diagram of the internal architecture of these cheap Broadcom WLAN routers:
The process for turning a DD-WRT router into a proper ethernet router is as follows:
- start with a nice clean slate (30-30-30 reset – hold reset with power on for 30 seconds, turn it off and keep it held for 30 more, turn it on and keep holding it until your fingers go numb)
- set the password, change the name… get the basics out of the way
- assign the desired IP for the “router” or “LAN”. this will be associated, by default, with VLAN1 which will, by default, be part of bridge group BR0 with the WLAN (which is the eth1 ethernet interface)
- disable the wireless radio (we’re creating a “proper wired router” so it goes)
- at this point I like to reboot. I reboot DD-WRT when setting it up a lot 🙂
- on the security tab under setup, clear all of the security checkboxes, then disable the SPI firewall (if intranet filtering is desired, then leave it on and build IPTABLE rule flow later)
- set the WAN port to disabled and add the WAN port to the switch off the the “Basic Setup” tab
- reboot again
- on the Network Setup tab, set VLAN2 to “unbridged” and assign an IP and subnet mask for the second intranet subnet
- on the Advanced Routing tab, change the router mode to “Router” from “Gateway” (in my case I did RIP2 router)
- if a flavor of routing is desired, configure it (in my case I set dynamic routing to both WAN and LAN/WLAN)
- configure static routes as needed (for any subnets that are not direct attached or will not propagate dynamically) and add a default gateway entry (0.0.0.0/0, pointing to internet GW)
- at this point things should be working, but DD-WRT is always YMMV
Some shots of the finished product for reference:
The VLAN Configuration Tab:
The Advanced Routing Tab:
The Networking Tab:
With DD-WRT configured, and connectivity established across 192.168.1.0 and 192.168.2.0, the next step is to handshake with Amazon and establish the tunnel.
Well Hello There Cloud! Bringing up the IPSEC Tunnel with pfSense
There is no doubt that these are good days to be a technologist. It’s truly amazing that today there are a broad range of free do-it-yourself options for establishing IPSEC VPN tunnels. With that said, I’ll cut to the chase. If the task is bringing up an IPSEC tunnel to Amazon VPC, use pfSense. Do not pass go and do not stop at DD-WRT (no IPSEC), Mikrotik (virtual interface config too limited), or even Astaro (free edition lacks the functionality). pfSense is the right tool for this job and is a truly amazing piece of kit. To get started, head on over to the projects home page: http://www.pfsense.org/
Installation is very easy from the small downloadable ISO file. There are a few things you’ll want to make sure of before getting started:
- allocate a machine (physical or virtual) with dual NICs and connectivity to both a public segment and a private segment
- if possible put the public NIC on a DMZ to avoid NAT traversal complexity (Amazon explicitly forbids tunnel through the NAT, but I have heard it can be made to work. I avoided this however)
- if you’re routing multiple internal subnets, make sure everything is working internally first and document both the existing network and what you want the endstate to look like
- have the installation guide handy for reference – it is straightforward, but can’t hurt to have
Once the software is up and running, connect to the web GUI to configure it. We will be focusing on:
- Firewall->Virtual IPs
- Firewall->NAT if needed – was required in my case because my normal default gateway, the WNDR4500, will only NAT local addresses. pfSense NAT is full featured and will allow you to create rules for multiple private subnets
Before we begin there is a quick update we need to do to the router itself. As mentioned earlier, Amazon requires BGP in order to exchange route information through the tunnel. BGP is not part of the standard pfSense installation, but luckily is only a download away! Navigate to System->Packages and scroll through the list of available packages until you find OpenBGPD. Click the grey “+” to install it. Confirm that you want to proceed and the package will download and install as long as pfSense has been properly configured with internet connectivity and DNS entries. When the installation completes, reboot the router for good measure. Once it is back online, return to the Package Manager and verify that OpenBGPD is there on the “Installed Packages” tab:
Once BGP has been added, the first stop is the Routing menu found under System. We are going to create some entries in the Gateway tab. The way to think of this is that pfSense configuration screens generally utilize named references. So in establishing a route, instead of entering an IP address for gateway, the GUI will present a list of gateways that have been configured here. This is part of the interface design of pfSense and makes sense once you are familiar with it. What we are going to do first is create an entry for the public IP address. We will use this entry as a reference for creating the tunnel. The default gateway will be there by default. If there are any other internal gateways (for additional private subnets) that you want to add as static, this is the place to create entries for those as well.
The UI is self explanatory but as a reference, to “add” objects use the small grey “+” icon. The topmost “+” will create a new entry, the “+” next to an existing entry will create a new entry based on the existing one (template copy). The “x” icons will delete entries and the “e” icons will edit them. Go ahead and add a new gateway:
The Edit Gateway dialog requires some basic information. You’ll want to name the gateway, provide its IP address and associate it with an interface. In this case since we are referencing the public address which will be used to build the tunnel, the interface will be the WAN interface. You can also set the gateway as the default which in this case would not make sense and provide options for gateway health monitoring. You can choose to monitor it or not and, if appropriate, point at a different IP address to determine the health of this one. For example if it were normal for this address to be off and online on demand, but the device had an alternate address that was always up, you could use the alternate address to determine if the device was alive. In this case the address is local to pfSense so monitoring is not necessary. If desired add a description and then save the entry. This will bring you back to the Gateway dialog where you will see the newly created entry listed. You can now “Apply” the added entry to make it live. Repeat this process using the appropriate IP if there are any local gateways to be added.
Next stop is the “Routes” tab if there are any local subnets that you would like to add static route entries for. The UI operation is the same and the fields here are very straightforward. The “Gateway” field will now reference the local gateway entry we created optionally in the prior step:
Once all gateways and routes and have been created and the changes applied, we can leave this tab. The next stop is the Firewall->Virtual IP’s tab where we will establish the virtual IP addresses provided by Amazon for the two tunnel end points. This is a critical step and is part of why we need pfSense. Many of the free options for routing and firewall services lack this flexibility. You can see a preview of what the finished product will look like. Amazon generally uses the same end point addressing scheme within the 169.254.255 address scope, but will sometimes reverse the Tunnel 1 and Tunnel 2 assignments, so pay close attention to the generic IPSEC config file you downloaded earlier:
Click the “+” to add a new virtual IP:
The options here are pretty straightforward. Two of these entries will be created, one for each tunnel end-point address assigned by Amazon. Amazon allocates two tunnel address spaces:
- 169.254.255.0/30 – can be either tunnel 1 or tunnel 2 – 169.254.255.1 will be the Amazon address, 169.254.255.2 will be the customer side address
- 169.254.255.4/30 – can be either tunnel 1 or tunnel 2 – 169.254.255.5 will be the Amazon address, 169.254.255.6 will be the customer side address
Create a virtual IP entry for each customer address and give it a description that will remind you which tunnel it is associated with as per the generic configuration file (Tunnel 1 or Tunnel 2). When each entry is complete, save it and then apply it. Once the virtual IP’s are done we are ready to create the IPSEC tunnels. Navigate to VPN->IPSEC next:
By now you have read the primer on IPSEC, but the basic idea is that two public end points, connected through the internet, establish an encrypted connection (a “tunnel”) and then pass local traffic through it. The configuration bits center around how these two end points recognize and authenticate each other, what traffic they pass through the tunnel, what the rules of engagement are and how they exchange information. Lets take a look at the overall architecture in the case of the IPSEC tunnel specification prescribed by Amazon:
As depicted in the diagram, two IP addresses per side per tunnel are relevant here. Amazon assigns inside addresses from the 169.254.255.0 subnet to both sides of each tunnel and also assigns a public 72. net address to the each end point on the AWS side. On the customer side, a single public address is expected to terminate both tunnels. Within the tunnel, obviously, private network data from each end will be passed. Amazon specifics that BGP be implemented to exchange route information for the private networks. As per standard BGP procedure, RIP, OSPF or static routes may be propagated over BGP. With this in mind, lets get back to pfSense configuration. IPSEC negotiation takes place across two phases. Phase 1 is where each IPSEC end point authenticates each other and agrees to establish connectivity via IKE and negotiates rules for the pair of Security Associations (SAs, unidirectional data paths) which will make up the “road” of the tunnel. Phase 2 actually establishes the Security Associations so traffic can begin to flow. This is all represented by pfSense in a beautifully straightforward manner. Clicking the grey “+” from VPN->IPSEC will invoke a Phase 1 creation dialog box to start the creation of a new tunnel:
Here we specify the ground rules for our tunnel. Amazon keeps this part simple by utilizing pre-shared keys which are provided (one for each tunnel) in the generic configuration file. At this point, we can go ahead and complete the form for our first tunnel. The remote IP will be the 72. net IP address associated with the tunnel instance from the generic config file. It is a good idea to enter a description along the lines of “Tunnel 1” at this point to keep things obvious in the GUI. The other critical piece to get right for Phase 1 is the set of authentication parameters:
- Authentication method: Mutual PSK
- Pre-Shared key: provided in generic config
- Encryption algorithm: AES 128bit
- Hash algorithm: SHA1
- DH key group: 2
Descriptions for these fields are out of scope, but once again the primer will make all of this clear. The only other option to consider here is NAT traversal which will be required if your end point is hiding behind a NAT rather than living in the DMZ. Once the form is complete, save it and apply the changes. Then repeat the above procedure substituting the appropriate values for the second tunnel. Once the Phase 1 entries have been completed there are two more steps before ticking that “enable IPSEC” checkbox firing up the tunnels; first Phase 2 must be completed, then BGP should be configured. For Phase 2 configuration, click the large grey “+” icon below each Phase 1 entry in order to expand the Phase 2 entry list. Now click the small grey “+” to the right to add a new entry for Phase 2:
There are a number of key fields to complete here:
- Mode: set this to tunnel
- Source and Destination IP: these should be set to the inside IP addresses specified by Amazon for this tunnel entry. Refer to the above tunnel architecture diagram as a reference. These will be within the 169.254.255 subnet and the remote addresses will be .1 and .5 while the local will be the .2 and .6 addresses that we have used previously. The “type” on these entries is “network” and the subnet mask is a /30 for these ranges
- Protocol: the encryption protocol should be set to ESP
- Encryption algorithms: only AES 128 should be selected and the word size should be set to 128bits
- Hash algorithm: set to SHA1
- PFS key group: 2
Once the Phase 2 entry for the main tunnel end point has been created, save the entry and apply it. The next step is to create entries for each private subnet that will need to pass through the tunnel for each destination. This step is critical for establishing connectivity. In my example I have a single AWS VPC subnet, 192.168.3.0/24 and two local subnets, 192.168.2.0/24 and 192.168.1.0/24. You can see from the “finished product” shot below that I have created two Phase 2 entries. The first one allows “LAN” (the local interface of pfSense – 192.168.1.0/24) to connect to 192.168.3.0/24 and the second entry allows my second private subnet, 192.168.2.0, to connect to 192.168.3.0. Additional networks on either side would require additional entries as appropriate.
Once all Phase 1 top level entries and Phase 2 sub-entries have been created and saved, there is just one step left, configuration of BGP. For this, head over to Services->OpenBGPD. First configure the base level settings:
For the base configuration options, there are two key things that need to be entered. The first is the ASN number that identifies our premises over BGP. In my case this was a new BGP installation so I stuck with the default Amazon provided ASN of 65000. The other piece that needs to be completed is the “Networks” section where we specify the network entries that will be advertised via BGP. Here we want to be sure to specify the default gateway (0.0.0.0/0) and any private networks that originate on our premises. After these fields are complete, save the entry and move to the “Group” tab and click the grey “+” to add a new BGP group:
This is where we define Amazon in BGP terms for pfSense. Name the BGP group (in this case “VPC”) and provide the Amazon ASN (7224) A description, as always, is helpful for navigating the GUI. Once complete, save the configuration and move to the “BGP Neighbors” tab.
What we are specifying here are the BGP routers we will be communicating with. Enter the inside IP address of the Amazon side of the tunnel and provide a description that will serve as a reminder in the GUI and add it to the VPC group created in the prior step.
This step should be performed twice, once for each Amazon tunnel endpoint (169.254.255.1 and 169.254.255.5) Once this configuration has been saved and applied, the BGP daemon will have everything it needs to begin routing.
One more step before we are ready to bring up the IPSEC tunnel. We need to visit the firewall rules and ensure that IPSEC can flow properly. We create one straightforward rule under “Firewall->Rules” on the IPSEC tab to allow all traffic to flow:
The last step is now to return to the VPN->IPSEC tab and click that “enable IPSEC” check box to bring up the tunnels! If everything was done correctly, you should see the following in the Amazon AWS Management Console under VPC->VPN momentarily:
In pfSense, under Status->IPSEC you should see something similar to the following:
As long as at least one of the tunnel end points is green, you should be able to successfully test bi-directional connectivity. As an additional step, if required, you can configure NAT within pfSense to allow any private subnet access to the internet. For reference, this is my pfSense NAT configuration:
The Home Stretch: Back to the AWS Management Console
At this point there is network connectivity via IPSEC between private subnets locally and within Amazon. In order to ensure that the instances within the Amazon VPC can actually communicate with our local hosts some additional housekeeping on the AWS side must be performed:
- subnet ACL configuration
- routing table configuration
- security group configuration
Subnet ACLs in AWS are exactly what they would be in a traditional network infrastructure. With subnet ACLs, you are able to restrict traffic flow at the router level within the VPC. For the purposes of my testing, I do not want an access control at the subnet level. Anything I would like to accomplish can be handled just fine with security groups (more on those in a bit). By default, every subnet is associated with the default subnet ACL. Additional ACLs can be applied as needed and are processed in the usual access control list manner. The default rule can also be edited. Within the AWS Management Console, selecting “Network ACLs” brings us to the subnet ACL configuration UI. Creation of a new ACL or editing of the default one is straightforward from here (a knowledge of firewall configuration is required) Rules are set, by protocol or by TCP port range and by source address (inbound) or destination address (outbound) and an action is applied (ALLOW, DENY).
Once a rule is created it can be applied to the VPC subnets by selecting the “subnet” section of the VPC management console, right clicking the desired subnet entry and replacing the network ACL listed in the detail pane:
Network ACLs are a powerful VPC capability and really warrant their own blog entry, but the possibilities should be apparent to any network administrator.
Once the subnet ACL is set, the next step is to ensure that the routers have all the required routes defined in order to pass traffic to our private subnets. To configure this, we select “Routes” from the AWS VPC Management Console. This is a very straightforward routing configuration table editor. Entries should be added for each private subnet pointing to the Virtual Private Gateway we created way back at the beginning of this entry. In addition, a default route (0.0.0.0/0) should be added pointing either to an existing “internet gateway” (another AWS facility which provides a preconfigured NAT for VPC instances allowing them to reach the internet) or to the Virtual Private Gateway (which would either strand them from the internet or require configuration of the on premises NAT to allow them to pass). Creation of an Internet Gateway is a very simple two click process from the Management Console – “create” the gateway and “attach to VPC”. Once all route information has been entered we can right click and associate it with our existing subnet. Additional route tables may be created and associated with other subnets as required:
The last step for ensuring connectivity is to configure a Security Group for our instance. I am not going to cover the launching of instances, bundling of AMIs or creation of Security Groups in detail since these topics are very well covered elsewhere. Security Groups are basically hypervisor level firewall configurations (IPTABLES defined for the guest within XEN) that control network access to the instance. Much like a personal firewall, or the subnet ACLs above, rules are defined for both inbound and outbound traffic which govern traffic flow. Whenever there are connectivity issues with an instance, it is a good idea to start troubleshooting by double checking the Security Group associations and settings currently in effect. AWS maintains separate security groups for your account for both classic EC2 and VPC. My default VPC security group is show below as a reference:
Extra Credit: Joining an AD Domain
At this point, with connectivity established, there is no reason we can’t do something interesting like deploy a Windows instance and join it to our Active Directory domain. Some thoughts here are that, for performance sake, it would probably be a good idea to deploy a read only domain controller (W2k8) into the VPC, but the initial join of the first instance launched can be done via the IPSEC tunnel without issue. The easy way is to keep both the tunnel, and all of the ACLs, wide open. Masochists, or really strict enterprise security officers, might want to lock AD down. If so, for reference, here are the ports required for AD straight from Microsoft:
Two things will jump out at any network administrator right away. First is “thats a lot of ports!” which is true. Second is “woah… dynamic high ports!” which is also unfortunately true. AD relies on dynamically mapping, via RPC locator (TCP 135), a set of high ports. This behavior can be changed, however, from the default with a registry hack (which somehow still persists to W2k8R2):
Once all of the required ports have been quantified it is a pretty straightforward exercise in ACL creation to ensure proper traffic flow through the tunnel. If everything goes well, a domain join should lead to the following dialog box (which brought tears to my eyes, honestly):
Some basic refreshers for configuring AD might be useful. As per AD best practice, sites and subnets should be well maintained within Active Directory Sites and Services. A subnet entry should be created for each subnet, and associated with a site. I chose to define the AWS VPC as its own site container with its associated subnets. This will allow for fine tuning of replication rules which is going to come in handy once domain controllers are deployed into the cloud (especially if the cloud sits on the other side of an IPSEC link). Here is my AD site configuration:
A few additional things worth noting when promoting a server to a domain controller within an AWS VPC. The process will run as expected for the most part, but this dialog in particular requires some explanation:
DC promo is basically trying to protect you from yourself here, and with good reason, but in this case it isn’t warranted. VPC instances are configured as DHCP from the Windows guest OS view of the universe, but in reality they are all DHCP reservations set to the private IP address you assign when you configure the instance. It is perfectly safe to say “yes” here.
Another thing to consider, in the DC promo process, is how initial replication will take place. I allowed it to occur via the network through my 15Mbps cable modem IPSEC tunnel, and it worked fine, but my AD also has the bare minimum of objects. For massive initial replication cycles, it might not be a bad idea to do an offline replication from media (lots of references for this process on the web – nothing new introduced by EC2).
Normal “branch office” sizing rules will apply to AD architecture and AWS. In many cases it may be necessary to install a dedicated circuit (which Amazon allows via the “Direct Connect” offering) rather than relying on IPSEC tunnels for connectivity.
At this point you should have enough information to bring up a VPN to an AWS VPC on the cheap and extend your Active Directory infrastructure into it. Absolutely amazing stuff! I hope this entry was useful and, time permitted, it should be just the beginning of a series of entries around AWS!
Oh and PS:
PPTP over 4G in, RDP out via IPSEC to domain controller in VPC? On a phone (well “phablet”)??? Now thats just showing off! 😉