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