def edit_table(table_name=None): """Edit a table""" # Save edit or new table if request.method == 'POST': table_addrs = translate_table(request.form) if not isinstance(table_addrs, list): raise BadRequestError(table) if ' ' in str(table_name).strip(): raise BadRequestError('Table name cannot contain spaces') elif table_name: try: packetfilter.set_addrs(table_name, *table_addrs) except IOError: raise BadRequestError('Invalid address') else: if is_blank(request.form.get('name')): raise BadRequestError('Table name cannot be empty') elif ' ' in request.form.get('name').strip(): raise BadRequestError('Table name cannot contain spaces') packetfilter.add_tables( pf.PFTable(request.form['name'].strip(), *table_addrs, flags=pf.PFR_TFLAG_PERSIST)) save_pfconf(packetfilter) return redirect(url_for('tables'), code=302) # Load existing or create new rule if table_name: # Load the current tableset and parse existing table tables = packetfilter.get_tables() for t in tables: if str(t.name) == str(table_name): table = get_table(t) break else: raise BadRequestError("No such table") else: # Create new blank table blank_table = pf.PFTable() table = get_table(blank_table) return render_template('edit_table.html', logged_in=flask_login.current_user.get_id(), fw_tab='active', table=table)
def _add_table(self, tblname="test_table"): table = pf.PFTable(tblname, "10.0.1.10", flags=pf.PFR_TFLAG_PERSIST) self.pf.clear_tables() return self.pf.add_tables(table)
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))