summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTuomas Jaakola <tuomas.jaakola@iki.fi>2011-07-22 13:24:58 +0300
committerTimo Teräs <timo.teras@iki.fi>2011-07-22 13:31:18 +0300
commitfcca67d52532a16ef0e9cbbecf2c623582364ab5 (patch)
treeb6c110653118e283bbc3c99defffd4de45bb1394
parenta1f9da29de6d5abcb0adb7bfa4a4baeb9d930a08 (diff)
downloadacf-dnsmasq-fcca67d52532a16ef0e9cbbecf2c623582364ab5.tar.bz2
acf-dnsmasq-fcca67d52532a16ef0e9cbbecf2c623582364ab5.tar.xz
Support for DNS filtering added
-rw-r--r--dnsmasq-config-html.lsp12
-rw-r--r--dnsmasq-model.lua120
2 files changed, 120 insertions, 12 deletions
diff --git a/dnsmasq-config-html.lsp b/dnsmasq-config-html.lsp
index edfe950..a9db81a 100644
--- a/dnsmasq-config-html.lsp
+++ b/dnsmasq-config-html.lsp
@@ -20,13 +20,23 @@ end %>
displayformitem(form.value.domain, "domain")
%>
</DL>
-<H2>DNS Parameters</H2>
+<H2>DNS settings</H2>
+<H3>DNS Parameters</H3>
<DL>
<%
displayformitem(form.value.mx_host, "mx_host")
%>
</DL>
+<H3>DNS filtering</H3>
+<DL>
+<%
+ displayformitem(form.value.dns_filtering, "dns_filtering")
+ displayformitem(form.value.dns_whitelist, "dns_whitelist")
+ displayformitem(form.value.dns_default_address, "dns_default_address")
+%>
+</DL>
+
<H2>DHCP Parameters</H2>
<DL>
<%
diff --git a/dnsmasq-model.lua b/dnsmasq-model.lua
index 1e6c5b8..b2a6465 100644
--- a/dnsmasq-model.lua
+++ b/dnsmasq-model.lua
@@ -11,6 +11,7 @@ local configfile = "/etc/dnsmasq.conf"
local processname = "dnsmasq"
local packagename = "dnsmasq"
local leasefile = "/var/lib/misc/dnsmasq.leases"
+local dnsfilterfile = "/etc/dnsmasq-dnsfilter.conf"
-- ################################################################################
-- LOCAL FUNCTIONS
@@ -47,11 +48,8 @@ local function update_file (file, search_name, value_in)
if a and (search_name == a) then
-- Figure out the value
local b = string.match ( l, '=%s*(.*%S)%s*$' ) or ""
- -- remove comments from end of line
- if string.find ( b, '#' ) then
- b = string.match ( b, '^(.*%S)%s*#.*$' ) or ""
- end
-
+ -- no need to remove comments from end of line, they
+ -- should not be there, see 'man dnsmasq'
-- We found the name, change the value
if not value then
l = nil
@@ -124,11 +122,8 @@ local function parse_file (file)
if a then
-- Figure out the value
local b = string.match ( l, '=%s*(.*%S)%s*$' ) or ""
- -- remove comments from end of line
- if string.find ( b, '#' ) then
- b = string.match ( b, '^(.*%S)%s*#.*$' ) or ""
- end
-
+ -- no need to remove comments from end of line, they
+ -- should not be there, see 'man dnsmasq'
if not (opts) then opts = {} end
if not opts[a] then
opts[a] = {b}
@@ -157,7 +152,14 @@ local function validateconfig(config)
end
end
end
-
+
+ function testtext(param, test, errtxt)
+ if test(param.value) then
+ param.errtxt = errtxt
+ success = false
+ end
+ end
+
testlist(config.value.domain, function(v) return string.find(v, "%s") end, "Cannot contain spaces")
testlist(config.value.interface, function(v) return string.find(v, "%W") end, "Illegal character")
testlist(config.value.listen_address, function(v) return not validator.is_ipv4(v) end, "Invalid IP Address")
@@ -166,10 +168,94 @@ local function validateconfig(config)
testlist(config.value.dhcp_host, function(v) return string.find(v, "%s") end, "Cannot contain spaces")
testlist(config.value.dhcp_option, function(v) return string.find(v, "%s") end, "Cannot contain spaces")
testlist(config.value.mx_host, function(v) return string.find(v, "%s") end, "Cannot contain spaces")
+ if config.value.dns_filtering.value then
+ -- validate ip address only if dns filtering is enabled
+ testtext(config.value.dns_default_address, function(v) return not validator.is_ipv4(v) end, "Invalid IP Address")
+ end
return success, config
end
+local function dns_filtering_is_enabled(conf)
+ -- Returns true if dnsfilterfile is included in configfile.
+ -- conf - config variable from parse_file()
+ local conf_files = conf["conf-file"] or {}
+ for i,conf_file in ipairs(conf_files) do
+ if conf_file == dnsfilterfile then
+ return true
+ end
+ end
+ return false
+end
+
+local function set_dns_filtering(file, enable)
+ -- Returns new table of conf["conf-file"].
+ -- Includes existing conf-files and adds or removes dnsfilterfile.
+ -- file - config data
+ -- enabled - boolean for dns filtering
+ local conf = parse_file(file) or {}
+ local enabled = dns_filtering_is_enabled(conf)
+ local conf_files = conf["conf-file"] or {}
+ if enabled ~= enable then
+ -- state changed, we have to modify conf_files table
+ if enable then
+ -- add dnsfilterfile to conf-files
+ table.insert(conf_files, dnsfilterfile)
+ else
+ -- remove dnsfilterfile from conf-files
+ for i,conf_file in ipairs(conf_files) do
+ if conf_file == dnsfilterfile then
+ table.remove(conf_files, i)
+ break
+ end
+ end
+ end
+ end
+ return conf_files
+end
+
+local function update_dns_whitelist(servers, default_address)
+ -- Updates dnsfilterfile
+ -- servers - value from web form as table
+
+ local file = fs.read_file(dnsfilterfile) or ""
+ local serverlines = {}
+ for i,server in ipairs(servers or {}) do
+ local modified = "/" .. server .. "/#"
+ table.insert(serverlines, modified)
+ end
+ file = update_file(file, "server", serverlines)
+ -- update address to point to default_address
+ file = update_file(file, "address", "/#/" .. default_address)
+ fs.write_file(dnsfilterfile, file)
+ return true
+end
+
+local function parse_whitelist(file)
+ -- Parses dnsfilterfile and returns table of servers and
+ -- default address.
+ -- Format should be in:
+ -- server=/whitelisted.com/#
+ -- server=/another.com/#
+ -- address=/#/192.168.1.1
+ local servers = {}
+ local parsed = parse_file(file) or {}
+ local serverlines = parsed["server"] or {}
+ for i,value in ipairs(serverlines) do
+ -- remove '/' and '/#' from value
+ local server = string.match(value, "^/%s*([^=]*%S)%s*/#")
+ table.insert(servers, server)
+ end
+ -- parse default address
+ local default_address = ""
+ local addresses = parsed["address"] or {}
+ if #addresses > 0 then
+ -- get first address, anyway there shouldn't be more than 1?
+ default_address = string.match(addresses[1], "^/#/(.*%S)")
+ end
+ return servers, default_address
+end
+
-- ################################################################################
-- PUBLIC FUNCTIONS
@@ -183,6 +269,9 @@ end
function getconfig()
local conf = parse_file(fs.read_file(configfile) or "") or {}
+ local dns_filtering = {}
+ dns_filtering.enabled = dns_filtering_is_enabled(conf)
+ dns_filtering.whitelist, dns_filtering.default_address = parse_whitelist(fs.read_file(dnsfilterfile) or "")
local output = {}
output.domain = cfe({ type="list", value=conf.domain or {}, label="Local Domain",
@@ -196,6 +285,9 @@ function getconfig()
output.dhcp_option = cfe({ type="list", value=conf["dhcp-option"] or {}, label="DHCP Option", descr="List of different or extra options to DHCP clients. See dnsmasq documentation." })
output.mx_host = cfe({ type="list", value=conf["mx-host"] or {}, label="MX Record", descr="List of MX records 'mx_name,hostname'." })
+ output.dns_filtering = cfe({ type="boolean", value=dns_filtering.enabled or false, label="DNS filtering enabled", descr="State of DNS filtering." })
+ output.dns_whitelist = cfe({ type="list", value=dns_filtering.whitelist or {}, label="DNS whitelist", descr="DNS whitelist for filtering. Type one allowed domain per one line." })
+ output.dns_default_address = cfe({ type="text", value=dns_filtering.default_address or "", label="Blocked page server address", descr="All DNS requests which are not on the white list, will be redirected to this IP address. This address should have a web server running that shows an address blocked page. Example: 192.168.1.1" })
return cfe({ type="group", value=output, label="DNS Masq Config" })
end
@@ -212,11 +304,17 @@ function setconfig(config)
file = update_file(file,"dhcp-host",config.value.dhcp_host.value)
file = update_file(file,"dhcp-option",config.value.dhcp_option.value)
file = update_file(file,"mx-host",config.value.mx_host.value)
+ -- dns filtering
+ local conf_file_value = set_dns_filtering(file, config.value.dns_filtering.value)
+ file = update_file(file,"conf-file",conf_file_value)
fs.write_file(configfile, file)
else
config.errtxt = "Failed to set config"
end
+ -- update dns filter file
+ update_dns_whitelist(config.value.dns_whitelist.value, config.value.dns_default_address.value)
+
return config
end