Configuration
pelotech-nat is configured via /etc/pelotech-nat.conf (preferred) or /etc/fck-nat.conf (fallback), a shell-sourced configuration file. All variables are optional.
Configuration File
The file is sourced as a shell script at boot by the pelotech-nat systemd service. The service checks for /etc/pelotech-nat.conf first; if not found, it falls back to /etc/fck-nat.conf. If neither file exists, the instance starts with default behavior (NAT on the primary interface with no EIP or secondary ENI).
Example
# /etc/pelotech-nat.conf (or /etc/fck-nat.conf)
# Associate an Elastic IP at boot
eip_id=eipalloc-0123456789abcdef0
# Enable CloudWatch agent
cwagent_enabled=true
cwagent_cfg_param_name=/pelotech-nat/cloudwatch-config
# Tune connection tracking
nf_conntrack_max=131072
ip_local_port_range="1024 65535"
# Force FIPS endpoints (auto-detected by default in US/GovCloud regions)
fips_endpoints=true
Variables
| Variable | Description | Default |
|---|---|---|
eip_id |
Elastic IP allocation ID to associate at boot. The instance will call ec2:AssociateAddress with --allow-reassociation. |
(none) |
eni_id |
Secondary ENI ID to attach at boot (device index 1). Used for dual-ENI setups where private traffic arrives on a separate interface. | (none) |
interface |
Override the interface name for NAT rules. Only used if eni_id is not set. |
(auto-detected from IMDS) |
ip_local_port_range |
Kernel ephemeral port range (sysctl net.ipv4.ip_local_port_range). Widening this increases the number of concurrent NAT connections. |
(kernel default: 32768 60999) |
nf_conntrack_max |
Maximum number of tracked connections (sysctl net.netfilter.nf_conntrack_max). Increase for high-throughput workloads. |
(kernel default) |
cwagent_enabled |
Set to any non-empty value to enable the CloudWatch agent. Requires cwagent_cfg_param_name to also be set. |
(none) |
cwagent_cfg_param_name |
SSM Parameter Store path containing the CloudWatch agent JSON configuration. | (none) |
fips_endpoints |
Force AWS FIPS endpoint usage. Set to true to enable, false to disable. When empty (default), FIPS endpoints are auto-enabled in US regions (us-east-1, us-east-2, us-west-1, us-west-2) and GovCloud regions. |
(auto-detect) |
Boot Sequence
The pelotech-nat.service is a Type=oneshot systemd unit that runs after network-online.target:
systemd (multi-user.target)
└─ pelotech-nat.service (oneshot, after network-online.target)
├─ Source /etc/pelotech-nat.conf (or /etc/fck-nat.conf fallback)
├─ Fetch IMDSv2 token
├─ Query instance-id, region, MAC, ENI-id from IMDS
├─ Validate IMDS metadata (exit on failure)
├─ Auto-detect FIPS endpoints (based on region or fips_endpoints config)
├─ Disable source/destination check (ec2:ModifyNetworkInterfaceAttribute)
├─ Associate EIP (if eip_id set)
├─ Attach secondary ENI (if eni_id set)
├─ sysctl: enable IPv4 forwarding
├─ sysctl: tune ip_local_port_range (if set)
├─ sysctl: tune nf_conntrack_max (if set)
├─ sysctl: disable reverse path filtering (rp_filter=0)
├─ Apply nftables masquerade rule on outbound interface
├─ sysctl: enable IPv6 forwarding + accept_ra
└─ Start CloudWatch agent (if cwagent_enabled set)
Passing Configuration via User Data
Use EC2 user data to write the configuration file before the service starts:
#!/bin/bash
cat <<'CONF' > /etc/pelotech-nat.conf
eip_id=eipalloc-0123456789abcdef0
cwagent_enabled=true
cwagent_cfg_param_name=/pelotech-nat/cloudwatch-config
CONF
When using the terraform-aws-fck-nat module, configuration is passed automatically via the module's variables.
Troubleshooting
Checking Service Status
# Service status and recent logs
systemctl status pelotech-nat
# Full service logs
journalctl -u pelotech-nat --no-pager
# Follow logs in real time (useful during boot debugging)
journalctl -u pelotech-nat -f
Common Failure Modes
Missing configuration file
The service runs without a config file but won't associate an EIP or attach a secondary ENI. If you expect these features, ensure /etc/pelotech-nat.conf exists and is populated before the service starts (typically via user data).
IAM permissions errors
The instance profile must have permissions for ec2:ModifyNetworkInterfaceAttribute, ec2:AssociateAddress (if using EIP), and ec2:AttachNetworkInterface (if using secondary ENI). Look for AccessDeniedException in the journal output.
ENI already attached to another instance
If eni_id is set and the ENI is still attached to a previous instance (e.g., after a replace), the attachment loop will retry for 60 seconds then fail. Detach the ENI from the old instance or use a lifecycle hook to release it before the new instance starts.
IMDS errors The service requires IMDSv2. If IMDS calls fail, check that the instance metadata service is enabled and that the hop limit is sufficient (at least 2 if running inside a container or behind a proxy).
Restarting After Fixing Issues
# Restart the service after fixing config or permissions
sudo systemctl restart pelotech-nat
# Check if it succeeded
systemctl is-active pelotech-nat
The service has a restart limit of 5 attempts within 5 minutes. If the limit is reached, systemctl reset-failed pelotech-nat clears the counter before restarting.