Setting Up a VPN into Amazon's Public Cloud VPC » History » Version 27
Tobias Brunner, 05.11.2013 11:06
1 | 1 | Yaron Sheffer | h1. Setting Up a VPN into Amazon's Public Cloud VPC |
---|---|---|---|
2 | 1 | Yaron Sheffer | |
3 | 10 | Tobias Brunner | "Amazon Web Services' VPC":http://aws.amazon.com/vpc/ (Virtual Private Cloud) is somewhat inconvenient for developers. The standard way to access it is through an IPsec "hardware VPN". In practice this means having to deal not just with IPsec, but also with BGP. This document simplifies things by using strongSwan to access the VPC instances. Neither hardware nor BGP are required. |
4 | 1 | Yaron Sheffer | |
5 | 1 | Yaron Sheffer | h2. Scenario |
6 | 1 | Yaron Sheffer | |
7 | 6 | Yaron Sheffer | We assume a single VPC subnet with Internet access (i.e., located behind an Internet Gateway). We have a small number of clients accessing the VPC remotely, all running on Linux machines. I believe the solution can be tweaked to allow for larger deployments. For example, you will want to replace preshared key authentication by certificate-based authentication to support a large number of clients. |
8 | 1 | Yaron Sheffer | |
9 | 1 | Yaron Sheffer | h2. Solution Overview |
10 | 1 | Yaron Sheffer | |
11 | 10 | Tobias Brunner | We create a new, dedicated instance serving as a VPN gateway for the whole VPC. The solution uses tunnel-mode IPsec with IKEv2 and a virtual IP pool. For simplicity, we use preshared keys rather than certificates. strongSwan is deployed on both client and gateway. |
12 | 1 | Yaron Sheffer | |
13 | 6 | Yaron Sheffer | h2. General Warnings |
14 | 6 | Yaron Sheffer | |
15 | 6 | Yaron Sheffer | * Debugging IPsec is hard. Debugging networking on public cloud virtual machines is hard. Please *follow these instructions carefully*. |
16 | 12 | Adam Feuer | * Amazon's cloud is constantly changing, mostly for the better. This document has been validated with the current feature set, as of today (May 2012). It may not be valid tomorrow. |
17 | 6 | Yaron Sheffer | |
18 | 1 | Yaron Sheffer | h2. Solution Steps |
19 | 1 | Yaron Sheffer | |
20 | 18 | Adam Feuer | # Create a new VPC instance (the minimal instance type in VPC is @m1.small@). This will become your VPN Gateway. We have used standard Ubuntu images, (Oneirc @ami-a562a9cc@ and Precise @ami-a29943cb@). Instead of launching a new, dedicated instance, you can reuse an existing instance but that would be much less secure. Note that the VPN Gateway instance can be stopped when not in use, and later restarted. |
21 | 25 | Michael Rasmussen | # Disable source/destination check on the VPN Gateway instance. (Right click on the instance in the Amazon Console. The option is in the pop up menu.) |
22 | 25 | Michael Rasmussen | # Assign an Elastic IP for the instance. This will be the VPN gateway's public address, but first we will use it to access the gateway to install strongSwan. |
23 | 10 | Tobias Brunner | # Install strongSwan on the gateway (and on your client, too). We have used the version available in the repository, 4.5.2. Modify the configuration files per the next section. |
24 | 8 | Yaron Sheffer | # Enable IP forwarding on the gateway (you need to do _both_ of the following): |
25 | 24 | Michael Rasmussen | ## Edit @/etc/sysctl.conf@ and uncomment the line @net.ipv4.ip_forward=1@. The next time the system reboots, it will load these settings. |
26 | 24 | Michael Rasmussen | ## For the current session, run @sysctl -p@ to apply the changes to the running system. |
27 | 27 | Tobias Brunner | # Define the gateway's security group(s) to allow incoming TCP/22, UDP/500 and UDP/4500. |
28 | 25 | Michael Rasmussen | #* Once the gateway is fully set up, you will be able to disable TCP/22 in the security group and tunnel SSH through IPsec instead of directly accessing the VPN gateway. |
29 | 26 | Naer Chang | # Define a subnet for the virtual IP pool in ipsec.conf. It doesn't need to be inside the VPC. In our example the VPC encompasses 10.10.0.0/16, and the virtual IP pool will be drawn from 10.100.0.0/16. |
30 | 25 | Michael Rasmussen | # The strongSwan Gateway will assign addresses for IPsec clients from the virtual address pool. But it needs a bit of routing help: First, note the instance ID of the VPN gateway. Then locate the routing table associated with the subnet of protected instances (this may or may not be the main routing table), and add a routing rule that routes all traffic destined to the pool's subnet (10.100.0.0/16) through the VPN gateway. |
31 | 1 | Yaron Sheffer | # Allow any incoming traffic from the pool's subnet into all VPC instances. For example, by adding an "all traffic" rule to the @default@ security group of your VPC. |
32 | 26 | Naer Chang | # For each instance that is in the VPC, disable the instance's Source/Dest. check (from the EC2 Instances page). *Edit:* this is only required for step #4 in the Bonus section below. Do not make this change unless you implement the guest instance routing-table changes. *Edit2:* exception, you need to disable source/destination check (on affected instances; namely all instances in the routing path; ex: VPN <--> proxy instances) if you want to do any kind of policy based routing because this spoofing check will supersede OS level spoofing check and you will not be able to catch the packet loss through tshark or tcpdump. |
33 | 26 | Naer Chang | |
34 | 1 | Yaron Sheffer | # Finally, @sudo ipsec restart@ on the gateway and the client, and you are good to go! |
35 | 1 | Yaron Sheffer | |
36 | 9 | Yaron Sheffer | h2. Bonus |
37 | 9 | Yaron Sheffer | |
38 | 9 | Yaron Sheffer | The only job of Amazon's NAT instance is to run a single iptables rule. You can deploy that rule on your VPN gateway and save the price of a dedicated NAT instance. |
39 | 9 | Yaron Sheffer | |
40 | 9 | Yaron Sheffer | # Add the "masquerade" NAT rule for the entire VPC: @sudo iptables --table nat --append POSTROUTING --source 10.10.0.0/16 -j MASQUERADE@ |
41 | 23 | Michael Rasmussen | # Save the iptables configuration so that it will survive a reboot. |
42 | 23 | Michael Rasmussen | #* RHEL/CentOS machines |
43 | 23 | Michael Rasmussen | #** @/sbin/service iptables save@ |
44 | 23 | Michael Rasmussen | #** This will write the rules to /etc/sysconfig/iptables. |
45 | 23 | Michael Rasmussen | #* Debian/Ubuntu machines |
46 | 23 | Michael Rasmussen | #** Install iptables-persistent, if not already installed: @apt-get install iptables-persistent@ |
47 | 23 | Michael Rasmussen | #** This during install it will prompt to save current rules. Say yes, to have it create /etc/iptables/rules.v4 and /etc/iptables/rules.v6 for you. |
48 | 23 | Michael Rasmussen | #** In the future, after making changes, run @iptables-save > /etc/iptables/rules.v4@ to save. |
49 | 21 | Yaron Sheffer | # Change the EC2 routing table so that the VPN gateway (rather than the NAT instance) becomes the default route of your private subnet. |
50 | 21 | Yaron Sheffer | # As an alternative to the previous step, update the /etc/network/interfaces file on your non-accessible VPC instances to use the VPN gateway as their default route: |
51 | 13 | Adam Feuer | <pre> |
52 | 13 | Adam Feuer | # static routes |
53 | 16 | Adam Feuer | up route del -net 0.0.0.0/0 gw 10.0.10.1 dev eth0 |
54 | 14 | Adam Feuer | up route add -net 0.0.0.0/0 gw 10.0.10.10 dev eth0 |
55 | 1 | Yaron Sheffer | </pre> |
56 | 1 | Yaron Sheffer | *Edit:* changing the routing table on a guest is "discouraged by Amazon":https://forums.aws.amazon.com/thread.jspa?threadID=89866. Therefore the preceding method (modification of the EC2 routing table) is preferred. |
57 | 26 | Naer Chang | *Edit2:* you can't change default routing (<VPC CIDR block> to local) but you can certainly add your custom routing in the instance (or console) on top of the default ones (ex: if you want to do policy based routing). In VPC private IP doesn't change across reboot so adding routing rules should be safe (you don't use elastic IP to do routing). Amazon console's routing changes supersede OS level routing (I am guessing they happen at higher up router level). In the console you are able to specify <VPC CIDR block>. In a VPC instance your are residing under VPC CIDR block - in a subnet. Static routing would be for advanced users under VPC instance (there is a potential to lock yourself out; from the console Amazon guarantees you can't remove the default routing so you can't lock yourself out). |
58 | 9 | Yaron Sheffer | |
59 | 15 | Adam Feuer | h2. Debugging |
60 | 15 | Adam Feuer | |
61 | 15 | Adam Feuer | These instructions didn't work for me out of the box, because I set my network up a little differently. To debug, I found it useful to do the following: |
62 | 15 | Adam Feuer | |
63 | 17 | Adam Feuer | * Ping the IP address of the next closest interface. |
64 | 19 | Yaron Sheffer | * If you don't get replies, you need to find out what's wrong - if there is a wrong route, IP Tables rule, or something else. Use tshark to capture and display ICMP packets (replace 192.168.254.10 with the IP address of the host you are interested in): |
65 | 15 | Adam Feuer | ** To capture: |
66 | 15 | Adam Feuer | <pre> |
67 | 15 | Adam Feuer | sudo tshark -f "host 192.168.254.10" -i eth0 -w /tmp/capture.cap |
68 | 15 | Adam Feuer | </pre> |
69 | 15 | Adam Feuer | ** To display: |
70 | 15 | Adam Feuer | <pre> |
71 | 15 | Adam Feuer | sudo tshark -R "icmp and host 192.168.254.10" -r /tmp/capture.cap |
72 | 1 | Yaron Sheffer | </pre> |
73 | 1 | Yaron Sheffer | * You may need to install tshark on the client, VPN gateway, and VPC box to get a good view of what is happening. |
74 | 26 | Naer Chang | * if you are doing for example policy based routing use this to see if mac addresses are changed correctly (or not changed at all, which would indicate routing issues). Because policy based routing triggers spoofing violation make sure you disable these checks everywhere it matters (source and destination servers). You will not see packets drop in sniff tools, I can't stress this enough, all you will see is packet not going somewhere but not packet loss at destination server (nothing will show up in sniff tool) so it will be difficult to determine the reason (hardware/software router, OS, and 3rd party interception software like a proxy can drop packets): |
75 | 26 | Naer Chang | ** To verify routing changes (check source/destination mac addresses are correct): |
76 | 26 | Naer Chang | <pre> |
77 | 26 | Naer Chang | tcpdump -eqni eth0 'port 80' , if you routed port 80 traffic to a remote proxy server do this on both VPN/Proxy servers |
78 | 26 | Naer Chang | </pre> |
79 | 15 | Adam Feuer | |
80 | 1 | Yaron Sheffer | h2. Configuration Files |
81 | 5 | Yaron Sheffer | |
82 | 5 | Yaron Sheffer | h3. /etc/ipsec.conf on the Client |
83 | 4 | Yaron Sheffer | |
84 | 4 | Yaron Sheffer | <pre> |
85 | 4 | Yaron Sheffer | # ipsec.conf - strongSwan IPsec configuration file |
86 | 4 | Yaron Sheffer | |
87 | 4 | Yaron Sheffer | # basic configuration |
88 | 4 | Yaron Sheffer | |
89 | 4 | Yaron Sheffer | config setup |
90 | 4 | Yaron Sheffer | # nat_traversal=yes |
91 | 4 | Yaron Sheffer | charonstart=yes |
92 | 4 | Yaron Sheffer | plutostart=no |
93 | 4 | Yaron Sheffer | # charondebug="ike 2, knl 2, cfg 2, mgr 2, chd 2, net 2" |
94 | 4 | Yaron Sheffer | |
95 | 4 | Yaron Sheffer | # Connections into AWS VPC |
96 | 4 | Yaron Sheffer | conn %default |
97 | 4 | Yaron Sheffer | ikelifetime=60m |
98 | 4 | Yaron Sheffer | keylife=20m |
99 | 4 | Yaron Sheffer | rekeymargin=3m |
100 | 1 | Yaron Sheffer | keyingtries=1 |
101 | 4 | Yaron Sheffer | keyexchange=ikev2 |
102 | 1 | Yaron Sheffer | authby=secret |
103 | 4 | Yaron Sheffer | |
104 | 4 | Yaron Sheffer | conn us-east-1-vpc |
105 | 4 | Yaron Sheffer | left=%any |
106 | 4 | Yaron Sheffer | leftsourceip=%config |
107 | 4 | Yaron Sheffer | leftid=<my-email-address> |
108 | 4 | Yaron Sheffer | leftfirewall=yes |
109 | 4 | Yaron Sheffer | right=<gateway's elastic IP> |
110 | 1 | Yaron Sheffer | rightsubnet=10.10.0.0/16 |
111 | 6 | Yaron Sheffer | rightid=@us-east-gw.example.com |
112 | 4 | Yaron Sheffer | auto=start |
113 | 4 | Yaron Sheffer | |
114 | 4 | Yaron Sheffer | # Add connections here. |
115 | 4 | Yaron Sheffer | |
116 | 4 | Yaron Sheffer | # include /var/lib/strongswan/ipsec.conf.inc |
117 | 4 | Yaron Sheffer | </pre> |
118 | 4 | Yaron Sheffer | |
119 | 4 | Yaron Sheffer | h3. /etc/ipsec.secrets on the Client |
120 | 4 | Yaron Sheffer | |
121 | 4 | Yaron Sheffer | <pre> |
122 | 6 | Yaron Sheffer | us-east-gw.example.com : PSK "aa82c7a776e2175114213acc02dda9951a6bc25deb433e6d5d6ef7058626c589" |
123 | 4 | Yaron Sheffer | </pre> |
124 | 4 | Yaron Sheffer | |
125 | 4 | Yaron Sheffer | h3. /etc/ipsec.conf on the Gateway |
126 | 4 | Yaron Sheffer | |
127 | 4 | Yaron Sheffer | <pre> |
128 | 4 | Yaron Sheffer | # ipsec.conf - strongSwan IPsec configuration file |
129 | 4 | Yaron Sheffer | |
130 | 4 | Yaron Sheffer | # basic configuration |
131 | 4 | Yaron Sheffer | |
132 | 4 | Yaron Sheffer | config setup |
133 | 4 | Yaron Sheffer | # nat_traversal=yes |
134 | 4 | Yaron Sheffer | charonstart=yes |
135 | 4 | Yaron Sheffer | plutostart=no |
136 | 7 | Yaron Sheffer | # charondebug="ike 2, knl 2, cfg 2, mgr 3, chd 2, net 2" |
137 | 1 | Yaron Sheffer | |
138 | 4 | Yaron Sheffer | # /etc/ipsec.conf - strongSwan IPsec configuration file |
139 | 4 | Yaron Sheffer | |
140 | 4 | Yaron Sheffer | conn %default |
141 | 4 | Yaron Sheffer | ikelifetime=60m |
142 | 4 | Yaron Sheffer | keylife=20m |
143 | 4 | Yaron Sheffer | rekeymargin=3m |
144 | 4 | Yaron Sheffer | keyingtries=1 |
145 | 4 | Yaron Sheffer | keyexchange=ikev2 |
146 | 4 | Yaron Sheffer | authby=secret |
147 | 4 | Yaron Sheffer | |
148 | 4 | Yaron Sheffer | conn client |
149 | 7 | Yaron Sheffer | # The leftid parameter is not a real DNS name |
150 | 4 | Yaron Sheffer | leftid=us-east-gw.example.com |
151 | 7 | Yaron Sheffer | # The "left" parameter is the gateway's private IP |
152 | 4 | Yaron Sheffer | left=10.10.0.10 |
153 | 4 | Yaron Sheffer | # We are protecting the entire VPC, not just this subnet |
154 | 1 | Yaron Sheffer | leftsubnet=10.10.0.0/16 |
155 | 4 | Yaron Sheffer | leftfirewall=yes |
156 | 4 | Yaron Sheffer | right=%any |
157 | 4 | Yaron Sheffer | # The virtual IP pool is outside the VPC! |
158 | 4 | Yaron Sheffer | rightsourceip=10.100.255.0/28 |
159 | 4 | Yaron Sheffer | auto=add |
160 | 4 | Yaron Sheffer | |
161 | 4 | Yaron Sheffer | # Add connections here. |
162 | 4 | Yaron Sheffer | |
163 | 1 | Yaron Sheffer | # include /var/lib/strongswan/ipsec.conf.inc |
164 | 4 | Yaron Sheffer | </pre> |
165 | 4 | Yaron Sheffer | |
166 | 4 | Yaron Sheffer | h3. /etc/ipsec.secrets on the Gateway |
167 | 6 | Yaron Sheffer | |
168 | 5 | Yaron Sheffer | <pre> |
169 | 4 | Yaron Sheffer | <my-email-address> : PSK "aa82c7a776e2175114213acc02dda9951a6bc25deb433e6d5d6ef7058626c589" |
170 | 1 | Yaron Sheffer | </pre> |