📜 ⬆️ ⬇️

Organization of accessibility of services on two external interfaces by means of natd and ipfw

The classic scheme of internet connection in a small office.


The figure shows a typical scheme for connecting small offices to the Internet.
If the main channel of access to the Internet (ISP1) and backup (ISP2), which are switched in case of problems with the main channel.
Switching is usually done by changing the default gateway on the router.

And if there are services on the router that should be accessible from the outside, then these services will be available only to the external address of the active, currently, channel on the Internet, since responses to requests coming from an inactive channel will be sent through the active channel and lost successfully . To establish BGP interaction with providers, as I was advised in one forum - this is a rare insanity shooting from a cannon on sparrows, and not every provider will go for it.
')
I will tell you how to make services available to both external addresses at the same time, using ipfw and natd.


Initial data
FREEBSD 6.3 router
Local network 192.168.1.0/24, which will natit.
Interface re0 looking to the local network with ip address 192.168.1.1
Interface xl0 looking to the Internet via ISP1 with ip address 111.111.111.1
Interface xl1 looking to the Internet via ISP2 with ip address 222.222.222.1
Services that need to be made available simultaneously on 111.111.111.1 and on 222.222.222.1.
Gateway of the first provider: 111.111.111.2
Gateway of the second provider: 222.222.222.2

On Habré already flashed a solution to a similar problem with the help of PF . PF has a magic reply-to () with which this task is solved. On IPFW, the solution is not so trivial, however, let's start in order.

We need to hang on both external interfaces on the natd instance, and the translation table should be common.

Configure natd to work with two instances.
/etc/rc.conf
natd_program="/sbin/natd" natd_enable="YES" natd_flags="-f /etc/natd.conf" 

Please note that we do not specify an interface.

/etc/natd.conf
 log instance default interface xl0 port 8668 use_sockets yes same_ports yes instance xl1 interface xl1 port 8669 use_sockets yes same_ports yes globalport 8670 

Instanse default must be specified.
If you run two instances of natd manually, as advised in some manuals, it will not work, since they will have their own translation table.

Configuring IPFW
I will not give here the safety rules, this is an intimate matter and in each case different requirements and tasks, so we add these rules to our taste.

/etc/rc.firewall
 ipfw="/sbin/ipfw -q " local="re0" ISP1="xl0" ISP2="xl1" localnet="192.168.1.0/24" ISP1_ip="111.111.111.1" ISP2_ip="222.222.222.1" ISP1_gw="111.111.111.2" ISP2_gw="222.222.222.2" nat_ISP1="8668" nat_ISP2="8669" nat_glob="8670" ${ipfw} -f flush #        . # sshd ${ipfw} add 20 allow tcp from any to me 22 # Web Server ${ipfw} add 25 allow tcp from any to me 80 # MailServer ${ipfw} add 26 allow tcp from any to me 25 ${ipfw} add 27 allow tcp from any to me 110 #   . #            ,         ,     . ${ipfw} add 100 fwd ${ISP1_gw} ip from ${ISP1_ip} to not ${localnet} ${ipfw} add 200 fwd ${ISP2_gw} ip from ${ISP2_ip} to not ${localnet} #        ,   #   ${ipfw} add 400 skipto 1000 all from any to any in recv ${local} ${ipfw} add 410 skipto 2000 all from any to any out xmit ${local} #   ${ipfw} add 500 skipto 3000 all from any to any in recv ${ISP1} ${ipfw} add 550 skipto 4000 all from any to any out xmit ${ISP1} ${ipfw} add 600 skipto 5000 all from any to any in recv ${ISP2} ${ipfw} add 650 skipto 6000 all from any to any out xmit ${ISP2} #        .      ,             ${ipfw} add 900 deny all from any to any #   ${ipfw} add 1000 allow all from any to any #   ${ipfw} add 2000 allow all from any to any # ISP1  (      natd) ${ipfw} add 3000 divert ${nat_ISP1} ip from any to ${ISP1_ip} ${ipfw} add 3010 allow all from any to any # ISP1  (   ) #    natd   globalport ${ipfw} add 4000 divert ${nat_global} ip from ${localnet} to any #       ,  natd         ,     #     ,           ${ipfw} add 4010 allow all from ${ISP1_ip} to any #     ,        . ${ipfw} add 4020 fwd ${ISP2_gw} ip from ${ISP2_ip} to any #   natd   ,        ,       natd ${ipfw} add 4030 divert ${nat_ISP1} ip from ${localnet} to any #   . ${ipfw} add 4040 allow all from any to any #      # ISP2  ${ipfw} add 5000 divert ${nat_ISP2} ip from any to ${ISP2_ip} ${ipfw} add 5010 allow all from any to any # ISP2  ${ipfw} add 6000 divert ${nat_global} ip from ${localnet} to any ${ipfw} add 6010 allow all from ${ISP2_ip} to any ${ipfw} add 6020 fwd ${ISP1_gw} ip from ${ISP1_ip} to any ${ipfw} add 6030 divert ${nat_ISP2} ip from ${localnet} to any ${ipfw} add 6040 allow all from any to any 

All the rules are written the same for the two providers, so changing the channel is done simply by replacing the main gateway on the router. There is no need to modify the rules.

For automation, you can create a static route to any resource through the main channel and monitor its availability. If it is not available, change the default gateway to the backup channel gateway.

Useful links:
man natd
man ipfw

UPD

Route switching script:
 #!/bin/sh IP1=111.111.111.1 IP2=222.222.222.1 GW1=111.111.111.2 GW2=222.222.222.2 /sbin/ping -q -c 1 -S $IP1 yandex.ru > /dev/null 2>&1 if [ $? != 0 ]; then /sbin/ping -q -c 1 -S $IP2 yandex.ru > /dev/null 2>&1 if [ $? = 0 ]; then if [ ! -f /tmp/gw.changed ]; then /sbin/route change default $GW2 && touch /tmp/gw.changed fi fi else if [ -f /tmp/gw.changed ]; then /sbin/route change default $GW1 && rm /tmp/gw.changed fi fi 


That is, we simply “ping” the resource through the desired interface (the -S flag in the ping command)
If the resource is not available through the main channel, then:
- we check the performance of the backup channel;
- we reconfigure the default route to the backup channel gateway;
- leave the “tag” /tmp/gw.changed, signaling the change of the gateway.

The next time you run (for example, the script can be run by cron once a minute), if GW1 is normal and there is a “tag”, then we return the main gateway to the site. If both gateways are unavailable, do not change the current state.

The main advantage of this method can be called transparency and simplicity.
Disadvantages - a certain inertia, albeit small, but still non-productive costs of traffic, a non-zero probability of false positives, especially when the channel is high.

Temporary unavailability of the resource itself (in this example, Yandex) during normal operation of both channels will not lead to channel switching, since its operation will also not be confirmed.

Source: https://habr.com/ru/post/124447/


All Articles