Simon Kelley | 1697269 | 2006-10-16 20:04:18 +0100 | [diff] [blame] | 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 | |
| 18 | PORTSFILE=/etc/portforward |
| 19 | LOGFILE=/var/log/dhcp.log |
| 20 | IPTABLES=/sbin/iptables |
| 21 | |
| 22 | action=${1:-0} |
| 23 | hostname=${4} |
| 24 | |
| 25 | # log what's going on. |
| 26 | if [ -f ${LOGFILE} ] ; then |
| 27 | date +"%D %T $*" >>${LOGFILE} |
| 28 | fi |
| 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" |
| 32 | if [ ${DNSMASQ_OLD_HOSTNAME} ] && [ ${action} = old ] ; then |
| 33 | action=del |
| 34 | hostname=${DNSMASQ_OLD_HOSTNAME} |
| 35 | fi |
| 36 | |
Simon Kelley | a953096 | 2012-03-20 22:07:35 +0000 | [diff] [blame] | 37 | # IPv6 leases are not our concern. no NAT there! |
| 38 | if [ ${DNSMASQ_IAID} ] ; then |
| 39 | exit 0 |
| 40 | fi |
| 41 | |
Simon Kelley | 1697269 | 2006-10-16 20:04:18 +0100 | [diff] [blame] | 42 | # action init is not relevant, and will only be seen when leasefile-ro is set. |
| 43 | if [ ${action} = init ] ; then |
| 44 | exit 0 |
| 45 | fi |
| 46 | |
Simon Kelley | a953096 | 2012-03-20 22:07:35 +0000 | [diff] [blame] | 47 | # action tftp is not relevant. |
| 48 | if [ ${action} = tftp ] ; then |
| 49 | exit 0 |
| 50 | fi |
| 51 | |
Simon Kelley | 1697269 | 2006-10-16 20:04:18 +0100 | [diff] [blame] | 52 | if [ ${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 |
| 74 | fi |
| 75 | |
| 76 | exit 0 |
| 77 | |
| 78 | |