Skip to content

Instantly share code, notes, and snippets.

@marcelomf
Last active August 29, 2015 14:21
Show Gist options
  • Save marcelomf/c8cc4b908f8f4068d28b to your computer and use it in GitHub Desktop.
Save marcelomf/c8cc4b908f8f4068d28b to your computer and use it in GitHub Desktop.
virtnet.sh
#!/bin/bash
# @author Marcelo Machado Fleury <marcelomf@gmail.com>
# @date 21/05/2015
# Other tools: pimd mrouted xorp igmpproxy dnsmasq
# printf 'DE:AD:BE:EF:%02X:%02X\n' $((RANDOM%256)) $((RANDOM%256))
multicasts=( "239.255.255.250" "224.0.0.1" "224.0.0.2" "224.0.1.1" "224.0.0.9" "224.0.1.2" "224.0.0.0" "224.0.1.0" "224.0.2.0" "224.1.0.0" "224.2.0.0" "224.3.0.0" "224.5.0.0" "225.0.0.0" "232.0.0.0" "233.0.0.0" "233.252.0.0" "234.0.0.0" "239.0.0.0" )
#echo $(basename "$0")
script_name=$(readlink -f $(dirname ${BASH_SOURCE[0]}))"/"$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")
commands=$(egrep '^ [a-zA-Z]+' $script_name | sed -e 's/\s\+/ /g' | cut -d' ' -f2 | sort | uniq | egrep -v '=|_|do|done|echo|exit|for|init|apt|while|pidof|sed|grep|egrep' | xargs echo)
packages="libvirt-bin ubuntu-vm-builder bridge-utils ebtables smcroute uml-utilities parprouted bcrelay dhcp-helper" #qemu-system qemu-kvm qemu-system-x86 qemu-system-common virt-manager apparmor apparmor-utils
libvirt_user="libvirt-qemu"
libvirt_group="kvm"
timewait=300
mode=$1
if_ext=$2
mac_ext=""
ip_ext=""
if_br=$3
ip_br="123.123.123.123"
mask_br="255.255.255.255"
if_tap=$4
ip_tap="0.0.0.0"
mac_vm=$5
ip_vm=$6
if [ "$if_br" = "" ]
then
if_br="br0"
fi
if [ "$if_tap" = "" ]
then
if_tap="tap0"
fi
user_mode() {
echo -e "Syntax:"
echo -e "\t./virtnex.sh mode [options]"
echo -e "Modes: "
echo -e "\t-daemon"
echo -e "\t\tOptions:"
echo -e "\t-auto"
echo -e "\t\tOptions:"
echo -e "\t-wire_bridge"
echo -e "\t\tOptions: if_ext if_bridge if_tap"
echo -e "\t-wifi_bridge"
echo -e "\t\tOptions: if_ext if_bridge if_tap"
echo -e "\t-wifi_bridge2"
echo -e "\t\tOptions: if_ext if_bridge if_tap mac_vm ip_vm"
echo -e "\t-nat1x1"
echo -e "\t\tOptions: if_ext if_bridge if_tap mac_vm ip_vm"
echo -e "\t-flush"
echo -e "\t\tOptions:"
echo -e "\t-show"
echo -e "\t\tOptions: if_ext if_bridge if_tap mac_vm ip_vm"
echo -e "\t-add_tap"
echo -e "\t\tOptions: if_tap"
}
show_vars() {
echo -n "Mode: "$mode
echo -n "If ext: "$if_ext
echo -n "Mac ext: "$mac_ext
echo -n "Ip ext: "$ip_ext
echo -n "If br: "$if_br
echo -n "Ip br: "$ip_br
echo -n "Mask br: "$mask_br
echo -n "If tap: "$if_tap
echo -n "Ip tap: "$ip_tap
echo -n "Mac vm: "$mac_vm
echo -n "Ip vm: "$ip_vm
}
disable_apparmor() {
service apparmor stop
update-rc.d -f apparmor remove
apt-get purge apparmor apparmor-utils -y > /dev/null 2>&1
return 0
bins=("/usr/sbin/libvirtd" "/usr/bin/qemu-system-x86_64" "/usr/lib/qemu-bridge-helper" "/usr/libexec/qemu-bridge-helper" "/usr/lib/libvirt/virt-aa-helper" "/usr/local/bin/qemu-system-x86_64" "/usr/local/lib/qemu-bridge-helper" "/usr/local/libexec/qemu-bridge-helper" "/usr/local/lib/libvirt/virt-aa-helper")
for bin in "${bins[@]}"
do
if test -f $bin
then
aa-complain $bin > /dev/null 2>&1
fi
done
profiles=("libvirt-lxc" "libvirt-qemu" "usr.libexec.qemu-bridge-helper" "usr.lib.libvirt.virt-aa-helper" "usr.sbin.libvirtd" "usr.local.libexec.qemu-bridge-helper" "usr.local.lib.libvirt.virt-aa-helper")
for profile in "${profiles[@]}"
do
if test -f /etc/apparmor.d/$profile
then
ln -s /etc/apparmor.d/$profile /etc/apparmor.d/disable/$profile > /dev/null 2>&1
fi
done
}
add_multicasts() {
pidof smcroute
if [ $? -ne 0 ]
then
smcroute -d
for network in "${multicasts[@]}"
do
smcroute -j $if_br $network
smcroute -a $if_br 0.0.0.0 $network $if_ext
done
fi
}
add_tap() {
if_tap=$1
tunctl -t $if_tap || true
mac_tap=$(ifconfig $if_tap | egrep -i HWaddr | sed -e 's/.*HWaddr.//gI')
#ip tuntap add dev $if_tap mode tap
#ip link set $if_tap up promisc on
ip link set $if_tap up
brctl addif $if_br $if_tap
echo 1 > /proc/sys/net/ipv4/conf/$if_tap/proxy_arp
}
add_bridge() {
if_br=$1
brctl addbr $if_br
mac_br=$mac_ext
#mac_br=$(ifconfig $if_br | grep HWaddr | sed -r 's/.*HWaddr ?//g')
ifconfig $if_br $ip_br netmask $mask_br hw ether $mac_br
#ifconfig $if_br hw ether $mac_br
ip link set $if_br up
echo 1 > /proc/sys/net/ipv4/conf/$if_br/proxy_arp
}
auto() {
if_ext=$(route -n | egrep -e '^0.0.0.0.*0.0.0.0' | head -n 1 | sed -e 's/\s\+/ /g' | rev | cut -d' ' -f1 | rev)
ip_ext=$(ifconfig | grep $if_ext -A 1 | tail -n 1 | sed -e 's/.*addr.//gI' -e 's/ .*//g')
mac_ext=$(ifconfig $if_ext | egrep -i HWaddr | sed -e 's/.*HWaddr.//gI')
echo 1 > /proc/sys/net/ipv4/conf/$if_ext/proxy_arp
brctl show | egrep -e 'tap|vnet'
if [ $? -eq 0 ]
then
if_br=$(brctl show | egrep -e 'br0' | head -n 1 | sed -e 's/\s\+/ /g' | cut -d' ' -f1)
if_tap=$(brctl show | egrep -e 'tap|vnet' | tail -n 1 | sed -e 's/\s\+/ /g' | rev | cut -d' ' -f1 | rev)
else
run_flush
add_bridge $if_br
add_tap $if_tap
fi
#mac_br=$(ifconfig $if_br | grep HWaddr | sed -r 's/.*HWaddr ?//g')
mac_br=$mac_ext
mac_tap=$(ifconfig $if_tap | egrep -i HWaddr | sed -e 's/.*HWaddr.//gI')
echo 1 > /proc/sys/net/ipv4/conf/$if_br/proxy_arp
echo 1 > /proc/sys/net/ipv4/conf/$if_tap/proxy_arp
echo $if_ext | egrep -i -e '^w'
if [ $? -eq 0 ]
then
set_kernel
run_iptables
pidof parprouted
if [ $? -ne 0 ]
then
parprouted $if_ext $if_br
fi
pidof bcrelay
if [ $? -ne 0 ]
then
bcrelay -d -i $if_br -o $if_ext
fi
pidof dhcp-helper
if [ $? -ne 0 ]
then
dhcp-helper -i $if_br -b $if_ext
fi
add_multicasts
else
set_kernel
run_iptables
brctl addif $if_br $if_ext
pidof dhcp-helper
if [ $? -ne 0 ]
then
dhcp-helper -i $if_br -b $if_ext
fi
add_multicasts
fi
}
init() {
ip_ext=$(ifconfig | grep $if_ext -A 1 | tail -n 1 | sed -e 's/.*addr.//gI' -e 's/ .*//g')
mac_ext=$(ifconfig $if_ext | egrep -i HWaddr | sed -e 's/.*HWaddr.//gI')
add_bridge $if_br
add_tap $if_tap
}
set_kernel() {
# sysctl net.ipv4.ip_forward=1
# sysctl net.ipv4.conf.$if_ext\.proxy_arp=1
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv4/conf/$if_ext/proxy_arp
}
run_flush() {
ifconfig $if_tap down || true
ifconfig $if_br down || true
tunctl -d $if_tap || true
brctl delbr $if_br || true
pkill parprouted || true
pkill bcrelay || true
pkill dhcp-helper || true
pkill smcroute || true
ebtables -F
ebtables -t nat -F
iptables -F
iptables -t nat -F
}
run_ebtables() {
ebtables -t nat -A POSTROUTING -o $if_ext -j snat --to-src $mac_ext --snat-arp --snat-target ACCEPT
ebtables -t nat -A PREROUTING -p IPv4 -i $if_ext -j dnat --to-dst $mac_vm --dnat-target ACCEPT
ebtables -t nat -A PREROUTING -p ARP -i $if_ext -j dnat --to-dst $mac_vm --dnat-target ACCEPT
}
run_iptables() {
iptables -t nat -A POSTROUTING -o $if_ext -j MASQUERADE
}
run_iptables_nat1x1() {
iptables -A PREROUTING -t nat -d $ip_ext -j DNAT --to $ip_vm
iptables -A POSTROUTING -t nat -s $ip_vm -j SNAT --to $ip_ext
}
show_status() {
ifconfig | grep -A 1 HWaddr
route -n
brctl show
arp -a -n
}
fix_perms() {
chown -R $libvirt_user:$libvirt_group /etc/qemu /usr/etc/qemu /var/lib/libvirt/qemu /etc/libvirt /var/run/libvirt /dev/kvm /var/log/libvirt > /dev/null 2>&1
chown root:root /usr/bin/qemu-system-x86_64 /usr/libexec/qemu-bridge-helper /usr/lib/libvirt/virt-aa-helper /usr/lib/qemu-bridge-helper /usr/local/bin/qemu-system-x86_64 /usr/local/lib/qemu-bridge-helper /usr/local/libexec/qemu-bridge-helper /usr/local/lib/libvirt/virt-aa-helper > /dev/null 2>&1
chmod 755 /usr/bin/qemu-system-x86_64 /usr/local/bin/qemu-system-x86_64 > /dev/null 2>&1
chmod 4755 /usr/libexec/qemu-bridge-helper /usr/lib/libvirt/virt-aa-helper /usr/lib/qemu-bridge-helper /usr/local/lib/qemu-bridge-helper /usr/local/libexec/qemu-bridge-helper /usr/local/lib/libvirt/virt-aa-helper > /dev/null 2>&1
}
fix_qemu_config() {
mkdir -p /etc/qemu
mkdir -p /usr/etc/qemu
touch /etc/qemu/bridge.conf
touch /usr/etc/qemu/bridge.conf
echo "allow br0" > /etc/qemu/bridge.conf
echo "allow br0" > /usr/etc/qemu/bridge.conf
}
fix_libvirt_config() {
restart=false
config="/etc/libvirt/qemu.conf"
#idvirt=$(egrep 'libvirt' /etc/passwd | head -n 1 | cut -d':' -f3)
#useradd -r -s /bin/false -d /var/lib/libvirt -c 'Libvirt manual user' -o -u $idvirt -g kvm libvirt
#egrep -e '^clear_emulator_capabilities.*0' $config
#if [ $? -ne 0 ]
#then
# echo "clear_emulator_capabilities = 0" >> $config
# restart=true
#fi
egrep -e "^user.*$libvirt_user" $config
if [ $? -ne 0 ]
then
sed -i -r -e "s/^user/#user/g" $config
echo "user = \"$libvirt_user\"" >> $config
restart=true
fi
egrep -e "^group.*$libvirt_group" $config
if [ $? -ne 0 ]
then
sed -i -r -e "s/^group/#group/g" $config
echo "group = \"$libvirt_group\"" >> $config
restart=true
fi
egrep -e "^cgroup_device_acl" $config
if [ $? -ne 0 ]
then
echo "cgroup_device_acl = [
\"/dev/null\", \"/dev/full\", \"/dev/zero\",
\"/dev/random\", \"/dev/urandom\",
\"/dev/ptmx\", \"/dev/kvm\", \"/dev/kqemu\",
\"/dev/rtc\", \"/dev/hpet\", \"/dev/net/tun\",
]">> $config
restart=true
fi
if [ "$restart" = true ]
then
service libvirt-bin reload
service libvirt-bin restart
fi
}
fix_depends() {
for command in $commands
do
#whereis $command | grep ': /' > /dev/null 2>&1 # wich
which $command
if [ $? -ne 0 ]
then
apt-get install -y $packages > /dev/null 2>&1
break
fi
done
}
geral() {
disable_apparmor
fix_qemu_config
fix_libvirt_config
fix_depends
fix_perms
}
if [ ! -n "$1" ] || [ ! -n "$2" ] || [ ! -n "$3" ] || [ ! -n "$4" ] && [ "$mode" != "-flush" ] && [ "$mode" != "-add_tap" ] && [ "$mode" != "-auto" ] && [ "$mode" != "-daemon" ]
then
user_mode
exit 1
fi
case "$mode" in
"-daemon")
while [ true ]
do
geral
auto
sleep $timewait #10m
done
;;
"-auto")
#run_flush
#init
geral
auto
;;
"-wire_bridge")
geral
run_flush
init
set_kernel
run_iptables
brctl addif $if_br $if_ext
dhcp-helper -i $if_br -b $if_ext
add_multicasts
;;
"-wifi_bridge")
geral
run_flush
init
set_kernel
run_iptables
parprouted $if_ext $if_br
bcrelay -d -i $if_br -o $if_ext
dhcp-helper -i $if_br -b $if_ext
add_multicasts
;;
"-add_tap")
geral
add_tap $2
;;
"-wifi_bridge2")
geral
run_flush
init
set_kernel
run_iptables
run_ebtables
;;
"-nat1x1")
geral
run_flush
init
set_kernel
run_iptables
run_iptables_nat1x1
;;
"-flush")
geral
run_flush
;;
"-show")
geral
run_flush
init
show_vars
;;
*)
user_mode
exit 1
;;
esac
show_status
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment