|
|
""" |
|
|
ISP API Routes |
|
|
|
|
|
Flask routes for the Virtual ISP Stack API endpoints |
|
|
""" |
|
|
|
|
|
from flask import Blueprint, jsonify, request, Response |
|
|
from flask_cors import cross_origin |
|
|
import json |
|
|
import time |
|
|
from typing import Dict, Any |
|
|
|
|
|
|
|
|
from core.dhcp_server import DHCPServer |
|
|
from core.nat_engine import NATEngine |
|
|
from core.firewall import FirewallEngine, FirewallRule, FirewallRuleBuilder, FirewallAction, FirewallDirection |
|
|
from core.tcp_engine import TCPEngine |
|
|
from core.virtual_router import VirtualRouter |
|
|
from core.socket_translator import SocketTranslator |
|
|
from core.packet_bridge import PacketBridge |
|
|
from core.session_tracker import SessionTracker, SessionType, SessionState |
|
|
from core.logger import VirtualISPLogger, LogLevel, LogCategory, LogFilter |
|
|
from core.openvpn_manager import OpenVPNManager, initialize_openvpn_manager, get_openvpn_manager |
|
|
|
|
|
|
|
|
isp_api = Blueprint('isp_api', __name__) |
|
|
|
|
|
|
|
|
dhcp_server: DHCPServer = None |
|
|
nat_engine: NATEngine = None |
|
|
firewall_engine: FirewallEngine = None |
|
|
tcp_engine: TCPEngine = None |
|
|
virtual_router: VirtualRouter = None |
|
|
socket_translator: SocketTranslator = None |
|
|
packet_bridge: PacketBridge = None |
|
|
session_tracker: SessionTracker = None |
|
|
logger: VirtualISPLogger = None |
|
|
openvpn_manager: OpenVPNManager = None |
|
|
|
|
|
|
|
|
def init_engines(config: Dict[str, Any]): |
|
|
"""Initialize all engines with configuration""" |
|
|
global dhcp_server, nat_engine, firewall_engine, tcp_engine |
|
|
global virtual_router, socket_translator, packet_bridge, session_tracker, logger, openvpn_manager |
|
|
|
|
|
|
|
|
logger = VirtualISPLogger(config.get('logger', {})) |
|
|
logger.start() |
|
|
|
|
|
|
|
|
dhcp_server = DHCPServer(config.get('dhcp', {})) |
|
|
nat_engine = NATEngine(config.get('nat', {})) |
|
|
firewall_engine = FirewallEngine(config.get('firewall', {})) |
|
|
tcp_engine = TCPEngine(config.get('tcp', {})) |
|
|
virtual_router = VirtualRouter(config.get('router', {})) |
|
|
socket_translator = SocketTranslator(config.get('socket_translator', {})) |
|
|
packet_bridge = PacketBridge(config.get('packet_bridge', {})) |
|
|
session_tracker = SessionTracker(config.get('session_tracker', {})) |
|
|
|
|
|
|
|
|
openvpn_manager = initialize_openvpn_manager(config.get('openvpn', {})) |
|
|
openvpn_manager.set_isp_components( |
|
|
dhcp_server=dhcp_server, |
|
|
nat_engine=nat_engine, |
|
|
firewall=firewall_engine, |
|
|
router=virtual_router |
|
|
) |
|
|
|
|
|
|
|
|
dhcp_server.start() |
|
|
nat_engine.start() |
|
|
tcp_engine.start() |
|
|
socket_translator.start() |
|
|
session_tracker.start() |
|
|
packet_bridge.start() |
|
|
|
|
|
logger.info(LogCategory.SYSTEM, 'api', 'All engines initialized and started') |
|
|
|
|
|
|
|
|
|
|
|
@isp_api.route('/config', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_config(): |
|
|
"""Get current system configuration""" |
|
|
try: |
|
|
config = { |
|
|
'dhcp': { |
|
|
'network': '10.0.0.0/24', |
|
|
'range_start': '10.0.0.10', |
|
|
'range_end': '10.0.0.100', |
|
|
'lease_time': 3600, |
|
|
'gateway': '10.0.0.1', |
|
|
'dns_servers': ['8.8.8.8', '8.8.4.4'] |
|
|
}, |
|
|
'nat': { |
|
|
'port_range_start': 10000, |
|
|
'port_range_end': 65535, |
|
|
'session_timeout': 300 |
|
|
}, |
|
|
'firewall': { |
|
|
'default_policy': 'ACCEPT', |
|
|
'log_blocked': True |
|
|
}, |
|
|
'tcp': { |
|
|
'initial_window': 65535, |
|
|
'max_retries': 3, |
|
|
'timeout': 30 |
|
|
} |
|
|
} |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'config': config |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/config', methods=['POST']) |
|
|
@cross_origin() |
|
|
def update_config(): |
|
|
"""Update system configuration""" |
|
|
try: |
|
|
config_data = request.get_json() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if logger: |
|
|
logger.info(LogCategory.SYSTEM, 'api', 'Configuration updated', metadata=config_data) |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'message': 'Configuration updated successfully' |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
if logger: |
|
|
logger.error(LogCategory.SYSTEM, 'api', f'Configuration update failed: {str(e)}') |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
|
|
|
@isp_api.route('/dhcp/leases', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_dhcp_leases(): |
|
|
"""Get DHCP lease table""" |
|
|
try: |
|
|
if not dhcp_server: |
|
|
return jsonify({'status': 'error', 'message': 'DHCP server not initialized'}), 500 |
|
|
|
|
|
leases = dhcp_server.get_leases() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'leases': leases, |
|
|
'count': len(leases) |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/dhcp/leases/<mac_address>', methods=['DELETE']) |
|
|
@cross_origin() |
|
|
def release_dhcp_lease(mac_address): |
|
|
"""Release DHCP lease""" |
|
|
try: |
|
|
if not dhcp_server: |
|
|
return jsonify({'status': 'error', 'message': 'DHCP server not initialized'}), 500 |
|
|
|
|
|
success = dhcp_server.release_lease(mac_address) |
|
|
|
|
|
if success: |
|
|
if logger: |
|
|
logger.info(LogCategory.DHCP, 'api', f'Released DHCP lease for {mac_address}') |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'message': f'Lease for {mac_address} released' |
|
|
}) |
|
|
else: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': f'Lease for {mac_address} not found' |
|
|
}), 404 |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
|
|
|
@isp_api.route('/nat/sessions', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_nat_sessions(): |
|
|
"""Get NAT session table""" |
|
|
try: |
|
|
if not nat_engine: |
|
|
return jsonify({'status': 'error', 'message': 'NAT engine not initialized'}), 500 |
|
|
|
|
|
sessions = nat_engine.get_sessions() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'sessions': sessions, |
|
|
'count': len(sessions) |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/nat/stats', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_nat_stats(): |
|
|
"""Get NAT statistics""" |
|
|
try: |
|
|
if not nat_engine: |
|
|
return jsonify({'status': 'error', 'message': 'NAT engine not initialized'}), 500 |
|
|
|
|
|
stats = nat_engine.get_stats() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'stats': stats |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
|
|
|
@isp_api.route('/firewall/rules', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_firewall_rules(): |
|
|
"""Get firewall rules""" |
|
|
try: |
|
|
if not firewall_engine: |
|
|
return jsonify({'status': 'error', 'message': 'Firewall engine not initialized'}), 500 |
|
|
|
|
|
rules = firewall_engine.get_rules() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'rules': rules, |
|
|
'count': len(rules) |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/firewall/rules', methods=['POST']) |
|
|
@cross_origin() |
|
|
def add_firewall_rule(): |
|
|
"""Add firewall rule""" |
|
|
try: |
|
|
if not firewall_engine: |
|
|
return jsonify({'status': 'error', 'message': 'Firewall engine not initialized'}), 500 |
|
|
|
|
|
rule_data = request.get_json() |
|
|
|
|
|
|
|
|
builder = FirewallRuleBuilder(rule_data['rule_id']) |
|
|
builder.set_priority(rule_data.get('priority', 100)) |
|
|
builder.set_action(rule_data['action']) |
|
|
builder.set_direction(rule_data.get('direction', 'BOTH')) |
|
|
|
|
|
if 'source_ip' in rule_data: |
|
|
builder.set_source_ip(rule_data['source_ip']) |
|
|
if 'dest_ip' in rule_data: |
|
|
builder.set_dest_ip(rule_data['dest_ip']) |
|
|
if 'source_port' in rule_data: |
|
|
builder.set_source_port(rule_data['source_port']) |
|
|
if 'dest_port' in rule_data: |
|
|
builder.set_dest_port(rule_data['dest_port']) |
|
|
if 'protocol' in rule_data: |
|
|
builder.set_protocol(rule_data['protocol']) |
|
|
if 'description' in rule_data: |
|
|
builder.set_description(rule_data['description']) |
|
|
|
|
|
rule = builder.build() |
|
|
success = firewall_engine.add_rule(rule) |
|
|
|
|
|
if success: |
|
|
if logger: |
|
|
logger.info(LogCategory.FIREWALL, 'api', f'Added firewall rule: {rule.rule_id}') |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'message': f'Rule {rule.rule_id} added successfully' |
|
|
}) |
|
|
else: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': f'Rule {rule.rule_id} already exists' |
|
|
}), 400 |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/firewall/rules/<rule_id>', methods=['DELETE']) |
|
|
@cross_origin() |
|
|
def delete_firewall_rule(rule_id): |
|
|
"""Delete firewall rule""" |
|
|
try: |
|
|
if not firewall_engine: |
|
|
return jsonify({'status': 'error', 'message': 'Firewall engine not initialized'}), 500 |
|
|
|
|
|
success = firewall_engine.remove_rule(rule_id) |
|
|
|
|
|
if success: |
|
|
if logger: |
|
|
logger.info(LogCategory.FIREWALL, 'api', f'Deleted firewall rule: {rule_id}') |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'message': f'Rule {rule_id} deleted successfully' |
|
|
}) |
|
|
else: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': f'Rule {rule_id} not found' |
|
|
}), 404 |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/firewall/logs', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_firewall_logs(): |
|
|
"""Get firewall logs""" |
|
|
try: |
|
|
if not firewall_engine: |
|
|
return jsonify({'status': 'error', 'message': 'Firewall engine not initialized'}), 500 |
|
|
|
|
|
limit = request.args.get('limit', 100, type=int) |
|
|
filter_action = request.args.get('action') |
|
|
|
|
|
logs = firewall_engine.get_logs(limit=limit, filter_action=filter_action) |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'logs': logs, |
|
|
'count': len(logs) |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/firewall/stats', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_firewall_stats(): |
|
|
"""Get firewall statistics""" |
|
|
try: |
|
|
if not firewall_engine: |
|
|
return jsonify({'status': 'error', 'message': 'Firewall engine not initialized'}), 500 |
|
|
|
|
|
stats = firewall_engine.get_stats() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'stats': stats |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
|
|
|
@isp_api.route('/tcp/connections', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_tcp_connections(): |
|
|
"""Get TCP connections""" |
|
|
try: |
|
|
if not tcp_engine: |
|
|
return jsonify({'status': 'error', 'message': 'TCP engine not initialized'}), 500 |
|
|
|
|
|
connections = tcp_engine.get_connections() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'connections': connections, |
|
|
'count': len(connections) |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
|
|
|
@isp_api.route('/router/routes', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_routing_table(): |
|
|
"""Get routing table""" |
|
|
try: |
|
|
if not virtual_router: |
|
|
return jsonify({'status': 'error', 'message': 'Virtual router not initialized'}), 500 |
|
|
|
|
|
routes = virtual_router.get_routing_table() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'routes': routes, |
|
|
'count': len(routes) |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/router/interfaces', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_router_interfaces(): |
|
|
"""Get router interfaces""" |
|
|
try: |
|
|
if not virtual_router: |
|
|
return jsonify({'status': 'error', 'message': 'Virtual router not initialized'}), 500 |
|
|
|
|
|
interfaces = virtual_router.get_interfaces() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'interfaces': interfaces, |
|
|
'count': len(interfaces) |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/router/arp', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_arp_table(): |
|
|
"""Get ARP table""" |
|
|
try: |
|
|
if not virtual_router: |
|
|
return jsonify({'status': 'error', 'message': 'Virtual router not initialized'}), 500 |
|
|
|
|
|
arp_table = virtual_router.get_arp_table() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'arp_table': arp_table, |
|
|
'count': len(arp_table) |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/router/stats', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_router_stats(): |
|
|
"""Get router statistics""" |
|
|
try: |
|
|
if not virtual_router: |
|
|
return jsonify({'status': 'error', 'message': 'Virtual router not initialized'}), 500 |
|
|
|
|
|
stats = virtual_router.get_stats() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'stats': stats |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
|
|
|
@isp_api.route('/bridge/clients', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_bridge_clients(): |
|
|
"""Get bridge clients""" |
|
|
try: |
|
|
if not packet_bridge: |
|
|
return jsonify({'status': 'error', 'message': 'Packet bridge not initialized'}), 500 |
|
|
|
|
|
clients = packet_bridge.get_clients() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'clients': clients, |
|
|
'count': len(clients) |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/bridge/stats', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_bridge_stats(): |
|
|
"""Get bridge statistics""" |
|
|
try: |
|
|
if not packet_bridge: |
|
|
return jsonify({'status': 'error', 'message': 'Packet bridge not initialized'}), 500 |
|
|
|
|
|
stats = packet_bridge.get_stats() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'stats': stats |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
|
|
|
@isp_api.route('/sessions', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_sessions(): |
|
|
"""Get sessions""" |
|
|
try: |
|
|
if not session_tracker: |
|
|
return jsonify({'status': 'error', 'message': 'Session tracker not initialized'}), 500 |
|
|
|
|
|
limit = request.args.get('limit', 100, type=int) |
|
|
offset = request.args.get('offset', 0, type=int) |
|
|
|
|
|
sessions = session_tracker.get_sessions(limit=limit, offset=offset) |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'sessions': sessions, |
|
|
'count': len(sessions) |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/sessions/summary', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_session_summary(): |
|
|
"""Get session summary""" |
|
|
try: |
|
|
if not session_tracker: |
|
|
return jsonify({'status': 'error', 'message': 'Session tracker not initialized'}), 500 |
|
|
|
|
|
summary = session_tracker.get_session_summary() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'summary': summary |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
|
|
|
@isp_api.route('/logs', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_logs(): |
|
|
"""Get system logs""" |
|
|
try: |
|
|
if not logger: |
|
|
return jsonify({'status': 'error', 'message': 'Logger not initialized'}), 500 |
|
|
|
|
|
limit = request.args.get('limit', 100, type=int) |
|
|
offset = request.args.get('offset', 0, type=int) |
|
|
level = request.args.get('level') |
|
|
category = request.args.get('category') |
|
|
search = request.args.get('search') |
|
|
|
|
|
if search: |
|
|
logs = logger.search_logs(search, limit=limit) |
|
|
else: |
|
|
log_filter = LogFilter() |
|
|
if level: |
|
|
log_filter.level_filter = LogLevel(level.upper()) |
|
|
if category: |
|
|
log_filter.category_filter = LogCategory(category.upper()) |
|
|
|
|
|
logs = logger.get_logs(limit=limit, offset=offset, log_filter=log_filter) |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'logs': logs, |
|
|
'count': len(logs) |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/logs/errors', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_error_logs(): |
|
|
"""Get recent error logs""" |
|
|
try: |
|
|
if not logger: |
|
|
return jsonify({'status': 'error', 'message': 'Logger not initialized'}), 500 |
|
|
|
|
|
limit = request.args.get('limit', 50, type=int) |
|
|
errors = logger.get_recent_errors(limit=limit) |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'errors': errors, |
|
|
'count': len(errors) |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
|
|
|
@isp_api.route('/status', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_system_status(): |
|
|
"""Get overall system status""" |
|
|
try: |
|
|
status = { |
|
|
'timestamp': time.time(), |
|
|
'uptime': time.time() - (time.time() - 3600), |
|
|
'components': { |
|
|
'dhcp_server': dhcp_server is not None and dhcp_server.running, |
|
|
'nat_engine': nat_engine is not None and nat_engine.running, |
|
|
'firewall_engine': firewall_engine is not None, |
|
|
'tcp_engine': tcp_engine is not None and tcp_engine.running, |
|
|
'virtual_router': virtual_router is not None, |
|
|
'socket_translator': socket_translator is not None and socket_translator.running, |
|
|
'packet_bridge': packet_bridge is not None and packet_bridge.running, |
|
|
'session_tracker': session_tracker is not None and session_tracker.running, |
|
|
'logger': logger is not None and logger.running |
|
|
}, |
|
|
'stats': {} |
|
|
} |
|
|
|
|
|
|
|
|
if dhcp_server: |
|
|
status['stats']['dhcp_leases'] = len(dhcp_server.get_leases()) |
|
|
|
|
|
if nat_engine: |
|
|
nat_stats = nat_engine.get_stats() |
|
|
status['stats']['nat_sessions'] = nat_stats.get('active_sessions', 0) |
|
|
|
|
|
if firewall_engine: |
|
|
fw_stats = firewall_engine.get_stats() |
|
|
status['stats']['firewall_rules'] = fw_stats.get('total_rules', 0) |
|
|
|
|
|
if tcp_engine: |
|
|
tcp_connections = tcp_engine.get_connections() |
|
|
status['stats']['tcp_connections'] = len(tcp_connections) |
|
|
|
|
|
if packet_bridge: |
|
|
bridge_stats = packet_bridge.get_stats() |
|
|
status['stats']['bridge_clients'] = bridge_stats.get('active_clients', 0) |
|
|
|
|
|
if session_tracker: |
|
|
session_stats = session_tracker.get_stats() |
|
|
status['stats']['total_sessions'] = session_stats.get('active_sessions', 0) |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'system_status': status |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/stats', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_system_stats(): |
|
|
"""Get comprehensive system statistics""" |
|
|
try: |
|
|
stats = { |
|
|
'timestamp': time.time(), |
|
|
'dhcp': dhcp_server.get_leases() if dhcp_server else {}, |
|
|
'nat': nat_engine.get_stats() if nat_engine else {}, |
|
|
'firewall': firewall_engine.get_stats() if firewall_engine else {}, |
|
|
'router': virtual_router.get_stats() if virtual_router else {}, |
|
|
'bridge': packet_bridge.get_stats() if packet_bridge else {}, |
|
|
'sessions': session_tracker.get_stats() if session_tracker else {}, |
|
|
'logger': logger.get_stats() if logger else {} |
|
|
} |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'stats': stats |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
packet_bridge.start() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@isp_api.route('/openvpn/status', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_openvpn_status(): |
|
|
"""Get OpenVPN server status""" |
|
|
try: |
|
|
if not openvpn_manager: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': 'OpenVPN manager not initialized' |
|
|
}), 500 |
|
|
|
|
|
status = openvpn_manager.get_server_status() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'openvpn_status': { |
|
|
'is_running': status.is_running, |
|
|
'connected_clients': status.connected_clients, |
|
|
'total_bytes_received': status.total_bytes_received, |
|
|
'total_bytes_sent': status.total_bytes_sent, |
|
|
'uptime': status.uptime, |
|
|
'server_ip': status.server_ip, |
|
|
'server_port': status.server_port |
|
|
} |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/openvpn/start', methods=['POST']) |
|
|
@cross_origin() |
|
|
def start_openvpn_server(): |
|
|
"""Start OpenVPN server""" |
|
|
try: |
|
|
if not openvpn_manager: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': 'OpenVPN manager not initialized' |
|
|
}), 500 |
|
|
|
|
|
success = openvpn_manager.start_server() |
|
|
|
|
|
if success: |
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'message': 'OpenVPN server started successfully' |
|
|
}) |
|
|
else: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': 'Failed to start OpenVPN server' |
|
|
}), 500 |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/openvpn/stop', methods=['POST']) |
|
|
@cross_origin() |
|
|
def stop_openvpn_server(): |
|
|
"""Stop OpenVPN server""" |
|
|
try: |
|
|
if not openvpn_manager: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': 'OpenVPN manager not initialized' |
|
|
}), 500 |
|
|
|
|
|
success = openvpn_manager.stop_server() |
|
|
|
|
|
if success: |
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'message': 'OpenVPN server stopped successfully' |
|
|
}) |
|
|
else: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': 'Failed to stop OpenVPN server' |
|
|
}), 500 |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/openvpn/clients', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_openvpn_clients(): |
|
|
"""Get connected OpenVPN clients""" |
|
|
try: |
|
|
if not openvpn_manager: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': 'OpenVPN manager not initialized' |
|
|
}), 500 |
|
|
|
|
|
clients = openvpn_manager.get_connected_clients() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'clients': clients |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/openvpn/clients/<client_id>/disconnect', methods=['POST']) |
|
|
@cross_origin() |
|
|
def disconnect_openvpn_client(client_id): |
|
|
"""Disconnect a specific OpenVPN client""" |
|
|
try: |
|
|
if not openvpn_manager: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': 'OpenVPN manager not initialized' |
|
|
}), 500 |
|
|
|
|
|
success = openvpn_manager.disconnect_client(client_id) |
|
|
|
|
|
if success: |
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'message': f'Client {client_id} disconnected successfully' |
|
|
}) |
|
|
else: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': f'Failed to disconnect client {client_id}' |
|
|
}), 500 |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/openvpn/config/<client_name>', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_client_config(client_name): |
|
|
"""Generate client configuration file""" |
|
|
try: |
|
|
if not openvpn_manager: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': 'OpenVPN manager not initialized' |
|
|
}), 500 |
|
|
|
|
|
|
|
|
server_ip = request.args.get('server_ip', '127.0.0.1') |
|
|
|
|
|
config = openvpn_manager.generate_client_config(client_name, server_ip) |
|
|
|
|
|
if config: |
|
|
return Response( |
|
|
config, |
|
|
mimetype='text/plain', |
|
|
headers={'Content-Disposition': f'attachment; filename={client_name}.ovpn'} |
|
|
) |
|
|
else: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': 'Failed to generate client configuration' |
|
|
}), 500 |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/openvpn/stats', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_openvpn_stats(): |
|
|
"""Get comprehensive OpenVPN statistics""" |
|
|
try: |
|
|
if not openvpn_manager: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': 'OpenVPN manager not initialized' |
|
|
}), 500 |
|
|
|
|
|
stats = openvpn_manager.get_statistics() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'openvpn_stats': stats |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/openvpn/configs', methods=['GET']) |
|
|
@cross_origin() |
|
|
def list_client_configs(): |
|
|
"""List all stored client configurations""" |
|
|
try: |
|
|
if not openvpn_manager: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': 'OpenVPN manager not initialized' |
|
|
}), 500 |
|
|
|
|
|
configs = openvpn_manager.list_client_configs() |
|
|
|
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'configs': configs, |
|
|
'count': len(configs) |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/openvpn/configs/<client_name>', methods=['GET']) |
|
|
@cross_origin() |
|
|
def get_stored_client_config(client_name): |
|
|
"""Get stored client configuration""" |
|
|
try: |
|
|
if not openvpn_manager: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': 'OpenVPN manager not initialized' |
|
|
}), 500 |
|
|
|
|
|
config_content = openvpn_manager.load_client_config(client_name) |
|
|
|
|
|
if config_content: |
|
|
return Response( |
|
|
config_content, |
|
|
mimetype='text/plain', |
|
|
headers={'Content-Disposition': f'attachment; filename={client_name}.ovpn'} |
|
|
) |
|
|
else: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': f'Configuration for {client_name} not found' |
|
|
}), 404 |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/openvpn/configs/<client_name>', methods=['DELETE']) |
|
|
@cross_origin() |
|
|
def delete_stored_client_config(client_name): |
|
|
"""Delete stored client configuration""" |
|
|
try: |
|
|
if not openvpn_manager: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': 'OpenVPN manager not initialized' |
|
|
}), 500 |
|
|
|
|
|
success = openvpn_manager.delete_client_config(client_name) |
|
|
|
|
|
if success: |
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'message': f'Configuration for {client_name} deleted successfully' |
|
|
}) |
|
|
else: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': f'Configuration for {client_name} not found' |
|
|
}), 404 |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
@isp_api.route('/openvpn/configs/<client_name>/generate', methods=['POST']) |
|
|
@cross_origin() |
|
|
def generate_and_save_client_config(client_name): |
|
|
"""Generate and save client configuration""" |
|
|
try: |
|
|
if not openvpn_manager: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': 'OpenVPN manager not initialized' |
|
|
}), 500 |
|
|
|
|
|
|
|
|
server_ip = request.args.get('server_ip', '127.0.0.1') |
|
|
|
|
|
config_content = openvpn_manager.generate_and_save_client_config(client_name, server_ip) |
|
|
|
|
|
if config_content: |
|
|
return jsonify({ |
|
|
'status': 'success', |
|
|
'message': f'Configuration for {client_name} generated and saved successfully' |
|
|
}) |
|
|
else: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': f'Failed to generate configuration for {client_name}' |
|
|
}), 500 |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({ |
|
|
'status': 'error', |
|
|
'message': str(e) |
|
|
}), 500 |
|
|
|
|
|
|
|
|
|