Commit cf51ea5b authored by Dimitris Aragiorgis's avatar Dimitris Aragiorgis

Add basic files

Include nfdhcpd and tools handling vlans

Include basic scripts for configuring networks in nodes
Signed-off-by: default avatarDimitris Aragiorgis <dimara@grnet.gr>
parent d07b449f
......@@ -32,15 +32,16 @@ GRNET's specific routed mode:
Single bridge setup. Private IPs. Masquerade:
For security and not being able to change ip-mac-tap key:
# ebtables -t filter -D INPUT -i tap0 -j TAP0
# ebtables -t filter -D FORWARD -i tap0 -j TAP0
# ebtables -t filter -X TAP0
# ebtables -t filter -N TAP0
# ebtables -t filter -A TAP0 --ip-source \! 192.168.100.2 -p ipv4 -j DROP
# ebtables -t filter -A TAP0 -s \! aa:00:00:8c:d3:a4 -j DROP
# ebtables -t filter -A INPUT -i tap0 -j TAP0 (for masquerading)
# ebtables -t filter -A FORWARD -i tap0 -j TAP0 (for private lans)
# ebtables -N FROMTAP0
# ebtables -A FROMTAP0 --ip-source \! 192.168.100.2 -p ipv4 -j DROP
# ebtables -A FROMTAP0 -s \! aa:00:00:8c:d3:a4 -j DROP
# ebtables -A INPUT -i tap0 -j FROMTAP0 (for masquerading)
# ebtables -A FORWARD -i tap0 -j FROMTAP0 (for private lans)
# ebtables -N TOTAP0
# ebtables -A FORWARD -o tap0 -j TOTAP0
# ebtables -A OUTPUT -o tap0 -j TOTAP0
# ebtables -A TOTAP0 -s 6e:10:e1:a0:c3:0f -j ACCEPT (from gateway)
# ebtables -A TOTAP0 -s \! aa:0:0:8c:d3:a4/ff:ff:ff:ff:0:0 -j DROP
Private LANs:
......
#!/bin/bash
DIR=/var/lib/snf-network
SUBNET=$1
GATEWAY=$2
TYPE=$3
NAME=$4
RT_TABLES=/etc/iproute2/rt_tables
if [ $# -ne 4 ]; then
echo "$0 <subnet> <gateway> <private/public> <name>"
exit 1
fi
cat > $DIR/networks/$NAME <<EOF
SUBNET=$SUBNET
GATEWAY=$GATEWAY
TYPE=$TYPE
EOF
IDX=$(ls $DIR/networks | wc -l)
# remove old entry
sed -i '/^'"$IDX"'\ / d' $RT_TABLES
echo "$IDX rt_$NAME" >> $RT_TABLES
#!/bin/bash
DIR=/var/lib/snf-network
NODES=$1
ROUTER=$2
IFACE=$3
VLAN=$4
VLANS=$5
NAME=$6
if [ $# -ne 6 ]; then
echo "$0 <list_nodes> <router> <iface> <public_vlan> <list_of_private_vlans> <name>"
echo "$0 'dev88 89' 'dev88' 'eth0' '101' '2990 2999' 'default'"
exit 1
fi
cat > $DIR/nodegroups/$NAME <<EOF
ROUTER=$ROUTER
INTERFACE=$IFACE
PUBLIC_VLAN=$VLAN
PRIVATE_VLANS=$VLANS
EOF
# Defaults for nfdhcpd initscript
# sourced by /etc/init.d/nfdhcpd
# installed at /etc/default/nfdhcpd by the maintainer scripts
#
# This is a POSIX shell fragment
#
RUN="yes"
# Additional options that are passed to the Daemon.
DAEMON_OPTS=""
#!/bin/sh
#
# This is free software; you may redistribute it and/or modify
# it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2,
# or (at your option) any later version.
#
# This is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License with
# the Debian operating system, in /usr/share/common-licenses/GPL; if
# not, write to the Free Software Foundation, Inc., 59 Temple Place,
# Suite 330, Boston, MA 02111-1307 USA
#
### BEGIN INIT INFO
# Provides: nfdhcpd
# Required-Start: $network $local_fs $remote_fs
# Required-Stop: $remote_fs
# Should-Start:
# Should-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: NFQueue DHCP/RA server
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/nfdhcpd
NAME=nfdhcpd
DESC="NFQUEUE-based DHCP/RA server"
LOGDIR=/var/log/nfdhcpd
PIDFILE=/var/run/$NAME.pid
test -x $DAEMON || exit 0
. /lib/lsb/init-functions
# Default options, these can be overriden by the information
# at /etc/default/$NAME
DAEMON_OPTS="" # Additional options given to the server
DIETIME=2 # Time to wait for the server to die, in seconds
# If this value is set too low you might not
# let some servers to die gracefully and
# 'restart' will not work
STARTTIME=1 # Time to wait for the server to start, in seconds
# If this value is set each time the server is
# started (on start or restart) the script will
# stall to try to determine if it is running
# If it is not set and the server takes time
# to setup a pid file the log message might
# be a false positive (says it did not start
# when it actually did)
LOGFILE=$LOGDIR/$NAME.log # Server logfile
#DAEMONUSER=nfdhcp # Users to run the daemons as. If this value
# is set start-stop-daemon will chuid the server
# Include defaults if available
if [ -f /etc/default/$NAME ] ; then
. /etc/default/$NAME
fi
# Use this if you want the user to explicitly set 'RUN' in
# /etc/default/
if [ "x$RUN" != "xyes" ] ; then
log_failure_msg "$NAME disabled, please adjust the configuration to your needs "
log_failure_msg "and then set RUN to 'yes' in /etc/default/$NAME to enable it."
exit 1
fi
# Check that the user exists (if we set a user)
# Does the user exist?
set -e
running_pid() {
# Check if a given process pid's cmdline matches a given name
pid=$1
name=$2
[ -z "$pid" ] && return 1
[ ! -d /proc/$pid ] && return 1
cmd=`cat /proc/$pid/cmdline | tr "\000" "\n"|head -n 1 |cut -d : -f 1`
# Is this the expected server
[ "$cmd" != "$name" ] && return 1
return 0
}
running() {
# Check if the process is running looking at /proc
# (works for all users)
# No pidfile, probably no daemon present
[ ! -f "$PIDFILE" ] && return 1
pid=`cat $PIDFILE`
running_pid $pid python || return 1
return 0
}
start_server() {
start_daemon -p $PIDFILE $DAEMON $DAEMON_OPTS
errcode=$?
return $errcode
}
stop_server() {
killproc -p $PIDFILE $DAEMON
rrcode=$?
return $errcode
}
reload_server() {
[ ! -f "$PIDFILE" ] && return 1
pid=pidofproc $PIDFILE # This is the daemon's pid
# Send a SIGHUP
kill -1 $pid
return $?
}
force_stop() {
# Force the process to die killing it manually
[ ! -e "$PIDFILE" ] && return
if running ; then
kill -15 $pid
# Is it really dead?
sleep "$DIETIME"s
if running ; then
kill -9 $pid
sleep "$DIETIME"s
if running ; then
echo "Cannot kill $NAME (pid=$pid)!"
exit 1
fi
fi
fi
rm -f $PIDFILE
}
case "$1" in
start)
log_daemon_msg "Starting $DESC " "$NAME"
# Check if it's running first
if running ; then
log_progress_msg "apparently already running"
log_end_msg 0
exit 0
fi
if start_server ; then
# NOTE: Some servers might die some time after they start,
# this code will detect this issue if STARTTIME is set
# to a reasonable value
[ -n "$STARTTIME" ] && sleep $STARTTIME # Wait some time
if running ; then
# It's ok, the server started and is running
log_end_msg 0
else
# It is not running after we did start
log_end_msg 1
fi
else
# Either we could not start it
log_end_msg 1
fi
;;
stop)
log_daemon_msg "Stopping $DESC" "$NAME"
if running ; then
# Only stop the server if we see it running
errcode=0
stop_server || errcode=$?
log_end_msg $errcode
else
# If it's not running don't do anything
log_progress_msg "apparently not running"
log_end_msg 0
exit 0
fi
;;
force-stop)
# First try to stop gracefully the program
$0 stop
if running; then
# If it's still running try to kill it more forcefully
log_daemon_msg "Stopping (force) $DESC" "$NAME"
errcode=0
force_stop || errcode=$?
log_end_msg $errcode
fi
;;
restart|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME"
errcode=0
stop_server || errcode=$?
# Wait some sensible amount, some server need this
[ -n "$DIETIME" ] && sleep $DIETIME
start_server || errcode=$?
[ -n "$STARTTIME" ] && sleep $STARTTIME
running || errcode=$?
log_end_msg $errcode
;;
status)
log_daemon_msg "Checking status of $DESC" "$NAME"
if running ; then
log_progress_msg "running"
log_end_msg 0
else
log_progress_msg "apparently not running"
log_end_msg 1
exit 1
fi
;;
reload)
log_warning_msg "Reloading $NAME daemon: not implemented, as the daemon"
log_warning_msg "cannot re-read the config file (use restart)."
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|force-stop|restart|force-reload|status}" >&2
exit 1
;;
esac
exit 0
#!/bin/bash
DIR=/var/lib/snf-network
NETWORK=$1
NODEGROUP=$2
MODE=$3
LINK=$4
source /etc/default/snf-network
if [ $# -ne 4 ]; then
echo "$0 <network> <nodegroup> <mode> <link>"
exit 1
fi
NETWORK_FILE=$DIR/networks/$NETWORK
NODEGROUP_FILE=$DIR/nodegoups/$NODEGROUP
INTERFACES=$DIR/interfaces/$NETWORK-$NODEGROUP
source $NETWORK_FILE
source $NODEGROUP_FILE
if [ $MODE == "routed" ]; then
VLAN=$LINK
if [ $TYPE == "public" ]; then
APR_IP=$(ipcalc $SUBNET | grep HostMax | awk '{print $2}')
cat > $INTERFACES<<EOF
# $VLAN $MODE
auto $VLAN
iface $VLAN inet manual
# ip-routing-table rt_$NETWORK
# ip-routes $SUBNET
# ip-gateway $GATEWAY
# ip-forwarding 1
# ip-proxy-arp 1
# arp-ip $ARP_IP
EOF
ifup -i $INTERFACES $VLAN
ip link set $VLAN up
ip rule add iif $VLAN table rt_$NAME
ip route add $SUBNET dev $VLAN table main
ip route add $SUBNET dev $VLAN table rt_$NAME
ip route add default via $GATEWAY dev $VLAN table rt_$NAME
echo 1 > /proc/sys/net/ipv4/conf/all/forwarding
arptables -A OUTPUT -o $VLAN --opcode request -j mangle --mangle-ip-s $ARP_IP
fi
fi
if [ $MODE == "bridged" ]; then
BRIDGE=$LINK
echo 1 > /proc/sys/net/ipv4/ip_forward
if [ $TYPE == "public" ]; then
VLAN=$INTERFACE.$PUBLIC_VLAN_ID
elif [ $TYPE == "private" ]; then
VLAN_ID=${PRIVATE_VLAN_IDS%% *}
VLAN_IDS=${PRIVATE_VLAN_IDS#* }
sed -i 's/PRIVATE_VLAN_IDS/ s/=.*/='"VLAN_IDS"'/' $NODEGROUP_FILE
#set -- $PRIVATE_VLAN_IDS
#VLAN=$1
#shift
#VLANS=$@
VLAN=$INTERFACE.$VLAN_ID
fi
cat > $INTERFACES <<EOF
# $VLAN $MODE $BRIDGE
auto $VLAN
iface $VLAN inet manual
auto $BRIDGE
iface $BRIDGE inet manual
bridge_ports $VLAN
bridge_stp off
bridge_fd 2
EOF
ifup -i $INTERFACES $BRIDGE
ip link set $VLAN up
ip route add $SUBNET dev $BRIDGE table main
ip route add $SUBNET dev $BRIDGE table rt_$NETWORK
if [ ! -z $GATEWAY ]; then
ip route add default via dev $BRIDGE table rt_$NETWORK
if [ $TYPE == "private" ]; then
if [ ! -z $ROUTER ]; then
if [ $(hostname) == $ROUTER ]; then
NETMASK=$(ipcalc $SUBNET | grep Netmask | awk '{print $4}')
ip addr add $GATEWAY/$NETMASK dev $BRIDGE
iptables -t nat -A POSTROUTING -s $SUBNET \! -d $SUBNET -j MASQUERADE
fi
fi
fi
fi
fi
#!/bin/bash
DIR=/var/lib/snf-network
NETWORK=$1
NODEGROUP=$2
source /etc/default/snf-network
if [ $# -ne 2 ]; then
echo "$0 <network> <nodegroup>"
exit 1
fi
NETWORK_FILE=$DIR/networks/$NETWORK
NODEGROUP_FILE=$DIR/nodegoups/$NODEGROUP
INTERFACES=$DIR/interfaces/$NETWORK-$NODEGROUP
read x VLAN BRIDGE < $INTERFACES
VLAN_ID=${VLAN#*:}
source $NETWORK_FILE
source $NODEGROUP_FILE
if [ $MODE == "routed" ]; then
if [ $TYPE == "public" ]; then
APR_IP=$(ipcalc $SUBNET | grep HostMax | awk '{print $2}')
ip rule del iif $VLAN table rt_$NAME
ip route del $SUBNET dev $VLAN table main
ip route del $SUBNET dev $VLAN table rt_$NAME
ip route del default via $GATEWAY dev $VLAN table rt_$NAME
arptables -D OUTPUT -o $VLAN --opcode request -j mangle --mangle-ip-s $ARP_IP
ifdown -i $INTERFACES $VLAN
rm $INTERFACES
fi
fi
if [ $MODE == "bridged" ]; then
if [ $TYPE == "private" ]; then
VLAN_IDS="$VLAN_ID $PRIVATE_VLAN_IDS"
sed -i 's/PRIVATE_VLAN_IDS/ s/=.*/='"VLAN_IDS"'/' $NODEGROUP_FILE
fi
ip route del $SUBNET dev $BRIDGE table main
ip route del $SUBNET dev $BRIDGE table rt_$NETWORK
if [ ! -z $GATEWAY ]; then
ip route del default via $GATEWAY dev $BRIDGE table rt_$NETWORK
if [ $TYPE == "private" ]; then
if [ ! -z $ROUTER ]; then
if [ $(hostname) == $ROUTER ]; then
NETMASK=$(ipcalc $SUBNET | grep Netmask | awk '{print $4}')
ip addr del $GATEWAY/$NETMASK dev $LINK
iptables -t nat -D POSTROUTING -s $SUBNET \! -d $SUBNET -j MASQUERADE
fi
fi
fi
fi
ifdown -i $INTERFACES $BRIDGE
rm $INTERFACES
fi
# IP-less inteface, used to route public IPv4
# for Synnefo VMs
auto eth0.101
iface eth0.101 inet manual
ip-routing-table rt_public
ip-routes 62.217.123.128/27
ip-gateway 62.217.123.129
ip-forwarding 1
ip-proxy-arp 1
arp-ip 62.217.123.158
#auto eth0.100
iface eth0.100 inet manual
up ip link set eth0.100 up
#auto br100
iface br100 inet static
# needed for being the rooter for the VMs
address 192.168.100.1
netmask 255.255.255.240
bridge_ports eth0.100
# needed by nfdhcpd to make DHCP responses
up ip route add 192.168.100.0/28 dev br100 table rt_net100
up ip route add default via 192.168.100.1 dev br100 table rt_net100
# needed for the VMs to connect to the world
up iptables -t nat -A POSTROUTING -s 192.168.100.0/28 \! -d 192.168.100.0/28 -j MASQUERADE
down iptables -t nat -D POSTROUTING -s 192.168.100.0/28 \! -d 192.168.100.0/28 -j MASQUERADE
bridge_stp off
bridge_fd 2
#auto br100:1
iface br100:1 inet static
# needed for being the rooter for the VMs
address 192.168.101.1
netmask 255.255.255.240
up ip route add 192.168.101.0/28 dev br100 table rt_net101
up ip route add default via 192.168.101.1 dev br100 table rt_net101
# needed for the VMs to connect to the world
up iptables -t nat -A POSTROUTING -s 192.168.101.0/28 \! -d 192.168.101.0/28 -j MASQUERADE
down iptables -t nat -D POSTROUTING -s 192.168.101.0/28 \! -d 192.168.101.0/28 -j MASQUERADE
#!/bin/bash
# This is an example of a Ganeti kvm ifup script that configures network
# interfaces based on the initial deployment of the Okeanos project
TAP_CONSTANT_MAC=cc:47:52:4e:45:54 # GRNET in hex :-)
MAC2EUI64=/usr/bin/mac2eui64
NFDHCPD_STATE_DIR=/var/lib/nfdhcpd
function routed_setup_ipv4 {
# get the link's default gateway
gw=$(ip route list table $TABLE | sed -n 's/default via \([^ ]\+\).*/\1/p' | head -1)
# mangle ARPs to come from the gw's IP
arptables -D OUTPUT -o $INTERFACE --opcode request -j mangle >/dev/null 2>&1
arptables -A OUTPUT -o $INTERFACE --opcode request -j mangle --mangle-ip-s "$gw"
# route interface to the proper routing table
while ip rule del dev $INTERFACE; do :; done
ip rule add dev $INTERFACE table $TABLE
# static route mapping IP -> INTERFACE
ip route replace $IP proto static dev $INTERFACE table $TABLE
# Enable proxy ARP
echo 1 > /proc/sys/net/ipv4/conf/$INTERFACE/proxy_arp
}
function routed_setup_ipv6 {
# Add a routing entry for the eui-64
prefix=$(ip -6 route list table $TABLE | awk '/\/64/ {print $1; exit}')
uplink=$(ip -6 route list table $TABLE | sed -n 's/default via .* dev \([^ ]\+\).*/\1/p' | head -1)
eui64=$($MAC2EUI64 $MAC $prefix)
while ip -6 rule del dev $INTERFACE; do :; done
ip -6 rule add dev $INTERFACE table $TABLE
ip -6 ro replace $eui64/128 dev $INTERFACE table $TABLE
ip -6 neigh add proxy $eui64 dev $uplink
# disable proxy NDP since we're handling this on userspace
# this should be the default, but better safe than sorry
echo 0 > /proc/sys/net/ipv6/conf/$INTERFACE/proxy_ndp
}
# pick a firewall profile per NIC, based on tags (and apply it)
function routed_setup_firewall {
ifprefix="synnefo:network:$INTERFACE_INDEX:"
for tag in $TAGS; do
case ${tag#$ifprefix} in
protected)
chain=protected
;;
unprotected)
chain=unprotected
;;
limited)
chain=limited
;;
esac
done
# Flush any old rules. We have to consider all chains, since
# we are not sure the instance was on the same chain, or had the same
# tap interface.
for oldchain in protected unprotected limited; do
iptables -D FORWARD -o $INTERFACE -j $oldchain 2>/dev/null
ip6tables -D FORWARD -o $INTERFACE -j $oldchain 2>/dev/null
done
if [ "x$chain" != "x" ]; then
iptables -A FORWARD -o $INTERFACE -j $chain
ip6tables -A FORWARD -o $INTERFACE -j $chain
fi
}
function routed_setup_nfdhcpd {
umask 022
cat >$NFDHCPD_STATE_DIR/$INTERFACE <<EOF
IFACE=$1
IP=$IP
MAC=$MAC
LINK=$TABLE
HOSTNAME=$INSTANCE
TAGS="$TAGS"
EOF
}
function make_ebtables {
TAP=$INTERFACE
FROM=FROM${TAP^^}
TO=TO${TAP^^}
ebtables -D INPUT -i $TAP -j $FROM
ebtables -D FORWARD -i $TAP -j $FROM
ebtables -D FORWARD -o $TAP -j $TO
ebtables -D OUTPUT -o $TAP -j $TO
ebtables -X $FROM
ebtables -X $TO
ebtables -N $FROM
ebtables -A $FROM --ip-source \! $IP -p ipv4 -j DROP
ebtables -A $FROM -s \! $MAC -j DROP
ebtables -A INPUT -i $TAP -j $FROM
ebtables -A FORWARD -i $TAP -j $FROM
ebtables -N $TO
ebtables -A FORWARD -o $TAP -j $TO
ebtables -A OUTPUT -o $TAP -j $TO
if [ $TYPE == "private" ]; then
ebtables -A $TO -s \! $MAC/$MAC_MASK -j DROP
if [ ! -z $GATEWAY ]; then
ebtables -A $TO -s $ROUTER_MAC -j ACCEPT
fi
fi
}
#FIXME: import router mac from the config files
# must know node group!! how???
ROUTER_MAC=6e:10:e1:a0:c3:0f
MAC_MASK=ff:ff:ff:0:0:0
TABLE=rt_$NETWORK
source /var/lib/snf-network/networks/$NETWORK
if [ "$MODE" = "routed" ]; then
# special proxy-ARP/NDP routing mode
# use a constant predefined MAC address for the tap
ip link set $INTERFACE addr $TAP_CONSTANT_MAC
# bring the tap up
ifconfig $INTERFACE 0.0.0.0 up
# Drop unicast BOOTP/DHCP packets
iptables -D FORWARD -i $INTERFACE -p udp --dport 67 -j DROP 2>/dev/null
iptables -A FORWARD -i $INTERFACE -p udp --dport 67 -j DROP
routed_setup_ipv4
routed_setup_ipv6
routed_setup_firewall
routed_setup_nfdhcpd $INTERFACE
elif [ "$MODE" = "bridged" ]; then
while ip rule del dev $INTERFACE; do :; done
ifconfig $INTERFACE 0.0.0.0 up
brctl addif $BRIDGE $INTERFACE
routed_setup_nfdhcpd $BRIDGE
make_ebtables
fi
#!/bin/bash
DIR=/var/lib/snf-network
NEW_GATEWAY=$1
NEW_TYPE=$2
NETWORK=$3
RT_TABLES=/etc/iproute2/rt_tables
if [ $# -ne 3 ]; then
echo "$0 <gateway> <private/public> <name>"
exit 1
fi
source /etc/default/snf-network
NETWORK_FILE=$DIR/networks/$NETWORK
source $NETWORK_FILE
OLD_GATEWAY=$GATEWAY
OLD_TYPE=$TYPE
INTERFACES=$(ls $DIR/interfaces/$NETWORK-*)
for IFACES in $INTERFACES ; do
NODEGROUP=$(echo $IFACES | sed 's/.*interfaces.*-//')
source $DIR/nodegroups/$NODEGROUP
read x VLAN MODE BRIDGE < $INTERFACES
if [ $MODE == "routed" ]; then
if [ $TYPE == "public" ]; then
ip route replace default via $GATEWAY dev $VLAN table rt_$NETWORK
fi
fi
if [ $MODE == "bridged" ]; then
if [ ! -z $GATEWAY ]; then
ip route replace default via $GATEWAY dev $BRIDGE table rt_$NETWORK
if [ $TYPE == "private" ]; then
if [ ! -z $ROUTER ]; then
if [ $(hostname) == $ROUTER ]; then
NETMASK=$(ipcalc $SUBNET | grep Netmask | awk '{print $4}')
ip addr del $GATEWAY/$NETMASK dev $BRIDGE
ip addr add $NEW_GATEWAY/$NETMASK dev $BRIDGE
fi
fi
fi
fi
fi
if [ ! -z $NEW_GATEWAY ]; then
sed -i '/^GATEWAY/ s/=.*/='"$NEW_GATEWAY"'/' $NETWORK_FILE
fi
if [ ! -z $NEW_TYPE ]; then
sed -i '/^TYPE/ s/=.*/='"$NEW_TYPE"'/' $NETWORK_FILE
fi
done
This diff is collapsed.
## nfdhcpd sample configuration file
## General options
[general]
pidfile = /var/run/nfdhcpd.pid
datapath = /var/lib/nfdhcpd # Where the client configuration will be read from
logdir = /var/log/nfdhcpd # Where to write our logs
user = nobody # An unprivileged user to run as