more RESTful APIs
This commit is contained in:
11
Dockerfile
11
Dockerfile
@@ -14,11 +14,10 @@ RUN bun run build
|
||||
|
||||
|
||||
#Building main conteiner
|
||||
FROM --platform=$TARGETARCH debian:trixie-slim AS base
|
||||
RUN apt-get update -qq && apt-get upgrade -qq && \
|
||||
apt-get install -qq python3-pip build-essential \
|
||||
libnetfilter-queue-dev libnfnetlink-dev libmnl-dev libcap2-bin\
|
||||
nftables libvectorscan-dev libtins-dev python3-nftables
|
||||
FROM --platform=$TARGETARCH registry.fedoraproject.org/fedora:latest
|
||||
RUN dnf -y update && dnf install -y python3-pip @development-tools gcc-c++ \
|
||||
libnetfilter_queue-devel libnfnetlink-devel libmnl-devel libcap-ng-utils \
|
||||
nftables vectorscan-devel libtins-devel python3-nftables libpcap-devel boost-devel
|
||||
|
||||
RUN mkdir -p /execute/modules
|
||||
WORKDIR /execute
|
||||
@@ -28,7 +27,7 @@ RUN pip3 install --no-cache-dir --break-system-packages -r /execute/requirements
|
||||
|
||||
COPY ./backend/binsrc /execute/binsrc
|
||||
RUN g++ binsrc/nfqueue.cpp -o modules/cppqueue -std=c++23 -O3 -lnetfilter_queue -pthread -lnfnetlink $(pkg-config --cflags --libs libtins libhs libmnl)
|
||||
RUN g++ binsrc/nfproxy-tun.cpp -o modules/cppnfproxy -std=c++23 -O3 -lnetfilter_queue -pthread -lnfnetlink $(pkg-config --cflags --libs libtins libmnl)
|
||||
#RUN g++ binsrc/nfproxy-tun.cpp -o modules/cppnfproxy -std=c++23 -O3 -lnetfilter_queue -pthread -lnfnetlink $(pkg-config --cflags --libs libtins libmnl)
|
||||
|
||||
COPY ./backend/ /execute/
|
||||
COPY --from=frontend /app/dist/ ./frontend/
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
#include <linux/netfilter/nfnetlink_queue.h>
|
||||
#include <libnetfilter_queue/libnetfilter_queue.h>
|
||||
#include <linux/netfilter/nfnetlink_conntrack.h>
|
||||
#include <tins/tins.h>
|
||||
#include <tins/tcp_ip/stream_follower.h>
|
||||
#include <tins/tcp_ip/stream_identifier.h>
|
||||
#include <libmnl/libmnl.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/types.h>
|
||||
#include <stdexcept>
|
||||
#include <thread>
|
||||
#include <hs.h>
|
||||
#include <iostream>
|
||||
|
||||
using Tins::TCPIP::Stream;
|
||||
using Tins::TCPIP::StreamFollower;
|
||||
using namespace std;
|
||||
|
||||
#ifndef NETFILTER_CLASS_CPP
|
||||
|
||||
@@ -133,10 +133,6 @@ class SocketTunnelQueue: public NfQueueExecutor {
|
||||
|
||||
SocketTunnelQueue(int queue) : NfQueueExecutor(queue, &queue_cb) {}
|
||||
|
||||
~SocketTunnelQueue() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // PROXY_TUNNEL_CPP
|
||||
@@ -130,6 +130,7 @@ class FirewallManager:
|
||||
def allow_dhcp(self):
|
||||
return self.db.get("allow_dhcp", "1") == "1"
|
||||
|
||||
@drop_invalid.setter
|
||||
def allow_dhcp_set(self, value):
|
||||
@allow_dhcp.setter
|
||||
def allow_dhcp(self, value):
|
||||
self.db.set("allow_dhcp", "1" if value else "0")
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ import traceback
|
||||
from utils import DEBUG
|
||||
from fastapi import HTTPException
|
||||
|
||||
#TODO copied file, review
|
||||
|
||||
nft = FiregexTables()
|
||||
|
||||
class RegexFilter:
|
||||
|
||||
@@ -4,6 +4,8 @@ from modules.nfregex.nftables import FiregexTables, FiregexFilter
|
||||
from modules.nfregex.models import Regex, Service
|
||||
from utils.sqlite import SQLite
|
||||
|
||||
#TODO copied file, review
|
||||
|
||||
class STATUS:
|
||||
STOP = "stop"
|
||||
ACTIVE = "active"
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import base64
|
||||
|
||||
class Service:
|
||||
def __init__(self, service_id: str, status: str, port: int, name: str, proto: str, ip_int: str, **other):
|
||||
self.id = service_id
|
||||
@@ -14,17 +12,14 @@ class Service:
|
||||
return cls(**var)
|
||||
|
||||
|
||||
class Regex:
|
||||
def __init__(self, regex_id: int, regex: bytes, mode: str, service_id: str, blocked_packets: int, is_case_sensitive: bool, active: bool, **other):
|
||||
self.regex = regex
|
||||
self.mode = mode
|
||||
self.service_id = service_id
|
||||
class PyFilter:
|
||||
def __init__(self, filter_id:int, name: str, blocked_packets: int, edited_packets: int, active: bool, **other):
|
||||
self.filter_id = filter_id
|
||||
self.name = name
|
||||
self.blocked_packets = blocked_packets
|
||||
self.id = regex_id
|
||||
self.is_case_sensitive = is_case_sensitive
|
||||
self.edited_packets = edited_packets
|
||||
self.active = active
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, var: dict):
|
||||
var['regex'] = base64.b64decode(var['regex'])
|
||||
return cls(**var)
|
||||
@@ -71,7 +71,7 @@ async def get_settings():
|
||||
"""Get the firewall settings"""
|
||||
return firewall.settings
|
||||
|
||||
@app.post("/settings/set", response_model=StatusMessageModel)
|
||||
@app.put("/settings", response_model=StatusMessageModel)
|
||||
async def set_settings(form: FirewallSettings):
|
||||
"""Set the firewall settings"""
|
||||
firewall.settings = form
|
||||
@@ -86,13 +86,13 @@ async def get_rule_list():
|
||||
"enabled": firewall.enabled
|
||||
}
|
||||
|
||||
@app.get('/enable', response_model=StatusMessageModel)
|
||||
@app.post('/enable', response_model=StatusMessageModel)
|
||||
async def enable_firewall():
|
||||
"""Request enabling the firewall"""
|
||||
firewall.enabled = True
|
||||
return await apply_changes()
|
||||
|
||||
@app.get('/disable', response_model=StatusMessageModel)
|
||||
@app.post('/disable', response_model=StatusMessageModel)
|
||||
async def disable_firewall():
|
||||
"""Request disabling the firewall"""
|
||||
firewall.enabled = False
|
||||
@@ -128,9 +128,9 @@ def parse_and_check_rule(rule:RuleModel):
|
||||
|
||||
return rule
|
||||
|
||||
@app.post('/rules/set', response_model=StatusMessageModel)
|
||||
@app.post('/rules', response_model=StatusMessageModel)
|
||||
async def add_new_service(form: RuleFormAdd):
|
||||
"""Add a new service"""
|
||||
"""Edit rule table"""
|
||||
rules = [parse_and_check_rule(ele) for ele in form.rules]
|
||||
try:
|
||||
db.queries(["DELETE FROM rules"]+
|
||||
|
||||
260
backend/routers/nfproxy.py
Normal file
260
backend/routers/nfproxy.py
Normal file
@@ -0,0 +1,260 @@
|
||||
import secrets
|
||||
import sqlite3
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from modules.nfproxy.nftables import FiregexTables
|
||||
from modules.nfproxy.firewall import STATUS, FirewallManager
|
||||
from utils.sqlite import SQLite
|
||||
from utils import ip_parse, refactor_name, socketio_emit, PortType
|
||||
from utils.models import ResetRequest, StatusMessageModel
|
||||
|
||||
# TODO copied file, review
|
||||
class ServiceModel(BaseModel):
|
||||
service_id: str
|
||||
status: str
|
||||
port: PortType
|
||||
name: str
|
||||
proto: str
|
||||
ip_int: str
|
||||
n_filters: int
|
||||
edited_packets: int
|
||||
blocked_packets: int
|
||||
|
||||
class RenameForm(BaseModel):
|
||||
name:str
|
||||
|
||||
class PyFilterModel(BaseModel):
|
||||
filter_id: int
|
||||
name: str
|
||||
blocked_packets: int
|
||||
edited_packets: int
|
||||
active: bool
|
||||
|
||||
class ServiceAddForm(BaseModel):
|
||||
name: str
|
||||
port: PortType
|
||||
proto: str
|
||||
ip_int: str
|
||||
|
||||
class ServiceAddResponse(BaseModel):
|
||||
status:str
|
||||
service_id: str|None = None
|
||||
|
||||
app = APIRouter()
|
||||
|
||||
db = SQLite('db/nft-pyfilters.db', {
|
||||
'services': {
|
||||
'service_id': 'VARCHAR(100) PRIMARY KEY',
|
||||
'status': 'VARCHAR(100) NOT NULL',
|
||||
'port': 'INT NOT NULL CHECK(port > 0 and port < 65536)',
|
||||
'name': 'VARCHAR(100) NOT NULL UNIQUE',
|
||||
'proto': 'VARCHAR(3) NOT NULL CHECK (proto IN ("tcp", "http"))',
|
||||
'ip_int': 'VARCHAR(100) NOT NULL',
|
||||
},
|
||||
'pyfilter': {
|
||||
'filter_id': 'INTEGER PRIMARY KEY',
|
||||
'name': 'VARCHAR(100) NOT NULL',
|
||||
'blocked_packets': 'INTEGER UNSIGNED NOT NULL DEFAULT 0',
|
||||
'edited_packets': 'INTEGER UNSIGNED NOT NULL DEFAULT 0',
|
||||
'service_id': 'VARCHAR(100) NOT NULL',
|
||||
'active' : 'BOOLEAN NOT NULL CHECK (active IN (0, 1)) DEFAULT 1',
|
||||
'FOREIGN KEY (service_id)':'REFERENCES services (service_id)',
|
||||
},
|
||||
'QUERY':[
|
||||
"CREATE UNIQUE INDEX IF NOT EXISTS unique_services ON services (port, ip_int, proto);",
|
||||
"CREATE UNIQUE INDEX IF NOT EXISTS unique_pyfilter_service ON pyfilter (name, service_id);"
|
||||
]
|
||||
})
|
||||
|
||||
async def refresh_frontend(additional:list[str]=[]):
|
||||
await socketio_emit(["nfproxy"]+additional)
|
||||
|
||||
async def reset(params: ResetRequest):
|
||||
if not params.delete:
|
||||
db.backup()
|
||||
await firewall.close()
|
||||
FiregexTables().reset()
|
||||
if params.delete:
|
||||
db.delete()
|
||||
db.init()
|
||||
else:
|
||||
db.restore()
|
||||
try:
|
||||
await firewall.init()
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
async def startup():
|
||||
db.init()
|
||||
try:
|
||||
await firewall.init()
|
||||
except Exception as e:
|
||||
print("WARNING cannot start firewall:", e)
|
||||
|
||||
async def shutdown():
|
||||
db.backup()
|
||||
await firewall.close()
|
||||
db.disconnect()
|
||||
db.restore()
|
||||
|
||||
def gen_service_id():
|
||||
while True:
|
||||
res = secrets.token_hex(8)
|
||||
if len(db.query('SELECT 1 FROM services WHERE service_id = ?;', res)) == 0:
|
||||
break
|
||||
return res
|
||||
|
||||
firewall = FirewallManager(db)
|
||||
|
||||
@app.get('/services', response_model=list[ServiceModel])
|
||||
async def get_service_list():
|
||||
"""Get the list of existent firegex services"""
|
||||
return db.query("""
|
||||
SELECT
|
||||
s.service_id service_id,
|
||||
s.status status,
|
||||
s.port port,
|
||||
s.name name,
|
||||
s.proto proto,
|
||||
s.ip_int ip_int,
|
||||
COUNT(f.filter_id) n_filters,
|
||||
COALESCE(SUM(f.blocked_packets),0) blocked_packets,
|
||||
COALESCE(SUM(f.edited_packets),0) edited_packets
|
||||
FROM services s LEFT JOIN pyfilter f ON s.service_id = f.service_id
|
||||
GROUP BY s.service_id;
|
||||
""")
|
||||
|
||||
@app.get('/services/{service_id}', response_model=ServiceModel)
|
||||
async def get_service_by_id(service_id: str):
|
||||
"""Get info about a specific service using his id"""
|
||||
res = db.query("""
|
||||
SELECT
|
||||
s.service_id service_id,
|
||||
s.status status,
|
||||
s.port port,
|
||||
s.name name,
|
||||
s.proto proto,
|
||||
s.ip_int ip_int,
|
||||
COUNT(f.filter_id) n_filters,
|
||||
COALESCE(SUM(f.blocked_packets),0) blocked_packets,
|
||||
COALESCE(SUM(f.edited_packets),0) edited_packets
|
||||
FROM services s LEFT JOIN pyfilter f ON s.service_id = f.service_id
|
||||
WHERE s.service_id = ? GROUP BY s.service_id;
|
||||
""", service_id)
|
||||
if len(res) == 0:
|
||||
raise HTTPException(status_code=400, detail="This service does not exists!")
|
||||
return res[0]
|
||||
|
||||
@app.post('/services/{service_id}/stop', response_model=StatusMessageModel)
|
||||
async def service_stop(service_id: str):
|
||||
"""Request the stop of a specific service"""
|
||||
await firewall.get(service_id).next(STATUS.STOP)
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.post('/services/{service_id}/start', response_model=StatusMessageModel)
|
||||
async def service_start(service_id: str):
|
||||
"""Request the start of a specific service"""
|
||||
await firewall.get(service_id).next(STATUS.ACTIVE)
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.delete('/services/{service_id}', response_model=StatusMessageModel)
|
||||
async def service_delete(service_id: str):
|
||||
"""Request the deletion of a specific service"""
|
||||
db.query('DELETE FROM services WHERE service_id = ?;', service_id)
|
||||
db.query('DELETE FROM pyfilter WHERE service_id = ?;', service_id)
|
||||
await firewall.remove(service_id)
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.put('/services/{service_id}/rename', response_model=StatusMessageModel)
|
||||
async def service_rename(service_id: str, form: RenameForm):
|
||||
"""Request to change the name of a specific service"""
|
||||
form.name = refactor_name(form.name)
|
||||
if not form.name:
|
||||
raise HTTPException(status_code=400, detail="The name cannot be empty!")
|
||||
try:
|
||||
db.query('UPDATE services SET name=? WHERE service_id = ?;', form.name, service_id)
|
||||
except sqlite3.IntegrityError:
|
||||
raise HTTPException(status_code=400, detail="This name is already used")
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.get('/services/{service_id}/pyfilters', response_model=list[PyFilterModel])
|
||||
async def get_service_pyfilter_list(service_id: str):
|
||||
"""Get the list of the pyfilters of a service"""
|
||||
if not db.query("SELECT 1 FROM services s WHERE s.service_id = ?;", service_id):
|
||||
raise HTTPException(status_code=400, detail="This service does not exists!")
|
||||
return db.query("""
|
||||
SELECT
|
||||
filter_id, name, blocked_packets, edited_packets, active
|
||||
FROM pyfilter WHERE service_id = ?;
|
||||
""", service_id)
|
||||
|
||||
@app.get('/pyfilters/{filter_id}', response_model=PyFilterModel)
|
||||
async def get_pyfilter_by_id(filter_id: int):
|
||||
"""Get pyfilter info using his id"""
|
||||
res = db.query("""
|
||||
SELECT
|
||||
filter_id, name, blocked_packets, edited_packets, active
|
||||
FROM pyfilter WHERE filter_id = ?;
|
||||
""", filter_id)
|
||||
if len(res) == 0:
|
||||
raise HTTPException(status_code=400, detail="This filter does not exists!")
|
||||
return res[0]
|
||||
|
||||
@app.delete('/pyfilters/{filter_id}', response_model=StatusMessageModel)
|
||||
async def pyfilter_delete(filter_id: int):
|
||||
"""Delete a pyfilter using his id"""
|
||||
res = db.query('SELECT * FROM pyfilter WHERE filter_id = ?;', filter_id)
|
||||
if len(res) != 0:
|
||||
db.query('DELETE FROM pyfilter WHERE filter_id = ?;', filter_id)
|
||||
await firewall.get(res[0]["service_id"]).update_filters()
|
||||
await refresh_frontend()
|
||||
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.post('/pyfilters/{filter_id}/enable', response_model=StatusMessageModel)
|
||||
async def pyfilter_enable(filter_id: int):
|
||||
"""Request the enabling of a pyfilter"""
|
||||
res = db.query('SELECT * FROM pyfilter WHERE filter_id = ?;', filter_id)
|
||||
if len(res) != 0:
|
||||
db.query('UPDATE pyfilter SET active=1 WHERE filter_id = ?;', filter_id)
|
||||
await firewall.get(res[0]["service_id"]).update_filters()
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.post('/pyfilters/{filter_id}/disable', response_model=StatusMessageModel)
|
||||
async def pyfilter_disable(filter_id: int):
|
||||
"""Request the deactivation of a pyfilter"""
|
||||
res = db.query('SELECT * FROM pyfilter WHERE filter_id = ?;', filter_id)
|
||||
if len(res) != 0:
|
||||
db.query('UPDATE pyfilter SET active=0 WHERE filter_id = ?;', filter_id)
|
||||
await firewall.get(res[0]["service_id"]).update_filters()
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.post('/services', response_model=ServiceAddResponse)
|
||||
async def add_new_service(form: ServiceAddForm):
|
||||
"""Add a new service"""
|
||||
try:
|
||||
form.ip_int = ip_parse(form.ip_int)
|
||||
except ValueError:
|
||||
raise HTTPException(status_code=400, detail="Invalid address")
|
||||
if form.proto not in ["tcp", "http"]:
|
||||
raise HTTPException(status_code=400, detail="Invalid protocol")
|
||||
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)
|
||||
except sqlite3.IntegrityError:
|
||||
raise HTTPException(status_code=400, detail="This type of service already exists")
|
||||
await firewall.reload()
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok', 'service_id': srv_id}
|
||||
|
||||
#TODO check all the APIs and add
|
||||
# 1. API to change the python filter file
|
||||
# 2. a socketio mechanism to lock the previous feature
|
||||
@@ -134,7 +134,7 @@ async def get_service_list():
|
||||
GROUP BY s.service_id;
|
||||
""")
|
||||
|
||||
@app.get('/service/{service_id}', response_model=ServiceModel)
|
||||
@app.get('/services/{service_id}', response_model=ServiceModel)
|
||||
async def get_service_by_id(service_id: str):
|
||||
"""Get info about a specific service using his id"""
|
||||
res = db.query("""
|
||||
@@ -154,21 +154,21 @@ async def get_service_by_id(service_id: str):
|
||||
raise HTTPException(status_code=400, detail="This service does not exists!")
|
||||
return res[0]
|
||||
|
||||
@app.get('/service/{service_id}/stop', response_model=StatusMessageModel)
|
||||
@app.post('/services/{service_id}/stop', response_model=StatusMessageModel)
|
||||
async def service_stop(service_id: str):
|
||||
"""Request the stop of a specific service"""
|
||||
await firewall.get(service_id).next(STATUS.STOP)
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.get('/service/{service_id}/start', response_model=StatusMessageModel)
|
||||
@app.post('/services/{service_id}/start', response_model=StatusMessageModel)
|
||||
async def service_start(service_id: str):
|
||||
"""Request the start of a specific service"""
|
||||
await firewall.get(service_id).next(STATUS.ACTIVE)
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.get('/service/{service_id}/delete', response_model=StatusMessageModel)
|
||||
@app.delete('/services/{service_id}', response_model=StatusMessageModel)
|
||||
async def service_delete(service_id: str):
|
||||
"""Request the deletion of a specific service"""
|
||||
db.query('DELETE FROM services WHERE service_id = ?;', service_id)
|
||||
@@ -177,7 +177,7 @@ async def service_delete(service_id: str):
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.post('/service/{service_id}/rename', response_model=StatusMessageModel)
|
||||
@app.put('/services/{service_id}/rename', response_model=StatusMessageModel)
|
||||
async def service_rename(service_id: str, form: RenameForm):
|
||||
"""Request to change the name of a specific service"""
|
||||
form.name = refactor_name(form.name)
|
||||
@@ -190,7 +190,7 @@ async def service_rename(service_id: str, form: RenameForm):
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.get('/service/{service_id}/regexes', response_model=list[RegexModel])
|
||||
@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"""
|
||||
if not db.query("SELECT 1 FROM services s WHERE s.service_id = ?;", service_id):
|
||||
@@ -202,7 +202,7 @@ async def get_service_regexe_list(service_id: str):
|
||||
FROM regexes WHERE service_id = ?;
|
||||
""", service_id)
|
||||
|
||||
@app.get('/regex/{regex_id}', response_model=RegexModel)
|
||||
@app.get('/regexes/{regex_id}', response_model=RegexModel)
|
||||
async def get_regex_by_id(regex_id: int):
|
||||
"""Get regex info using his id"""
|
||||
res = db.query("""
|
||||
@@ -215,7 +215,7 @@ async def get_regex_by_id(regex_id: int):
|
||||
raise HTTPException(status_code=400, detail="This regex does not exists!")
|
||||
return res[0]
|
||||
|
||||
@app.get('/regex/{regex_id}/delete', response_model=StatusMessageModel)
|
||||
@app.delete('/regexes/{regex_id}', response_model=StatusMessageModel)
|
||||
async def regex_delete(regex_id: int):
|
||||
"""Delete a regex using his id"""
|
||||
res = db.query('SELECT * FROM regexes WHERE regex_id = ?;', regex_id)
|
||||
@@ -226,7 +226,7 @@ async def regex_delete(regex_id: int):
|
||||
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.get('/regex/{regex_id}/enable', response_model=StatusMessageModel)
|
||||
@app.post('/regexes/{regex_id}/enable', response_model=StatusMessageModel)
|
||||
async def regex_enable(regex_id: int):
|
||||
"""Request the enabling of a regex"""
|
||||
res = db.query('SELECT * FROM regexes WHERE regex_id = ?;', regex_id)
|
||||
@@ -236,7 +236,7 @@ async def regex_enable(regex_id: int):
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.get('/regex/{regex_id}/disable', response_model=StatusMessageModel)
|
||||
@app.post('/regexes/{regex_id}/disable', response_model=StatusMessageModel)
|
||||
async def regex_disable(regex_id: int):
|
||||
"""Request the deactivation of a regex"""
|
||||
res = db.query('SELECT * FROM regexes WHERE regex_id = ?;', regex_id)
|
||||
@@ -246,7 +246,7 @@ async def regex_disable(regex_id: int):
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.post('/regexes/add', response_model=StatusMessageModel)
|
||||
@app.post('/regexes', response_model=StatusMessageModel)
|
||||
async def add_new_regex(form: RegexAddForm):
|
||||
"""Add a new regex"""
|
||||
try:
|
||||
@@ -263,7 +263,7 @@ async def add_new_regex(form: RegexAddForm):
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.post('/services/add', response_model=ServiceAddResponse)
|
||||
@app.post('/services', response_model=ServiceAddResponse)
|
||||
async def add_new_service(form: ServiceAddForm):
|
||||
"""Add a new service"""
|
||||
try:
|
||||
@@ -299,7 +299,8 @@ async def metrics():
|
||||
FROM regexes r LEFT JOIN services s ON s.service_id = r.service_id;
|
||||
""")
|
||||
metrics = []
|
||||
sanitize = lambda s : s.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n')
|
||||
def sanitize(s):
|
||||
return s.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n')
|
||||
for stat in stats:
|
||||
props = f'service_name="{sanitize(stat["name"])}",regex="{sanitize(b64decode(stat["regex"]).decode())}",mode="{stat["mode"]}",is_case_sensitive="{stat["is_case_sensitive"]}"'
|
||||
metrics.append(f'firegex_blocked_packets{{{props}}} {stat["blocked_packets"]}')
|
||||
|
||||
@@ -92,7 +92,7 @@ async def get_service_list():
|
||||
"""Get the list of existent firegex services"""
|
||||
return db.query("SELECT service_id, active, public_port, proxy_port, name, proto, ip_src, ip_dst FROM services;")
|
||||
|
||||
@app.get('/service/{service_id}', response_model=ServiceModel)
|
||||
@app.get('/services/{service_id}', response_model=ServiceModel)
|
||||
async def get_service_by_id(service_id: str):
|
||||
"""Get info about a specific service using his id"""
|
||||
res = db.query("SELECT service_id, active, public_port, proxy_port, name, proto, ip_src, ip_dst FROM services WHERE service_id = ?;", service_id)
|
||||
@@ -100,21 +100,21 @@ async def get_service_by_id(service_id: str):
|
||||
raise HTTPException(status_code=400, detail="This service does not exists!")
|
||||
return res[0]
|
||||
|
||||
@app.get('/service/{service_id}/stop', response_model=StatusMessageModel)
|
||||
@app.post('/services/{service_id}/stop', response_model=StatusMessageModel)
|
||||
async def service_stop(service_id: str):
|
||||
"""Request the stop of a specific service"""
|
||||
await firewall.get(service_id).disable()
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.get('/service/{service_id}/start', response_model=StatusMessageModel)
|
||||
@app.post('/services/{service_id}/start', response_model=StatusMessageModel)
|
||||
async def service_start(service_id: str):
|
||||
"""Request the start of a specific service"""
|
||||
await firewall.get(service_id).enable()
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.get('/service/{service_id}/delete', response_model=StatusMessageModel)
|
||||
@app.delete('/services/{service_id}', response_model=StatusMessageModel)
|
||||
async def service_delete(service_id: str):
|
||||
"""Request the deletion of a specific service"""
|
||||
db.query('DELETE FROM services WHERE service_id = ?;', service_id)
|
||||
@@ -122,7 +122,7 @@ async def service_delete(service_id: str):
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.post('/service/{service_id}/rename', response_model=StatusMessageModel)
|
||||
@app.put('/services/{service_id}/rename', response_model=StatusMessageModel)
|
||||
async def service_rename(service_id: str, form: RenameForm):
|
||||
"""Request to change the name of a specific service"""
|
||||
form.name = refactor_name(form.name)
|
||||
@@ -139,7 +139,7 @@ class ChangeDestination(BaseModel):
|
||||
ip_dst: str
|
||||
proxy_port: PortType
|
||||
|
||||
@app.post('/service/{service_id}/change-destination', response_model=StatusMessageModel)
|
||||
@app.put('/services/{service_id}/change-destination', response_model=StatusMessageModel)
|
||||
async def service_change_destination(service_id: str, form: ChangeDestination):
|
||||
"""Request to change the proxy destination of the service"""
|
||||
|
||||
@@ -162,7 +162,7 @@ async def service_change_destination(service_id: str, form: ChangeDestination):
|
||||
await refresh_frontend()
|
||||
return {'status': 'ok'}
|
||||
|
||||
@app.post('/services/add', response_model=ServiceAddResponse)
|
||||
@app.post('/services', response_model=ServiceAddResponse)
|
||||
async def add_new_service(form: ServiceAddForm):
|
||||
"""Add a new service"""
|
||||
try:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { ServerResponse } from "../../js/models"
|
||||
import { getapi, postapi } from "../../js/utils"
|
||||
import { getapi, postapi, putapi } from "../../js/utils"
|
||||
|
||||
export enum Protocol {
|
||||
TCP = "tcp",
|
||||
@@ -79,15 +79,15 @@ export const firewall = {
|
||||
return await getapi("firewall/settings") as FirewallSettings;
|
||||
},
|
||||
setsettings: async(data:FirewallSettings) => {
|
||||
return await postapi("firewall/settings/set", data) as ServerResponse;
|
||||
return await putapi("firewall/settings", data) as ServerResponse;
|
||||
},
|
||||
enable: async() => {
|
||||
return await getapi("firewall/enable") as ServerResponse;
|
||||
return await postapi("firewall/enable") as ServerResponse;
|
||||
},
|
||||
disable: async() => {
|
||||
return await getapi("firewall/disable") as ServerResponse;
|
||||
return await postapi("firewall/disable") as ServerResponse;
|
||||
},
|
||||
ruleset: async (data:RuleAddForm) => {
|
||||
return await postapi("firewall/rules/set", data) as ServerResponseListed;
|
||||
return await postapi("firewall/rules", data) as ServerResponseListed;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { RegexFilter, ServerResponse } from "../../js/models"
|
||||
import { getapi, postapi } from "../../js/utils"
|
||||
import { deleteapi, getapi, postapi, putapi } from "../../js/utils"
|
||||
import { RegexAddForm } from "../../js/models"
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query"
|
||||
|
||||
@@ -40,44 +40,44 @@ export const nfregex = {
|
||||
return await getapi("nfregex/services") as Service[];
|
||||
},
|
||||
serviceinfo: async (service_id:string) => {
|
||||
return await getapi(`nfregex/service/${service_id}`) as Service;
|
||||
return await getapi(`nfregex/services/${service_id}`) as Service;
|
||||
},
|
||||
regexdelete: async (regex_id:number) => {
|
||||
const { status } = await getapi(`nfregex/regex/${regex_id}/delete`) as ServerResponse;
|
||||
const { status } = await deleteapi(`nfregex/regexes/${regex_id}`) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
},
|
||||
regexenable: async (regex_id:number) => {
|
||||
const { status } = await getapi(`nfregex/regex/${regex_id}/enable`) as ServerResponse;
|
||||
const { status } = await postapi(`nfregex/regexes/${regex_id}/enable`) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
},
|
||||
regexdisable: async (regex_id:number) => {
|
||||
const { status } = await getapi(`nfregex/regex/${regex_id}/disable`) as ServerResponse;
|
||||
const { status } = await postapi(`nfregex/regexes/${regex_id}/disable`) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
},
|
||||
servicestart: async (service_id:string) => {
|
||||
const { status } = await getapi(`nfregex/service/${service_id}/start`) as ServerResponse;
|
||||
const { status } = await postapi(`nfregex/services/${service_id}/start`) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
},
|
||||
servicerename: async (service_id:string, name: string) => {
|
||||
const { status } = await postapi(`nfregex/service/${service_id}/rename`,{ name }) as ServerResponse;
|
||||
const { status } = await putapi(`nfregex/services/${service_id}/rename`,{ name }) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
},
|
||||
servicestop: async (service_id:string) => {
|
||||
const { status } = await getapi(`nfregex/service/${service_id}/stop`) as ServerResponse;
|
||||
const { status } = await postapi(`nfregex/services/${service_id}/stop`) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
},
|
||||
servicesadd: async (data:ServiceAddForm) => {
|
||||
return await postapi("nfregex/services/add",data) as ServiceAddResponse;
|
||||
return await postapi("nfregex/services",data) as ServiceAddResponse;
|
||||
},
|
||||
servicedelete: async (service_id:string) => {
|
||||
const { status } = await getapi(`nfregex/service/${service_id}/delete`) as ServerResponse;
|
||||
const { status } = await deleteapi(`nfregex/services/${service_id}`) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
},
|
||||
regexesadd: async (data:RegexAddForm) => {
|
||||
const { status } = await postapi("nfregex/regexes/add",data) as ServerResponse;
|
||||
const { status } = await postapi("nfregex/regexes",data) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
},
|
||||
serviceregexes: async (service_id:string) => {
|
||||
return await getapi(`nfregex/service/${service_id}/regexes`) as RegexFilter[];
|
||||
return await getapi(`nfregex/services/${service_id}/regexes`) as RegexFilter[];
|
||||
}
|
||||
}
|
||||
@@ -29,24 +29,6 @@ function ServiceRow({ service }:{ service:Service }) {
|
||||
validate:{ proxy_port: (value) => (value > 0 && value < 65536)? null : "Invalid proxy port" }
|
||||
})
|
||||
|
||||
const onChangeProxyPort = ({proxy_port}:{proxy_port:number}) => {
|
||||
if (proxy_port === service.proxy_port) return
|
||||
if (proxy_port > 0 && proxy_port < 65536 && proxy_port !== service.public_port){
|
||||
porthijack.changedestination(service.service_id, service.ip_dst, proxy_port).then( res => {
|
||||
if (res.status === "ok"){
|
||||
okNotify(`Service ${service.name} destination port has changed in ${ proxy_port }`, `Successfully changed destination port`)
|
||||
}else{
|
||||
errorNotify(`Error while changing the destination port of ${service.name}`,`Error: ${res.status}`)
|
||||
}
|
||||
}).catch( err => {
|
||||
errorNotify("Request for changing port failed!",`Error: [ ${err} ]`)
|
||||
})
|
||||
}else{
|
||||
form.setFieldValue("proxy_port", service.proxy_port)
|
||||
errorNotify(`Error while changing the destination port of ${service.name}`,`Insert a valid port number`)
|
||||
}
|
||||
}
|
||||
|
||||
const stopService = async () => {
|
||||
setButtonLoading(true)
|
||||
|
||||
@@ -119,21 +101,7 @@ function ServiceRow({ service }:{ service:Service }) {
|
||||
<Space h="sm" />
|
||||
<Badge color="blue" radius="sm" size="md" variant="filled">
|
||||
<Box className="center-flex">
|
||||
TO {service.ip_dst} :
|
||||
<form onSubmit={form.onSubmit((v)=>portInputRef.current?.blur())}>
|
||||
<PortInput
|
||||
defaultValue={service.proxy_port}
|
||||
size="xs"
|
||||
variant="unstyled"
|
||||
style={{
|
||||
width: (10+form.values.proxy_port.toString().length*6.2) +"px"
|
||||
}}
|
||||
className="firegex__porthijack__servicerow__portInput"
|
||||
onBlur={(e)=>{onChangeProxyPort({proxy_port:parseInt(e.target.value)})}}
|
||||
ref={portInputRef}
|
||||
{...form.getInputProps("proxy_port")}
|
||||
/>
|
||||
</form>
|
||||
TO {service.ip_dst} : service.proxy_port
|
||||
</Box>
|
||||
</Badge>
|
||||
</Box>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ServerResponse } from "../../js/models"
|
||||
import { getapi, postapi } from "../../js/utils"
|
||||
import { deleteapi, getapi, postapi, putapi } from "../../js/utils"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
|
||||
export type GeneralStats = {
|
||||
@@ -37,28 +37,28 @@ export const porthijack = {
|
||||
return await getapi("porthijack/services") as Service[];
|
||||
},
|
||||
serviceinfo: async (service_id:string) => {
|
||||
return await getapi(`porthijack/service/${service_id}`) as Service;
|
||||
return await getapi(`porthijack/services/${service_id}`) as Service;
|
||||
},
|
||||
servicestart: async (service_id:string) => {
|
||||
const { status } = await getapi(`porthijack/service/${service_id}/start`) as ServerResponse;
|
||||
const { status } = await postapi(`porthijack/services/${service_id}/start`) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
},
|
||||
servicerename: async (service_id:string, name: string) => {
|
||||
const { status } = await postapi(`porthijack/service/${service_id}/rename`,{ name }) as ServerResponse;
|
||||
const { status } = await putapi(`porthijack/services/${service_id}/rename`,{ name }) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
},
|
||||
servicestop: async (service_id:string) => {
|
||||
const { status } = await getapi(`porthijack/service/${service_id}/stop`) as ServerResponse;
|
||||
const { status } = await postapi(`porthijack/services/${service_id}/stop`) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
},
|
||||
servicesadd: async (data:ServiceAddForm) => {
|
||||
return await postapi("porthijack/services/add",data) as ServiceAddResponse;
|
||||
return await postapi("porthijack/services",data) as ServiceAddResponse;
|
||||
},
|
||||
servicedelete: async (service_id:string) => {
|
||||
const { status } = await getapi(`porthijack/service/${service_id}/delete`) as ServerResponse;
|
||||
const { status } = await deleteapi(`porthijack/services/${service_id}`) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
},
|
||||
changedestination: async (service_id:string, ip_dst:string, proxy_port:number) => {
|
||||
return await postapi(`porthijack/service/${service_id}/change-destination`, {proxy_port, ip_dst}) as ServerResponse;
|
||||
return await putapi(`porthijack/services/${service_id}/change-destination`, {proxy_port, ip_dst}) as ServerResponse;
|
||||
}
|
||||
}
|
||||
@@ -22,26 +22,6 @@ export const queryClient = new QueryClient({ defaultOptions: { queries: {
|
||||
staleTime: Infinity
|
||||
} }})
|
||||
|
||||
export async function getapi(path:string):Promise<any>{
|
||||
|
||||
return await new Promise((resolve, reject) => {
|
||||
fetch(`${IS_DEV?`http://${DEV_IP_BACKEND}`:""}/api/${path}`,{
|
||||
credentials: "same-origin",
|
||||
headers: { "Authorization" : "Bearer " + window.localStorage.getItem("access_token")}
|
||||
}).then(res => {
|
||||
if(res.status === 401) window.location.reload()
|
||||
if(!res.ok){
|
||||
const errorDefault = res.statusText
|
||||
return res.json().then( res => reject(getErrorMessageFromServerResponse(res, errorDefault)) ).catch( _err => reject(errorDefault))
|
||||
}
|
||||
res.json().then( res => resolve(res) ).catch( err => reject(err))
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
export function getErrorMessage(e: any) {
|
||||
let error = "Unknown error";
|
||||
if(typeof e == "string") return e
|
||||
@@ -56,7 +36,6 @@ export function getErrorMessage(e: any) {
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
export function getErrorMessageFromServerResponse(e: any, def:string = "Unknown error") {
|
||||
if (e.status){
|
||||
return e.status
|
||||
@@ -74,17 +53,17 @@ export function getErrorMessageFromServerResponse(e: any, def:string = "Unknown
|
||||
}
|
||||
|
||||
|
||||
export async function postapi(path:string,data:any,is_form:boolean=false):Promise<any>{
|
||||
export async function genericapi(method:string,path:string,data:any = undefined, is_form:boolean=false):Promise<any>{
|
||||
return await new Promise((resolve, reject) => {
|
||||
fetch(`${IS_DEV?`http://${DEV_IP_BACKEND}`:""}/api/${path}`, {
|
||||
method: 'POST',
|
||||
method: method,
|
||||
credentials: "same-origin",
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
'Content-Type': is_form ? 'application/x-www-form-urlencoded' : 'application/json',
|
||||
...(data?{'Content-Type': is_form ? 'application/x-www-form-urlencoded' : 'application/json'}:{}),
|
||||
"Authorization" : "Bearer " + window.localStorage.getItem("access_token")
|
||||
},
|
||||
body: is_form ? (new URLSearchParams(data)).toString() : JSON.stringify(data)
|
||||
body: data? (is_form ? (new URLSearchParams(data)).toString() : JSON.stringify(data)) : undefined
|
||||
}).then(res => {
|
||||
if(res.status === 401) window.location.reload()
|
||||
if(res.status === 406) resolve({status:"Wrong Password"})
|
||||
@@ -100,6 +79,22 @@ export async function postapi(path:string,data:any,is_form:boolean=false):Promis
|
||||
});
|
||||
}
|
||||
|
||||
export async function getapi(path:string):Promise<any>{
|
||||
return await genericapi("GET",path)
|
||||
}
|
||||
|
||||
export async function postapi(path:string,data:any=undefined,is_form:boolean=false):Promise<any>{
|
||||
return await genericapi("POST",path,data,is_form)
|
||||
}
|
||||
|
||||
export async function deleteapi(path:string):Promise<any>{
|
||||
return await genericapi("DELETE",path)
|
||||
}
|
||||
|
||||
export async function putapi(path:string,data:any):Promise<any>{
|
||||
return await genericapi("PUT",path,data)
|
||||
}
|
||||
|
||||
export function getMainPath(){
|
||||
const paths = window.location.pathname.split("/")
|
||||
if (paths.length > 1) return paths[1]
|
||||
|
||||
1
start.py
1
start.py
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from __future__ import annotations
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
@@ -19,11 +19,17 @@ class BearerSession():
|
||||
headers["Content-Type"] = "application/x-www-form-urlencoded"
|
||||
return self.s.post(endpoint, json=json, data=data, headers=headers)
|
||||
|
||||
def delete(self, endpoint, json={}):
|
||||
return self.s.delete(endpoint, json=json, headers=self.headers)
|
||||
|
||||
def put(self, endpoint, json={}):
|
||||
return self.s.put(endpoint, json=json, headers=self.headers)
|
||||
|
||||
def get(self, endpoint, json={}):
|
||||
return self.s.get(endpoint, json=json, headers=self.headers)
|
||||
|
||||
def set_token(self,token):
|
||||
self.headers = {"Authorization": f"Bearer {token}"}
|
||||
self.headers = {"Authorization": f"Bearer {token}"}
|
||||
|
||||
def unset_token(self):
|
||||
self.headers = {}
|
||||
@@ -72,62 +78,57 @@ class FiregexAPI:
|
||||
def reset(self, delete: bool):
|
||||
self.s.post(f"{self.address}api/reset", json={"delete":delete})
|
||||
|
||||
#Netfilter regex
|
||||
def nf_get_stats(self):
|
||||
req = self.s.get(f"{self.address}api/nfregex/stats")
|
||||
return req.json()
|
||||
|
||||
def nf_get_services(self):
|
||||
req = self.s.get(f"{self.address}api/nfregex/services")
|
||||
return req.json()
|
||||
|
||||
def nf_get_service(self,service_id: str):
|
||||
req = self.s.get(f"{self.address}api/nfregex/service/{service_id}")
|
||||
req = self.s.get(f"{self.address}api/nfregex/services/{service_id}")
|
||||
return req.json()
|
||||
|
||||
def nf_stop_service(self,service_id: str):
|
||||
req = self.s.get(f"{self.address}api/nfregex/service/{service_id}/stop")
|
||||
req = self.s.post(f"{self.address}api/nfregex/services/{service_id}/stop")
|
||||
return verify(req)
|
||||
|
||||
def nf_start_service(self,service_id: str):
|
||||
req = self.s.get(f"{self.address}api/nfregex/service/{service_id}/start")
|
||||
req = self.s.post(f"{self.address}api/nfregex/services/{service_id}/start")
|
||||
return verify(req)
|
||||
|
||||
def nf_delete_service(self,service_id: str):
|
||||
req = self.s.get(f"{self.address}api/nfregex/service/{service_id}/delete")
|
||||
req = self.s.delete(f"{self.address}api/nfregex/services/{service_id}")
|
||||
return verify(req)
|
||||
|
||||
def nf_rename_service(self,service_id: str, newname: str):
|
||||
req = self.s.post(f"{self.address}api/nfregex/service/{service_id}/rename" , json={"name":newname})
|
||||
req = self.s.put(f"{self.address}api/nfregex/services/{service_id}/rename" , json={"name":newname})
|
||||
return verify(req)
|
||||
|
||||
def nf_get_service_regexes(self,service_id: str):
|
||||
req = self.s.get(f"{self.address}api/nfregex/service/{service_id}/regexes")
|
||||
req = self.s.get(f"{self.address}api/nfregex/services/{service_id}/regexes")
|
||||
return req.json()
|
||||
|
||||
def nf_get_regex(self,regex_id: str):
|
||||
req = self.s.get(f"{self.address}api/nfregex/regex/{regex_id}")
|
||||
req = self.s.get(f"{self.address}api/nfregex/regexes/{regex_id}")
|
||||
return req.json()
|
||||
|
||||
def nf_delete_regex(self,regex_id: str):
|
||||
req = self.s.get(f"{self.address}api/nfregex/regex/{regex_id}/delete")
|
||||
req = self.s.delete(f"{self.address}api/nfregex/regexes/{regex_id}")
|
||||
return verify(req)
|
||||
|
||||
def nf_enable_regex(self,regex_id: str):
|
||||
req = self.s.get(f"{self.address}api/nfregex/regex/{regex_id}/enable")
|
||||
req = self.s.post(f"{self.address}api/nfregex/regexes/{regex_id}/enable")
|
||||
return verify(req)
|
||||
|
||||
def nf_disable_regex(self,regex_id: str):
|
||||
req = self.s.get(f"{self.address}api/nfregex/regex/{regex_id}/disable")
|
||||
req = self.s.post(f"{self.address}api/nfregex/regexes/{regex_id}/disable")
|
||||
return verify(req)
|
||||
|
||||
def nf_add_regex(self, service_id: str, regex: str, mode: str, active: bool, is_case_sensitive: bool):
|
||||
req = self.s.post(f"{self.address}api/nfregex/regexes/add",
|
||||
req = self.s.post(f"{self.address}api/nfregex/regexes",
|
||||
json={"service_id": service_id, "regex": regex, "mode": mode, "active": active, "is_case_sensitive": is_case_sensitive})
|
||||
return verify(req)
|
||||
|
||||
def nf_add_service(self, name: str, port: int, proto: str, ip_int: str):
|
||||
req = self.s.post(f"{self.address}api/nfregex/services/add" ,
|
||||
req = self.s.post(f"{self.address}api/nfregex/services" ,
|
||||
json={"name":name,"port":port, "proto": proto, "ip_int": ip_int})
|
||||
return req.json()["service_id"] if verify(req) else False
|
||||
|
||||
@@ -137,30 +138,30 @@ class FiregexAPI:
|
||||
return req.json()
|
||||
|
||||
def ph_get_service(self,service_id: str):
|
||||
req = self.s.get(f"{self.address}api/porthijack/service/{service_id}")
|
||||
req = self.s.get(f"{self.address}api/porthijack/services/{service_id}")
|
||||
return req.json()
|
||||
|
||||
def ph_stop_service(self,service_id: str):
|
||||
req = self.s.get(f"{self.address}api/porthijack/service/{service_id}/stop")
|
||||
req = self.s.post(f"{self.address}api/porthijack/services/{service_id}/stop")
|
||||
return verify(req)
|
||||
|
||||
def ph_start_service(self,service_id: str):
|
||||
req = self.s.get(f"{self.address}api/porthijack/service/{service_id}/start")
|
||||
req = self.s.post(f"{self.address}api/porthijack/services/{service_id}/start")
|
||||
return verify(req)
|
||||
|
||||
def ph_delete_service(self,service_id: str):
|
||||
req = self.s.get(f"{self.address}api/porthijack/service/{service_id}/delete")
|
||||
req = self.s.delete(f"{self.address}api/porthijack/services/{service_id}")
|
||||
return verify(req)
|
||||
|
||||
def ph_rename_service(self,service_id: str,newname: str):
|
||||
req = self.s.post(f"{self.address}api/porthijack/service/{service_id}/rename" , json={"name":newname})
|
||||
req = self.s.put(f"{self.address}api/porthijack/services/{service_id}/rename" , json={"name":newname})
|
||||
return verify(req)
|
||||
|
||||
def ph_change_destination(self,service_id: str, ip_dst:string , proxy_port: int):
|
||||
req = self.s.post(f"{self.address}api/porthijack/service/{service_id}/change-destination", json={"ip_dst": ip_dst, "proxy_port": proxy_port})
|
||||
req = self.s.put(f"{self.address}api/porthijack/services/{service_id}/change-destination", json={"ip_dst": ip_dst, "proxy_port": proxy_port})
|
||||
return verify(req)
|
||||
|
||||
def ph_add_service(self, name: str, public_port: int, proxy_port: int, proto: str, ip_src: str, ip_dst: str):
|
||||
req = self.s.post(f"{self.address}api/porthijack/services/add" ,
|
||||
req = self.s.post(f"{self.address}api/porthijack/services" ,
|
||||
json={"name":name, "public_port": public_port, "proxy_port":proxy_port, "proto": proto, "ip_src": ip_src, "ip_dst": ip_dst})
|
||||
return req.json()["service_id"] if verify(req) else False
|
||||
|
||||
Reference in New Issue
Block a user