1ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#!/bin/bash
2ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# 
3ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# /usr/sbin/dnsmasq-portforward
4ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#
5ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# A script which gets run when the dnsmasq DHCP lease database changes.
6ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# It logs to $LOGFILE, if it exists, and maintains port-forwards using
7ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# IP-tables so that they always point to the correct host. See
8ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# $PORTSFILE for details on configuring this. dnsmasq must be version 2.34 
9ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# or later.
10ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#
11ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# To enable this script, add 
12ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#    dhcp-script=/usr/sbin/dnsmasq-portforward
13ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# to /etc/dnsmasq.conf
14ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#
15ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# To enable logging, touch $LOGFILE
16ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat#
17ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
18ffd68729961f7383f2e35494a03ccdef20f86c98San MehatPORTSFILE=/etc/portforward
19ffd68729961f7383f2e35494a03ccdef20f86c98San MehatLOGFILE=/var/log/dhcp.log
20ffd68729961f7383f2e35494a03ccdef20f86c98San MehatIPTABLES=/sbin/iptables
21ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
22ffd68729961f7383f2e35494a03ccdef20f86c98San Mehataction=${1:-0}
23ffd68729961f7383f2e35494a03ccdef20f86c98San Mehathostname=${4}
24ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
25ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# log what's going on.
26ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatif [ -f ${LOGFILE} ] ; then
27ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    date +"%D %T $*" >>${LOGFILE}
28ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatfi
29ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
30ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# If a lease gets stripped of a name, we see that as an "old" action
31ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# with DNSMASQ_OLD_HOSTNAME set, convert it into a "del" 
32ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatif [ ${DNSMASQ_OLD_HOSTNAME} ] && [ ${action} = old ] ; then
33ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    action=del
34ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    hostname=${DNSMASQ_OLD_HOSTNAME}
35ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatfi
36ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
37ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# action init is not relevant, and will only be seen when leasefile-ro is set.
38ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatif [ ${action} = init ] ; then
39ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    exit 0
40ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatfi
41ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
42ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatif [ ${hostname} ]; then
43ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    ports=$(sed -n -e "/^${hostname}\ .*/ s/^.* //p" ${PORTSFILE})
44ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
45ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    for port in $ports; do
46ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	verb=removed
47ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	protocol=tcp
48ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	if [ ${port:0:1} = u ] ; then
49ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	    protocol=udp 
50ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	    port=${port/u/}
51ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	fi
52ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	src=${port/:*/}
53ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	dst=${port/*:/}
54ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat# delete first, to avoid multiple copies of rules.
55ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	${IPTABLES} -t nat -D PREROUTING -p $protocol --destination-port $src -j DNAT --to-destination ${3}:$dst
56ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat        if [ ${action} != del ] ; then
57ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	    ${IPTABLES} -t nat -A PREROUTING -p $protocol --destination-port $src -j DNAT --to-destination ${3}:$dst
58ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	    verb=added
59ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	fi
60ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	if [ -f ${LOGFILE} ] ; then
61ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	    echo "     DNAT $protocol $src to ${3}:$dst ${verb}." >>${LOGFILE}
62ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat	fi
63ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    done
64ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatfi
65ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat    
66ffd68729961f7383f2e35494a03ccdef20f86c98San Mehatexit 0
67ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
68ffd68729961f7383f2e35494a03ccdef20f86c98San Mehat
69