diff options
author | Jo-Philipp Wich <jow@openwrt.org> | 2009-02-08 03:56:50 +0000 |
---|---|---|
committer | Jo-Philipp Wich <jow@openwrt.org> | 2009-02-08 03:56:50 +0000 |
commit | f52ec227175c9db1bfee95f8a59c7c56d01911d4 (patch) | |
tree | 7ba7e2d346b2cea378267fee607001d4eb841a9d | |
parent | e3c8b9a10b383138ba1a5ed7bea51fd3694f596d (diff) |
modules/admin-full: implement iptables status page
i18n/english: resync xml, add strings for iptables page
libs/sys/iptparser: implement chain() and is_custom_target()
-rw-r--r-- | i18n/english/luasrc/i18n/admin-core.en.lua | 31 | ||||
-rw-r--r-- | i18n/english/luasrc/i18n/admin-core.en.xml | 29 | ||||
-rw-r--r-- | i18n/english/luasrc/i18n/wifi.en.xml | 2 | ||||
-rw-r--r-- | libs/sys/luasrc/sys/iptparser.lua | 72 | ||||
-rw-r--r-- | modules/admin-full/luasrc/controller/admin/status.lua | 19 | ||||
-rw-r--r-- | modules/admin-full/luasrc/view/admin_status/iptables.htm | 137 |
6 files changed, 278 insertions, 12 deletions
diff --git a/i18n/english/luasrc/i18n/admin-core.en.lua b/i18n/english/luasrc/i18n/admin-core.en.lua index e22b01917..6b7195c64 100644 --- a/i18n/english/luasrc/i18n/admin-core.en.lua +++ b/i18n/english/luasrc/i18n/admin-core.en.lua @@ -41,6 +41,29 @@ a_s_flash = 'Flash Firmware' a_s_i_system1 = 'Change settings related to the system itself, its identification, installed hard- and software, authentication or mount points.' a_s_i_system2 = 'These settings define the base of your system.' a_s_i_system3 = 'Pay attention as any misconfiguration here may prevent your device from booting or may lock yourself out of it.' +a_s_ipt = 'Firewall' +a_s_ipt_actions = 'Actions' +a_s_ipt_bytes = 'Traffic' +a_s_ipt_chain = 'Chain' +a_s_ipt_destination = 'Destination' +a_s_ipt_flags = 'Flags' +a_s_ipt_inputif = 'In' +a_s_ipt_nochains = 'No chains in this table' +a_s_ipt_norules = 'No Rules in this chain' +a_s_ipt_options = 'Options' +a_s_ipt_outputif = 'Out' +a_s_ipt_packets = 'Packets' +a_s_ipt_pkts = 'Pkts.' +a_s_ipt_policy = 'Policy' +a_s_ipt_prot = 'Prot.' +a_s_ipt_references = 'References' +a_s_ipt_reset = 'Reset Counters' +a_s_ipt_restart = 'Restart Firewall' +a_s_ipt_rulenum = '#' +a_s_ipt_source = 'Source' +a_s_ipt_status = 'Firewall Status' +a_s_ipt_table = 'Table' +a_s_ipt_target = 'Target' a_s_packages_do = 'Perform Actions' a_s_packages_install = 'Install' a_s_packages_installurl = 'Download and install package' @@ -104,7 +127,7 @@ a_srv_dropbear1 = 'Dropbear offers <abbr title="Secure Shell">SSH</abbr> network a_srv_d_pwauth = 'Password authentication' a_srv_d_pwauth1 = 'Allow <abbr title="Secure Shell">SSH</abbr> password authentication' a_w_channel = 'Channel' -a_w_wifi1 = 'On this pages you find confiugration options for <abbr title="Wireless Local Area Network">WLAN</abbr> based wireless networks.' +a_w_wifi1 = 'On this pages you can find configuration options for <abbr title="Wireless Local Area Network">WLAN</abbr> based wireless networks.' a_w_wifi2 = 'You can easily integrate your 802.11a/b/g/n-devices into your physical network and use the virtual adapter support to build wireless repeaters or offer several networks with one device.' a_w_wifi3 = 'There is support for Managed, Client, Ad-Hoc and <abbr title="Wireless Distribution System">WDS</abbr> operating modes as well as <abbr title="Wi-Fi Protected Access">WPA</abbr> and <abbr title="Wi-Fi Protected Access 2">WPA2</abbr> encryption for secure communnication.' a_w_devices1 = 'Here you can configure installed wifi devices.' @@ -228,7 +251,6 @@ network_interface_service = 'Service type' network_interface_maxwait = 'Setup wait time' network_interface_maxwait_desc = 'Seconds to wait for the modem to become ready before attempting to connect' network_interface_encaps = 'PPPoA Encapsulation' - a_n_r_routes1 = 'Routes specify over which interface and gateway a certain host or network can be reached.' a_n_routes_static = 'Static Routes' a_n_routes_static4 = 'Static IPv4 Routes' @@ -328,6 +350,5 @@ hostnames = 'Hostnames' hostnames_entries = 'Host entries' hostnames_hostname = 'Hostname' hostnames_address = 'IP address' -luci_components = "LuCI Components" -m_n_mssfix = "Clamp Segment Size" -m_n_mssfix_desc = "Fixes problems with unreachable websites, submitting forms or other unexpected behaviour for some ISPs." +m_n_mssfix = 'Clamp Segment Size' +m_n_mssfix_desc = 'Fixes problems with unreachable websites, submitting forms or other unexpected behaviour for some ISPs.' diff --git a/i18n/english/luasrc/i18n/admin-core.en.xml b/i18n/english/luasrc/i18n/admin-core.en.xml index 23ab06ed5..4c11c8b5c 100644 --- a/i18n/english/luasrc/i18n/admin-core.en.xml +++ b/i18n/english/luasrc/i18n/admin-core.en.xml @@ -15,7 +15,7 @@ <i18n:msg xml:id="a_i_i_admin2"><abbr title="Lua Configuration Interface">LuCI</abbr> is a free, flexible, and user friendly graphical interface for configuring OpenWrt Kamikaze.</i18n:msg> <i18n:msg xml:id="a_i_i_admin3">On the following pages you can adjust all important settings of your router.</i18n:msg> <i18n:msg xml:id="a_i_i_admin4">Notice: In <abbr title="Lua Configuration Interface">LuCI</abbr> changes have to be confirmed by clicking Changes - Save & Apply before being applied.</i18n:msg> -<i18n:msg xml:id="a_i_i_admin5">As we are always want to improve this interface we are looking forward to your feedback and suggestions.</i18n:msg> +<i18n:msg xml:id="a_i_i_admin5">As we always want to improve this interface we are looking forward to your feedback and suggestions.</i18n:msg> <i18n:msg xml:id="a_i_i_admin6">And now have fun with your router!</i18n:msg> <i18n:msg xml:id="a_i_i_team">The <abbr title="Lua Configuration Interface">LuCI</abbr> Team</i18n:msg> <i18n:msg xml:id="a_i_luci1">Here you can customize the settings and the functionality of <abbr title="Lua Configuration Interface">LuCI</abbr>.</i18n:msg> @@ -45,6 +45,29 @@ <i18n:msg xml:id="a_s_i_system1">Change settings related to the system itself, its identification, installed hard- and software, authentication or mount points.</i18n:msg> <i18n:msg xml:id="a_s_i_system2">These settings define the base of your system.</i18n:msg> <i18n:msg xml:id="a_s_i_system3">Pay attention as any misconfiguration here may prevent your device from booting or may lock yourself out of it.</i18n:msg> +<i18n:msg xml:id="a_s_ipt">Firewall</i18n:msg> +<i18n:msg xml:id="a_s_ipt_actions">Actions</i18n:msg> +<i18n:msg xml:id="a_s_ipt_bytes">Traffic</i18n:msg> +<i18n:msg xml:id="a_s_ipt_chain">Chain</i18n:msg> +<i18n:msg xml:id="a_s_ipt_destination">Destination</i18n:msg> +<i18n:msg xml:id="a_s_ipt_flags">Flags</i18n:msg> +<i18n:msg xml:id="a_s_ipt_inputif">In</i18n:msg> +<i18n:msg xml:id="a_s_ipt_nochains">No chains in this table</i18n:msg> +<i18n:msg xml:id="a_s_ipt_norules">No Rules in this chain</i18n:msg> +<i18n:msg xml:id="a_s_ipt_options">Options</i18n:msg> +<i18n:msg xml:id="a_s_ipt_outputif">Out</i18n:msg> +<i18n:msg xml:id="a_s_ipt_packets">Packets</i18n:msg> +<i18n:msg xml:id="a_s_ipt_pkts">Pkts.</i18n:msg> +<i18n:msg xml:id="a_s_ipt_policy">Policy</i18n:msg> +<i18n:msg xml:id="a_s_ipt_prot">Prot.</i18n:msg> +<i18n:msg xml:id="a_s_ipt_references">References</i18n:msg> +<i18n:msg xml:id="a_s_ipt_reset">Reset Counters</i18n:msg> +<i18n:msg xml:id="a_s_ipt_restart">Restart Firewall</i18n:msg> +<i18n:msg xml:id="a_s_ipt_rulenum">#</i18n:msg> +<i18n:msg xml:id="a_s_ipt_source">Source</i18n:msg> +<i18n:msg xml:id="a_s_ipt_status">Firewall Status</i18n:msg> +<i18n:msg xml:id="a_s_ipt_table">Table</i18n:msg> +<i18n:msg xml:id="a_s_ipt_target">Target</i18n:msg> <i18n:msg xml:id="a_s_packages_do">Perform Actions</i18n:msg> <i18n:msg xml:id="a_s_packages_install">Install</i18n:msg> <i18n:msg xml:id="a_s_packages_installurl">Download and install package</i18n:msg> @@ -100,6 +123,10 @@ <i18n:msg xml:id="a_srv_http_authrealm1">The realm which will be displayed at the authentication prompt for protected pages.</i18n:msg> <i18n:msg xml:id="a_srv_http_config1">defaults to <code>/etc/httpd.conf</code></i18n:msg> <i18n:msg xml:id="a_srv_http_root">Document root</i18n:msg> +<i18n:msg xml:id="a_srv_http_keepalive">Enable Keep-Alive</i18n:msg> +<i18n:msg xml:id="a_srv_http_timeout">Connection timeout</i18n:msg> +<i18n:msg xml:id="a_srv_http_path">Plugin path</i18n:msg> +<i18n:msg xml:id="a_srv_lucittpd">A lightweight HTTP/1.1 webserver written in C and Lua designed to serve LuCI</i18n:msg> <i18n:msg xml:id="a_srv_dropbear1">Dropbear offers <abbr title="Secure Shell">SSH</abbr> network shell access and an integrated <abbr title="Secure Copy">SCP</abbr> server</i18n:msg> <i18n:msg xml:id="a_srv_d_pwauth">Password authentication</i18n:msg> <i18n:msg xml:id="a_srv_d_pwauth1">Allow <abbr title="Secure Shell">SSH</abbr> password authentication</i18n:msg> diff --git a/i18n/english/luasrc/i18n/wifi.en.xml b/i18n/english/luasrc/i18n/wifi.en.xml index fd6751f32..75a3cbf4b 100644 --- a/i18n/english/luasrc/i18n/wifi.en.xml +++ b/i18n/english/luasrc/i18n/wifi.en.xml @@ -37,7 +37,7 @@ <i18n:msg xml:id="wifi_xr">XR Support</i18n:msg> <i18n:msg xml:id="wifi_ar">AR Support</i18n:msg> <i18n:msg xml:id="wifi_nosbeacon">Disable HW-Beacon timer</i18n:msg> -<i18n:msg xml:id="wifi_noprobereq">Don not send probe responses</i18n:msg> +<i18n:msg xml:id="wifi_noprobereq">Do not send probe responses</i18n:msg> <i18n:msg xml:id="wifi_wpareq">WPA-Encryption requires wpa_supplicant (for client mode) or hostapd (for AP and ad-hoc mode) to be installed.</i18n:msg> diff --git a/libs/sys/luasrc/sys/iptparser.lua b/libs/sys/luasrc/sys/iptparser.lua index c11fb5d56..338fb7dad 100644 --- a/libs/sys/luasrc/sys/iptparser.lua +++ b/libs/sys/luasrc/sys/iptparser.lua @@ -32,8 +32,8 @@ module("luci.sys.iptparser") IptParser = luci.util.class() function IptParser.__init__( self, ... ) - self._rules = { } - self._chain = nil + self._rules = { } + self._chains = { } self:_parse_rules() end @@ -109,7 +109,7 @@ function IptParser.find( self, args ) local match = true -- match table - if not ( not args.table or args.table == rule.table ) then + if not ( not args.table or args.table:lower() == rule.table ) then match = false end @@ -202,16 +202,76 @@ function IptParser.resync( self ) end +--- Find the names of all chains within the given table name. +-- @param table String containing the table name +-- @return Table of chain names in the order they occur. +function IptParser.chains( self, table ) + local lookup = { } + local chains = { } + for _, r in ipairs(self:find({table=table})) do + if not lookup[r.chain] then + lookup[r.chain] = true + chains[#chains+1] = r.chain + end + end + return chains +end + + +--- Return the given firewall chain within the given table name. +-- @param table String containing the table name +-- @param chain String containing the chain name +-- @return Table containing the fields "policy", "packets", "bytes" +-- and "rules". The "rules" field is a table of rule tables. +function IptParser.chain( self, table, chain ) + return self._chains[table:lower()] and self._chains[table:lower()][chain] +end + + +--- Test whether the given target points to a custom chain. +-- @param target String containing the target action +-- @return Boolean indicating whether target is a custom chain. +function IptParser.is_custom_target( self, target ) + for _, r in ipairs(self._rules) do + if r.chain == target then + return true + end + end + return false +end + + -- [internal] Parse iptables output from all tables. function IptParser._parse_rules( self ) for i, tbl in ipairs({ "filter", "nat", "mangle" }) do + self._chains[tbl] = { } + for i, rule in ipairs(luci.util.execl("iptables -t " .. tbl .. " --line-numbers -nxvL")) do if rule:find( "Chain " ) == 1 then - self._chain = rule:gsub("Chain ([^%s]*) .*", "%1") + local crefs + local cname, cpol, cpkt, cbytes = rule:match( + "Chain ([^%s]*) %(policy (%w+) " .. + "(%d+) packets, (%d+) bytes%)" + ) + + if not cname then + cname, crefs = rule:match( + "Chain ([^%s]*) %((%d+) references%)" + ) + end + + self._chain = cname + self._chains[tbl][cname] = { + policy = cpol, + packets = tonumber(cpkt or 0), + bytes = tonumber(cbytes or 0), + references = tonumber(crefs or 0), + rules = { } + } else if rule:find("%d") == 1 then @@ -238,6 +298,10 @@ function IptParser._parse_rules( self ) end self._rules[#self._rules+1] = rule_details + + self._chains[tbl][self._chain].rules[ + #self._chains[tbl][self._chain].rules + 1 + ] = rule_details end end end diff --git a/modules/admin-full/luasrc/controller/admin/status.lua b/modules/admin-full/luasrc/controller/admin/status.lua index 09e7766c1..fd61459e9 100644 --- a/modules/admin-full/luasrc/controller/admin/status.lua +++ b/modules/admin-full/luasrc/controller/admin/status.lua @@ -19,7 +19,8 @@ function index() entry({"admin", "status"}, template("admin_status/index"), i18n("status", "Status"), 20).index = true entry({"admin", "status", "syslog"}, call("action_syslog"), i18n("syslog", "Systemprotokoll"), 1) - entry({"admin", "status", "dmesg"}, call("action_dmesg"), i18n("dmesg", "Kernelprotokoll"), 2) + entry({"admin", "status", "dmesg"}, call("action_dmesg"), i18n("dmesg", "Kernelprotokoll"), 2) + entry({"admin", "status", "iptables"}, call("action_iptables"), i18n("a_s_ipt", "Firewall"), 3) end function action_syslog() @@ -31,3 +32,19 @@ function action_dmesg() local dmesg = luci.sys.dmesg() luci.template.render("admin_status/dmesg", {dmesg=dmesg}) end + +function action_iptables() + if luci.http.formvalue("zero") == "1" then + luci.util.exec("iptables -Z") + luci.http.redirect( + luci.dispatcher.build_url("admin", "status", "iptables") + ) + elseif luci.http.formvalue("restart") == "1" then + luci.util.exec("/etc/init.d/firewall restart") + luci.http.redirect( + luci.dispatcher.build_url("admin", "status", "iptables") + ) + else + luci.template.render("admin_status/iptables") + end +end diff --git a/modules/admin-full/luasrc/view/admin_status/iptables.htm b/modules/admin-full/luasrc/view/admin_status/iptables.htm new file mode 100644 index 000000000..da0a994d9 --- /dev/null +++ b/modules/admin-full/luasrc/view/admin_status/iptables.htm @@ -0,0 +1,137 @@ +<%# +LuCI - Lua Configuration Interface +Copyright 2009 Steven Barth <steven@midlink.org> +Copyright 2009 Jo-Philipp Wich <xm@leipzig.freifunk.net> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +$Id$ + +-%> + +<%- + + require "luci.sys.iptparser" + require "luci.tools.webadmin" + + local ipt = luci.sys.iptparser.IptParser() + local wba = luci.tools.webadmin + + local rowcnt = 1 + function rowstyle() + rowcnt = rowcnt + 1 + return (rowcnt % 2) + 1 + end + + function link_target(t,c) + if ipt:is_custom_target(c) then + return '<a href="#rule_%s_%s">%s</a>' %{ t:lower(), c, c } + end + return c + end + + function link_iface(i) + local net = wba.iface_get_network(i) + if net and i ~= "lo" then + return '<a href="%s">%s</a>' %{ + luci.dispatcher.build_url("admin", "network", "network", net), i + } + + end + return i + end + +-%> + +<%+header%> + +<h2><a id="content" name="content"><%:a_s_ipt_status Firewall Status%></a></h2> + +<form method="post" action="<%=REQUEST_URI%>"> + <div class="cbi-map"> + <fieldset class="cbi-section"> + <fieldset class="cbi-section-node"> + <h3><%:a_s_ipt_actions Actions%></h3> + <ul> + <li><a href="<%=REQUEST_URI%>?zero=1"><%:a_s_ipt_reset Reset Counters%></a></li> + <li><a href="<%=REQUEST_URI%>?restart=1"><%:a_s_ipt_restart Restart Firewall%></a></li> + </ul> + </fieldset> + <br /> + + <fieldset class="cbi-section-node"> + <% for _, tbl in ipairs({"Filter", "NAT", "Mangle"}) do chaincnt = 0 %> + <h3><%:a_s_ipt_table Table%>: <%=tbl%></h3> + <table class="cbi-section-table" style="font-size:90%"> + <% for _, chain in ipairs(ipt:chains(tbl)) do + rowcnt = 0 + chaincnt = chaincnt + 1 + chaininfo = ipt:chain(tbl, chain) + %> + <tr class="cbi-section-table-titles cbi-rowstyle-<%=rowstyle()%>"> + <th class="cbi-section-table-cell" style="text-align:left" colspan="11"> + <br /><a name="rule_<%=tbl:lower()%>_<%=chain%>"></a> + <%:a_s_ipt_chain Chain%> <em><%=chain%></em> + (<%- if chaininfo.policy then -%> + <%:a_s_ipt_policy Policy%>: <em><%=chaininfo.policy%></em>, <%:a_s_ipt_packets Packets%>: <%=chaininfo.packets%>, <%:a_s_ipt_bytes Traffic%>: <%=wba.byte_format(chaininfo.bytes)-%> + <%- else -%> + <%:a_s_ipt_references References%>: <%=chaininfo.references-%> + <%- end -%>) + </th> + </tr> + <tr class="cbi-section-table-descr"> + <th class="cbi-section-table-cell"><%:a_s_ipt_rulenum Rule #%></th> + <th class="cbi-section-table-cell"><%:a_s_ipt_packets Pkts.%></th> + <th class="cbi-section-table-cell"><%:a_s_ipt_bytes Traffic%></th> + <th class="cbi-section-table-cell"><%:a_s_ipt_target Target%></th> + <th class="cbi-section-table-cell"><%:a_s_ipt_proto Prot.%></th> + <th class="cbi-section-table-cell"><%:a_s_ipt_flags Flags%></th> + <th class="cbi-section-table-cell"><%:a_s_ipt_inputif In%></th> + <th class="cbi-section-table-cell"><%:a_s_ipt_outputif Out%></th> + <th class="cbi-section-table-cell"><%:a_s_ipt_source Source%></th> + <th class="cbi-section-table-cell"><%:a_s_ipt_destination Destination%></th> + <th class="cbi-section-table-cell"><%:a_s_ipt_options Options%></th> + </tr> + + <% for _, rule in ipairs(ipt:find({table=tbl, chain=chain})) do %> + <tr class="cbi-section-table-row cbi-rowstyle-<%=rowstyle()%>"> + <td><%=rule.index%></td> + <td><%=rule.packets%></td> + <td><%=wba.byte_format(rule.bytes)%></td> + <td><%=link_target(tbl, rule.target)%></td> + <td><%=rule.protocol%></td> + <td><%=rule.flags%></td> + <td><%=link_iface(rule.inputif)%></td> + <td><%=link_iface(rule.outputif)%></td> + <td><%=rule.source%></td> + <td><%=rule.destination%></td> + <td><small><%=#rule.options > 0 and table.concat(rule.options, " ") or "-"%></small></td> + </tr> + <% end %> + + <% if rowcnt == 1 then %> + <tr class="cbi-section-table-titles cbi-rowstyle-<%=rowstyle()%>"> + <td colspan="11"><em><%:a_s_ipt_norules No rules in this chain%></em></td> + </tr> + <% end %> + <% end %> + + <% if chaincnt == 0 then %> + <tr class="cbi-section-table-titles cbi-rowstyle-<%=rowstyle()%>"> + <td colspan="11"><em><%:a_s_ipt_nochains No chains in this table%></em></td> + </tr> + <% end %> + </table> + <br /><br /> + <% end %> + </fieldset> + </fieldset> + </div> +</form> + +<%+footer%> +<% if ret == 0 then luci.sys.reboot() end %> |