Skip to content

Instantly share code, notes, and snippets.

@cyphunk
Last active August 22, 2020 12:52
Show Gist options
  • Save cyphunk/eb8cbfef47981f59e428bb77e070d2d1 to your computer and use it in GitHub Desktop.
Save cyphunk/eb8cbfef47981f59e428bb77e070d2d1 to your computer and use it in GitHub Desktop.
use dnsmasq to setup dhcp server or share network
#!/usr/bin/env bash
# sudo call integrity check: only root should be able to change script
l=($(ls -l `readlink -f $0`))
[ ${l[0]:2:1} != "-" ] && [ "${l[2]}" != "root" ] ||
[ ${l[0]:5:1} != "-" ] && [ "${l[3]}" != "root" ] ||
[ ${l[0]:8:1} != "-" ] && { echo -e "only root should be able to modify\n${l[@]}"; exit 1;}
# Defaults
IP="192.168.20.1"
PORTS="53 443" # auto add 53 later
MASK="255.255.255.0"
MASKBITS="/24"
if [ $# -lt 1 ]; then
cat <<USAGE
usage: $0 <eth> [ip] [port ...] [<nat>]
eth interface
ip IP for interface in '$MASKBITS' network (default '$IP')
port List of ports to open on firewall ('$PORTS')
nat if set to 1 setup firewall to NAT clients
optionally set dnsmasq upstream server with:
DNSIP=<IP> $0 ...
examples:
$0 eth0 1 # start on eth0 default IP range and NAT forwarding
$0 eth0 10.0.0.1 # assign eth0 10.0.0.1, serve 10.0.0.100-154
USAGE
exit
fi
# SET INTERFACE
ETH=$1; shift
#test "$ETH" == "eth0" && ETH=`ls /sys/class/net/|grep en|head -1`
# SET IP
shopt -s extglob
if [ "${1/+([0-9]).+([0-9]).+([0-9]).+([0-9])/isip}" == "isip" ]; then
IP=$1; shift
fi
NETPREFIX=${IP/%.+([0-9])/} # all but last ip octect
# SET NAT CLIENTS OR NOT
USENAT=0
if [ $# -gt 0 ] && [ "${@:$#}" == "1" ]; then
USENAT=1
# $@ = all but last arg
set -- ${@:1:$#-1}
elif [ $# -gt 0 ] && [ "${@:$#}" == "0" ]; then
set -- ${@:1:$#-1}
fi
# SET FIREWALL PORTS
if [ $# -gt 0 ]; then
PORTS="53 $@"
fi
echo "eth: '$ETH' ip: '$IP' net: '${NETPREFIX}.0$MASKBITS' nat: '$USENAT'"
echo "ports: $PORTS"
echo ""
sleep 1
# SET OPTIONAL DNS SERVER FOR DNSMASQ
DNSIP=${DNSIP:-} #if not defined in env set to nothing
if [ "$DNSIP" != "" ]; then
DNSMASQDNSCFG="\ndhcp-option=dns-server,$DNSIP\nno-resolv\nserver=$DNSIP\n"
else
DNSMASQDNSCFG=""
fi
# GO
# kill dhclient on $ETH
PIDS=$(ps -aux | grep dhclient | grep $ETH | awk "{print \$2}" | xargs)
test "$PIDS" && sudo kill $PIDS
set -x
sudo ufw allow in on $ETH from any port 68 to any port 67 proto udp
# could replace. ufw allows multi ports as "n,n,n"
for PORT in $PORTS; do
sudo ufw allow in on $ETH to any port $PORT
done
sudo ifconfig $ETH $IP netmask 255.255.255.0
if [ $USENAT -ne 0 ]; then
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -A FORWARD -i $ETH -s ${NETPREFIX}.0$MASKBITS -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
fi
test -d /tmp/$ETH || mkdir /tmp/$ETH
DIR=/tmp/$ETH
cat >$DIR/dnsmasq.conf <<EOF
dhcp-option=option:router,${IP}
dhcp-range=${NETPREFIX}.100,${NETPREFIX}.154,${MASK},96h
enable-ra
dhcp-option=option6:dns-server,[2001:db8:4b:222::1]
dhcp-range=::100,::1ff,constructor:em1
EOF
echo "DNSIP: $DNSIP"
if [ "$DNSIP" != "" ]; then
# port=0 disables dnsmasq dns server
cat >>$DIR/dnsmasq.conf <<EOF
dhcp-option=option:dns-server,$DNSIP
dhcp-option=option6:dns-server,[::]
enable-ra
port=0
EOF
#no-resolv
#server=$DNSIP
fi
sudo dnsmasq -d -i $ETH \
--conf-file="$DIR/dnsmasq.conf" \
--dhcp-leasefile="$DIR/leases" \
--pid-file="$DIR/pid"
# --dhcp-host="20:f1:7c:75:e6:ee,${NETPREFIX}.49,HOST" \
# --dhcp-host="00:80:2f:ff:ff:ff,192.168.1.111,HOSTNAME" \
# --dhcp-option="option:ntp-server,${IP}.1" \
# --domain=local
# END CLEANUP
sudo ufw delete allow in on $ETH from any port 68 to any port 67 proto udp
for PORT in $PORTS; do
sudo ufw delete allow in on $ETH to any port $PORT
done
if [ $USENAT -ne 0 ]; then
sudo sysctl -w net.ipv4.ip_forward=0
sudo iptables -D FORWARD -i $ETH -s ${NETPREFIX}.0$MASKBITS -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -D FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -t nat -F
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment