Skip to content

Instantly share code, notes, and snippets.

@nogweii
Created August 19, 2013 23:09
Show Gist options
  • Save nogweii/6275272 to your computer and use it in GitHub Desktop.
Save nogweii/6275272 to your computer and use it in GitHub Desktop.
Converts a single, physical interface into 2 virtual vlans that can route to each other. There is no need for a second physical interface or cable.
#!/bin/sh
#
###############################################################################
# Magical Single-Interface Routing Script (MSIRS)
#
# Converts a single, physical interface to 2 separate vlans that can route to
# each other. There is no need for a second physical interface or cable.
# However, since you are not literally in the middle of every packet, there is
# still a chance of an internal computer being connected to directly. It's
# unlikely, but because of this risk you should not run this in a production
# environment.
#
# It's a neat trick, though.
#
# Copyright (C) 2012 Scott Fraser <[email protected]> &
# Colin Shea <[email protected]>
#
# Licensed under MIT
# Must be run as root. If not, quit early
if [ $EUID -ne 0 ] ; then
echo "$0: Must run this as root."
exit 2
fi
# Make sure we have the absolutely required commands
for mandatory_command in ip iptables ; do
command -v $mandatory_command >/dev/null 2>/dev/null
if [ $? -eq 1 ] ; then
echo "Missing mandatory command: ${mandatory_command}"
exit 1
fi
done
# Default settings. Edit manually if you don't have dialog.
# {{{{ EDIT HERE
outnetwork=192.168.4.0
outip=192.168.4.15
outipwmask=192.168.4.15/24
outnetmask=192.168.4.0/24
default=192.168.4.1
innetwork=10.5.0.0
inip=10.5.1.1
inipwmask=10.5.1.1/24
innetmask=10.5.1.0/24
phyint=wlan0
internal=internal
external=external
vlanidoutside=5
vlanidinside=10
# }}}}
# Do we have dialog? Can we use a 'gui'?
command -v dialog >/dev/null 2>/dev/null
if [ $? -eq 0 ]; then
echo 'lol, dialog, yay'
rightalign=25
tmpfilename=/tmp/${0%.sh}$$${RANDOM}${RANDOM}.txt
# Yep! Present a form to the user to collect information
dialog --form "IP Settings" 0 0 0 "External Network" 2 1 "192.168.4.0" 2 $rightalign 15 0 \
"Outwards netmask" 3 1 "192.168.4.0/24" 3 $rightalign 18 0 \
"External IP address" 4 1 "192.168.4.15" 4 $rightalign 15 0 \
"External Netmask" 5 1 "192.168.4.15/24" 5 $rightalign 18 0 \
"Gateway IP address" 6 1 "192.168.4.1" 6 $rightalign 15 0 \
" Internal config" 7 1 "" 7 $rightalign 0 0 \
"Internal network" 8 1 "10.5.0.0" 8 $rightalign 15 0 \
"Internal IP address" 9 1 "10.5.1.1" 9 $rightalign 15 0 \
"Internal IP netmask" 10 1 "10.5.1.1/24" 10 $rightalign 18 0 \
"Inwards netmask" 11 1 "10.5.1.0/24" 11 $rightalign 18 0 \
" Interfaces config" 12 1 "" 12 $rightalign 0 0 \
"Physical interface" 13 1 "eth0" 13 $rightalign 10 0 \
"Internal interface name" 14 1 "internal" 14 $rightalign 12 0 \
"Internal VLAN ID" 15 1 "5" 15 $rightalign 3 0 \
"External interface name" 16 1 "external" 16 $rightalign 12 0 \
"External VLAN ID" 17 1 "10" 17 $rightalign 3 0 2> $tmpfilename || exit 1
# Introduced in bash v4: mapflie
mapfile -t settings < "$tmpfilename"
# Map the lines of the file to the various variables
outnetwork="${settings[0]}"
outip="${settings[2]}"
outipwmask="${settings[3]}"
outnetmask="${settings[1]}"
default="${settings[4]}"
innetwork="${settings[5]}"
inip="${settings[6]}"
inipwmask="${settings[7]}"
innetmask="${settings[8]}"
phyint="${settings[9]}"
internal="${settings[10]}"
external="${settings[12]}"
vlanidoutside="${settings[11]}"
vlanidinside="${settings[13]}"
# clean up after ourselves
rm $tmpfilename
else
# Tell the user that they need to edit the file
echo "No dialog, edit $0 manually. Lines 36-53"
# Give the user a chance to react before continuing on
sleep 4
fi
echo "*********Adding subinterfaces and addresses to interfaces*********"
ip link add link ${phyint} name ${external} type vlan id ${vlanidoutside}
ip addr add ${outipwmask} brd + dev ${external}
ip link set ${external} up
ip link add link ${phyint} name ${internal} type vlan id ${vlanidinside}
ip addr add ${inipwmask} brd + dev ${internal}
ip link set ${internal} up
echo "**********Changing routing tables in Main*****************"
ip route change ${outnetmask} dev ${phyint} src ${outip}
ip route add default via ${default}
ip route change ${innetmask} dev ${phyint} src ${inip}
echo "********Adding routing rule and routes to table*******"
ip route add ${innetmask} dev ${phyint} src ${inip} table 5
echo "add route"
ip rule add prio 5 to ${innetmask} table 5
echo "add rule"
#cant take the route out of main until it is in a table
ip route delete ${innetmask}
echo "**********Configuring IPTables to do NAT******************"
echo "**********************Warning*****************************"
echo "******************Flushing Rules!*************************"
iptables -F -t nat
# allow forwarding
echo 1 > "/proc/sys/net/ipv4/ip_forward"
# enable masquerading
iptables -t nat -A POSTROUTING -o ${phyint} -s ${innetmask} -j MASQUERADE
# enable logging
iptables -A FORWARD -j LOG
# Display iptables configuration
iptables -L -v -t nat --line-numbers
echo "************END**************"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment