Deploying fck-nat
The most well-supported way to deploy fck-nat with all of its features available out of the box is via CDK. If you're using another Infrastructure-as-code provider, you can still deploy a basic NAT instance with fck-nat, but it is more intensive to support some of fck-nat's additional features.
Notably missing at the moment is a Terraform module. If you're using Terraform and would like to leverage fck-nat, please +1 this issue: Create a fck-nat Terraform module
CDK
fck-nat provides an official CDK module which supports all of fck-nat's features (namely high-availability mode) out-of-the-box. The CDK module is currently available both in Typescript and Python. You can find detailed documentation on Construct Hub. Here's an example use of the CDK construct in Typescript:
const natGatewayProvier = new FckNatInstanceProvider({
instanceType: InstanceType.of(InstanceClass.T4G, InstanceSize.MICRO),
});
const vpc = new Vpc(this, 'vpc', {
natGatewayProvider,
});
natGatewayProvider.securityGroup.addIngressRule(Peer.ipv4(vpc.vpcCidrBlock), Port.allTraffic());
That's it! This will deploy your VPC using fck-nat as your NAT provider in high availability mode. This includes all necessary routing configurations and deploys fck-nat in an Autoscaling group to ensure that a new instance is brought up automatically in case the NAT instance is terminated.
You can also deploy fck-nat in non-HA mode using CDK's built-in NatInstanceProvider
like so:
const natGatewayProvider = new NatInstanceProvider({
instanceType: InstanceType.of(InstanceClass.T4G, InstanceSize.MICRO),
machineImage: new LookupMachineImage({
name: 'fck-nat-amzn2-*-arm64-ebs',
owners: ['568608671756'],
})
})
const vpc = new Vpc(this, 'vpc', {
natGatewayProvider,
});
natGatewayProvider.securityGroup.addIngressRule(Peer.ipv4(vpc.vpcCidrBlock), Port.allTraffic());
Read more about the NatInstanceProvider
construct
Cloudformation
For brevity, this document assumes you already have a VPC with public and private subnets defined in your Cloudformation template. This example template provisions the minimum resources required to connect fck-nat in your VPC. This is a good option for those that have an existing VPC and NAT Gateway and are looking to switch over.
- A security group allowing ingress traffic from within the VPC and egress out to the internet
- A auto scaling group that creates an EC2 instance using the fck-nat AMI
- A route in the private subnet route table directing traffic to the fck-nat instance.
This snippet assumes the following resources are already defined:
VPC
: AnAWS::EC2::VPC
resource.PublicSubnet
: AnAWS::EC2::Subnet
which has anAWS::EC2::InternetGateway
attached.PrivateSubnetRouteTable
: AnAWS::EC2::RouteTable
with anAWS::EC2::SubnetRouteTableAssociation
to aAWS::EC2::Subnet
Steps to deploy:
- Paste your VPC ID, public subnet ID, and CIDR block into the parameters. Change the ImageId based on the region fck-nat is deployed to.
- Ensure that your public subnet has
Enable auto-assign public IPv4 address
turned on. This can be found in the Console atVPC > Subnets > Edit subnet settings > Auto-assign IP settings
. - Deploy with cloudformation
aws cloudformation deploy --force-upload --capabilities CAPABILITY_IAM --template-file template.yml --stack-name FckNat
- Add the default route to your route table on the subnet. It is best to do this manually so you can do a seamless cut over from your existing nat gateway. Go to
VPC > Route Tables > Private route table > Routes > Edit Routes
Add a 0.0.0.0/0 route pointing to the network interface.
Parameters:
vpc:
Type: String
Default: "vpc-121212121212121212"
subnet:
Type: String
Default: "subnet-121212121212121212"
CIDR:
Type: String
Default: "10.0.0.0/16"
Resources:
FckNatInterface:
Type: AWS::EC2::NetworkInterface
Properties:
SubnetId: !Sub "${subnet}"
GroupSet:
- Fn::GetAtt:
- NatSecurityGroup
- GroupId
SourceDestCheck: false
FckNatAsgInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Roles:
- Ref: NatRole
FckNatAsgLaunchConfig:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
ImageId: ami-05b6d5a2e26f13c93
InstanceType: t4g.nano
IamInstanceProfile:
Ref: FckNatAsgInstanceProfile
SecurityGroups:
- Fn::GetAtt:
- NatSecurityGroup
- GroupId
UserData:
Fn::Base64:
Fn::Join:
- ""
- - |-
#!/bin/bash
echo "eni_id=
- Ref: FckNatInterface
- |-
" >> /etc/fck-nat.conf
service fck-nat restart
DependsOn:
- NatRole
FckNatAsg:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
MaxSize: "1"
MinSize: "1"
DesiredCapacity: "1"
LaunchConfigurationName:
Ref: FckNatAsgLaunchConfig
VPCZoneIdentifier:
- !Sub "${subnet}"
UpdatePolicy:
AutoScalingScheduledAction:
IgnoreUnmodifiedGroupSizeProperties: true
NatSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security Group for NAT
SecurityGroupIngress:
- CidrIp: !Sub "${CIDR}"
IpProtocol: "-1"
SecurityGroupEgress:
- CidrIp: 0.0.0.0/0
Description: Allow all outbound traffic by default
IpProtocol: "-1"
VpcId: !Sub "${vpc}"
NatRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: ec2.amazonaws.com
Version: "2012-10-17"
Policies:
- PolicyDocument:
Statement:
- Action:
- ec2:AttachNetworkInterface
- ec2:ModifyNetworkInterfaceAttribute
Effect: Allow
Resource: "*"
Version: "2012-10-17"
PolicyName: attachNatEniPolicy
- PolicyDocument:
Statement:
- Action:
- ec2:AssociateAddress
- ec2:DisassociateAddress
Effect: Allow
Resource: "*"
Version: "2012-10-17"
PolicyName: associateNatAddressPolicy
Manual - Web Console
The following instructions can be used to deploy the fck-nat AMI manually.
**Summary: **
1. Launch fck-nat AMI
2. Modify ENI to disable source/dest check
3. Modify the private route table, default route to fck-nat target
4. Validate
NOTE: The following example uses fck-nat AMI version 1.2.0 for arm64 on t4g.nano.
EC2 Instance Launch
- Visit the EC2 service in your preferred region: EC2 Link
- Click Launch Instances
- Give the instance a name
- Search for AMIs owned by "568608671756"
- Select the ARM64 1.2.0 fck-nat AMI
- Select Instance Type t4g.nano
- Modify Network Settings
- Select VPC
- Place in public subnet, ensure Public IP is assigned
- Attached Security group that permits
inbound: entire VPC CIDR inbound, all traffic
outbound: 0.0.0.0/0, all traffic
- Leave Storage at 2GB
- Review and launch
Wait for Launch
Modify EC2 Network Interface
We must modify the ENI attached to the newly launched instance to disable source/destination checks, this allows us to route through (actually hairpinning) the instance.
1. Click on the ENI of the instance
2. Select ENI, Click Actions -> Change source/dest. check
3. Disable Source/Dest check and Save
Modify VPC Routing Table
The VPC routing table associated with your private subnets must be modified to route traffic matching the default route to the new fck-nat instance.
1. Open the VPC Service, Route Tables
2. Open the private route table, edit routes
3. Add a default route, target: fck-nat instance
Validate
Log into an instance in a private subnet and validate the external IP is the public IP assigned to your fck-nat instance.