From 12da0d675c8a8f720d70d2ad82f29f12552a9bfc Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Mon, 26 Aug 2019 12:19:31 +0300 Subject: filter: ignore IPv6 addresses of NAT destination --- README.md | 15 +++++++------- awall/modules/filter.lua | 53 ++++++++++++++++++++++++++---------------------- 2 files changed, 37 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 4a5aca8..fe2c8af 100644 --- a/README.md +++ b/README.md @@ -455,13 +455,14 @@ whether to consider the source (**src**, default) or destination defaults to **pass** and cannot be set to any other value. Filter objects may have an attribute named **dnat**, the value of -which is an IPv4 address. If defined, this enables destination NAT for -all IPv4 packets matching the rule, such that the specified address -replaces the original destination address. If also port translation is -desired, the attribute may be defined as an object consisting of -attributes **addr** and **port**. The format of the **port** attribute -is similar to that of the **to-port** attribute of [NAT -rules](#nat). This option has no effect on IPv6 packets. +which is an IPv4 address or a DNS name resolving to a single IPv4 +address. If defined, this enables destination NAT for all IPv4 packets +matching the rule, such that the specified address replaces the +original destination address. If also port translation is desired, the +attribute may be defined as an object consisting of attributes +**addr** and **port**. The format of the **port** attribute is similar +to that of the **to-port** attribute of [NAT rules](#nat). This option +has no effect on IPv6 packets. Filter objects may have a boolean attribute named **no-track**. If set to **true**, connection tracking is bypassed for the matching diff --git a/awall/modules/filter.lua b/awall/modules/filter.lua index 33a2eed..0a6b2b0 100644 --- a/awall/modules/filter.lua +++ b/awall/modules/filter.lua @@ -100,7 +100,34 @@ local TranslatingRule = class(Rule) function TranslatingRule:init(...) TranslatingRule.super(self):init(...) - if type(self.dnat) == 'string' then self.dnat = {addr=self.dnat} end + + if self.dnat then + if self.ipset then + self:error('dnat and ipset options cannot be used simultaneously') + end + + if type(self.dnat) == 'string' then self.dnat = {addr=self.dnat} end + + if self.dnat.addr:find('/') then + self:error('DNAT target cannot be a network address') + end + + local dnataddr + for _, addr in ipairs(resolve(self.dnat.addr, self)) do + if addr[1] == 'inet' then + if dnataddr then + self:error( + self.dnat.addr..' resolves to multiple IPv4 addresses' + ) + end + dnataddr = addr[2] + end + end + if not dnataddr then + self:error(self.dnat.addr..' does not resolve to any IPv4 address') + end + self.dnat.addr = dnataddr + end end function TranslatingRule:destoptfrags() @@ -274,34 +301,12 @@ function Filter:extratrules() if self['no-track'] then self:error('dnat option not allowed with no-track') end - if self.ipset then - self:error('dnat and ipset options cannot be used simultaneously') - end - - if self.dnat.addr:find('/') then - self:error('DNAT target cannot be a network address') - end - - local dnataddr - for i, addr in ipairs(resolve(self.dnat.addr, self)) do - if addr[1] == 'inet' then - if dnataddr then - self:error( - self.dnat.addr..' resolves to multiple IPv4 addresses' - ) - end - dnataddr = addr[2] - end - end - if not dnataddr then - self:error(self.dnat.addr..' does not resolve to any IPv4 address') - end extrarules( 'dnat', 'dnat', { - update={['to-addr']=dnataddr, ['to-port']=self.dnat.port}, + update={['to-addr']=self.dnat.addr, ['to-port']=self.dnat.port}, discard='out' } ) -- cgit v1.2.3