<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://www.hentschel.net/w/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://www.hentschel.net/w/index.php?action=history&amp;feed=atom&amp;title=Dual-homed_Internet_connection_in_FreeBSD</id>
		<title>Dual-homed Internet connection in FreeBSD - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://www.hentschel.net/w/index.php?action=history&amp;feed=atom&amp;title=Dual-homed_Internet_connection_in_FreeBSD"/>
		<link rel="alternate" type="text/html" href="http://www.hentschel.net/w/index.php?title=Dual-homed_Internet_connection_in_FreeBSD&amp;action=history"/>
		<updated>2026-04-10T22:25:44Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.23.15</generator>

	<entry>
		<id>http://www.hentschel.net/w/index.php?title=Dual-homed_Internet_connection_in_FreeBSD&amp;diff=4&amp;oldid=prev</id>
		<title>Thomas: Created page with &quot;= Load Balancing =  == Description ==  Load balancing between multiple ISP's in case if there is no BGP/OSPF/RIP can be achieved by using following software:  # FreeBSD as bas...&quot;</title>
		<link rel="alternate" type="text/html" href="http://www.hentschel.net/w/index.php?title=Dual-homed_Internet_connection_in_FreeBSD&amp;diff=4&amp;oldid=prev"/>
				<updated>2016-12-14T02:24:09Z</updated>
		
		<summary type="html">&lt;p&gt;Created page with &amp;quot;= Load Balancing =  == Description ==  Load balancing between multiple ISP&amp;#039;s in case if there is no BGP/OSPF/RIP can be achieved by using following software:  # FreeBSD as bas...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Load Balancing =&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
Load balancing between multiple ISP's in case if there is no BGP/OSPF/RIP can be achieved by using following software:&lt;br /&gt;
&lt;br /&gt;
# FreeBSD as base system;&lt;br /&gt;
# IPFW firewall;&lt;br /&gt;
# Optional MPD5 as PPPoE client.&lt;br /&gt;
&lt;br /&gt;
== How it all works? ==&lt;br /&gt;
&lt;br /&gt;
Current config:&lt;br /&gt;
 FIB 0: ADSL PPPOE&lt;br /&gt;
 FIB 1: ADSL PPPOE&lt;br /&gt;
 FIB 2: DHCP client&lt;br /&gt;
&lt;br /&gt;
* DHCP client on FIB starts via RC.D script (see below);&lt;br /&gt;
* watchdog script periodically check's FIB 2 connection and reload rules on status change(see below);&lt;br /&gt;
* PPPOE connections managed by MPD5 daemon;;&lt;br /&gt;
* When connection established &amp;quot;/usr/local/etc/mpd5/up-script_fib_X.sh&amp;quot; script will be executed in order to reload firewall rules;&lt;br /&gt;
* If one or more PPPoE connection lost MPD5 will DOWN adsl interface and execute &amp;quot;/usr/local/etc/mpd5/down-script_fib_X.sh&amp;quot; script in order to reload firewall rules;&lt;br /&gt;
* arpalert daemon waits for new MAC's to appear and launches script which will put IP's to IPFW tables. This is actual load balancing.&lt;br /&gt;
&lt;br /&gt;
== Why configuration is so complicated? ==&lt;br /&gt;
If we use simple 'prob' and 'setfib' rules of IPFW some services may work incorrect(FTP, PPTP, HTTPS and etc.).&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
=== IPFW firewall ===&lt;br /&gt;
&lt;br /&gt;
Kernel options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
options         LIBALIAS&lt;br /&gt;
options         ROUTETABLES=5&lt;br /&gt;
options         IPFIREWALL&lt;br /&gt;
options         IPDIVERT&lt;br /&gt;
options         DUMMYNET&lt;br /&gt;
options         IPFIREWALL_NAT&lt;br /&gt;
options         IPFIREWALL_FORWARD&lt;br /&gt;
options         IPFIREWALL_DEFAULT_TO_ACCEPT&lt;br /&gt;
options         IPFIREWALL_VERBOSE&lt;br /&gt;
options         IPFIREWALL_VERBOSE_LIMIT=50&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/etc/sysctl.conf:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
net.inet.ip.fw.autoinc_step=5&lt;br /&gt;
net.inet.ip.fw.one_pass=0&lt;br /&gt;
net.inet.ip.fw.verbose=1&lt;br /&gt;
net.inet.ip.fw.dyn_short_lifetime=25&lt;br /&gt;
net.inet.ip.fw.verbose_limit=1000000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/etc/firewall:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
DELAY=`/usr/bin/jot -r 1 0 9`&lt;br /&gt;
&lt;br /&gt;
# Delay&lt;br /&gt;
echo &amp;quot;${DELAY} seconds delay...&amp;quot;&lt;br /&gt;
sleep ${DELAY} &lt;br /&gt;
&lt;br /&gt;
PIDS=`pgrep -f &amp;quot;/bin/sh /etc/firewall&amp;quot; | wc -l`&lt;br /&gt;
&lt;br /&gt;
#Check if copy of process is already running:&lt;br /&gt;
if [ ${PIDS} -gt 1 ]; then&lt;br /&gt;
  echo &amp;quot;Another copy is already running.&amp;quot;&lt;br /&gt;
  exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
#Flush out list before we begin.&lt;br /&gt;
ipfw -q -f flush&lt;br /&gt;
ipfw -q -f nat flush&lt;br /&gt;
ipfw -q pipe flush&lt;br /&gt;
ipfw -q queue flush&lt;br /&gt;
&lt;br /&gt;
################################################################################&lt;br /&gt;
&lt;br /&gt;
#Set rules command prefix&lt;br /&gt;
cmd=&amp;quot;ipfw -q&amp;quot;&lt;br /&gt;
&lt;br /&gt;
pif0=&amp;quot;adsl1&amp;quot;&lt;br /&gt;
pif0ip=`ifconfig $pif0 inet | grep inet | awk '{print $2}'`&lt;br /&gt;
pif0gw=`ifconfig $pif0 inet | grep inet | awk '{print $4}'`&lt;br /&gt;
&lt;br /&gt;
pif1=&amp;quot;adsl2&amp;quot;&lt;br /&gt;
pif1ip=`ifconfig $pif1 inet | grep inet | awk '{print $2}'`&lt;br /&gt;
pif1gw=`ifconfig $pif1 inet | grep inet | awk '{print $4}'`&lt;br /&gt;
&lt;br /&gt;
pif2=&amp;quot;vlan200&amp;quot;&lt;br /&gt;
pif2ip=&amp;quot;10.61.168.231&amp;quot;&lt;br /&gt;
pif2gw=&amp;quot;10.61.168.1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if [ ! -z &amp;quot;$pif0ip&amp;quot; ]; then&lt;br /&gt;
  pif0status=&amp;quot;UP&amp;quot;&lt;br /&gt;
  else&lt;br /&gt;
    pif0status=&amp;quot;DOWN&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ ! -z &amp;quot;$pif1ip&amp;quot; ]; then&lt;br /&gt;
  pif1status=&amp;quot;UP&amp;quot;&lt;br /&gt;
  else&lt;br /&gt;
    pif1status=&amp;quot;DOWN&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ -f /vlan200.status ]; then&lt;br /&gt;
  pif2status=`cat /vlan200.status`&lt;br /&gt;
else&lt;br /&gt;
  pif2status=&amp;quot;DOWN&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# Override&lt;br /&gt;
#pif0status=&amp;quot;DOWN&amp;quot;&lt;br /&gt;
#pif1status=&amp;quot;DOWN&amp;quot;&lt;br /&gt;
#pif2status=&amp;quot;DOWN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
pifs=&amp;quot;adsl*&amp;quot;&lt;br /&gt;
lif=&amp;quot;lan0&amp;quot;&lt;br /&gt;
zuznet=&amp;quot;192.168.1.0/24&amp;quot;&lt;br /&gt;
== How it all works? ==&lt;br /&gt;
&lt;br /&gt;
Current config:&lt;br /&gt;
 FIB 0: ADSL PPPOE&lt;br /&gt;
 FIB 1: ADSL PPPOE&lt;br /&gt;
 FIB 2: DHCP client&lt;br /&gt;
&lt;br /&gt;
* DHCP client on FIB starts via RC.D script (see below);&lt;br /&gt;
* watchdog script periodically check's FIB 2 connection and reload rules on status change(see below);&lt;br /&gt;
* PPPOE connections managed by MPD5 daemon;;&lt;br /&gt;
* When connection established &amp;quot;/usr/local/etc/mpd5/up-script_fib_X.sh&amp;quot; script will be executed in order to reload firewall rules;&lt;br /&gt;
* If one or more PPPoE connection lost MPD5 will DOWN adsl interface and execute &amp;quot;/usr/local/etc/mpd5/down-script_fib_X.sh&amp;quot; script in order to reload firewall rules;&lt;br /&gt;
* arpalert daemon waits for new MAC's to appear and launches script which will put IP's to IPFW tables. This is actual load balancing.&lt;br /&gt;
&lt;br /&gt;
################################################################################&lt;br /&gt;
&lt;br /&gt;
$cmd add 100 allow ip from any to any via lo0&lt;br /&gt;
$cmd add     deny ip from any to 127.0.0.0/8&lt;br /&gt;
$cmd add     deny ip from 127.0.0.0/8 to any&lt;br /&gt;
&lt;br /&gt;
$cmd add 1100 skipto 2040 ip from any to any out xmit $lif tagged 101 keep-state&lt;br /&gt;
$cmd add      skipto 2080 ip from any to any out xmit $lif tagged 102 keep-state&lt;br /&gt;
$cmd add      skipto 2100 ip from any to any out xmit $lif tagged 120 keep-state&lt;br /&gt;
&lt;br /&gt;
$cmd add 1500 deny gre from 192.168.1.XXX to any // This rule will drop first GRE packet from PPTP SERVER when VPN initiates &lt;br /&gt;
&lt;br /&gt;
# Next few IF's will keep firewall rules consistent in cases if ISP connections will go down&lt;br /&gt;
&lt;br /&gt;
if [ $pif0status == &amp;quot;UP&amp;quot; ] &amp;amp;&amp;amp; [ $pif1status == &amp;quot;UP&amp;quot; ]; then &lt;br /&gt;
  $cmd add 2000 skipto 2040 ip from table\(101\) to any in recv $lif // Smart Load balancing using arpalert &lt;br /&gt;
  $cmd add      skipto 2080 ip from table\(102\) to any in recv $lif // Smart Load balancing using arpalert &lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ $pif2status == &amp;quot;UP&amp;quot; ]; then&lt;br /&gt;
  $cmd add      skipto 2100 ip from table\(120\) to any in recv $lif // Smart Load balancing using arpalert &lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ $pif0status == &amp;quot;UP&amp;quot; ]; then&lt;br /&gt;
  $cmd add 2040 setfib 0 ip from any to any via $lif keep-state&lt;br /&gt;
  $cmd add 2050 allow tag 101 ip from any to any via $lif&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ $pif1status == &amp;quot;UP&amp;quot; ]; then&lt;br /&gt;
  $cmd add 2080 setfib 1 ip from any to any via $lif keep-state&lt;br /&gt;
  $cmd add 2090 allow tag 102 ip from any to any via $lif&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ $pif2status == &amp;quot;UP&amp;quot; ]; then&lt;br /&gt;
  $cmd add 2100 setfib 2 ip from any to any via $lif keep-state&lt;br /&gt;
  $cmd add 2110 allow tag 120 ip from any to any via $lif&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
################################################################################&lt;br /&gt;
&lt;br /&gt;
$cmd add 3050 deny ip from any to 192.168.0.0/16 in recv $pifs&lt;br /&gt;
$cmd add      deny ip from 192.168.0.0/16 to any in recv $pifs&lt;br /&gt;
$cmd add      deny ip from any to 172.16.0.0/12 in recv $pifs&lt;br /&gt;
$cmd add      deny ip from 172.16.0.0/12 to any in recv $pifs&lt;br /&gt;
$cmd add      deny ip from any to 10.0.0.0/8 in recv $pifs&lt;br /&gt;
$cmd add      deny ip from 10.0.0.0/8 to any in recv $pifs&lt;br /&gt;
$cmd add      deny ip from any to 169.254.0.0/16 in recv $pifs&lt;br /&gt;
$cmd add      deny ip from 169.254.0.0/16 to any in recv $pifs&lt;br /&gt;
&lt;br /&gt;
################################################################################&lt;br /&gt;
&lt;br /&gt;
if [ $pif1status == &amp;quot;UP&amp;quot; ]; then&lt;br /&gt;
  $cmd add 11000 fwd $pif1gw all from $pif1ip to any via $pif0 // Send reply to necessary interface&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ $pif2status == &amp;quot;UP&amp;quot; ]; then&lt;br /&gt;
  $cmd add 11100 fwd $pif2gw all from $pif2ip to any via $pif0 // Send reply to necessary interface&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
################################################################################&lt;br /&gt;
&lt;br /&gt;
$cmd add 13000 skipto 31000 log ip from any to $pif0ip 22 in recv $pif0 // sshd&lt;br /&gt;
$cmd add       skipto 31000 log ip from any to $pif1ip 22 in recv $pif1 // sshd&lt;br /&gt;
$cmd add       skipto 31000 log ip from any to $pif2ip 22 in recv $pif2 // sshd&lt;br /&gt;
$cmd add       skipto 31000 log ip from any to $pif0ip 1723 in recv $pif0 // PPTP server&lt;br /&gt;
$cmd add       skipto 31000 log ip from any to $pif1ip 1723 in recv $pif1 // PPTP server&lt;br /&gt;
$cmd add       skipto 31000 log ip from any to $pif2ip 1723 in recv $pif2 // PPTP server&lt;br /&gt;
$cmd add       skipto 31000 gre from any to $pif0ip in recv $pif0 // PPTP server&lt;br /&gt;
$cmd add       skipto 31000 gre from any to $pif1ip in recv $pif1 // PPTP server&lt;br /&gt;
$cmd add       skipto 31000 gre from any to $pif2ip in recv $pif2 // PPTP server&lt;br /&gt;
&lt;br /&gt;
################################################################################&lt;br /&gt;
&lt;br /&gt;
if [ $pif0status == &amp;quot;UP&amp;quot; ]; then&lt;br /&gt;
  $cmd add 20000 deny log ip from any to any in via $pif0 setup // Reject and Log all setup of incoming connections from the outside &lt;br /&gt;
  $cmd add       deny log ip from any to any in via $pif1 setup // Reject and Log all setup of incoming connections from the outside &lt;br /&gt;
  $cmd add       deny log ip from any to any in via $pif2 setup // Reject and Log all setup of incoming connections from the outside &lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
################################################################################&lt;br /&gt;
&lt;br /&gt;
if [ $pif0status == &amp;quot;UP&amp;quot; ]; then&lt;br /&gt;
  $cmd nat 101 config if $pif0 same_ports reset \&lt;br /&gt;
			redirect_port tcp 192.168.1.XXX:1723 $pif0ip:1723 \&lt;br /&gt;
                        redirect_proto gre 192.168.1.XXX $pif0ip&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ $pif1status == &amp;quot;UP&amp;quot; ]; then&lt;br /&gt;
  $cmd nat 102 config if $pif1 same_ports reset \&lt;br /&gt;
			redirect_port tcp 192.168.1.XXX:1723 $pif1ip:1723 \&lt;br /&gt;
                        redirect_proto gre 192.168.1.XXX $pif1ip&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ $pif2status == &amp;quot;UP&amp;quot; ]; then&lt;br /&gt;
  $cmd nat 120 config if $pif2 same_ports reset \&lt;br /&gt;
			redirect_port tcp 192.168.1.XXX:1723 $pif2ip:1723 \&lt;br /&gt;
                        redirect_proto gre 192.168.1.XXX $pif2ip&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
################################################################################&lt;br /&gt;
&lt;br /&gt;
# NAT&lt;br /&gt;
if [ $pif0status == &amp;quot;UP&amp;quot; ]; then&lt;br /&gt;
&lt;br /&gt;
  $cmd add 31000 nat 101 ip from any to any via $pif0 // $pif0 nat&lt;br /&gt;
  $cmd add       skipto 35000 tag 101 ip from any to any in recv $pif0&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ $pif1status == &amp;quot;UP&amp;quot; ]; then&lt;br /&gt;
  $cmd add 31500 nat 102 ip from any to any via $pif1 // $pif1 nat&lt;br /&gt;
  $cmd add       skipto 35000 tag 102 ip from any to any in recv $pif1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if [ $pif2status == &amp;quot;UP&amp;quot; ]; then&lt;br /&gt;
  $cmd add 32500 nat 120 ip from any to any via $pif2 // $pif2 nat &lt;br /&gt;
  $cmd add       skipto 35000 tag 120 ip from any to any in recv $pif2&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
################################################################################&lt;br /&gt;
&lt;br /&gt;
$cmd add 35000 allow tcp from any to any established // Allow TCP through if setup succeeded&lt;br /&gt;
&lt;br /&gt;
$cmd add 50000 allow all from any to any&lt;br /&gt;
$cmd add 65534 deny all from any to any&lt;br /&gt;
&lt;br /&gt;
################################################################################&lt;br /&gt;
&lt;br /&gt;
exit 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MPD5 as PPPoE client ===&lt;br /&gt;
&lt;br /&gt;
Default route will be set using up-script_fib_0.sh. This is workaround to avoid identical gateways in case of using two lines from on ISP. Use different fib's for each ISP.&lt;br /&gt;
&lt;br /&gt;
/usr/local/etc/mpd5/mpd.conf:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
startup:&lt;br /&gt;
# Name password password_user&lt;br /&gt;
  set user myuser mypass admin&lt;br /&gt;
# console on localhost&lt;br /&gt;
  set console self 127.0.0.1 5005&lt;br /&gt;
  set console open&lt;br /&gt;
  set web self 0.0.0.0 5006&lt;br /&gt;
  set web open&lt;br /&gt;
&lt;br /&gt;
# default settings&lt;br /&gt;
default:&lt;br /&gt;
  load pppoe_client_101&lt;br /&gt;
  load pppoe_client_102&lt;br /&gt;
&lt;br /&gt;
pppoe_client_101:&lt;br /&gt;
  create bundle static B1&lt;br /&gt;
  set iface name adsl1&lt;br /&gt;
  set iface enable tcpmssfix &lt;br /&gt;
  set iface up-script /usr/local/etc/mpd5/up-script_fib_0.sh&lt;br /&gt;
  set iface down-script /usr/local/etc/mpd5/down-script_fib_0.sh&lt;br /&gt;
# Default route is added via up-script&lt;br /&gt;
#  set iface route default&lt;br /&gt;
  set ipcp ranges 0.0.0.0/0 0.0.0.0/0&lt;br /&gt;
  create link static L1 pppoe&lt;br /&gt;
  set link action bundle B1&lt;br /&gt;
  set auth authname PPPOE_USERNAME&lt;br /&gt;
  set auth password PPPOE_PASSWORD&lt;br /&gt;
  set link max-redial 0&lt;br /&gt;
  set link mtu 1492&lt;br /&gt;
  set link mru 1492&lt;br /&gt;
  set link keep-alive 10 60&lt;br /&gt;
# interface to PPPoE&lt;br /&gt;
  set pppoe iface vlan101&lt;br /&gt;
#  set pppoe iface pif0 &lt;br /&gt;
  set pppoe service &amp;quot;&amp;quot;&lt;br /&gt;
# start connection&lt;br /&gt;
  open &lt;br /&gt;
&lt;br /&gt;
pppoe_client_102:&lt;br /&gt;
  create bundle static B2&lt;br /&gt;
  set iface name adsl2&lt;br /&gt;
  set iface enable tcpmssfix &lt;br /&gt;
  set iface up-script /usr/local/etc/mpd5/up-script_fib_1.sh&lt;br /&gt;
  set iface down-script /usr/local/etc/mpd5/down-script_fib_1.sh&lt;br /&gt;
# Default route is added via up-script&lt;br /&gt;
#  set iface route default&lt;br /&gt;
  set ipcp ranges 0.0.0.0/0 0.0.0.0/0&lt;br /&gt;
  create link static L2 pppoe&lt;br /&gt;
  set link action bundle B2&lt;br /&gt;
  set auth authname PPPOE_USERNAME&lt;br /&gt;
  set auth password PPPOE_PASSWORD&lt;br /&gt;
  set link max-redial 0&lt;br /&gt;
  set link mtu 1492&lt;br /&gt;
  set link mru 1492&lt;br /&gt;
  set link keep-alive 10 60&lt;br /&gt;
# interface to PPPoE&lt;br /&gt;
  set pppoe iface vlan102&lt;br /&gt;
#  set pppoe iface pif0&lt;br /&gt;
  set pppoe service &amp;quot;&amp;quot;&lt;br /&gt;
# start connection&lt;br /&gt;
  open&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/usr/local/etc/mpd5/up-script_fib_0.sh:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;`date` UP   $@&amp;quot; &amp;gt;&amp;gt; /tmp/firewall.sh.log&lt;br /&gt;
&lt;br /&gt;
# Manually adding default route to avoid error with identical destination gateways &lt;br /&gt;
EXT_IF_IP=$4&lt;br /&gt;
setfib 0 route add default -interface $1 &lt;br /&gt;
&lt;br /&gt;
/etc/firewall &amp;amp;&lt;br /&gt;
&lt;br /&gt;
exit 0&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/usr/local/etc/mpd5/down-script_fib_0.sh:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;`date` DOWN $@&amp;quot; &amp;gt;&amp;gt; /tmp/firewall.sh.log&lt;br /&gt;
&lt;br /&gt;
# Manually adding default route to avoid error with identical destination gateways&lt;br /&gt;
setfib 0 route del default -interface $1 &lt;br /&gt;
&lt;br /&gt;
/etc/firewall &amp;amp;&lt;br /&gt;
&lt;br /&gt;
exit 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== setfib + dhclient ==&lt;br /&gt;
&lt;br /&gt;
/etc/rc.conf:&lt;br /&gt;
 # setfib 2 dhclient vlan200 &lt;br /&gt;
 vlan200_enable=&amp;quot;YES&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/usr/local/etc/rc.d/vlan200:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
# PROVIDE: sumtel-watchdog&lt;br /&gt;
# REQUIRE: DAEMON&lt;br /&gt;
# KEYWORD: shutdown&lt;br /&gt;
#&lt;br /&gt;
# Add the following lines to /etc/rc.conf.local or /etc/rc.conf to&lt;br /&gt;
# enable vlan200:&lt;br /&gt;
#&lt;br /&gt;
# vlan200_enable (bool): Set to NO by default.  Set it to YES to&lt;br /&gt;
#         enable vlan200.&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
. /etc/rc.subr&lt;br /&gt;
&lt;br /&gt;
name=&amp;quot;vlan200&amp;quot;&lt;br /&gt;
rcvar=&amp;quot;vlan200_enable&amp;quot;&lt;br /&gt;
&lt;br /&gt;
pidfile=&amp;quot;/var/run/${name}.pid&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_cmd=${name}_start&lt;br /&gt;
stop_cmd=${name}_stop&lt;br /&gt;
&lt;br /&gt;
vlan200_start() {&lt;br /&gt;
  /usr/sbin/setfib 2 /sbin/dhclient vlan200&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
vlan200_stop() {&lt;br /&gt;
  /bin/pgrep -f &amp;quot;dhclient: vlan200&amp;quot; | /usr/bin/xargs kill&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
load_rc_config $name&lt;br /&gt;
&lt;br /&gt;
: ${vlan200_enable=&amp;quot;NO&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
run_rc_command &amp;quot;$1&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== watchdog script ==&lt;br /&gt;
Following script checks internet connectivity and reloads IPFW rules if status has changed.&lt;br /&gt;
&lt;br /&gt;
/etc/rc.conf:&lt;br /&gt;
 sumtelwatchdog_enable=&amp;quot;YES&amp;quot;&lt;br /&gt;
&lt;br /&gt;
usr/local/etc/rc.d/sumtelwatchdog:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
# PROVIDE: sumtel-watchdog&lt;br /&gt;
# REQUIRE: DAEMON&lt;br /&gt;
# KEYWORD: shutdown&lt;br /&gt;
#&lt;br /&gt;
# Add the following lines to /etc/rc.conf.local or /etc/rc.conf to&lt;br /&gt;
# enable sumtelwatchdog:&lt;br /&gt;
#&lt;br /&gt;
# sumtelwatchdog_enable (bool): Set to NO by default.  Set it to YES to&lt;br /&gt;
#         enable sumtelwatchdog.&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
. /etc/rc.subr&lt;br /&gt;
&lt;br /&gt;
name=&amp;quot;sumtelwatchdog&amp;quot;&lt;br /&gt;
rcvar=&amp;quot;sumtelwatchdog_enable&amp;quot;&lt;br /&gt;
&lt;br /&gt;
pidfile=&amp;quot;/var/run/${name}.pid&amp;quot;&lt;br /&gt;
&lt;br /&gt;
start_cmd=${name}_start&lt;br /&gt;
stop_cmd=${name}_stop&lt;br /&gt;
&lt;br /&gt;
sumtelwatchdog_start() {&lt;br /&gt;
  /usr/sbin/daemon -f -p /var/run/${name}.pid /root/${name}.sh&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sumtelwatchdog_stop() {&lt;br /&gt;
  kill `cat /var/run/${name}.pid`&lt;br /&gt;
  rm -f /var/run/${name}.pid&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
load_rc_config $name&lt;br /&gt;
&lt;br /&gt;
: ${sumtelwatchdog_enable=&amp;quot;NO&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
run_rc_command &amp;quot;$1&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/root/sumtelwatchdog.sh:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
# Variables&lt;br /&gt;
HOST1=&amp;quot;8.8.8.8&amp;quot;&lt;br /&gt;
HOST2=&amp;quot;172.29.61.11&amp;quot;&lt;br /&gt;
ADDRESS=&amp;quot;ya.ru&amp;quot;&lt;br /&gt;
FIB=&amp;quot;2&amp;quot;&lt;br /&gt;
FILE=&amp;quot;/vlan200.status&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Infinite loop&lt;br /&gt;
# If all three checks will fail then status will be &amp;quot;DOWN&amp;quot;&lt;br /&gt;
while :&lt;br /&gt;
do &lt;br /&gt;
  setfib ${FIB} dig @${HOST1} ${ADDRESS} 1&amp;gt;/dev/null 2&amp;gt;/dev/null &lt;br /&gt;
  STATUS1=`echo $?`&lt;br /&gt;
  sleep 20&lt;br /&gt;
&lt;br /&gt;
  setfib ${FIB} dig @${HOST2} ${ADDRESS} 1&amp;gt;/dev/null 2&amp;gt;/dev/null&lt;br /&gt;
  STATUS2=`echo $?`&lt;br /&gt;
  sleep 20&lt;br /&gt;
&lt;br /&gt;
  if [ ${STATUS1} -ne 0 ] &amp;amp;&amp;amp; [ ${STATUS2} -ne 0 ]; &lt;br /&gt;
    then &lt;br /&gt;
      STATUS=`cat ${FILE}`&lt;br /&gt;
      if [ ${STATUS} != &amp;quot;DOWN&amp;quot; ]; then&lt;br /&gt;
        echo &amp;quot;DOWN&amp;quot; &amp;gt; ${FILE}&lt;br /&gt;
        /etc/firewall&lt;br /&gt;
      fi&lt;br /&gt;
    else&lt;br /&gt;
      STATUS=`cat ${FILE}`&lt;br /&gt;
      if [ ${STATUS} != &amp;quot;UP&amp;quot; ]; then&lt;br /&gt;
        echo &amp;quot;UP&amp;quot; &amp;gt; ${FILE}&lt;br /&gt;
        /etc/firewall&lt;br /&gt;
      fi&lt;br /&gt;
  fi&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
exit 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== arpalert ==&lt;br /&gt;
Purpose of this following configuration is to add LAN IP's to IPFW tables. &lt;br /&gt;
&lt;br /&gt;
/usr/local/etc/rc.d/arpalert:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
# PROVIDE: arpalert&lt;br /&gt;
# REQUIRE: DAEMON&lt;br /&gt;
# KEYWORD: shutdown&lt;br /&gt;
#&lt;br /&gt;
# Add the following lines to /etc/rc.conf.local or /etc/rc.conf to&lt;br /&gt;
# enable arpalert:&lt;br /&gt;
#&lt;br /&gt;
# arpalert_enable (bool): Set to NO by default.  Set it to YES to&lt;br /&gt;
#         enable arpalert.&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
. /etc/rc.subr&lt;br /&gt;
&lt;br /&gt;
name=&amp;quot;arpalert&amp;quot;&lt;br /&gt;
rcvar=arpalert_enable&lt;br /&gt;
&lt;br /&gt;
command=&amp;quot;/usr/local/sbin/${name}&amp;quot;&lt;br /&gt;
required_files=&amp;quot;/usr/local/etc/arpalert/${name}.conf&amp;quot;&lt;br /&gt;
&lt;br /&gt;
load_rc_config $name&lt;br /&gt;
&lt;br /&gt;
: ${arpalert_enable=&amp;quot;NO&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
run_rc_command &amp;quot;$1&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/usr/local/etc/arpalert/arpalert.conf (only changed values):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
user = root&lt;br /&gt;
interface = lan0&lt;br /&gt;
action on detect = &amp;quot;/usr/local/etc/arpalert/script.pl&amp;quot;&lt;br /&gt;
mac timeout = 1200&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/usr/local/etc/arpalert/script.pl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/perl&lt;br /&gt;
&lt;br /&gt;
use strict;&lt;br /&gt;
use warnings;&lt;br /&gt;
&lt;br /&gt;
#Check if copy of process is already running:&lt;br /&gt;
my $pids=`pgrep -f &amp;quot;/usr/bin/perl /usr/local/etc/arpalert/script.pl&amp;quot; | wc -l`;&lt;br /&gt;
if ( $pids &amp;gt; 1 ) {&lt;br /&gt;
  print &amp;quot;Another copy is already running.\n&amp;quot;;&lt;br /&gt;
  exit 1;&lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
# Variables and initial data&lt;br /&gt;
my $interface=&amp;quot;lan0&amp;quot;;&lt;br /&gt;
my $prob;&lt;br /&gt;
my %arp_hash; &lt;br /&gt;
my %tables;&lt;br /&gt;
my @arp_out=`/usr/sbin/arp -a -i $interface`;&lt;br /&gt;
&lt;br /&gt;
# Writing timestamp&lt;br /&gt;
`date &amp;gt;&amp;gt; /tmp/table_balance.log`;&lt;br /&gt;
&lt;br /&gt;
# Output to file &lt;br /&gt;
open (LOGFILE, '&amp;gt;&amp;gt; /tmp/table_balance.log');&lt;br /&gt;
&lt;br /&gt;
# Storing IP from 'arp' command in %arp_hash&lt;br /&gt;
foreach (@arp_out) {&lt;br /&gt;
  $_ =~ m|\((\S+?)\)|;  # Match string&lt;br /&gt;
  $arp_hash{$1}='';&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
foreach my $table (101, 102, 120) {&lt;br /&gt;
&lt;br /&gt;
  # Storing IP from 'ipfw table' command in %tables&lt;br /&gt;
  foreach (`/sbin/ipfw table $table list`) {&lt;br /&gt;
    $_ =~ m|^(\S+?)\/|;&lt;br /&gt;
    $tables{&amp;quot;$table&amp;quot;}-&amp;gt;{&amp;quot;$1&amp;quot;} = '1';&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  # Checking existance of IP in %arp_hash&lt;br /&gt;
  foreach my $ip (keys %{$tables{$table}}) {&lt;br /&gt;
    if (exists $arp_hash{$ip}) {&lt;br /&gt;
      $arp_hash{$ip} = &amp;quot;$table&amp;quot;;&lt;br /&gt;
    } else {&lt;br /&gt;
      print LOGFILE &amp;quot;Removing IP:$ip from table $table\n&amp;quot;;&lt;br /&gt;
      print `/sbin/ipfw table $table delete $ip`;&lt;br /&gt;
      delete $tables{$table}-&amp;gt;{$ip};&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Adding new IP addreses to tables &lt;br /&gt;
foreach my $ip (keys %arp_hash) {&lt;br /&gt;
  if ($arp_hash{$ip} eq '') {&lt;br /&gt;
    $prob = rand(100); &lt;br /&gt;
    if ( $prob &amp;gt; 66 ) {&lt;br /&gt;
      print LOGFILE &amp;quot;Adding IP:$ip to the table 101. prob=$prob\n&amp;quot;;&lt;br /&gt;
      print `/sbin/ipfw table 101 add $ip`;&lt;br /&gt;
    } elsif ( $prob &amp;lt; 33 ) {&lt;br /&gt;
      print LOGFILE &amp;quot;Adding IP:$ip to the table 102. prob=$prob\n&amp;quot;;&lt;br /&gt;
      print `/sbin/ipfw table 102 add $ip`;&lt;br /&gt;
    } else {&lt;br /&gt;
      print LOGFILE &amp;quot;Adding IP:$ip to the table 120. prob=$prob\n&amp;quot;;&lt;br /&gt;
      print `/sbin/ipfw table 120 add $ip`;&lt;br /&gt;
    }&lt;br /&gt;
  } &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
# Debug info&lt;br /&gt;
#foreach my $ip (keys %arp_hash) {&lt;br /&gt;
#  print &amp;quot;key = '$ip'  value='$arp_hash{$ip}' \n&amp;quot; if ($arp_hash{$ip} ne ''); &lt;br /&gt;
#} &lt;br /&gt;
print &amp;quot;Done.\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
# Closing file&lt;br /&gt;
close (LOGFILE); &lt;br /&gt;
&lt;br /&gt;
exit 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Thomas</name></author>	</entry>

	</feed>