Fault Tolerant Routing with Alpine Linux: Difference between revisions

From Alpine Linux
(update links)
(use relative symlinks)
 
(3 intermediate revisions by 3 users not shown)
Line 1: Line 1:
This document will explain how to setup a fault-tolerant router using Alpine Linux.  It has been tested using Alpine Linux 2.2.3.
This document explains how to setup a fault-tolerant router using Alpine Linux.  It has been tested with Alpine Linux 2.2.3.
== Hardware and Network Setup ==
== Hardware and Network Setup ==
The network used in this example is as follows:
The network used in this example is as follows:
* Will run (at least initially) IPv4
* Will run (at least initially) IPv4
* Pre-existing border router that NATs from public IP(s) to the 10.0.0.0/8 network and has the address 10.0.0.1/24 on the transit network
* Pre-existing border router that performs NAT from public IP(s) to the 10.0.0.0/8 network and has the address 10.0.0.1/24 on the transit network
* The border router will have a default route to the internal network via 10.0.0.2 (the virtual IP address of the routers being setup in this doc)
* The border router will have a default route to the internal network via 10.0.0.2 (the virtual IP address of the routers being set up in this doc)
* A transit network between the border router and the fault-tolerant routers in this document will be on 10.0.0.0/24
* The transit network between the border router and the fault-tolerant routers described in this document, will be on 10.0.0.0/24
* The routers will also connect several internal subnets on the network:
* The routers will also connect several internal subnets on the network:
** 10.0.1.0/24
** 10.0.1.0/24
Line 11: Line 11:
** 10.0.3.0/24
** 10.0.3.0/24
* It's assumed that 10.0.0.0/24 and 10.0.1.0/24 are connected via dedicated interfaces (eth0 and eth1, respectively), while 10.0.2.0/24 and 10.0.3.0/24 share an interface(eth2), but traffic is segregated using 802.1q vlan tagging, with 10.0.2.0/24 using vlan id 2, and 10.0.3.0/24 using vlan id 3.
* It's assumed that 10.0.0.0/24 and 10.0.1.0/24 are connected via dedicated interfaces (eth0 and eth1, respectively), while 10.0.2.0/24 and 10.0.3.0/24 share an interface(eth2), but traffic is segregated using 802.1q vlan tagging, with 10.0.2.0/24 using vlan id 2, and 10.0.3.0/24 using vlan id 3.
* Finally, all computers in subnets 10.0.1.0/24, 10.0.2.0/24 and 10.0.3.0/24 are setup with a default gateway of 10.0.x.1
* Finally, all computers in subnets 10.0.1.0/24, 10.0.2.0/24 and 10.0.3.0/24 are set up with a default gateway of 10.0.x.1
Two computers will be needed, with at three NICs in them (more if you are connecting more network segments together), and they will act as routers.
Two computers will be needed, with at least three NICs in them (more if you are connecting more network segments together), to act as routers.


== Initial Setup ==
== Initial Setup ==
First, [[Create a Bootable USB|setup Alpine]] on a USB key or CF card on both computers.  Connect both computers initially to 10.0.0.0/24 on eth0, and assign them ip addresses of 10.0.0.3/24 and 10.0.0.4/24 in the setup-alpine script(for router1 and router2, respectively). Do not configure other interfaces initially.  Ensure that both machines are pingable.
First, [[Create a Bootable USB|setup Alpine]] on a USB key or CF card on both computers.  Connect both computers initially to 10.0.0.0/24 on eth0, and assign them ip addresses of 10.0.0.3/24 and 10.0.0.4/24 in the setup-alpine script(for router1 and router2, respectively). Do not configure other interfaces initially.  Ensure that both machines are pingable.


Next, connect them both to 10.0.1.0/24 on eth1, and assign them ip addresses of 10.0.1.2/24 and 10.0.1.3/24, respectively.  Ensure that they can also ping each other. /etc/network/interfaces (for router1) at this point should look like:
Next, connect them both to 10.0.1.0/24 on eth1, and assign them ip addresses of 10.0.1.2/24 and 10.0.1.3/24, respectively.  Ensure that they can also ping each other. At this point, /etc/network/interfaces (for router1) should look like this:
  auto eth0
  auto eth0
  iface eth0 inet static
  iface eth0 inet static
Line 28: Line 28:
         netmask 255.255.255.0
         netmask 255.255.255.0


Finally, get the last two networks connected (the ip addresses given are for router1, and these steps should be performed on router2 as well):
Finally, get the last two networks connected (the ip addresses given are for router1. The following steps should be performed on router2):
  modprobe 8021q
  modprobe 8021q
  echo "8021q" >> /etc/modules
  echo "8021q" >> /etc/modules
Line 51: Line 51:
         post-down vconfig rem $IFACE
         post-down vconfig rem $IFACE
  EOF
  EOF
Test that you can also ping between these interfaces.
Test that you can also ping between the two interfaces.


=== Start ip forwarding ===
=== Start ip forwarding ===
Next, turn them into simple routers by enabling ip forwarding (do this on each box):
Next, turn them into simple routers by enabling ip forwarding (do that on each box):
{{Cmd|echo 1 > /proc/sys/net/ipv4/ip_forward}}
{{Cmd|echo 1 > /proc/sys/net/ipv4/ip_forward}}


If you follow the ucarp section below, you'll also need to disable rp_filter (RFC3704 Ingress Filtering).  Since this howto is designed for an internal router this should (or might not) be acceptable.  Available options for this setting can be viewed at http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=Documentation/networking/ip-sysctl.txt;hb=HEAD#l855.
If you follow the ucarp section below, you'll also need to disable rp_filter (RFC3704 Ingress Filtering).  Since this how-to is designed for an internal router this should (or might not) be acceptable.  Available options for this setting can be viewed at https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
{{Cmd|echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
{{Cmd|echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/eth0/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/eth0/rp_filter
Line 69: Line 69:
* Copy the scripts for each the interface:
* Copy the scripts for each the interface:
{{Cmd|apk add ucarp
{{Cmd|apk add ucarp
ln -s /etc/init.d/ucarp /etc/init.d/ucarp.eth0
ln -s ucarp /etc/init.d/ucarp.eth0
ln -s /etc/init.d/ucarp /etc/init.d/ucarp.eth1
ln -s ucarp /etc/init.d/ucarp.eth1
ln -s /etc/init.d/ucarp /etc/init.d/ucarp.eth2.2
ln -s ucarp /etc/init.d/ucarp.eth2.2
ln -s /etc/init.d/ucarp /etc/init.d/ucarp.eth2.3
ln -s ucarp /etc/init.d/ucarp.eth2.3
cp /etc/conf.d/ucarp /etc/conf.d/ucarp.eth0
cp /etc/conf.d/ucarp /etc/conf.d/ucarp.eth0
cp /etc/conf.d/ucarp /etc/conf.d/ucarp.eth1
cp /etc/conf.d/ucarp /etc/conf.d/ucarp.eth1
Line 118: Line 118:
rc-update add ucarp.eth2.2
rc-update add ucarp.eth2.2
rc-update add ucarp.eth2.3
rc-update add ucarp.eth2.3
/etc/init.d/ucarp.eth0 start
rc-service ucarp.eth0 start
/etc/init.d/ucarp.eth1 start
rc-service ucarp.eth1 start
/etc/init.d/ucarp.eth2.2 start
rc-service ucarp.eth2.2 start
/etc/init.d/ucarp.eth2.3 start
rc-service ucarp.eth2.3 start
lbu commit}}
lbu commit}}
* Do the above steps for each router
* Do the above steps for each router
Line 129: Line 129:
== Install and configure Shorewall iptables frontend ==
== Install and configure Shorewall iptables frontend ==


We will name our Shorewall zones by letters to keep the config files simple, and they will correspond to subnets and interfaces as follows:
We will refer to the Shorewall zones by letters to keep the config files simple. They will correspond to subnets and interfaces as follows:
  A = eth0 = 10.0.0.0/24
  A = eth0 = 10.0.0.0/24
  B = eth1 = 10.0.1.0/24
  B = eth1 = 10.0.1.0/24
Line 158: Line 158:
  C_3 ipv4
  C_3 ipv4
  #LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONCE - DO NOT REMOVE
  #LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONCE - DO NOT REMOVE
Edit /etc/shorewall/policy: (note: this allows all traffic between internal subnets and all traffic outbound towards the Internet, but blocks all traffic inbound by default, this policy might need to be adjusted in your case)
Edit /etc/shorewall/policy: (note: this allows all traffic between internal subnets and all traffic outbound to the Internet, but blocks all traffic inbound by default, this policy might need to be adjusted in your case)
  #FIRST LINE
  #FIRST LINE
  A  all  REJECT  INFO
  A  all  REJECT  INFO
Line 172: Line 172:
  all all  REJECT  INFO
  all all  REJECT  INFO
  #LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONCE - DO NOT REMOVE  
  #LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONCE - DO NOT REMOVE  
Edit /etc/shorewall/rules: (the following simply allow SSH traffic in to your two routers - more will probably be needed to accept or reject traffic based on your needs)
Edit /etc/shorewall/rules: (the following simply allows SSH traffic in to your two routers - more will probably be needed to accept or reject traffic based on your needs)
  #FIRST LINE
  #FIRST LINE
  ACCEPT  A  fw  tcp  22
  ACCEPT  A  fw  tcp  22
Line 190: Line 190:
shorewall restart}}
shorewall restart}}


{{Tip|This gives you a basic set of redundant policy routers, however you can continue on with section(s) below to add features to them}}
{{Tip|This gives you a basic set of redundant policy routers, however you can continue with section(s) below to add features to them}}


== DHCP Relaying ==
== DHCP Relaying ==


This will allow DHCP broadcasts from one subnet to be sent on to a DHCP server in another subnet (so that you don't have to have your DHCP server have an interface in each subnet).
This will allow DHCP broadcasts from one subnet to be sent on to a DHCP server in another subnet (that way your DHCP server won't need an interface in each subnet).


First, install dhcrelay:
First, install dhcrelay:
Line 201: Line 201:
  IFACE="eth1 eth2.2 eth2.3"
  IFACE="eth1 eth2.2 eth2.3"
  DHCRELAY_SERVERS="10.0.1.100 10.0.1.101"
  DHCRELAY_SERVERS="10.0.1.100 10.0.1.101"
Finally, setup your scopes on 10.0.1.100 and 10.0.1.101 for the 10.0.1.0/24, 10.0.2.0/24, and 10.0.3.0/24 subnets and test by requesting a lease from a computer in either 10.0.2.0/24 or 10.0.3.0/24.
Finally, set up your scopes on 10.0.1.100 and 10.0.1.101 for the 10.0.1.0/24, 10.0.2.0/24, and 10.0.3.0/24 subnets and test by requesting a lease from a computer in either 10.0.2.0/24 or 10.0.3.0/24.


[[Category:Networking]]
[[Category:Networking]]

Latest revision as of 10:23, 17 November 2023

This document explains how to setup a fault-tolerant router using Alpine Linux. It has been tested with Alpine Linux 2.2.3.

Hardware and Network Setup

The network used in this example is as follows:

  • Will run (at least initially) IPv4
  • Pre-existing border router that performs NAT from public IP(s) to the 10.0.0.0/8 network and has the address 10.0.0.1/24 on the transit network
  • The border router will have a default route to the internal network via 10.0.0.2 (the virtual IP address of the routers being set up in this doc)
  • The transit network between the border router and the fault-tolerant routers described in this document, will be on 10.0.0.0/24
  • The routers will also connect several internal subnets on the network:
    • 10.0.1.0/24
    • 10.0.2.0/24
    • 10.0.3.0/24
  • It's assumed that 10.0.0.0/24 and 10.0.1.0/24 are connected via dedicated interfaces (eth0 and eth1, respectively), while 10.0.2.0/24 and 10.0.3.0/24 share an interface(eth2), but traffic is segregated using 802.1q vlan tagging, with 10.0.2.0/24 using vlan id 2, and 10.0.3.0/24 using vlan id 3.
  • Finally, all computers in subnets 10.0.1.0/24, 10.0.2.0/24 and 10.0.3.0/24 are set up with a default gateway of 10.0.x.1

Two computers will be needed, with at least three NICs in them (more if you are connecting more network segments together), to act as routers.

Initial Setup

First, setup Alpine on a USB key or CF card on both computers. Connect both computers initially to 10.0.0.0/24 on eth0, and assign them ip addresses of 10.0.0.3/24 and 10.0.0.4/24 in the setup-alpine script(for router1 and router2, respectively). Do not configure other interfaces initially. Ensure that both machines are pingable.

Next, connect them both to 10.0.1.0/24 on eth1, and assign them ip addresses of 10.0.1.2/24 and 10.0.1.3/24, respectively. Ensure that they can also ping each other. At this point, /etc/network/interfaces (for router1) should look like this:

auto eth0
iface eth0 inet static
        address 10.0.0.2
        netmask 255.255.255.0
        gateway 10.0.0.1
auto eth1
iface eth1 inet static
        address 10.0.1.2
        netmask 255.255.255.0

Finally, get the last two networks connected (the ip addresses given are for router1. The following steps should be performed on router2):

modprobe 8021q
echo "8021q" >> /etc/modules
cat >> /etc/network/interfaces << EOF
auto eth2
iface eth2 inet manual
        up ip link set eth2 up
        up ifup eth2.2 || true
        up ifup eth2.3 || true
        down ifdown eth2.3 || true
        down ifdown eth2.2 || true
        down ip link set dev eth2 down
iface eth2.2 inet static
        pre-up vconfig add eth2 2
        address 10.0.2.2
        netmask 255.255.255.0
        post-down vconfig rem $IFACE
iface eth2.3 inet static
        pre-up vconfig add eth2 3
        address 10.0.3.2
        netmask 255.255.255.0
        post-down vconfig rem $IFACE
EOF

Test that you can also ping between the two interfaces.

Start ip forwarding

Next, turn them into simple routers by enabling ip forwarding (do that on each box):

echo 1 > /proc/sys/net/ipv4/ip_forward

If you follow the ucarp section below, you'll also need to disable rp_filter (RFC3704 Ingress Filtering). Since this how-to is designed for an internal router this should (or might not) be acceptable. Available options for this setting can be viewed at https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt

echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter echo 0 > /proc/sys/net/ipv4/conf/eth0/rp_filter echo 0 > /proc/sys/net/ipv4/conf/eth1/rp_filter echo 0 > /proc/sys/net/ipv4/conf/eth2.2/rp_filter echo 0 > /proc/sys/net/ipv4/conf/eth2.3/rp_filter

Install and start ucarp

Ucarp will provide a virtual IP address for each subnet that the routers will share. That way, if either router fails, network connectivity stays up.

  • Copy the scripts for each the interface:

apk add ucarp ln -s ucarp /etc/init.d/ucarp.eth0 ln -s ucarp /etc/init.d/ucarp.eth1 ln -s ucarp /etc/init.d/ucarp.eth2.2 ln -s ucarp /etc/init.d/ucarp.eth2.3 cp /etc/conf.d/ucarp /etc/conf.d/ucarp.eth0 cp /etc/conf.d/ucarp /etc/conf.d/ucarp.eth1 cp /etc/conf.d/ucarp /etc/conf.d/ucarp.eth2.2 cp /etc/conf.d/ucarp /etc/conf.d/ucarp.eth2.3

  • edit the /etc/conf/ucarp.eth0 file:
REALIP=
VHID=1
VIP=10.0.0.2
PASSWORD=Password
  • edit the /etc/conf/ucarp.eth1 file:
REALIP=
VHID=2
VIP=10.0.1.1
PASSWORD=Password
  • edit the /etc/conf/ucarp.eth2.2 file:
REALIP=
VHID=3
VIP=10.0.2.1
PASSWORD=Password
  • edit the /etc/conf/ucarp.eth2.3 file:
REALIP=
VHID=4
VIP=10.0.3.1
PASSWORD=Password
  • Create etc/ucarp/vip-up-eth0.sh (and copy this script for each interface: vip-up-eth1.sh, vip-up-eth2.2.sh, vip-up-eth2.3.sh):
#!/bin/sh
 
 # Add the VIP address
 ip addr add $2/24 dev $1
 
 for a in 330 440 550; do beep -f $a -l 100; done
  • Create /etc/ucarp/vip-down-eth0.sh (and copy this script for each interface: vip-down-eth1.sh, vip-down-eth2.2.sh, vip-down-eth2.3.sh):
#!/bin/sh

 # Remove the VIP address
 ip addr del $2/24 dev $1

 for a in 550 440 330; do beep -f $a -l 100; done
  • Make the scripts executable

chmod +x /etc/ucarp/*.sh

  • Start ucarp and save the changes

rc-update add ucarp.eth0 rc-update add ucarp.eth1 rc-update add ucarp.eth2.2 rc-update add ucarp.eth2.3 rc-service ucarp.eth0 start rc-service ucarp.eth1 start rc-service ucarp.eth2.2 start rc-service ucarp.eth2.3 start lbu commit

  • Do the above steps for each router

At this point, you should have connectivity from your border router through to hosts on the internal subnets, and hosts on your subnets should be able to ping all interfaces on each router.

Install and configure Shorewall iptables frontend

We will refer to the Shorewall zones by letters to keep the config files simple. They will correspond to subnets and interfaces as follows:

A = eth0 = 10.0.0.0/24
B = eth1 = 10.0.1.0/24
C_2 = eth2.2 = 10.0.2.0/24
C_3 = eth2.3 = 10.0.3.0/24

Install the needed package

apk add shorewall

Edit /etc/shorewall/params:

#FIRST LINE
A_IF=eth0
B_IF=eth1
C_2_IF=eth2.2
C_3_IF=eth2.3
#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONCE - DO NOT REMOVE

Edit /etc/shorewall/interfaces:

#FIRST LINE
A  $A_IF  detect  dhcp
B  $B_IF  detect  dhcp
C_2  $C_2_IF  detect  dhcp
C_3  $C_3_IF  detect  dhcp
#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONCE - DO NOT REMOVE

Edit /etc/shorewall/zones:

#FIRST LINE
fw  firewall
A   ipv4
B   ipv4
C_2 ipv4
C_3 ipv4
#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONCE - DO NOT REMOVE

Edit /etc/shorewall/policy: (note: this allows all traffic between internal subnets and all traffic outbound to the Internet, but blocks all traffic inbound by default, this policy might need to be adjusted in your case)

#FIRST LINE
A   all   REJECT  INFO
B   A     ACCEPT
B   C_2   ACCEPT
B   C_3   ACCEPT
C_2 A     ACCEPT
C_2 B     ACCEPT
C_2 C_3   ACCEPT
C_3 A     ACCEPT
C_3 B     ACCEPT
C_3 C_2   ACCEPT
all all   REJECT  INFO
#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONCE - DO NOT REMOVE 

Edit /etc/shorewall/rules: (the following simply allows SSH traffic in to your two routers - more will probably be needed to accept or reject traffic based on your needs)

#FIRST LINE
ACCEPT   A   fw   tcp   22
#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONCE - DO NOT REMOVE

Edit /etc/shorewall/start:

#FIRST LINE
/bin/echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
/bin/echo 0 > /proc/sys/net/ipv4/conf/eth0/rp_filter
/bin/echo 0 > /proc/sys/net/ipv4/conf/eth1/rp_filter
/bin/echo 0 > /proc/sys/net/ipv4/conf/eth2.2/rp_filter
/bin/echo 0 > /proc/sys/net/ipv4/conf/eth2.3/rp_filter
#LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONCE - DO NOT REMOVE

Finally, edit STARTUP_ENABLED line in /etc/shorewall/shorewall.conf:

STARTUP_ENABLED=yes

Check config for errors then start shorewall:

shorewall check shorewall restart

Tip: This gives you a basic set of redundant policy routers, however you can continue with section(s) below to add features to them

DHCP Relaying

This will allow DHCP broadcasts from one subnet to be sent on to a DHCP server in another subnet (that way your DHCP server won't need an interface in each subnet).

First, install dhcrelay:

apk add dhcrelay

Next, adjust /etc/conf.d/dhcrelay: (assuming you don't need DHCP on the 10.0.0.0/24 subnet, and that your DHCP servers are 10.0.1.100 and 10.0.1.101)

IFACE="eth1 eth2.2 eth2.3"
DHCRELAY_SERVERS="10.0.1.100 10.0.1.101"

Finally, set up your scopes on 10.0.1.100 and 10.0.1.101 for the 10.0.1.0/24, 10.0.2.0/24, and 10.0.3.0/24 subnets and test by requesting a lease from a computer in either 10.0.2.0/24 or 10.0.3.0/24.