Configuring Multiple Network Interfaces with Netplan on Ubuntu 18.04 EC2 Instances for Dual Elastic IP Support


2 views

When working with AWS EC2 instances running Ubuntu 18.04, you might encounter a situation where only one Elastic IP (EIP) responds properly despite having multiple network interfaces configured. This typically happens when:

  • Using Ubuntu's Netplan configuration system (which replaced ifupdown)
  • Having interfaces in different subnets within the same VPC
  • Needing both interfaces to respond to public traffic via Elastic IPs

Your current 50-cloud-init.yaml shows a basic dual-interface setup:

network:
    version: 2
    ethernets:
        eth0:
            dhcp4: true
            match:
                macaddress: 06:05:14:4a:26:ce
            set-name: eth0
        eth1:
            dhcp4: true
            match:
                macaddress: 06:86:ef:73:d4:1a
            set-name: eth1

The key issues with this configuration are:

  1. Missing source-based routing rules
  2. No policy routing for multiple default routes
  3. Incomplete handling of multiple gateways

Here's the full Netplan configuration that properly handles multiple interfaces:

network:
    version: 2
    renderer: networkd
    ethernets:
        eth0:
            dhcp4: true
            match:
                macaddress: 06:05:14:4a:26:ce
            set-name: eth0
            routes:
              - to: 0.0.0.0/0
                via: 172.31.16.1
                metric: 100
                table: 100
            routing-policy:
              - from: 172.31.24.184
                table: 100
        eth1:
            dhcp4: true
            match:
                macaddress: 06:86:ef:73:d4:1a
            set-name: eth1
            routes:
              - to: 0.0.0.0/0
                via: 172.31.48.1
                metric: 200
                table: 200
            routing-policy:
              - from: 172.31.52.86
                table: 200

To apply this configuration:

sudo netplan generate
sudo netplan apply

Verify the routing tables:

ip route show table 100
ip route show table 200

If issues persist:

  1. Check security group rules for both interfaces
  2. Verify Elastic IP association in AWS console
  3. Test connectivity to private IPs first
  4. Examine networkd logs: journalctl -u systemd-networkd

To ensure the configuration survives instance reboots and AMI creation:

  1. Remove MAC address matching if creating an AMI
  2. Use interface names (eth0, eth1) directly
  3. Consider using cloud-init for dynamic configuration

When working with AWS EC2 instances running Ubuntu 18.04, you might encounter a specific networking challenge: adding a second network interface with its own Elastic IP while maintaining connectivity through both interfaces. The Amazon Linux AMI handles this seamlessly, but Ubuntu requires additional configuration.

The typical scenario involves:

  • Two ENIs (Elastic Network Interfaces) in the same VPC but different subnets
  • Each interface has its own Elastic IP association
  • Security groups allowing necessary traffic for both interfaces

The symptom manifests as only one interface responding to public traffic despite both private IPs working correctly.

Ubuntu 18.04 uses Netplan for network configuration. The default /etc/netplan/50-cloud-init.yaml needs modification for multiple interfaces:


network:
    version: 2
    ethernets:
        eth0:
            dhcp4: true
            dhcp4-overrides:
                route-metric: 100
            match:
                macaddress: 06:05:14:4a:26:ce
            set-name: eth0
        eth1:
            dhcp4: true
            dhcp4-overrides:
                route-metric: 200
            match:
                macaddress: 06:86:ef:73:d4:1a
            set-name: eth1

The key to making both interfaces work lies in the routing configuration. Add these rules to ensure proper traffic flow:


# Create custom routing table for eth1
echo "200 eth1-rt" >> /etc/iproute2/rt_tables

# Add rules for source-based routing
ip rule add from 172.31.24.184 lookup main
ip rule add from 172.31.52.86 lookup eth1-rt

# Add routes to the new table
ip route add default via 172.31.16.1 dev eth1 table eth1-rt
ip route add 172.31.48.0/20 dev eth1 src 172.31.52.86 table eth1-rt

# Make changes persistent
cat < /etc/network/if-up.d/eth1-routing
#!/bin/sh
if [ "\$IFACE" = "eth1" ]; then
    ip rule add from 172.31.52.86 lookup eth1-rt
    ip route add default via 172.31.16.1 dev eth1 table eth1-rt
fi
EOF
chmod +x /etc/network/if-up.d/eth1-routing

After applying changes with netplan apply, verify with these commands:


# Check interface status
ip -4 addr show

# View routing tables
ip route show
ip route show table eth1-rt

# Test connectivity from both interfaces
curl --interface eth0 ifconfig.me
curl --interface eth1 ifconfig.me

To ensure the configuration survives instance termination or AMI creation:

  1. Replace MAC addresses in netplan with device names
  2. Create systemd service for routing rules
  3. Test thoroughly before creating the AMI

# Example systemd service for persistent routing
[Unit]
Description=Eth1 custom routing
After=network.target

[Service]
Type=oneshot
ExecStart=/etc/network/if-up.d/eth1-routing

[Install]
WantedBy=multi-user.target

If you encounter problems:

  • Check AWS route tables for both subnets
  • Verify security group rules apply to both ENIs
  • Ensure no conflicting iptables/nftables rules exist
  • Monitor traffic with tcpdump -i eth0 and tcpdump -i eth1