Script de init para vde_switch+dnsmasq+NAT

17 Dec
Published by antonio.hernandez in

Dejo a continuación un script de init para iniciar un vde_switch con dnsmasq como servidor de DNS/DHCP sobre una interfaz tap... en otras palabras, te permitirá crear un switch virtual en el cual se podrán conectar tus máquinas virtuales de KVM, obtener una dirección IP dinámica y conectarse a la Internet. La forma en como iniciarías tu máquina virtual sería qemu-kvm -net vde,sock=/var/run/vde2/switch1.ctl ...

Me he basado principalmente en: http://alien.slackbook.org/dokuwiki/doku.php?id=slackware:qemu y http://alien.slackbook.org/dokuwiki/doku.php?id=slackware:vde

#!/bin/sh
# About: init script for vde_switch+dnsmasq+NAT / Slackware Linux

# Copyright © 2013 Antonio Hernández Blas <hba.nihilismus@gmail.com>
# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What The Fuck You Want
# To Public License, Version 2, as published by Sam Hocevar. See
# http://www.wtfpl.net/ for more details.

TAP_IF="tap0"
TAP_NET="172.16.16.1/24" 
TAP_DHCP_RANGE=172.16.16.100,172.16.16.105,255.255.255.0,8h

SWITCH=switch1
VDE_PID=/var/run/vde2/$SWITCH.pid
VDE_SOCK=/var/run/vde2/$SWITCH.ctl
VDE_MGMT=/var/run/vde2/$SWITCH.mgmt
DNSMASQ_PID=/var/run/vde2/dnsmasq/dnsmasq.pid
DNSMASQ_LEASE=/var/run/vde2/dnsmasq/dhcpd.leases
DNSMASQ_DOMAIN="node.vde2"
DNSMASQ_HOSTS=(
  "52:54:00:00:EE:02,172.16.16.101,dragonfly"
  "52:54:00:00:EE:03,172.16.16.102,ubuntu"
  "52:54:00:00:EE:05,172.16.16.103,slackware"
  "52:54:00:00:EE:06,172.16.16.104,plan9"
)

start(){
  status 1>/dev/null
  if [ $? -eq 0 ]; then
    echo "$SWITCH is already running: $VDE_SOCK $VDE_MGMT"
    exit 1
  fi

  echo "Starting $SWITCH..."
  mkdir -p /var/run/vde2
  mkdir -p /var/run/vde2/dnsmasq

  # Load tun module
  modprobe tun
  if [ $? -ne 0 ]; then
    echo "Error, cannot load 'tun' module."
    exit 1 
  fi

  # Start tap switch
  vde_switch \
    -tap ${TAP_IF} \
    -daemon \
    -pidfile $VDE_PID \
    -sock $VDE_SOCK \
    -mgmt $VDE_MGMT
  if [ $? -ne 0 ]; then
    echo "Error, execution of vde_switch failed."
    exit 1
  fi

  # Bring tap interface up
  ip addr add ${TAP_NET} dev ${TAP_IF} || exit 1
  ip link set ${TAP_IF} up || exit 1
   
  # Set user/group permissions
  chgrp -R users $VDE_SOCK $VDE_MGMT
  chmod -R g+rwx $VDE_SOCK $VDE_MGMT

  # Start IP packet forwarding
  sh /etc/rc.d/rc.ip_forward start 1>/dev/null

  # Add iptables rules for NAT
  for NIC in eth+ wlan+; do
    /usr/sbin/iptables \
    -t nat \
    -A POSTROUTING \
    -o ${NIC} \
    -j MASQUERADE
  done

  # DHCP per host parameter
  if [ -n "$DNSMASQ_HOSTS" ]; then
    for dnsmasq_host in ${DNSMASQ_HOSTS[@]}; do
      dhcp_hosts="$dhcp_hosts --dhcp-host=$dnsmasq_host"
    done
  fi

  if [ ! -z "$DNSMASQ_DOMAIN" ]; then
    domain="--domain=$DNSMASQ_DOMAIN"
  fi

  # Start dnsmasq
  dnsmasq \
    --log-queries \
    --user=nobody \
    $domain \
    --dhcp-leasefile=$DNSMASQ_LEASE \
    --dhcp-range=$TAP_DHCP_RANGE \
    $dhcp_hosts \
    --interface=$TAP_IF \
    --listen-address=$(echo $TAP_NET | cut -d '/' -f 1) \
    --pid-file=$DNSMASQ_PID
  if [ $? -ne 0 ]; then
    echo "Error, execution of dnsmasq failed."
  fi
}

stop(){
  echo "Stopping $SWITCH..."

  # Bring tap interface down
  ip addr flush dev ${TAP_IF} 2>/dev/null
  ip link set ${TAP_IF} down 2>/dev/null
  
  # Shutdown switch
  vdecmd -s $VDE_MGMT shutdown 2>/dev/null

  # Kill dnsmasq
  (
    kill $(cat $DNSMASQ_PID)
    rm -f $DNSMASQ_PID
  ) 2>/dev/null
}

status(){
  if [ -d $VDE_SOCK -a -S $VDE_MGMT ]; then
    echo "$SWITCH is running: $VDE_SOCK $VDE_MGMT"
    return 0
  fi
  echo "$SWITCH is not running."
  return 1
}

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    stop
    sleep 3
    start
    ;;
  status)
    status 
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|status}"
    ;;
esac