If your VPC has a private subnet with instances which need to access the internet, then you need a NAT instance.
You may be using the default Amazon built AMI ami-vpc-nat which by defaults allows all traffic from the private instances to go out via the NAT.
But chances are you want to have greater control on the NATing rules. For example you may want to only allow the private instances to access the repositories for OS upgrades.
Also you may want to use your favorite Linux OS instead of the default Amazon Linux OS.
NATing can be configured using iptables or ufw but there’s a great Puppetlabs firewall module which makes NATing easy to configure http://forge.puppetlabs.com/puppetlabs/firewall
Initial VPC setup
Create the VPC, Security Group and Route Table as explained in the Amazon documentation at:
http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_NAT_Instance.html
Launch Instance
Launch an instance using your favorite Linux OS, in this example we’ll be using Ubuntu 12.04 LTS.
Launch it into your public subnet. Assign an Elastic IP address. Then update the Route Table as explained in the documentation link.
Important: remember to disable the Change Source / Dest Check option on the instance.
Enable IP Forwarding
To enable NATing you need to enable IP forward on the OS. This Puppet manifest snippet will enable it:
1 2 3 4 |
exec { 'enable_ip_forward': command => 'sysctl -w net.ipv4.ip_forward=1', unless => 'sysctl net.ipv4.ip_forward | grep "1$"', } |
To make the change more permanent, change the setting in sysctl.conf
1 2 3 4 5 6 7 |
file { 'sysctl.conf': path => '/etc/sysctl.conf', source => "puppet:///modules/${module_name}/sysctl.conf" ), owner => 'root', group => 'root', mode => 0644, } |
You can put those two manifest resources in a module called sysctl.
Install Puppet plugin
On the Puppetmaster server, install the module:
1 |
sudo puppet module install puppetlabs/firewall |
You must enable plugin sync on all Puppet agents and the master. Add the following to puppet.conf
1 2 |
[main] pluginsync = true |
To clear any unmanaged firewall rules on the instance, add the following to your site.pp or any similar top-scope file.
1 2 3 |
resources { "firewall": purge => true } |
NATing Manifest
Here’s what the NATing manifest would look like if you want to allow just NATing for the ubuntu apt repositories:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
class nat { include sysctl # for setting up ip_forward in stsctl include firewall # include puppetlabs/firewall module Firewall { require => Class[ 'sysctl', 'firewall' ], } firewall { '001 Allow access to ubuntu apt': ensure => present, chain => 'POSTROUTING', jump => 'MASQUERADE', table => 'nat', outiface => 'eth0', proto => 'tcp', dport => 80, destination => 'au.archive.ubuntu.com', } firewall { '002 Allow access to ubuntu security apt': ensure => present, chain => 'POSTROUTING', jump => 'MASQUERADE', table => 'nat', outiface => 'eth0', proto => 'tcp', dport => 80, destination => 'security.ubuntu.com', } } |
Remember to include the sysctl ip_forward settings and the firewall module which are required for each firewall resource.
Conclusion
The Puppetlabs firwall modules makes it quick and easy to add new firewall rules and ensure greater security with refined NATing rules.
If your NAT instance is critical in allowing outgoing traffic for your production systems, consider implementing NAT high availability described in this blog entry: /aws-high-availability-on-nat-instances/