#!/usr/bin/perl # # Module: vyatta-dns-forwarding.pl # # **** License **** # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # This code was originally developed by Vyatta, Inc. # Portions created by Vyatta are Copyright (C) 2008 Vyatta, Inc. # All Rights Reserved. # # Author: Mohit Mehta # Date: August 2008 # Description: Script to glue Vyatta CLI to dnsmasq daemon # # **** End License **** # use lib "/opt/vyatta/share/perl5/"; use VyattaConfig; use VyattaMisc; use Getopt::Long; use strict; use warnings; my $dnsforwarding_init = '/etc/init.d/dnsmasq'; my $dnsforwarding_conf = '/etc/dnsmasq.conf'; sub dnsforwarding_restart { system("$dnsforwarding_init restart >&/dev/null"); print "Setting up DNS forwarding.\n"; } sub dnsforwarding_stop { system("$dnsforwarding_init stop >&/dev/null"); print "Stopping DNS forwarding.\n"; } sub dnsforwarding_get_constants { my $output; my $date = `date`; chomp $date; $output = "#\n# autogenerated by vyatta-dns-forwarding.pl on $date\n#\n"; $output .= "domain-needed\nbogus-priv\n"; return $output; } sub dnsforwarding_get_values { my $output = ''; my $config = new VyattaConfig; my $use_dnsmasq_conf = 0; $config->setLevel("service dns forwarding"); my @ignore_interfaces = $config->returnValues("ignore-interface"); if ($#ignore_interfaces >= 0) { foreach my $interface (@ignore_interfaces) { $output .= "except-interface=$interface\n"; } } my $cache_size = $config->returnValue("cache-size"); if (defined $cache_size) { $output .= "cache-size=$cache_size\n"; } my @use_nameservers = $config->returnValues("name-server"); if (@use_nameservers != 0){ $use_dnsmasq_conf = 1; foreach my $cli_nameserver (@use_nameservers) { $output .= "server=$cli_nameserver\n"; } } my $use_system_nameservers = $config->exists("system"); if (defined($use_system_nameservers)) { $use_dnsmasq_conf = 1; my $sys_config = new VyattaConfig; $sys_config->setLevel("system"); my @system_nameservers = $sys_config->returnValues("name-server"); if (@system_nameservers > 0) { foreach my $system_nameserver (@system_nameservers) { $output .= "server=$system_nameserver\n"; } } } my @use_dhcp_nameservers = $config->returnValues("dhcp"); if (@use_dhcp_nameservers != 0) { $use_dnsmasq_conf = 1; foreach my $interface (@use_dhcp_nameservers) { my $dhcp_nameserver_count=`grep nameserver /etc/resolv.conf.dhclient-new-$interface | wc -l`; if ($dhcp_nameserver_count > 0) { my @dhcp_nameservers = `grep nameserver /etc/resolv.conf.dhclient-new-$interface`; for my $each_nameserver (@dhcp_nameservers) { my @nameserver = split(/ /, $each_nameserver, 2); my $ns = $nameserver[1]; chomp $ns; $output .= "server=$ns\n"; } } } } if ($use_dnsmasq_conf == 1) { $output .= "resolv-file=/etc/dnsmasq.conf\n"; } return $output; } sub dnsforwarding_write_file { my ($config) = @_; open(my $fh, '>', $dnsforwarding_conf) || die "Couldn't open $dnsforwarding_conf - $!"; print $fh $config; close $fh; } sub check_nameserver { my $cmd = `grep nameserver /etc/resolv.conf|wc -l`; return $cmd; } sub check_system_nameserver { my $config = new VyattaConfig; $config->setLevel("system"); my @system_nameservers = $config->returnValues("name-server"); return(@system_nameservers); } sub check_dhcp_nameserver { my $intf = shift; my $cmd = `grep nameserver /etc/resolv.conf.dhclient-new-$intf|wc -l`; return $cmd; } sub is_dhcp_enabled { my $intf = shift; my $config = new VyattaConfig; if ($intf =~ m/^eth/) { if ($intf =~ m/(\w+)\.(\d+)/) { $config->setLevel("interfaces ethernet $1 vif $2"); } else { $config->setLevel("interfaces ethernet $intf"); } } elsif ($intf =~ m/^br/) { $config->setLevel("interfaces bridge $intf"); } else { # # currently we only support dhcp on ethernet # and bridge interfaces. # return 0; } my @addrs = $config->returnOrigValues("address"); foreach my $addr (@addrs) { if (defined $addr && $addr eq "dhcp") { return 1; } } return 0; } sub check_dhcp_interface { my $interface = shift; if (!is_dhcp_enabled($interface)) { print "$interface is not using DHCP to get an IP address\n"; return 0; } if (-e "/var/run/vyatta/dhclient/dhclient_release_$interface") { # dhcp released for the interface print "DHCP lease for $interface has been released.\n"; print "Renew lease for $interface before setting this parameter.\n"; return 0; } return 1; } # # main # my ($update_dnsforwarding, $stop_dnsforwarding, $system_nameserver, $dhcp_interface, $dhcp_interface_nameserver); GetOptions("update-dnsforwarding!" => \$update_dnsforwarding, "stop-dnsforwarding!" => \$stop_dnsforwarding, "system-nameserver!" => \$system_nameserver, "dhcp-interface-nameserver=s" => \$dhcp_interface_nameserver, "dhcp-interface=s" => \$dhcp_interface); if (defined $system_nameserver) { my $system_nameserver_exists = check_system_nameserver(); if ($system_nameserver_exists < 1){ print "Warning: No DNS servers set in system to forward queries.\n"; } } if (defined $dhcp_interface_nameserver) { my $dhcp_interface_nameserver_exists = check_dhcp_nameserver($dhcp_interface_nameserver); if ($dhcp_interface_nameserver_exists < 1){ print "Warning: No DNS servers received from DHCP server for $dhcp_interface_nameserver.\n"; } } if (defined $dhcp_interface) { if (!check_dhcp_interface($dhcp_interface)){ exit 1; } } if (defined $update_dnsforwarding) { my $config; my $vyatta_config = new VyattaConfig; $vyatta_config->setLevel("service dns forwarding"); my $use_system_nameservers = $vyatta_config->exists("system"); my @use_dhcp_nameservers = $vyatta_config->returnValues("dhcp"); my @use_nameservers = $vyatta_config->returnValues("name-server"); if (!(defined $use_system_nameservers) && (@use_dhcp_nameservers == 0) && (@use_nameservers == 0)) { my $nameserver_exists = check_nameserver(); if ($nameserver_exists < 1){ print "Warning: No DNS servers ('system set' or 'dhcp received') to forward queries.\n"; } } $config = dnsforwarding_get_constants(); $config .= dnsforwarding_get_values(); dnsforwarding_write_file($config); dnsforwarding_restart(); } if (defined $stop_dnsforwarding) { dnsforwarding_stop(); } exit 0; # end of file