In the 3.2 core it's easy to use bonding with the network.preservice, if you also need a bridge (example for kvm-qemu machines, connected to the outer world)
Prerequisites:
- Your interfaces support bonding (use ethtool to check)
- Configure the first bridge (br?) in zentyal network module and use the fixed address you need.
If you have modified the DFT variables, out of the box the code is desinged to work like ...
[lan or wan]
/ \
[eth0] [eth1]
\ /
[bond0]
|
[br?]
Warning:
Dont use the following script without modification if you have more than one interface configured or virtual cards on your bridge in zentyal.In the case you're still here, continue with ...
sudo apt-get install ifenslave
sudo modprobe bonding
sudo grep -q bonding /etc/modules || echo bonding >>/etc/modules
Then put a hook in
/etc/zentyal/hooks/network.preservice with the following ...
#!/bin/bash
# Revision: 0.57
# Date: 2013-09-27
# Author: Markus Neubauer
# License: GPLv2
# Zentyal Version: 3.2
# Description: Add bonding with bond0 using eth0/1 connected to a bridge on br?
# Use it as /etc/zentyal/hooks/network.preservice and make
# it executable
# Remarks: Placed in public for the zentyal community at:
# http://forum.zentyal.org/index.php/topic,17839.html
# This script can safely be removed when zentyal has official support for bonded interfaces
# Prerequisites:
# sudo apt-get install ifenslave
# comment next line out, if done so already in /etc/modules...
lsmod | grep -q "^bonding" || modprobe bonding
# uncomment next line to stop samba from searching an ip for bond0
# sed -i "s#ifaces_to_ignore = sit,tun#ifaces_to_ignore = bond,sit,tun#" /etc/zentyal/network.conf
# trunk interfaces
RAW_IF1="eth0" # modify this if using the new naming
RAW_IF2="eth1" # modify this if using the new naming
# ... extend to your needs and modify bond0 block if extended
# change "balance-alb" to your bonding mode if required
# Declare your own fallback variables, just in case something goes wrong
# adapt to your needs and put some meaningful values here
# you may safely want to delete the default definition for HWaddr, but set up your values for the rest
declare -r DFT_IF='0 inet static' # THIS IS br0, oimitting the "br"
declare -r DFT_IPAddress='192.168.X.X'
declare -r DFT_NetMask='255.255.255.X'
declare -r DFT_BroadCast='192.168.X.255'
declare -r DFT_GateWay='192.168.X.X'
declare -r DFT_HWaddr='XX:XX:XX:XX:XX:XX' # you may want to try http://www.miniwebtool.com/mac-address-generator/
if [ 'XX:XX:XX:XX:XX:XX' = "${DFT_HWaddr}" ]; then
echo "DOING NOTHING IN HOOK ${0} - NOT CONFIGURED on `date`" >>/etc/network/interfaces
exit 1
fi
# backup zentyal config (debugging)
# makes you find a /etc/network/.interfaces.zentyal-hook.*.last
# which is the zentyal's fromer config
TMP_FILE="/etc/network/.interfaces.zentyal-hook.${0##*/}.last"
SAVE_FILE="${TMP_FILE}-`date`"
cp /etc/network/interfaces "${SAVE_FILE}"
[ -L "${TMP_FILE}" ] && rm "${TMP_FILE}"
ln -s "${SAVE_FILE}" "${TMP_FILE}"
TMP_FILE=`tempfile`
# save zentyal network module config variables
grep -m1 -A5 "iface br" /etc/network/interfaces >${TMP_FILE}
TEMP_VAR=`grep -m1 'iface br' ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*iface br}
IF=${TEMP_VAR:-${DFT_IF}}
TEMP_VAR=`grep -m1 address ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*address }
IPAddress=${TEMP_VAR:-${DFT_IPAddress}}
TEMP_VAR=`grep -m1 netmask ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*netmask }
NetMask=${TEMP_VAR:-${DFT_NetMask}}
TEMP_VAR=`grep -m1 broadcast ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*broadcast }
BroadCast=${TEMP_VAR:-${DFT_BroadCast}}
TEMP_VAR=`grep -m1 gateway ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*gateway }
GateWay=${TEMP_VAR:-${DFT_GateWay}}
TEMP_VAR=`grep -m1 'hwaddress ether' ${TMP_FILE}`
if [ -n "${DFT_HWaddr}" ]; then
HWaddr=${DFT_HWaddr}
elif [ -f /sys/class/net/br${IF:0:1}/address ]; then
HWaddr=`cat /sys/class/net/br${IF:0:1}/address`
elif [ -n "${TEMP_VAR}" ]; then
HWaddr=${TEMP_VAR##*hwaddress ether }
fi
rm ${TMP_FILE}
# start a new config file with overwritting the previous one
echo "# replaced by zentyal hook ${0}
# on $(date)
auto lo
iface lo inet loopback
auto ${RAW_IF1}
iface ${RAW_IF1} inet manual
bond-master bond0
auto ${RAW_IF2}
iface ${RAW_IF2} inet manual
bond-master bond0
# add more raw interface blocks if needed (and extend the following bond)
# leave the bonded device entries above the bond entry
# to avoid race conditions in certain environments
auto bond0
iface bond0 inet manual
bond-mode balance-alb # should be selectable in GUI
bond-miimon 100
bond-lcap-rate 1
bond-slaves ${RAW_IF1} ${RAW_IF2}
up /sbin/ifconfig ${RAW_IF1} up || /bin/true
up /sbin/ifconfig ${RAW_IF2} up || /bin/true
up /sbin/ifenslave bond0 ${RAW_IF1} ${RAW_IF2} || /bin/true
down /sbin/ifenslave -d bond0 ${RAW_IF1} ${RAW_IF2} || /bin/true
post-down /sbin/ifconfig ${RAW_IF2} down || /bin/true
post-down /sbin/ifconfig ${RAW_IF1} down || /bin/true
auto br${IF:0:1}
iface br${IF}" >/etc/network/interfaces
# restore zentyal network module config variables (append)
echo " address ${IPAddress}" >>/etc/network/interfaces
echo " netmask ${NetMask}" >>/etc/network/interfaces
echo " broadcast ${BroadCast}" >>/etc/network/interfaces
echo " gateway ${GateWay}" >>/etc/network/interfaces
[ -n "${HWaddr}" ] && echo " hwaddress ether ${HWaddr}" >>/etc/network/interfaces
# append the rest of your config
echo " bridge_ports bond0
bridge_fd 9
bridge_hello 2
bridge_maxage 12
bridge_stp off
pre-up ifup bond0
up /sbin/ifconfig ${RAW_IF1} up || /bin/true
up /sbin/ifconfig ${RAW_IF2} up || /bin/true
down /sbin/ifconfig ${RAW_IF1} down || /bin/true
down /sbin/ifconfig ${RAW_IF2} down || /bin/true
post-down ifdown bond0
# in the case you are using virtual hosts,
# you'll have to add the defines here, too!
#auto br${IF:0:1}:yourvhost
#iface br${IF:0:1}:yourvhost inet static
# address <your_other_ip>
# netmask <your_mask>
# broadcast <your_bcast>
## eof" >>/etc/network/interfaces
exit 0
Make the script executable and test it by calling it yourself, review result in
/etc/network/interfaces. Even if not all defs are necessary, i've tried to make the code failsafe...
Reconfiguring the zentyal dhcp module might be needed and also check your gateway/routing in the GUI
I had some trouble to get the routing back stable and have added a second (fallback) script as
/etc/zentyal/hooks/network.postservice for the default route ...
#!/bin/sh
# change <your_gateway> to a meaningful ip and uncomment next line
#route -n | grep -q "^0.0.0.0" || /sbin/route add default gw <your_gateway>
(make it executable and test)
You could try
ifdown br0 and then
ifup br0 to see wether things are working. Be near to the console (just in case) or have IPMI access and enjoy your bonded if's.
You may also want to edit /etc/zentyal/network.conf:
Find the line containing:
ifaces_to_ignore = sit,tun,tap,lo,...and change it to:
ifaces_to_ignore = bond,sit,tun,tap,lo,...to avoid sambas searching for an ip on the bond interface (see sambas log). The drawback is you wont have access to this interface in the firewall.
It's easy to adapt if you just need bonding but no bridge, do
not make the change to /etc/zentyal/network.conf and move the address configuration part of br to the bond defs and then remove the rest br part from code, see the following example ...
#!/bin/bash
# Revision: 0.58
# Date: 2013-10-04
# Author: Markus Neubauer
# License: GPLv2
# Zentyal Version: 3.2
# Description: Add bonding with bond0 using eth0/1
# Use it as /etc/zentyal/hooks/network.preservice and make
# it executable
# Remarks: Placed in public for the zentyal community at:
# http://forum.zentyal.org/index.php/topic,17839.html
# This script can safely be removed when zentyal has official support for bonded interfaces
# Prerequisites:
# sudo apt-get install ifenslave
# comment next line out, if done so already in /etc/modules...
lsmod | grep -q "^bonding" || modprobe bonding
# trunk interfaces
RAW_IF1="eth0" # modify this if using the new naming
RAW_IF2="eth1" # modify this if using the new naming
# ... extend to your needs and modify bond0 block if extended
# change "balance-alb" to your bonding mode if required
# Declare your own fallback variables, just in case something goes wrong
# adapt to your needs and put some meaningful values here
# you may safely want to delete the default definition for HWaddr, but set up your values for the rest
declare -r DFT_IF='0 inet static' # THIS IS bond0, oimitting the "bond"
declare -r DFT_IPAddress='192.168.X.X'
declare -r DFT_NetMask='255.255.255.X'
declare -r DFT_BroadCast='192.168.X.255'
declare -r DFT_GateWay='192.168.X.X'
# backup zentyal config (debugging)
# makes you find a /etc/network/.interfaces.zentyal-hook.*.last
# which is the zentyal's fromer config
TMP_FILE="/etc/network/.interfaces.zentyal-hook.${0##*/}.last"
SAVE_FILE="${TMP_FILE}-`date`"
cp /etc/network/interfaces "${SAVE_FILE}"
[ -L "${TMP_FILE}" ] && rm "${TMP_FILE}"
ln -s "${SAVE_FILE}" "${TMP_FILE}"
TMP_FILE=`tempfile`
# save zentyal network module config variables
grep -m1 -A5 "iface bond" /etc/network/interfaces >${TMP_FILE}
TEMP_VAR=`grep -m1 'iface bond' ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*iface bond}
IF=${TEMP_VAR:-${DFT_IF}}
TEMP_VAR=`grep -m1 address ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*address }
IPAddress=${TEMP_VAR:-${DFT_IPAddress}}
TEMP_VAR=`grep -m1 netmask ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*netmask }
NetMask=${TEMP_VAR:-${DFT_NetMask}}
TEMP_VAR=`grep -m1 broadcast ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*broadcast }
BroadCast=${TEMP_VAR:-${DFT_BroadCast}}
TEMP_VAR=`grep -m1 gateway ${TMP_FILE}`
TEMP_VAR=${TEMP_VAR##*gateway }
GateWay=${TEMP_VAR:-${DFT_GateWay}}
rm ${TMP_FILE}
# start a new config file with overwritting the previous one
echo "# replaced by zentyal hook ${0}
# on $(date)
auto lo
iface lo inet loopback
auto ${RAW_IF1}
iface ${RAW_IF1} inet manual
bond-master bond0
auto ${RAW_IF2}
iface ${RAW_IF2} inet manual
bond-master bond0
# add more raw interface blocks if needed (and extend the following bond)
# leave the bonded device entries above the bond entry
# to avoid race conditions in certain environments
auto bond${IF:0:1}
iface bond${IF}" >/etc/network/interfaces
# restore zentyal network module config variables (append)
echo " address ${IPAddress}" >>/etc/network/interfaces
echo " netmask ${NetMask}" >>/etc/network/interfaces
echo " broadcast ${BroadCast}" >>/etc/network/interfaces
echo " gateway ${GateWay}" >>/etc/network/interfaces
# append the rest of your config
echo " bond-mode balance-alb # should be selectable in GUI
bond-miimon 100
bond-lcap-rate 1
bond-slaves ${RAW_IF1} ${RAW_IF2}
up /sbin/ifconfig ${RAW_IF1} up || /bin/true
up /sbin/ifconfig ${RAW_IF2} up || /bin/true
up /sbin/ifenslave bond0 ${RAW_IF1} ${RAW_IF2} || /bin/true
down /sbin/ifenslave -d bond0 ${RAW_IF1} ${RAW_IF2} || /bin/true
post-down /sbin/ifconfig ${RAW_IF2} down || /bin/true
post-down /sbin/ifconfig ${RAW_IF1} down || /bin/true
# in the case you are using virtual hosts,
# you'll have to add the defines here, too!
#auto bond${IF:0:1}:yourvhost
#iface bond${IF:0:1}:yourvhost inet static
# address <your_other_ip>
# netmask <your_mask>
# broadcast <your_bcast>
## eof" >>/etc/network/interfaces
exit 0
In the case your are using DHCP you should remove the addressing part and dont save the former setup in tmp which will make the script very short
In recent versions of Ubuntu the code is very straight, you simply copy the following script to
/etc/zentyal/hooks/network.preservice ...
#!/bin/bash
# Revision: 0.59
# Date: 2013-10-04
# Author: Markus Neubauer
# License: GPLv2
# Zentyal Version: 3.2
# Description: Add bonding with bond0 using eth0/1 on DHCP
# Use it as /etc/zentyal/hooks/network.preservice and make
# it executable
# Remarks: Placed in public for the zentyal community at:
# http://forum.zentyal.org/index.php/topic,17839.html
# This script can safely be removed when zentyal has official support for bonded interfaces
# Prerequisites:
# sudo apt-get install ifenslave
# comment next line out, if done so already in /etc/modules...
lsmod | grep -q "^bonding" || modprobe bonding
# change "balance-alb" to your bonding mode if required
# start a new config file with overwritting the previous one
echo "# replaced by zentyal hook ${0}
# on $(date)
auto lo
iface lo inet loopback
# raw network interface 1
auto eth0
iface eth0 inet manual
bond-master bond0
# raw network interface 2
auto eth1
iface eth1 inet manual
bond-master bond0
auto bond0
iface bond0 inet dhcp
bond-mode balance-alb
bond-miimon 100
bond-lcap-rate 1
bond-slaves eth0 eth1
iface bond0 inet6 auto
# in the case you are using virtual hosts,
# you'll have to add the defines here, too!
#auto bond0:yourvhost
#iface bond0:yourvhost inet static
# address <your_other_ip>
# netmask <your_mask>
# broadcast <your_bcast>
## eof" >/etc/network/interfaces
If you are using KVM/QEMU, for a powerful and fast way of bridging, and if you are using bonding without a (userspace) own bridge, you may want to look at
macvtap device support for the kvm/qemu (
modprobe vhost_net) which will give you a kernel bridge and full access from internet side if you use the virtio bridge mode. The xml part for qemu looks similar like ...
<interface type='direct'>
<mac address='<your mac address>'/>
<source dev='bond0' mode='bridge'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</interface>
... which gives you the qemu parameter part
-netdev tap,id=hostnet0,vhost=on -device virtio-net-pci,netdev=hostnet0,id=net0,mac=<your mac address>,bus=pci.0,addr=0x4The drawback of this solution is, you wont ping your virtual host from bare metal host and may want to have a second (internal bridge) interface to access host from virtual host and vs. - or return to the first solution here. You then use the vhost-net to connect via a vnet interface on the bridge. You still can use a macvtap device, connected to the bond, to achive full speed on an other kvm machine. Some may think about "if I use Zentyal in a KVM and setup a second one in a KVM I can test changes before going to production mode"...
... adapt the settings for your interfaces as needed, suggestions are welcome.
Maybe someone could come along with a nice UI part for this purpose in the network module.
hth Markus
You may want to read
https://www.kernel.org/doc/Documentation/networking/bonding.txt and
an example for a complex network config can be found here:
https://www.stgraber.org/download/complex-interfacesA mac-address generator for the bridge was found here
http://www.miniwebtool.com/mac-address-generator/