📜 ⬆️ ⬇️

Balancing 2 or more channels on FreeBSD using PF + Squid

Good time of the day, habrozhiteli!



Due to the fact that although my previous attempt to share thoughts brought me an invite, however, Karma went into the minus, so now I will try to rehabilitate myself again trying to please the audience with a recipe for setting up the buzzing thing in the corner.
So, about the task: there are two Internet channels, a gateway on FreeBSD

gate# uname -a FreeBSD gate 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Thu Nov 1 06:48:52 OMST 2012 root@gate:/usr/obj/usr/src/sys/GATE amd64 

Not that a necessity, but a desire to create a flexible system with balancing traffic by channel and a desire to receive an award from management.
Channel number 1: unlimited, speed 7 MB, real ip-address
Channel number 2: unlimited, speed up to 60Mb, real ip-address.
On the provider’s side, gateways were installed through which I implemented the DMZ on “traps” for hackers, so the PF and SQUID settings are minimal


Description of raising the balancing

')
All manipulations from the root user. (Connect to the host by any user, then su, root password).

1. Kernel options for enabling PF:
If you do not consider traffic as PF, then the second paragraph can be disabled
 cd /sys/amd64/conf cp GENERIC GATE ee GATE device pf device pflog options ALTQ options ALTQ_CBQ options ALTQ_RED options ALTQ_RIO options ALTQ_HFSC options ALTQ_PRIQ options ALTQ_NOPCC 


2. kernel assembly
 make kernel KERNCONF=GATE 


3. 2 network cards are installed in the gateway, one integrated into the motherboard:
 re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=389b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_UCAST,WOL_MCAST,WOL_MAGIC> inet 192.168.1.2 netmask 0xffffff00 broadcast 192.168.1.255 re1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=389b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_UCAST,WOL_MCAST,WOL_MAGIC> inet 192.168.63.26 netmask 0xfffffff8 broadcast 192.168.63.31 nfe0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=82008<VLAN_MTU,WOL_MAGIC,LINKSTATE> inet 10.1.1.30 netmask 0xffffff00 broadcast 10.1.1.255 

re0 provider # 1, re1 - provider # 2. The internal interface nfe0 (assigning ip addresses and masks has developed historically, I work with what is). And of course, vlan is raised on the internal interface, scattering video surveillance ip and various departments of the company on them.

4. Configure rc.conf
 ee /etc/rc.conf pf_enable=«YES» pf_rules=«/etc/pf.conf» squid_enable=«YES» reboot 


That is, when loading, the rules from the /etc/pf.conf file are executed.

5. Listing pf.conf.

 cat pf.conf # ,  int_if -  , ext_if - . int_if=«nfe0» ext_if=«re1» ext_if2=«re0» int_net=«10.1.1.0/24» freeBSD=«10.1.1.30» icmp_types=«{ echoreq, unreach}» http=«80» https=«443» ssh=«22» #     . gw1=«192.168.63.25» gw2=«192.168.1.1» # ,             . #, -       ip-  . to_ertel=«{10.1.1.42, 10.1.1.33, 10.1.1.4, 10.1.1.12, 10.1.1.5, 10.1.1.48, 10.1.1.25, 10.1.1.3, 10.1.1.243, 10.1.1.5 }» to_trans=«{ 10.1.1.27, 10.1.1.2, 10.1.1.181, 10.1.1.46, 10.1.1.39, 10.1.1.27, 10.1.1.31, 10.1.1.113 }» #   -    , set block-policy drop set skip on lo #     . scrub in all #   - nat on $ext_if inet from any to any -> ($ext_if) #   - nat on $ext_if2 inet from any to any -> ($ext_if2) #  SQUID rdr on $int_if inet proto tcp from any to any port www -> 127.0.0.1 port 3128 block in from any to any block out from any to any # antispoof quick for $int_if inet #        pass out on $int_if from any to $int_net #   (  ) pass in quick on $int_if route-to ($ext_if2 $gw2) from $to_trans to !$int_net keep state pass in quick on $int_if route-to ($ext_if $gw1) from $to_ertel to !$int_net keep state #  (quick)     pass in quick on $int_if from $int_net to $int_if pass in quick on $int_if route-to { ($ext_if $gw1), ($ext_if2 $gw2)} round-robin sticky-address proto tcp from $int_net to any flags S/SA keep state # sticky-address    RicoX #   icmp  udp      pass in on $int_if route-to { ($ext_if $gw1), ($ext_if2 $gw2) } round-robin proto { udp, icmp } from $int_net to any keep state #  ""     pass out on $ext_if proto tcp from any to any flags S/SA modulate state pass out on $ext_if proto { udp, icmp } from any to any keep state pass out on $ext_if2 proto tcp from any to any flags S/SA modulate state pass out on $ext_if2 proto { udp, icmp } from any to any keep state #      IP  $ext_if1  $ext_gw1  #    $ext_if2  $ext_gw2 pass out on $ext_if route-to ($ext_if2 $gw2) from $ext_if2 to any pass out on $ext_if2 route-to ($ext_if $gw1) from $ext_if to any 


The bandwidth setting did not, as there was no need. It turns on quite simply and quickly, I think in the future it will be possible to add a config.

The disadvantage of this path is that sometimes, when something happens to one of the providers, load balancing stops working.
To solve this problem, the following configuration files were created: pf.conf.ertelecom and pf.conf.trans, which differ from the main configuration file only in that the line:
 #pass in on $int_if route-to { ($ext_if $gw1), ($ext_if2 $gw2) } round-robin proto { udp, icmp } from $int_net to any keep state 

thrown out of them. Two lines appear instead:

 pass out route-to ($ext_if $gw1) from $int_if to any pass out route-to ($ext_if2 $gw2) from $int_if to any 


one of which works, depending on which gateway is installed by default.

Switching scripts look like this:

 cat er_conn.sh #!/bin/sh GW1=«192.168.63.25» if1=«192.168.63.26» #  /sbin/pfctl -d #      №2 /sbin/pfctl -e -f /etc/pf.conf.dom #  - /sbin/route del default #  -   №2 /sbin/route add default $GW1 


Similar to this script, the scripts for controlling the inclusion of the provider â„–1 and load balancing work. Only the gateway address and the pf configuration rules file change.
In cron, we include a script that every few (optional) minutes checks for a response from the gateway:
ping -S <ip address of the provider's gateway> <our real ip-address>.
If there is no answer, we automatically load the rules of the live channel.

As for the SQUID setting, there I did everything in a primitive way. I assembled squid 3 from ports, without changing anything except the transparent setting, that is, a transparent proxy. I give its configuration file:

 cat squid.conf http_port 127.0.0.1:3128 transparent icp_port 0 hierarchy_stoplist cgi-bin ? acl QUERY urlpath_regex cgi-bin \? no_cache deny QUERY cache_mem 256 MB maximum_object_size 8092 KB maximum_object_size_in_memory 512 KB cache_dir ufs /bkp/var/squid/cache 2048 64 256 cache_access_log /bkp/var/squid/access.log cache_log /bkp/var/squid/cache.log cache_store_log /bkp/var/squid/store.log cache_mgr root@xxx.ru cache_effective_user squid cache_effective_group squid visible_hostname gate coredump_dir /bkp/var/squid/cache pid_filename /var/run/squid/squid.pid acl our_networks src 10.1.1.0/24 http_access allow our_networks 


We have been working with this for about two years, almost nothing crashes, the gateway reboots only at the whims of electricians, users have forgotten what Internet access problems are.
I consider traffic as alcohol (cnupm), followed by uploading its logs to the MySQL database.

A small bonus: when I took the farm, all the IPs were set manually for the machines. In addition, to these IP (and not machine names) there was a binding of some services of the local network. Therefore, the following script was born for the quick transfer of IP settings to the DHCP format of the server configuration file, namely, the part that assigns IP to the MAC address.
Here is the listing:
 gate# cat do_dhcp #!/bin/sh arp -an | grep <   > > /usr/arp.txt # IFS     IFS=« » cat /usr/arp.txt | while read line do set -- $line; echo -e «host $1 { hardware ethernet $4; fixed-address $2; }\n» done 


The output occurs on the terminal screen, but if you add to echo after the last quotation mark> /usr/dhcp.txt, the output will be in the file. Next came copy-paste output to the appropriate section of the dhcpd.conf file. It is possible so:
 cat dhcpd.txt >> /usr/local/etc/dhcpd.conf 

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


All Articles