add: ipv6/ipv4 rules
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
from modules.firewall.models import Rule
|
from modules.firewall.models import Rule
|
||||||
from utils import nftables_int_to_json, ip_parse, ip_family, NFTableManager, nftables_json_to_int
|
from utils import nftables_int_to_json, ip_parse, ip_family, NFTableManager
|
||||||
|
|
||||||
|
|
||||||
class FiregexHijackRule():
|
class FiregexHijackRule():
|
||||||
@@ -80,6 +80,13 @@ class FiregexTables(NFTableManager):
|
|||||||
for ele in srvs[::-1]: self.add(ele)
|
for ele in srvs[::-1]: self.add(ele)
|
||||||
|
|
||||||
def add(self, srv:Rule):
|
def add(self, srv:Rule):
|
||||||
|
ip_filters = []
|
||||||
|
if srv.ip_src.lower() != "any" and srv.ip_dst.lower() != "any":
|
||||||
|
ip_filters = [
|
||||||
|
{'match': {'left': {'payload': {'protocol': ip_family(srv.ip_src), 'field': 'saddr'}}, 'op': '==', 'right': nftables_int_to_json(srv.ip_src)}},
|
||||||
|
{'match': {'left': {'payload': {'protocol': ip_family(srv.ip_dst), 'field': 'daddr'}}, 'op': '==', 'right': nftables_int_to_json(srv.ip_dst)}},
|
||||||
|
]
|
||||||
|
|
||||||
port_filters = []
|
port_filters = []
|
||||||
if srv.proto != "any":
|
if srv.proto != "any":
|
||||||
if srv.port_src_from != 1 or srv.port_src_to != 65535: #Any Port
|
if srv.port_src_from != 1 or srv.port_src_to != 65535: #Any Port
|
||||||
@@ -91,14 +98,12 @@ class FiregexTables(NFTableManager):
|
|||||||
if len(port_filters) == 0:
|
if len(port_filters) == 0:
|
||||||
port_filters.append({'match': {'left': {'payload': {'protocol': str(srv.proto), 'field': 'sport'}}, 'op': '!=', 'right': 0}}) #filter the protocol if no port is specified
|
port_filters.append({'match': {'left': {'payload': {'protocol': str(srv.proto), 'field': 'sport'}}, 'op': '!=', 'right': 0}}) #filter the protocol if no port is specified
|
||||||
|
|
||||||
|
end_rules = [{'accept': None} if srv.action == "accept" else {'reject': {}} if (srv.action == "reject" and not srv.output_mode) else {'drop': None}]
|
||||||
|
|
||||||
self.cmd({ "insert":{ "rule": {
|
self.cmd({ "insert":{ "rule": {
|
||||||
"family": "inet",
|
"family": "inet",
|
||||||
"table": self.table_name,
|
"table": self.table_name,
|
||||||
"chain": self.rules_chain_out if srv.output_mode else self.rules_chain_in,
|
"chain": self.rules_chain_out if srv.output_mode else self.rules_chain_in,
|
||||||
"expr": [
|
"expr": ip_filters + port_filters + end_rules
|
||||||
{'match': {'left': {'payload': {'protocol': ip_family(srv.ip_src), 'field': 'saddr'}}, 'op': '==', 'right': nftables_int_to_json(srv.ip_src)}},
|
|
||||||
{'match': {'left': {'payload': {'protocol': ip_family(srv.ip_dst), 'field': 'daddr'}}, 'op': '==', 'right': nftables_int_to_json(srv.ip_dst)}},
|
|
||||||
] + port_filters +
|
|
||||||
[{'accept': None} if srv.action == "accept" else {'reject': {}} if (srv.action == "reject" and not srv.output_mode) else {'drop': None}]
|
|
||||||
#If srv.output_mode is True, then the rule is in the output chain, so the reject action is not allowed
|
#If srv.output_mode is True, then the rule is in the output chain, so the reject action is not allowed
|
||||||
}}})
|
}}})
|
||||||
@@ -108,42 +108,16 @@ async def disable_firewall():
|
|||||||
db.set("ENABLED", "0")
|
db.set("ENABLED", "0")
|
||||||
return await apply_changes()
|
return await apply_changes()
|
||||||
|
|
||||||
@app.get('/rule/{rule_id}/disable', response_model=StatusMessageModel)
|
|
||||||
async def service_disable(rule_id: str):
|
|
||||||
"""Request disabling a specific rule"""
|
|
||||||
if len(db.query('SELECT 1 FROM rules WHERE rule_id = ?;', rule_id)) == 0:
|
|
||||||
return {'status': 'Rule not found'}
|
|
||||||
db.query('UPDATE rules SET active = 0 WHERE rule_id = ?;', rule_id)
|
|
||||||
return await apply_changes()
|
|
||||||
|
|
||||||
@app.get('/rule/{rule_id}/enable', response_model=StatusMessageModel)
|
|
||||||
async def service_start(rule_id: str):
|
|
||||||
"""Request the enabling a specific rule"""
|
|
||||||
if len(db.query('SELECT 1 FROM rules WHERE rule_id = ?;', rule_id)) == 0:
|
|
||||||
return {'status': 'Rule not found'}
|
|
||||||
db.query('UPDATE rules SET active = 1 WHERE rule_id = ?;', rule_id)
|
|
||||||
return await apply_changes()
|
|
||||||
|
|
||||||
@app.post('/service/{rule_id}/rename', response_model=StatusMessageModel)
|
|
||||||
async def service_rename(rule_id: str, form: RenameForm):
|
|
||||||
"""Request to change the name of a specific service"""
|
|
||||||
if len(db.query('SELECT 1 FROM rules WHERE rule_id = ?;', rule_id)) == 0:
|
|
||||||
return {'status': 'Rule not found'}
|
|
||||||
form.name = refactor_name(form.name)
|
|
||||||
if not form.name: return {'status': 'The name cannot be empty!'}
|
|
||||||
try:
|
|
||||||
db.query('UPDATE rules SET name=? WHERE rule_id = ?;', form.name, rule_id)
|
|
||||||
except sqlite3.IntegrityError:
|
|
||||||
return {'status': 'This name is already used'}
|
|
||||||
await refresh_frontend()
|
|
||||||
return {'status': 'ok'}
|
|
||||||
|
|
||||||
def parse_and_check_rule(rule:RuleModel):
|
def parse_and_check_rule(rule:RuleModel):
|
||||||
try:
|
|
||||||
rule.ip_src = ip_parse(rule.ip_src)
|
if rule.ip_src.lower().strip() == "any" or rule.ip_dst.lower().split() == "any":
|
||||||
rule.ip_dst = ip_parse(rule.ip_dst)
|
rule.ip_dst = rule.ip_src = "any"
|
||||||
except ValueError:
|
else:
|
||||||
return {"status":"Invalid address"}
|
try:
|
||||||
|
rule.ip_src = ip_parse(rule.ip_src)
|
||||||
|
rule.ip_dst = ip_parse(rule.ip_dst)
|
||||||
|
except ValueError:
|
||||||
|
return {"status":"Invalid address"}
|
||||||
|
|
||||||
rule.port_dst_from, rule.port_dst_to = min(rule.port_dst_from, rule.port_dst_to), max(rule.port_dst_from, rule.port_dst_to)
|
rule.port_dst_from, rule.port_dst_to = min(rule.port_dst_from, rule.port_dst_to), max(rule.port_dst_from, rule.port_dst_to)
|
||||||
rule.port_src_from, rule.port_src_to = min(rule.port_src_from, rule.port_src_to), max(rule.port_src_from, rule.port_src_to)
|
rule.port_src_from, rule.port_src_to = min(rule.port_src_from, rule.port_src_to), max(rule.port_src_from, rule.port_src_to)
|
||||||
@@ -156,7 +130,6 @@ def parse_and_check_rule(rule:RuleModel):
|
|||||||
return {"status":"Invalid action"}
|
return {"status":"Invalid action"}
|
||||||
return rule
|
return rule
|
||||||
|
|
||||||
|
|
||||||
@app.post('/rules/set', response_model=RuleAddResponse)
|
@app.post('/rules/set', response_model=RuleAddResponse)
|
||||||
async def add_new_service(form: RuleFormAdd):
|
async def add_new_service(form: RuleFormAdd):
|
||||||
"""Add a new service"""
|
"""Add a new service"""
|
||||||
|
|||||||
Reference in New Issue
Block a user