ldx / python-iptables

Python bindings for iptables
730 stars 182 forks source link

to_destination issue in DNAT #302

Closed zkryakgul closed 4 years ago

zkryakgul commented 4 years ago

Hi, i have a problem when defining a DNAT target on iptc. Normally you can do something like this in iptables:

iptables -t nat -A PREROUTING -p tcp -m tcp -s 192.168.6.100 -d 185.X.X.X --dport 80 -j DNAT --to-destination :443

but when i try this on iptc

rule = iptc.Rule()
.
.
.
target = iptc.Target(rule, 'DNAT')
target.to_destination = ":443"

it's getting this error:

---------------------------------------------------------------------------
XTablesError                              Traceback (most recent call last)
<ipython-input-4-49e38c75e6f6> in <module>()
----> 1 target.to_destination = ":443"

/usr/local/lib/python3.5/dist-packages/iptc/ip4tc.py in __setattr__(self, name, value)
    453     def __setattr__(self, name, value):
    454         if not name.startswith('_') and name not in dir(self):
--> 455             self.parse(name.replace("_", "-"), value)
    456         else:
    457             object.__setattr__(self, name, value)

/usr/local/lib/python3.5/dist-packages/iptc/ip4tc.py in parse(self, parameter, value)
    330         entry = self._rule.entry and ct.pointer(self._rule.entry) or None
    331 
--> 332         self._parse(argv, inv, entry)
    333 
    334     def _parse(self, argv, inv, entry):

/usr/local/lib/python3.5/dist-packages/iptc/ip4tc.py in _parse(self, argv, inv, entry)
    791         self._xt.parse_target(argv, inv, self._module, entry,
    792                               ct.cast(self._ptrptr, ct.POINTER(ct.c_void_p)),
--> 793                               self._orig_parse, self._orig_options)
    794         self._target_buf = ct.cast(self._module.t, ct.POINTER(ct.c_ubyte))
    795         if self._buffer.buffer != self._target_buf:

/usr/local/lib/python3.5/dist-packages/iptc/xtables.py in new(*args)
    867         xtobj = args[0]
    868         xtables._xtables_set_nfproto(xtobj.proto)
--> 869         return fn(*args)
    870     return new
    871 

/usr/local/lib/python3.5/dist-packages/iptc/xtables.py in parse_target(self, argv, invert, t, fw, ptr, x6_parse, x6_options)
   1121             if rv != 0:
   1122                 raise XTablesError("%s: parameter error %d (%s)" % (t.name, rv,
-> 1123                                                                     argv[1]))
   1124             t.tflags |= cb.xflags
   1125             return

XTablesError: b'DNAT': parameter error -2 (b':443')
ldx commented 4 years ago

Can you try providing an IP:port instead of just :port for target.to_destination?

zkryakgul commented 4 years ago

I tried but the result is the same. XTablesError: b'DNAT': parameter error -2 (b'192.168.6.100:443')

It only accepts if you enter the ip address without port.

ldx commented 4 years ago

I think the only thing missing is specifying the protocol:

import iptc

rule = iptc.Rule()
rule.protocol = 'tcp'
target = iptc.Target(rule, 'DNAT')
target.to_destination = ':443'
jllorente commented 4 years ago

Alternatively try with iptc.easy functions? Look in the readme for High level abstractions section, there are some examples

zkryakgul commented 4 years ago

I think the only thing missing is specifying the protocol:

import iptc

rule = iptc.Rule()
rule.protocol = 'tcp'
target = iptc.Target(rule, 'DNAT')
target.to_destination = ':443'

Yes, it's fix my issue. Thanks!