From: Urban Wallasch Date: Mon, 22 Apr 2019 14:33:23 +0000 (+0200) Subject: * CAVEAT: THIS VERSION IS BROKEN!!! X-Git-Url: https://git.packet-gain.de/?a=commitdiff_plain;h=0d0558cfcf35d892b297713cc3476058d59e8ebd;p=netutil.git * CAVEAT: THIS VERSION IS BROKEN!!! * First parameter may specify a config file name. * Copy host's resolv.conf, if NAMESRV is empty. * Start dhclient in guest only if no static address is provided. * Do not try to run anything, if XCMD1 empty. * Replaced `brctl` with equivalent `ip` invocations. * Removed even more clutter. --- diff --git a/nns.sh b/nns.sh index 97f5f0e..74d2a4d 100755 --- a/nns.sh +++ b/nns.sh @@ -10,33 +10,31 @@ # TODO: # ----- # -# * Replace legacy tool invocations by `ip` incantations. -# -# * Outsource configuration to sourceable script fragment. -# # * (Run dhclient to obtain bridge IP, if none was specified?) # # * Add "run" command to start a process in already existing namespace # via `ip netns exec`. # -# * Fix or remove obsolete comments. -# ############################### ############################### -# Configuration variables: +# Default configuration; can be overriden by specifying +# a shell script fragment as first parameter: + +NNSNAME= BASE_IF=vpn_tap1 -GUEST_ADDR=dhcp +GUEST_ADDR= GUEST_NET=192.168.30.0/24 BRIDGE_IF=br0 BRIDGE_ADDR=192.168.30.3 -# List of nameservers to provide DNS in the new network namespace: -NAMESRV="208.67.222.222 204.152.184.76 8.8.8.8" +# List of nameservers to provide DNS in the new network namespace; +# If empty, host resolv.conf will be used. +NAMESRV="8.8.8.8 8.8.4.4" # Program to run in the new network namespace: XCMD1=xterm @@ -55,8 +53,8 @@ SHORTNAME=${0##*/} usemsg() { echo "Usage: $1 name action" - echo "where name is the network namespace name" - echo "and action is one of start| stop| reload." + echo "where name is the name of a config file or the network" + echo "namespace name and action is one of start | stop | reload." } if [ $# -lt 2 ]; then @@ -67,6 +65,15 @@ fi # Become root if not already: [ "root" != "$USER" ] && exec sudo -E $0 "$@" +# Check, if first parameter looks like a config file name. +# If so: source it. Otherwise take $1 as namespace name. +if [ -f "$1" ] && [ -r "$1" ] ; then + . "$1" +else + # Clear the proposed namespace name of blank characters: + NNSNAME=${1//[[:space:]]} +fi + # Locate essential commands: IP=$(command -v ip) if [ -z $IP ] ; then @@ -83,23 +90,23 @@ if [ -z $DHCLIENT ] ; then echo "please install the dhclient package" exit 1 fi -XCMD=$(command -v $XCMD1) -if [ -z $XCMD ] ; then - echo "please install the $XCMD1 package" - exit 1 -fi - -# Clear the proposed namespace name of blank characters: -NNSNAME=${1//[[:space:]]} +if [ -n "XCMD1" ] ; then + XCMD=$(command -v $XCMD1) + if [ -z $XCMD ] ; then + echo "please install the $XCMD1 package" + exit 1 + fi +fi # Assign and create directory to keep runtime information: RUNDIR=/var/run/newns/$NNSNAME /bin/mkdir -p $RUNDIR + # Check whether a namespace with given name exists: exist_nns() { - $IP netns list | /bin/grep $1 2> /dev/null + $IP netns list | /bin/grep -F $1 1>/dev/null 2>&1 } @@ -117,27 +124,31 @@ start_nns() { # Take care of DNS in the new namespace: /bin/mkdir -p /etc/netns/$1 - /bin/rm /etc/netns/$1/resolv.conf 2> /dev/null - for NS in $NAMESRV ; do - echo "nameserver $NS" >> /etc/netns/$1/resolv.conf - done + if [ -n "$NAMESRV" ] ; then + /bin/rm /etc/netns/$1/resolv.conf 2> /dev/null + for NS in $NAMESRV ; do + echo "nameserver $NS" >> /etc/netns/$1/resolv.conf + done + else + cp /etc/resolv.conf /etc/netns/$1/resolv.conf + fi # Create the new namespace, the veth cable and the bridge interface: $IP netns add $1 $IP link add $VETH_HOST type veth peer name $VETH_GUEST - brctl addbr $BRIDGE_IF - brctl addif $BRIDGE_IF $BASE_IF - brctl addif $BRIDGE_IF $VETH_HOST - $IP link set dev $VETH_HOST up + $IP link add $BRIDGE_IF type bridge + $IP link set $BASE_IF master $BRIDGE_IF + $IP link set $VETH_HOST master $BRIDGE_IF $IP addr add $BRIDGE_ADDR dev $BRIDGE_IF + $IP link set dev $VETH_HOST up $IP link set dev $BRIDGE_IF up # Assign the veth guest interface to the new network namespace, # set an IP address (either static or via dhclient) to it, bring # up this and the lo interface: $IP link set $VETH_GUEST netns $1 - if [ "$GUEST_ADDR" == "dhcp" ] ; then - $IP netns exec $1 $DHCLIENT -pf "$RUNDIR/dhclient.pid" -v $VETH_GUEST 1> /dev/null 2>&1 + if [ -z "$GUEST_ADDR" ] ; then + $IP netns exec $1 $DHCLIENT -pf "$RUNDIR/dhclient.$VETH_GUEST.pid" -v $VETH_GUEST else $IP netns exec $1 $IP addr add $GUEST_ADDR dev $VETH_GUEST $IP netns exec $1 $IP link set dev $VETH_GUEST up @@ -148,9 +159,11 @@ start_nns() { $IPTABLES -t nat -A POSTROUTING --source $GUEST_NET --jump MASQUERADE $IP netns exec $1 /sbin/route add default gw $BRIDGE_ADDR - # Run the configured user process inside the namespace: - $IP netns exec $1 su -p -c "$XCMD" $SUDO_USER & - $IP netns exec $1 echo "$!" > "$RUNDIR/xcmd_.pid" + # Run the configured command, if any, inside the namespace: + if [ -n "$XCMD" ] ; then + $IP netns exec $1 su -p -c "$XCMD" $SUDO_USER & + $IP netns exec $1 echo "$!" > "$RUNDIR/xcmd_.pid" + fi } @@ -174,9 +187,9 @@ stop_nns() { # Burn the bridge: $IP link set dev $BRIDGE_IF down - brctl delif $BRIDGE_IF $BASE_IF - brctl delif $BRIDGE_IF $VETH_HOST - brctl delbr $BRIDGE_IF + $IP link set dev $BASE_IF nomaster + $IP link set dev $VETH_HOST nomaster + $IP link del $BRIDGE_IF # Unplug the virtual cable and remove network namespace: $IP netns exec $1 $IP link del $VETH_GUEST