#!/bin/bash # # /usr/sbin/dnsmasq-portforward # # A script which gets run when the dnsmasq DHCP lease database changes. # It logs to $LOGFILE, if it exists, and maintains port-forwards using # IP-tables so that they always point to the correct host. See # $PORTSFILE for details on configuring this. dnsmasq must be version 2.34 # or later. # # To enable this script, add # dhcp-script=/usr/sbin/dnsmasq-portforward # to /etc/dnsmasq.conf # # To enable logging, touch $LOGFILE # PORTSFILE=/etc/portforward LOGFILE=/var/log/dhcp.log IPTABLES=/sbin/iptables action=${1:-0} hostname=${4} # log what's going on. if [ -f ${LOGFILE} ] ; then date +"%D %T $*" >>${LOGFILE} fi # If a lease gets stripped of a name, we see that as an "old" action # with DNSMASQ_OLD_HOSTNAME set, convert it into a "del" if [ ${DNSMASQ_OLD_HOSTNAME} ] && [ ${action} = old ] ; then action=del hostname=${DNSMASQ_OLD_HOSTNAME} fi # IPv6 leases are not our concern. no NAT there! if [ ${DNSMASQ_IAID} ] ; then exit 0 fi # action init is not relevant, and will only be seen when leasefile-ro is set. if [ ${action} = init ] ; then exit 0 fi # action tftp is not relevant. if [ ${action} = tftp ] ; then exit 0 fi if [ ${hostname} ]; then ports=$(sed -n -e "/^${hostname}\ .*/ s/^.* //p" ${PORTSFILE}) for port in $ports; do verb=removed protocol=tcp if [ ${port:0:1} = u ] ; then protocol=udp port=${port/u/} fi src=${port/:*/} dst=${port/*:/} # delete first, to avoid multiple copies of rules. ${IPTABLES} -t nat -D PREROUTING -p $protocol --destination-port $src -j DNAT --to-destination ${3}:$dst if [ ${action} != del ] ; then ${IPTABLES} -t nat -A PREROUTING -p $protocol --destination-port $src -j DNAT --to-destination ${3}:$dst verb=added fi if [ -f ${LOGFILE} ] ; then echo " DNAT $protocol $src to ${3}:$dst ${verb}." >>${LOGFILE} fi done fi exit 0