optional nfqueue fail-open option
This commit is contained in:
@@ -19,10 +19,17 @@ class ServiceModel(BaseModel):
|
||||
ip_int: str
|
||||
n_regex: int
|
||||
n_packets: int
|
||||
fail_open: bool
|
||||
|
||||
class RenameForm(BaseModel):
|
||||
name:str
|
||||
|
||||
class SettingsForm(BaseModel):
|
||||
port: PortType|None = None
|
||||
proto: str|None = None
|
||||
ip_int: str|None = None
|
||||
fail_open: bool|None = None
|
||||
|
||||
class RegexModel(BaseModel):
|
||||
regex:str
|
||||
mode:str
|
||||
@@ -44,6 +51,7 @@ class ServiceAddForm(BaseModel):
|
||||
port: PortType
|
||||
proto: str
|
||||
ip_int: str
|
||||
fail_open: bool = False
|
||||
|
||||
class ServiceAddResponse(BaseModel):
|
||||
status:str
|
||||
@@ -59,6 +67,7 @@ db = SQLite('db/nft-regex.db', {
|
||||
'name': 'VARCHAR(100) NOT NULL UNIQUE',
|
||||
'proto': 'VARCHAR(3) NOT NULL CHECK (proto IN ("tcp", "udp"))',
|
||||
'ip_int': 'VARCHAR(100) NOT NULL',
|
||||
'fail_open': 'BOOLEAN NOT NULL CHECK (fail_open IN (0, 1)) DEFAULT 1'
|
||||
},
|
||||
'regexes': {
|
||||
'regex': 'TEXT NOT NULL',
|
||||
@@ -128,6 +137,7 @@ async def get_service_list():
|
||||
s.name name,
|
||||
s.proto proto,
|
||||
s.ip_int ip_int,
|
||||
s.fail_open fail_open,
|
||||
COUNT(r.regex_id) n_regex,
|
||||
COALESCE(SUM(r.blocked_packets),0) n_packets
|
||||
FROM services s LEFT JOIN regexes r ON s.service_id = r.service_id
|
||||
@@ -145,6 +155,7 @@ async def get_service_by_id(service_id: str):
|
||||
s.name name,
|
||||
s.proto proto,
|
||||
s.ip_int ip_int,
|
||||
s.fail_open fail_open,
|
||||
COUNT(r.regex_id) n_regex,
|
||||
COALESCE(SUM(r.blocked_packets),0) n_packets
|
||||
FROM services s LEFT JOIN regexes r ON s.service_id = r.service_id
|
||||
@@ -190,6 +201,45 @@ async def service_rename(service_id: str, form: RenameForm):
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.put('/services/{service_id}/settings', response_model=StatusMessageModel)
|
||||
async def service_settings(service_id: str, form: SettingsForm):
|
||||
"""Request to change the settings of a specific service (will cause a restart)"""
|
||||
|
||||
if form.proto is not None and form.proto not in ["tcp", "udp"]:
|
||||
raise HTTPException(status_code=400, detail="Invalid protocol")
|
||||
|
||||
if form.port is not None and (form.port < 1 or form.port > 65535):
|
||||
raise HTTPException(status_code=400, detail="Invalid port")
|
||||
|
||||
if form.ip_int is not None:
|
||||
try:
|
||||
form.ip_int = ip_parse(form.ip_int)
|
||||
except ValueError:
|
||||
raise HTTPException(status_code=400, detail="Invalid address")
|
||||
|
||||
keys = []
|
||||
values = []
|
||||
|
||||
for key, value in form.model_dump(exclude_none=True).items():
|
||||
keys.append(key)
|
||||
values.append(value)
|
||||
|
||||
if len(keys) == 0:
|
||||
raise HTTPException(status_code=400, detail="No settings to change provided")
|
||||
|
||||
try:
|
||||
db.query(f'UPDATE services SET {", ".join([f"{key}=?" for key in keys])} WHERE service_id = ?;', *values, service_id)
|
||||
except sqlite3.IntegrityError:
|
||||
raise HTTPException(status_code=400, detail="A service with these settings already exists")
|
||||
|
||||
old_status = firewall.get(service_id).status
|
||||
await firewall.remove(service_id)
|
||||
await firewall.reload()
|
||||
await firewall.get(service_id).next(old_status)
|
||||
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.get('/services/{service_id}/regexes', response_model=list[RegexModel])
|
||||
async def get_service_regexe_list(service_id: str):
|
||||
"""Get the list of the regexes of a service"""
|
||||
@@ -275,8 +325,8 @@ async def add_new_service(form: ServiceAddForm):
|
||||
srv_id = None
|
||||
try:
|
||||
srv_id = gen_service_id()
|
||||
db.query("INSERT INTO services (service_id ,name, port, status, proto, ip_int) VALUES (?, ?, ?, ?, ?, ?)",
|
||||
srv_id, refactor_name(form.name), form.port, STATUS.STOP, form.proto, form.ip_int)
|
||||
db.query("INSERT INTO services (service_id ,name, port, status, proto, ip_int, fail_open) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
||||
srv_id, refactor_name(form.name), form.port, STATUS.STOP, form.proto, form.ip_int, form.fail_open)
|
||||
except sqlite3.IntegrityError:
|
||||
raise HTTPException(status_code=400, detail="This type of service already exists")
|
||||
await firewall.reload()
|
||||
|
||||
Reference in New Issue
Block a user