Beispiel #1
0
def translate_pool_rule(trans_type, addr, addr_type, addr_table, port_from,
                        port_to, proto, addr_iface, af):
    """Parses fields given in the pfweb form to a pf.PFPool object"""
    pfaddr = False
    if addr_type == 'addrmask':
        pfaddr = translate_addrmask(af, addr)
    elif addr_type == 'table':
        if not addr_table:
            return "Table cannot be empty"
        pfaddr = pf.PFAddr("<{}>".format(addr_table))
    elif addr_type == 'dynif':
        if trans_type.lower() == 'rdr':
            return "Cannot RDR to an interface"
        if not addr_iface:
            return "Interface cannot be empty"
        # Set PFAddr to interface and IPv4
        pfaddr = pf.PFAddr("({})".format(addr_iface), af)

    pool_id = pf.PF_POOL_NAT
    port = False
    if trans_type.lower() == 'rdr' and (proto == socket.IPPROTO_TCP
                                        or proto == socket.IPPROTO_UDP):
        # Set ports to 0 if they were left blank
        if port_from == '':
            port_from = 0
            port_to = 0
        if port_to == '':
            port_to = 0

        pool_id = pf.PF_POOL_RDR
        try:
            port = pf.PFPort((int(port_from), int(port_to)))
        except ValueError:
            # The user didn't give us a valid number
            return "Invalid port number"
    elif trans_type.lower() == 'rdr' and not (proto == socket.IPPROTO_TCP
                                              or proto == socket.IPPROTO_UDP):
        return "TCP or UDP must be used for RDR"

    pool = pf.PFPool(pool_id, pfaddr)
    if port:
        pool.proxy_port = port

    return pool
Beispiel #2
0
    def test_load_ruleset(self):
        iface = pf.PFAddr(type=pf.PF_ADDR_DYNIFTL, ifname=self.testif)
        tables = [pf.PFTable("web_srv", "10.0.1.20", "10.0.1.21", "10.0.1.22")]
        rules = [
            # match out on $ifname inet from !($ifname) to any nat-to ($ifname)
            pf.PFRule(action=pf.PF_MATCH,
                      direction=pf.PF_OUT,
                      ifname=self.testif,
                      af=AF_INET,
                      src=pf.PFRuleAddr(iface, neg=True),
                      nat=pf.PFPool(pf.PF_POOL_NAT, iface)),
            # pass out quick
            pf.PFRule(action=pf.PF_PASS,
                      direction=pf.PF_OUT,
                      quick=True,
                      flags="S", flagset="SA",
                      keep_state=pf.PF_STATE_NORMAL),
            # anchor "test_anchor"
            pf.PFRuleset("test_anchor"),
            # pass in on $ifname inet proto tcp from any to $ifname port ssh
            pf.PFRule(action=pf.PF_PASS,
                      direction=pf.PF_IN,
                      ifname=self.testif,
                      af=AF_INET,
                      proto=IPPROTO_TCP,
                      dst=pf.PFRuleAddr(iface, pf.PFPort("ssh", IPPROTO_TCP)),
                      flags="S", flagset="SA",
                      keep_state=pf.PF_STATE_NORMAL),
            # pass in on $ifname inet proto tcp to $ifname port www \
            #     rdr-to <web_srv> round-robin sticky-address
            pf.PFRule(action=pf.PF_PASS,
                      direction=pf.PF_IN,
                      ifname=self.testif,
                      af=AF_INET,
                      proto=IPPROTO_TCP,
                      dst=pf.PFRuleAddr(iface, pf.PFPort("www", IPPROTO_TCP)),
                      flags="S", flagset="SA",
                      keep_state=pf.PF_STATE_NORMAL,
                      rdr=pf.PFPool(pf.PF_POOL_RDR, pf.PFAddr("<web_srv>"),
                                    opts=(pf.PF_POOL_ROUNDROBIN|
                                          pf.PF_POOL_STICKYADDR))),
            # pass out on $ifname inet proto tcp to port 80 \
            #     divert-packet port 700
            pf.PFRule(action=pf.PF_PASS,
                      direction=pf.PF_OUT,
                      ifname=self.testif,
                      af=AF_INET,
                      proto=IPPROTO_TCP,
                      dst=pf.PFRuleAddr(port=pf.PFPort("www", IPPROTO_TCP)),
                      divert=pf.PFDivert(pf.PF_DIVERT_PACKET, port=700)),
            # pass in inet proto icmp all icmp-type echoreq max-pkt-rate 100/10
            pf.PFRule(action=pf.PF_PASS,
                      direction=pf.PF_IN,
                      af=AF_INET,
                      proto=IPPROTO_ICMP,
                      type=pf.ICMP_ECHO+1,
                      keep_state=pf.PF_STATE_NORMAL,
                      pktrate=pf.PFThreshold(100, 10))]

        rules[2].append(
            pf.PFTable("spammers", flags=pf.PFR_TFLAG_PERSIST),
            # pass in on $ifname inet proto tcp from ! <spammers> \
            #    to $ifname port 25 rdr-to 10.0.1.23
            pf.PFRule(action=pf.PF_PASS,
                      direction=pf.PF_IN,
                      ifname=self.testif,
                      af=AF_INET,
                      proto=IPPROTO_TCP,
                      src=pf.PFRuleAddr(pf.PFAddr("<spammers>"), neg=True),
                      dst=pf.PFRuleAddr(iface, pf.PFPort(25, IPPROTO_TCP)),
                      flags="S", flagset="SA",
                      keep_state=pf.PF_STATE_NORMAL,
                      rdr=pf.PFPool(pf.PF_POOL_RDR, pf.PFAddr("10.0.1.23"))))
            
        self.pf.clear_rules()
        rs = pf.PFRuleset()
        rs.append(*tables)
        rs.append(*rules)
        self.pf.load_ruleset(rs)
        self.assertEqual(len(self.pf.get_ruleset().rules), len(rules))