6.1 Αρχιτεκτονική Αυτόνομου Δικτύου: Μια Συστημική Προσέγγιση 6.1.1 Το Μοντέλο Αποκεντρωμένης Υποδομής Η δικτυακή αρχιτεκτονική για το cyber-autonomy server βασίζεται σε ένα υβριδικό μοντέλο που συνδυάζει: Πυρήνας Δικτύου: Autonomous routing και switching Περιφερειακή Συνδεσιμότητα: Wireless AP, Ethernet, mesh networking Υπηρεσίες Δικτύου: DNS, DHCP, VPN, firewall Εφαρμογές: Reverse proxy, load balancing, caching 6.1.2 Συνολική Αρχιτεκτονική text ΕΠΙΠΕΔΟ 1: ΦΥΣΙΚΗ ΣΥΝΔΕΣΙΜΟΤΗΤΑ ├── Primary: Wi-Fi 6 Access Point (5GHz/2.4GHz) ├── Secondary: Gigabit Ethernet switch ├── Tertiary: Mesh networking (Reticulum/OLSR) └── Fallback: Bluetooth PAN (έκτακτη ανάγκη) ΕΠΙΠΕΔΟ 2: ΔΙΚΤΥΑΚΕΣ ΥΠΗΡΕΣΙΕΣ ├── DNS: Unbound (recursive resolver) + dnsmasq (local) ├── DHCP: ISC DHCP server με static leases ├── Routing: Babel/OLSR για mesh └── VPN: WireGuard (site-to-site & remote access) ΕΠΙΠΕΔΟ 3: ΑΣΦΑΛΕΙΑ ├── Firewall: nftables με stateful inspection ├── IDS/IPS: Suricata με community rules ├── VPN: WireGuard tunnel encryption └── Monitoring: NetFlow, sFlow, log analysis ΕΠΙΠΕΔΟ 4: ΥΠΗΡΕΣΙΕΣ ΕΦΑΡΜΟΓΩΝ ├── Reverse Proxy: Traefik με Let's Encrypt (εσωτερικό) ├── Load Balancing: Round-robin με health checks ├── Caching: Varnish για στατικό content └── Service Discovery: Consul για dynamic configuration 6.2 Ρύθμιση Wireless Access Point: Επαγγελματικός Σχεδιασμός 6.2.1 Ανάλυση Απαιτήσεων και Σχεδιασμός Κριτήρια Σχεδιασμού: Χωρητικότητα: 20+ ταυτόχρονες συσκευές Εμβέλεια: 100μ εντός κτιρίου, 50μ εκτός Επίδοση: >100Mbps πραγματική απόδοση Ασφάλεια: WPA3 Enterprise, 802.1X authentication Υπολογισμός RF Planning: python import math class RFPlanning: def __init__(self, frequency, tx_power, antenna_gain): self.frequency = frequency # GHz self.tx_power = tx_power # dBm self.antenna_gain = antenna_gain # dBi def free_space_path_loss(self, distance): """Υπολογισμός απωλειών διαδρομής""" # FSPL = 20log10(d) + 20log10(f) + 92.45 # d in km, f in GHz fspl = 20*math.log10(distance/1000) + 20*math.log10(self.frequency) + 92.45 return fspl def received_power(self, distance, rx_gain=0, obstacles=0): """Υπολογισμός ισχύος λήψης""" # Prx = Ptx + Gtx + Grx - L - obstacles fspl = self.free_space_path_loss(distance) prx = self.tx_power + self.antenna_gain + rx_gain - fspl - obstacles return prx def coverage_radius(self, min_rx_power=-70, rx_gain=0, obstacles=0): """Υπολογισμός ακτίνας κάλυψης""" # Επίλυση FSPL equation για απόσταση total_gain = self.tx_power + self.antenna_gain + rx_gain - min_rx_power - obstacles # FSPL = 20log10(d) + 20log10(f) + 92.45 # 20log10(d) = total_gain - 20log10(f) - 92.45 d_log = (total_gain - 20*math.log10(self.frequency) - 92.45) / 20 distance = 10**d_log * 1000 # Μετατροπή σε μέτρα return distance # Παράδειγμα: 5GHz AP, 20dBm TX power, 5dBi antenna rf_5ghz = RFPlanning(5.2, 20, 5) radius_5ghz = rf_5ghz.coverage_radius(obstacles=15) # 15dB για τοίχους print(f"Ακτίνα κάλυψης 5GHz: {radius_5ghz:.1f}m") # 2.4GHz για καλύτερη διείσδυση rf_24ghz = RFPlanning(2.4, 20, 5) radius_24ghz = rf_24ghz.coverage_radius(obstacles=10) print(f"Ακτίνα κάλυψης 2.4GHz: {radius_24ghz:.1f}m") 6.2.2 Σύνθετη Ρύθμιση hostapd Προχωρημένο Configuration για Dual-Band AP: bash #!/bin/bash # setup-advanced-ap.sh # Εγκατάσταση εξαρτήσεων sudo apt update sudo apt install -y hostapd dnsmasq iw wireless-tools rfkill # Απενεργοποίηση προσωρινή υπηρεσιών sudo systemctl stop hostapd sudo systemctl stop dnsmasq # Ρύθμιση wireless interface WIFI_INTERFACE=$(iw dev | awk '$1=="Interface"{print $2}' | head -1) sudo ip link set $WIFI_INTERFACE down sudo ip addr add 192.168.100.1/24 dev $WIFI_INTERFACE sudo ip link set $WIFI_INTERFACE up # Δημιουργία προηγμένου hostapd configuration sudo tee /etc/hostapd/hostapd.conf << 'EOF' # Βασικές ρυθμίσεις interface=${WIFI_INTERFACE} driver=nl80211 ssid=CyberAutonomy country_code=GR hw_mode=a channel=36 beacon_int=100 dtim_period=2 max_num_sta=50 rts_threshold=2347 fragm_threshold=2346 ignore_broadcast_ssid=0 # WPA3 Configuration wpa=2 wpa_key_mgmt=WPA-PSK SAE wpa_pairwise=CCMP rsn_pairwise=CCMP wpa_passphrase=${WIFI_PASSWORD} sae_require_mfp=1 # IEEE 802.11n (2.4GHz) ht_capab=[HT40+][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40] ieee80211n=1 # IEEE 802.11ac (5GHz) ieee80211ac=1 vht_oper_chwidth=1 vht_capab=[MAX-MPDU-11454][SHORT-GI-80][TX-STBC-2BY1][RX-STBC-1] vht_oper_centr_freq_seg0_idx=42 # IEEE 802.11ax (Wi-Fi 6) ieee80211ax=1 he_oper_chwidth=1 he_oper_centr_freq_seg0_idx=42 # Multiple BSSID για guest network bss=${WIFI_INTERFACE}_guest bssid=02:00:00:00:00:01 ssid=CyberAutonomy-Guest wpa_key_mgmt=WPA-PSK wpa_passphrase=${GUEST_PASSWORD} wpa_pairwise=CCMP rsn_pairwise=CCMP ignore_broadcast_ssid=1 # QoS και traffic shaping wmm_enabled=1 wmm_ac_bk_cwmin=4 wmm_ac_bk_cwmax=10 wmm_ac_bk_aifs=7 wmm_ac_bk_txop_limit=0 wmm_ac_bk_acm=0 # AirTime Fairness airtime_mode=1 airtime_update_interval=100 # Client isolation για guest network ap_isolate=1 # RADIUS authentication (προαιρετικό) #auth_server_addr=192.168.100.1 #auth_server_port=1812 #auth_server_shared_secret=${RADIUS_SECRET} EOF # Ενεργοποίηση hostapd sudo systemctl unmask hostapd sudo systemctl enable hostapd sudo systemctl start hostapd Προχωρημένο Configuration για Multi-SSID: ini # /etc/hostapd/hostapd-multi.conf # Κυρίως δίκτυο - Υψηλή ασφάλεια interface=wlan0 driver=nl80211 ssid=CyberAutonomy-Secure hw_mode=a channel=36 wpa=2 wpa_key_mgmt=WPA-PSK WPA-EAP wpa_pairwise=CCMP rsn_pairwise=CCMP wpa_passphrase=${SECURE_PASSWORD} ieee80211w=2 # PMF required sae_require_mfp=1 auth_algs=3 # Δεύτερο BSSID για IoT devices bss=wlan0_iot bssid=02:00:00:00:00:02 ssid=CyberAutonomy-IoT wpa_key_mgmt=WPA-PSK wpa_passphrase=${IOT_PASSWORD} wpa_pairwise=TKIP CCMP rsn_pairwise=CCMP macaddr_acl=1 accept_mac_file=/etc/hostapd/hostapd.accept.iot # Guest network με rate limiting bss=wlan0_guest bssid=02:00:00:00:00:03 ssid=CyberAutonomy-Guest wpa_key_mgmt=WPA-PSK wpa_passphrase=${GUEST_PASSWORD} wpa_pairwise=CCMP rsn_pairwise=CCMP ap_isolate=1 client_isolation=1 rate_limit=1000 # 1 Mbps per client # VLAN tagging vlan_file=/etc/hostapd/hostapd.vlan per_sta_vif=1 VLAN Configuration: bash # /etc/hostapd/hostapd.vlan # VLAN mapping per BSSID 02:00:00:00:00:01 10 # Secure - VLAN 10 02:00:00:00:00:02 20 # IoT - VLAN 20 02:00:00:00:00:03 30 # Guest - VLAN 30 * br0 # Default bridge 6.2.3 Σύστημα Radio Resource Management Dynamic Channel Selection Script: python #!/usr/bin/env python3 # auto-channel-select.py import subprocess import json import numpy as np from datetime import datetime, timedelta import sqlite3 class ChannelOptimizer: def __init__(self, interface="wlan0"): self.interface = interface self.db_conn = sqlite3.connect('/var/lib/wifi/channel_stats.db') self.init_database() def init_database(self): """Αρχικοποίηση βάσης για ιστορικό channels""" cursor = self.db_conn.cursor() cursor.execute(''' CREATE TABLE IF NOT EXISTS channel_quality ( timestamp DATETIME, channel INTEGER, frequency INTEGER, noise REAL, utilization REAL, clients INTEGER, PRIMARY KEY (timestamp, channel) ) ''') self.db_conn.commit() def scan_channels(self): """Σάρωση όλων των καναλιών για interference""" channels = {} # Σάρωση με iw for freq in [2412, 2437, 2462, 5180, 5200, 5220, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700]: try: # Μετατροπή συχνότητας σε channel if 2400 <= freq < 2500: channel = (freq - 2407) / 5 else: channel = (freq - 5000) / 5 # Σάρωση καναλιού cmd = f"sudo iw dev {self.interface} scan freq {freq} duration 100" result = subprocess.run(cmd, shell=True, capture_output=True, text=True) # Ανάλυση αποτελεσμάτων noise = self.extract_noise_level(result.stdout) utilization = self.calculate_utilization(result.stdout) clients = self.count_clients(result.stdout) channels[channel] = { 'frequency': freq, 'noise': noise, 'utilization': utilization, 'clients': clients, 'score': self.calculate_score(noise, utilization, clients) } # Αποθήκευση στη βάση self.save_to_db(channel, freq, noise, utilization, clients) except Exception as e: print(f"Error scanning channel {channel}: {e}") return channels def calculate_score(self, noise, utilization, clients): """Υπολογισμός score για κανάλι (υψηλότερο = καλύτερο)""" # Βάρη: noise 40%, utilization 40%, clients 20% noise_score = max(0, 100 - abs(noise + 95) * 2) # -95dBm ιδανικό util_score = max(0, 100 - utilization * 100) client_score = max(0, 100 - clients * 10) total_score = (noise_score * 0.4 + util_score * 0.4 + client_score * 0.2) return total_score def select_best_channel(self, band='5GHz'): """Επιλογή βέλτιστου καναλιού βάσει ιστορικού""" cursor = self.db_conn.cursor() if band == '5GHz': cursor.execute(''' SELECT channel, AVG(noise) as avg_noise, AVG(utilization) as avg_util, COUNT(DISTINCT timestamp) as samples FROM channel_quality WHERE frequency >= 5180 AND timestamp > datetime('now', '-1 hour') GROUP BY channel ORDER BY (100 - avg_noise) * 0.5 + (100 - avg_util * 100) * 0.5 DESC ''') else: cursor.execute(''' SELECT channel, AVG(noise) as avg_noise, AVG(utilization) as avg_util, COUNT(DISTINCT timestamp) as samples FROM channel_quality WHERE frequency BETWEEN 2412 AND 2484 AND timestamp > datetime('now', '-1 hour') GROUP BY channel ORDER BY (100 - avg_noise) * 0.5 + (100 - avg_util * 100) * 0.5 DESC ''') results = cursor.fetchall() if results: best_channel = results[0][0] return int(best_channel) # Default channels αν δεν υπάρχουν δεδομένα return 36 if band == '5GHz' else 6 def apply_channel(self, channel, interface='wlan0'): """Εφαρμογή νέου καναλιού""" # Μετατροπή channel σε συχνότητα if 1 <= channel <= 13: frequency = 2407 + (channel * 5) elif 36 <= channel <= 165: frequency = 5180 + ((channel - 36) * 20) else: frequency = 5180 # default 5GHz # Εφαρμογή νέου καναλιού cmd = f"sudo hostapd_cli -i {interface} chan_switch 1 {frequency}" subprocess.run(cmd, shell=True) print(f"Changed {interface} to channel {channel} ({frequency}MHz)") def extract_noise_level(self, scan_output): """Εξαγωγή επιπέδου θορύβου από scan""" lines = scan_output.split('\n') for line in lines: if 'noise:' in line: try: noise = float(line.split(':')[1].strip().split()[0]) return noise except: pass return -95.0 # Default def calculate_utilization(self, scan_output): """Υπολογισμός αξιοποίησης καναλιού""" # Αυτός είναι ένας απλοποιημένος αλγόριθμος # Στην πράξη θα χρησιμοποιούσατε πιο προχωρημένες μεθόδους lines = scan_output.split('\n') bss_count = 0 for line in lines: if 'BSS' in line: bss_count += 1 # Normalize: περισσότερα BSS = υψηλότερη αξιοποίηση utilization = min(1.0, bss_count / 20.0) return utilization def count_clients(self, scan_output): """Μέτρηση συνδεδεμένων clients""" lines = scan_output.split('\n') client_count = 0 in_station = False for line in lines: if 'Station' in line and 'signal:' in line: client_count += 1 return client_count def save_to_db(self, channel, frequency, noise, utilization, clients): """Αποθήκευση μετρήσεων στη βάση""" cursor = self.db_conn.cursor() cursor.execute(''' INSERT INTO channel_quality (timestamp, channel, frequency, noise, utilization, clients) VALUES (datetime('now'), ?, ?, ?, ?, ?) ''', (channel, frequency, noise, utilization, clients)) self.db_conn.commit() # Κυρίως εκτέλεση if __name__ == "__main__": optimizer = ChannelOptimizer() # Σάρωση τρεχουσών συνθηκών channels = optimizer.scan_channels() # Επιλογή καλύτερων καναλιών για κάθε band best_24 = optimizer.select_best_channel('2.4GHz') best_5 = optimizer.select_best_channel('5GHz') print(f"Βέλτιστο 2.4GHz channel: {best_24}") print(f"Βέλτιστο 5GHz channel: {best_5}") # Εφαρμογή καναλιών (αν χρειάζεται αλλαγή) # optimizer.apply_channel(best_5, 'wlan0') # optimizer.apply_channel(best_24, 'wlan1') # αν υπάρχει δεύτερη κάρτα 6.3 Σύνθετο Σύστημα DNS και DHCP 6.3.1 Υβριδική Αρχιτεκτονική DNS Πλήρης DNS Infrastructure: text ΕΠΙΠΕΔΟ 1: LOCAL AUTHORITY ├── Unbound: Recursive resolver με DNSSEC ├── dnsmasq: Caching και local records ├── Πλατφόρμα: Docker containers με redundancy └── Monitoring: DNS query logging και analysis ΕΠΙΠΕΔΟ 2: DYNAMIC DNS ├── nsupdate: Dynamic updates για εσωτερικές συσκευές ├── API: REST interface για service discovery └── Database: SQLite για zone management ΕΠΙΠΕΔΟ 3: ADVANCED FEATURES ├── DNS-over-TLS/HTTPS: Ενκρυπτωμένα queries ├── Response Policy Zones: Content filtering ├── Query Logging: Στατιστικά και ανάλυση └── High Availability: Anycast DNS με keepalived 6.3.2 Προχωρημένη Ρύθμιση Unbound Unbound Configuration με DNSSEC και DoT: yaml # /etc/unbound/unbound.conf.d/advanced.conf server: # Διεπαφές και θύρες interface: 192.168.100.1 interface: ::1 port: 53 do-ip4: yes do-ip6: yes do-udp: yes do-tcp: yes # DNS-over-TLS tls-service-key: "/etc/unbound/unbound_server.key" tls-service-pem: "/etc/unbound/unbound_server.pem" tls-port: 853 tls-cert-bundle: "/etc/ssl/certs/ca-certificates.crt" # Πρόσβαση και ασφάλεια access-control: 192.168.100.0/24 allow access-control: 127.0.0.0/8 allow access-control: ::1/128 allow # Privacy options hide-identity: yes hide-version: yes identity: "CyberAutonomy DNS" version: "DNS Server" # Hardening harden-glue: yes harden-dnssec-stripped: yes harden-referral-path: yes use-caps-for-id: yes cache-min-ttl: 3600 cache-max-ttl: 86400 prefetch: yes prefetch-key: yes # Επιδόσεις num-threads: 4 msg-cache-size: 100m rrset-cache-size: 200m key-cache-size: 50m neg-cache-size: 10m so-rcvbuf: 4m so-sndbuf: 4m so-reuseport: yes # DNSSEC auto-trust-anchor-file: "/var/lib/unbound/root.key" val-clean-additional: yes val-permissive-mode: no # Query minimization qname-minimisation: yes qname-minimisation-strict: yes # Aggressive NSEC aggressive-nsec: yes # Local zones και overrides local-zone: "local." static local-data: "wiki.local. IN A 192.168.100.1" local-data: "maps.local. IN A 192.168.100.1" local-data: "portal.local. IN A 192.168.100.1" local-data: "search.local. IN A 192.168.100.1" local-data: 'wiki.local. IN TXT "CyberAutonomy Wikipedia Server"' # Blocklists (προαιρετικό) include: /etc/unbound/blocklist.conf # Logging verbosity: 1 logfile: "/var/log/unbound/unbound.log" log-time-ascii: yes statistics-interval: 3600 statistics-cumulative: yes # Remote control remote-control: control-enable: yes control-interface: 127.0.0.1 control-port: 8953 control-use-cert: no server-key-file: "/etc/unbound/unbound_server.key" server-cert-file: "/etc/unbound/unbound_server.pem" # Forwarders για εξωτερικά queries (αν είναι διαθέσιμο internet) forward-zone: name: "." forward-tls-upstream: yes forward-addr: 1.1.1.1@853#cloudflare-dns.com forward-addr: 8.8.8.8@853#dns.google forward-addr: 9.9.9.9@853#dns.quad9.net Dynamic DNS Update Script: python #!/usr/bin/env python3 # dynamic-dns-manager.py import sqlite3 import json import hashlib from datetime import datetime import subprocess import socket import netifaces class DynamicDNSManager: def __init__(self, db_path='/var/lib/dns/dynamic_dns.db'): self.db_path = db_path self.init_database() def init_database(self): """Αρχικοποίηση βάσης για dynamic DNS""" conn = sqlite3.connect(self.db_path) cursor = conn.cursor() # Πίνακας για συσκευές cursor.execute(''' CREATE TABLE IF NOT EXISTS devices ( mac_address TEXT PRIMARY KEY, hostname TEXT NOT NULL, ip_address TEXT, last_seen DATETIME, first_seen DATETIME, device_type TEXT, owner TEXT, lease_time INTEGER DEFAULT 86400, dns_record TEXT, is_active INTEGER DEFAULT 1 ) ''') # Πίνακας για DNS records cursor.execute(''' CREATE TABLE IF NOT EXISTS dns_records ( record_id INTEGER PRIMARY KEY AUTOINCREMENT, hostname TEXT NOT NULL, record_type TEXT DEFAULT 'A', record_value TEXT, ttl INTEGER DEFAULT 300, created DATETIME, updated DATETIME, is_active INTEGER DEFAULT 1, UNIQUE(hostname, record_type) ) ''') # Πίνακας για lease history cursor.execute(''' CREATE TABLE IF NOT EXISTS lease_history ( lease_id INTEGER PRIMARY KEY AUTOINCREMENT, mac_address TEXT, ip_address TEXT, start_time DATETIME, end_time DATETIME, hostname TEXT, FOREIGN KEY (mac_address) REFERENCES devices(mac_address) ) ''') conn.commit() conn.close() def register_device(self, mac, hostname, ip=None, device_type='unknown'): """Εγγραφή νέας συσκευής""" conn = sqlite3.connect(self.db_path) cursor = conn.cursor() # Έλεγχος αν υπάρχει ήδη cursor.execute('SELECT * FROM devices WHERE mac_address = ?', (mac,)) existing = cursor.fetchone() now = datetime.now().isoformat() if existing: # Ενημέρωση υπάρχοντος cursor.execute(''' UPDATE devices SET hostname = ?, ip_address = ?, last_seen = ?, device_type = ? WHERE mac_address = ? ''', (hostname, ip, now, device_type, mac)) else: # Νέα εγγραφή cursor.execute(''' INSERT INTO devices (mac_address, hostname, ip_address, first_seen, last_seen, device_type) VALUES (?, ?, ?, ?, ?, ?) ''', (mac, hostname, ip, now, now, device_type)) # Δημιουργία DNS record if ip: self.create_dns_record(hostname, ip) conn.commit() # Ενημέρωση DHCP lease file self.update_dhcp_leases() # Ενημέρωση DNS zone self.update_dns_zone() conn.close() return True def create_dns_record(self, hostname, ip, record_type='A', ttl=300): """Δημιουργία DNS record""" conn = sqlite3.connect(self.db_path) cursor = conn.cursor() now = datetime.now().isoformat() cursor.execute(''' INSERT OR REPLACE INTO dns_records (hostname, record_type, record_value, ttl, created, updated) VALUES (?, ?, ?, ?, ?, ?) ''', (hostname, record_type, ip, ttl, now, now)) conn.commit() conn.close() return True def update_dhcp_leases(self): """Ενημέρωση αρχείου DHCP leases""" conn = sqlite3.connect(self.db_path) cursor = conn.cursor() cursor.execute(''' SELECT mac_address, hostname, ip_address, lease_time FROM devices WHERE is_active = 1 AND ip_address IS NOT NULL ''') devices = cursor.fetchall() leases_content = "# Static DHCP leases\n" for mac, hostname, ip, lease_time in devices: leases_content += f"dhcp-host={mac},{hostname},{ip},{lease_time}h\n" # Εγγραφή στο αρχείο with open('/etc/dnsmasq.d/static-leases.conf', 'w') as f: f.write(leases_content) # Reload dnsmasq subprocess.run(['systemctl', 'reload', 'dnsmasq']) conn.close() def update_dns_zone(self): """Ενημέρωση DNS zone file""" conn = sqlite3.connect(self.db_path) cursor = conn.cursor() cursor.execute(''' SELECT hostname, record_type, record_value, ttl FROM dns_records WHERE is_active = 1 ORDER BY hostname, record_type ''') records = cursor.fetchall() zone_content = """$ORIGIN local. $TTL 3600 @ IN SOA ns1.local. admin.local. ( %s ; serial 3600 ; refresh 1800 ; retry 604800 ; expire 3600 ; minimum TTL ) @ IN NS ns1.local. ns1 IN A 192.168.100.1 ; Static records wiki IN A 192.168.100.1 maps IN A 192.168.100.1 portal IN A 192.168.100.1 search IN A 192.168.100.1 ; Dynamic records """ % datetime.now().strftime('%Y%m%d%H') current_hostname = None for hostname, record_type, value, ttl in records: if hostname != current_hostname: zone_content += f"\n; {hostname}\n" current_hostname = hostname zone_content += f"{hostname} {ttl} IN {record_type} {value}\n" # Εγγραφή zone file with open('/var/lib/unbound/local.zone', 'w') as f: f.write(zone_content) # Reload unbound subprocess.run(['systemctl', 'reload', 'unbound']) conn.close() def scan_network(self): """Αυτόματη σάρωση δικτύου για συσκευές""" import nmap nm = nmap.PortScanner() # Σάρωση LAN nm.scan(hosts='192.168.100.0/24', arguments='-sn') for host in nm.all_hosts(): if 'mac' in nm[host]['addresses']: mac = nm[host]['addresses']['mac'] ip = nm[host]['addresses']['ipv4'] # Προσπάθεια ανάκτησης hostname try: hostname = socket.gethostbyaddr(ip)[0] except: hostname = f"device-{mac.replace(':', '')[:8]}" # Καθορισμός τύπου συσκευής από MAC OUI device_type = self.detect_device_type(mac) # Εγγραφή συσκευής self.register_device(mac, hostname, ip, device_type) def detect_device_type(self, mac): """Ανίχνευση τύπου συσκευής από MAC address""" # Πρώτα 3 bytes (OUI) καθορίζουν τον κατασκευαστή oui = mac[:8].upper() # Γνωστά OUI device_types = { '00:1A:11': 'Cisco', '00:0C:29': 'VMware', '00:50:56': 'VMware', '00:1B:63': 'Apple', '00:1E:52': 'Apple', '00:23:DF': 'Apple', '00:25:BC': 'Apple', '00:26:BB': 'Apple', '00:26:08': 'Samsung', '00:17:88': 'Philips Hue', '34:CE:00': 'Raspberry Pi', 'B8:27:EB': 'Raspberry Pi', 'DC:A6:32': 'Raspberry Pi', } for prefix, manufacturer in device_types.items(): if oui.startswith(prefix): return manufacturer return 'unknown' # Κυρίως εκτέλεση if __name__ == "__main__": dns_manager = DynamicDNSManager() # Σάρωση δικτύου dns_manager.scan_network() # Ενημέρωση DHCP και DNS dns_manager.update_dhcp_leases() dns_manager.update_dns_zone() 6.3.3 Προχωρημένο DHCP Server Configuration ISC DHCP Server με Advanced Features: bash # /etc/dhcp/dhcpd.conf # Global configuration option domain-name "local"; option domain-name-servers 192.168.100.1; option routers 192.168.100.1; option broadcast-address 192.168.100.255; default-lease-time 3600; max-lease-time 7200; authoritative; # Logging log-facility local7; # DDNS updates ddns-update-style interim; ddns-domainname "local."; ddns-rev-domainname "in-addr.arpa."; # Zone για dynamic updates zone local. { primary 127.0.0.1; key rndc-key; } zone 100.168.192.in-addr.arpa. { primary 127.0.0.1; key rndc-key; } # Key για DDNS updates key rndc-key { algorithm hmac-sha256; secret "${RNDC_SECRET}"; } # Subnet configuration subnet 192.168.100.0 netmask 255.255.255.0 { range 192.168.100.100 192.168.100.200; # Static routes (αν χρειάζονται) # option rfc3442-classless-static-routes 24, 192, 168, 100, 192, 168, 100, 1; # Vendor classes για συγκεκριμένες συσκευές class "RaspberryPi" { match if substring(hardware, 1, 3) = 34:ce:00 or substring(hardware, 1, 3) = b8:27:eb or substring(hardware, 1, 3) = dc:a6:32; } subclass "RaspberryPi" 1:34:ce:00:00:00; subclass "RaspberryPi" 1:b8:27:eb:00:00; subclass "RaspberryPi" 1:dc:a6:32:00:00; pool { allow members of "RaspberryPi"; range 192.168.100.50 192.168.100.60; option host-name = concat("raspberrypi-", binary-to-ascii(16, 8, ":", substring(hardware, 1, 6))); } # IoT devices pool class "IoT-Devices" { match if substring(hardware, 1, 3) = 00:17:88 or # Philips Hue substring(hardware, 1, 3) = 18:b4:30 or # Tuya substring(hardware, 1, 3) = 34:ce:00; # ESP devices } pool { allow members of "IoT-Devices"; range 192.168.100.61 192.168.100.80; option routers 192.168.100.1; option domain-name-servers 192.168.100.1; } # Guest network pool (διαφορετικό VLAN) shared-network "Guest-VLAN" { subnet 192.168.101.0 netmask 255.255.255.0 { authoritative; range 192.168.101.100 192.168.101.150; option routers 192.168.101.1; option domain-name-servers 192.168.100.1; option broadcast-address 192.168.101.255; # Client isolation deny unknown-clients; deny bootp; # Rate limiting max-lease-time 1800; # 30 minutes για guests } } # Static leases from database include "/etc/dhcp/static-leases.conf"; # Failover configuration (αν έχουμε δεύτερο server) # failover peer "dhcp-failover" { # primary; # address 192.168.100.1; # port 647; # peer address 192.168.100.2; # peer port 647; # max-response-delay 30; # max-unacked-updates 10; # load balance max seconds 3; # } } # Host declarations για συγκεκριμένες συσκευές host server { hardware ethernet ${SERVER_MAC}; fixed-address 192.168.100.1; option host-name "cyberautonomy"; } host admin-laptop { hardware ethernet ${ADMIN_MAC}; fixed-address 192.168.100.10; option host-name "admin-pc"; } # Αποθήκευση leases στη βάση δεδομένων lease-file-name "/var/lib/dhcp/dhcpd.leases"; persistent; one-lease-per-client true; 6.4 Προηγμένο Firewall και Network Security 6.4.1 nftables Configuration με Stateful Inspection Πλήρης nftables Configuration: bash #!/bin/bash # setup-advanced-firewall.sh # Καθαρισμός existing rules nft flush ruleset # Ορισμός tables και chains nft add table inet firewall nft add chain inet firewall input { type filter hook input priority 0\; policy drop\; } nft add chain inet firewall forward { type filter hook forward priority 0\; policy drop\; } nft add chain inet firewall output { type filter hook output priority 0\; policy accept\; } # Set definitions nft add set inet firewall whitelist_ipv4 { type ipv4_addr\; flags timeout\; } nft add set inet firewall whitelist_ipv6 { type ipv6_addr\; flags timeout\; } nft add set inet firewall blacklist { type ipv4_addr\; flags timeout\; } nft add set inet firewall admin_macs { type ether_addr\; } # Προσθήκη διευθύνσεων στις whitelists nft add element inet firewall whitelist_ipv4 { 192.168.100.0/24 } nft add element inet firewall whitelist_ipv4 { 127.0.0.1 } nft add element inet firewall admin_macs { ${ADMIN_MAC_1}, ${ADMIN_MAC_2} } # Connection tracking nft add chain inet firewall connection_tracking nft add rule inet firewall connection_tracking ct state established,related accept nft add rule inet firewall connection_tracking ct state invalid drop # Rate limiting για DoS protection nft add chain inet firewall dos_protection nft add rule inet firewall dos_protection ip protocol tcp ct state new \ limit rate over 10/minute burst 5 packets drop nft add rule inet firewall dos_protection ip protocol udp \ limit rate over 1000/minute burst 100 packets drop # INPUT chain rules # Τοπική loopback nft add rule inet firewall input iif lo accept # ICMP (ping) nft add rule inet firewall input ip protocol icmp icmp type { echo-request, echo-reply, destination-unreachable, time-exceeded } accept nft add rule inet firewall input ip6 nexthdr icmpv6 icmpv6 type { echo-request, echo-reply, destination-unreachable, time-exceeded } accept # Established connections nft add rule inet firewall input ct state established,related accept # SSH access (μόνο από admin MACs και whitelist IPs) nft add rule inet firewall input tcp dport 22 ip saddr @whitelist_ipv4 ether saddr @admin_macs accept nft add rule inet firewall input tcp dport 2222 ip saddr @whitelist_ipv4 ether saddr @admin_macs accept # DNS nft add rule inet firewall input udp dport 53 accept nft add rule inet firewall input tcp dport 53 accept nft add rule inet firewall input udp dport 853 accept # DNS-over-TLS nft add rule inet firewall input tcp dport 853 accept # DHCP nft add rule inet firewall input udp dport 67-68 accept # HTTP/HTTPS services nft add rule inet firewall input tcp dport 80 accept nft add rule inet firewall input tcp dport 443 accept nft add rule inet firewall input tcp dport 8080 accept # Kiwix nft add rule inet firewall input tcp dport 8081 accept # Maps # VPN (WireGuard) nft add rule inet firewall input udp dport 51820 accept # NTP nft add rule inet firewall input udp dport 123 accept # Monitoring (Prometheus, Grafana) nft add rule inet firewall input tcp dport 9090 ip saddr 192.168.100.0/24 accept nft add rule inet firewall input tcp dport 3000 ip saddr 192.168.100.0/24 accept # Drop invalid packets nft add rule inet firewall input ct state invalid drop # Logging για αποτυχημένες συνδέσεις nft add rule inet firewall input log prefix "DROP-INPUT: " group 0 # FORWARD chain rules (για routing και NAT) # Allow forwarding εντός LAN nft add rule inet firewall forward ip saddr 192.168.100.0/24 ip daddr 192.168.100.0/24 accept # NAT rules nft add table ip nat nft add chain ip nat prerouting { type nat hook prerouting priority 0\; } nft add chain ip nat postrouting { type nat hook postrouting priority 100\; } # MASQUERADE για εξωτερική σύνδεση nft add rule ip nat postrouting ip saddr 192.168.100.0/24 oif eth0 masquerade # Port forwarding (παραδείγματα) nft add rule ip nat prerouting iif eth0 tcp dport 80 dnat to 192.168.100.1:80 nft add rule ip nat prerouting iif eth0 tcp dport 443 dnat to 192.168.100.1:443 # QoS και traffic shaping nft add table ip mangle nft add chain ip mangle prerouting { type filter hook prerouting priority -150\; } nft add chain ip mangle output { type route hook output priority -150\; } # Διαφορετική QoS για διαφορετικές υπηρεσίες nft add rule ip mangle prerouting ip daddr 192.168.100.1 tcp dport {80, 443} meta priority set 1:1 nft add rule ip mangle prerouting ip daddr 192.168.100.1 tcp dport {8080, 8081} meta priority set 1:2 nft add rule ip mangle prerouting ip daddr 192.168.100.1 udp dport 53 meta priority set 1:3 # Συμφραζόμενα για Dynamic Blacklisting nft add chain inet firewall blacklist_chain nft add rule inet firewall blacklist_chain ip saddr @blacklist drop nft add rule inet firewall blacklist_chain ip6 saddr @blacklist drop # IPS/IDS integration nft add chain inet firewall ids_alert nft add rule inet firewall ids_alert log prefix "IDS-ALERT: " group 0 nft add rule inet firewall ids_alert reject with icmp type admin-prohibited # Αποθήκευση ruleset nft list ruleset > /etc/nftables.conf # Ενεργοποίηση κατά την εκκίνηση systemctl enable nftables systemctl start nftables 6.4.2 Suricata IDS/IPS Integration Suricata Configuration για Home Network: yaml # /etc/suricata/suricata.yaml # Network configuration vars: address-groups: HOME_NET: "[192.168.100.0/24]" EXTERNAL_NET: "!$HOME_NET" port-groups: HTTP_PORTS: "80" HTTPS_PORTS: "443" SSH_PORTS: "22" DNS_PORTS: "53" # Logging outputs: - fast: enabled: yes filename: fast.log append: yes - eve-log: enabled: yes filetype: regular filename: eve.json types: - alert: payload: yes http-body: yes http-body-printable: yes - http: extended: yes - dns: version: 2 - tls: extended: yes # Rules configuration default-rule-path: /var/lib/suricata/rules rule-files: - suricata.rules - emerging-threats.rules - tls-events.rules - http-events.rules # Performance tuning max-pending-packets: 1024 runmode: workers detect-engine: - profile: high - sgh-mpm-context: full # Network interface af-packet: - interface: eth0 cluster-id: 99 cluster-type: cluster_flow defrag: yes use-mmap: yes tpacket-v3: yes # App-layer protocols app-layer: protocols: tls: enabled: yes detection-ports: dp: 443 http: enabled: yes dns: enabled: yes ssh: enabled: yes # Threading threading: set-cpu-affinity: yes cpu-affinity: - management-cpu-set: cpu: [0] - receive-cpu-set: cpu: [1] - worker-cpu-set: cpu: [2, 3, 4, 5] mode: "balanced" # Advanced settings defrag: memcap: 256mb hash-size: 65536 flow: memcap: 256mb hash-size: 131072 # Streaming API stream: memcap: 256mb Suricata Rules Management Script: bash #!/bin/bash # update-suricata-rules.sh RULES_DIR="/var/lib/suricata/rules" ET_URL="https://rules.emergingthreats.net/open/suricata-5.0/emerging.rules.tar.gz" GITOCAL_URL="https://raw.githubusercontent.com/giterlizzi/nagios-logwatch/master/etc/suricata/rules/gitolocal.rules" # Κατέβασμα Emerging Threats rules wget -qO /tmp/emerging.rules.tar.gz $ET_URL tar -xzf /tmp/emerging.rules.tar.gz -C $RULES_DIR # Κατέβασμα custom rules wget -qO $RULES_DIR/gitolocal.rules $GITOCAL_URL # Custom rules για home network cat > $RULES_DIR/local.rules << 'EOF' # Προσαρμοσμένοι κανόνες για CyberAutonomy network # Alert για port scanning alert ip any any -> $HOME_NET any (msg:"ET SCAN Potential Port Scan"; flow:to_server; flags:S,12; threshold: type both, track by_src, count 5, seconds 60; sid:1000001; rev:1;) # Alert για πολλά failed SSH attempts alert tcp $EXTERNAL_NET any -> $HOME_NET $SSH_PORTS (msg:"ET POLICY Multiple Failed SSH Connections"; flow:to_server; flags:S,12; threshold: type both, track by_src, count 5, seconds 60; sid:1000002; rev:1;) # Προστασία από DNS amplification alert udp $HOME_NET any -> any 53 (msg:"ET DOS Possible DNS Amplification Attack"; dsize:>512; sid:1000003; rev:1;) # Ανίχνευση IoT device anomalies alert tcp $HOME_NET any -> any any (msg:"LOCAL IoT Device Beaconing"; flow:to_server; content:"|55 4d 31 2e 30|"; sid:1000004; rev:1;) # Tuya devices # HTTP attacks against local services alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORTS (msg:"LOCAL HTTP Attack Attempt"; flow:to_server; content:"/etc/passwd"; http_uri; sid:1000005; rev:1;) # WiFi deauth attacks detection alert tcp any any -> any any (msg:"LOCAL WiFi Deauth Attack"; content:"|c0 00|"; depth:2; offset:30; sid:1000006; rev:1;) # Ρυθμίσεις για rate limiting alerts alert ip any any -> $HOME_NET any (msg:"LOCAL High Rate Traffic"; threshold: type threshold, track by_src, count 1000, seconds 1; sid:1000007; rev:1;) EOF # Ενημέρωση rule files index echo "local.rules" > $RULES_DIR/suricata.rules echo "gitolocal.rules" >> $RULES_DIR/suricata.rules echo "emerging.rules" >> $RULES_DIR/suricata.rules # Επαλήθευση κανόνων suricata -T -c /etc/suricata/suricata.yaml # Επανεκκίνηση Suricata systemctl restart suricata # Δημιουργία report echo "Suricata rules updated: $(date)" >> /var/log/suricata/update.log echo "Active rules: $(grep -c '^alert' $RULES_DIR/suricata.rules)" >> /var/log/suricata/update.log 6.5 WireGuard VPN: Site-to-Site και Remote Access 6.5.1 Προχωρημένη WireGuard Configuration Πλήρες WireGuard Setup με Multiple Peers: bash #!/bin/bash # setup-wireguard-advanced.sh # Εγκατάσταση apt update && apt install -y wireguard wireguard-tools qrencode # Δημιουργία κλειδιών mkdir -p /etc/wireguard/keys cd /etc/wireguard/keys # Server keys wg genkey | tee server_private.key | wg pubkey > server_public.key wg genpsk > server_psk.key # Client keys (παράδειγμα για 3 clients) for i in {1..3}; do wg genkey | tee client${i}_private.key | wg pubkey > client${i}_public.key done # Server configuration cat > /etc/wireguard/wg0.conf << EOF [Interface] Address = 10.10.0.1/24 ListenPort = 51820 PrivateKey = $(cat server_private.key) PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE MTU = 1420 # Peer 1: Admin laptop [Peer] PublicKey = $(cat client1_public.key) PresharedKey = $(cat server_psk.key) AllowedIPs = 10.10.0.2/32, 192.168.100.0/24 PersistentKeepalive = 25 # Peer 2: Mobile phone [Peer] PublicKey = $(cat client2_public.key) PresharedKey = $(cat server_psk.key) AllowedIPs = 10.10.0.3/32 PersistentKeepalive = 25 # Peer 3: Site-to-site (άλλος server) [Peer] PublicKey = $(cat client3_public.key) PresharedKey = $(cat server_psk.key) AllowedIPs = 10.10.0.4/32, 192.168.200.0/24 PersistentKeepalive = 25 EOF # Client configurations for i in {1..3}; do cat > /etc/wireguard/client${i}.conf << EOF [Interface] Address = 10.10.0.$((i+1))/32 PrivateKey = $(cat client${i}_private.key) DNS = 192.168.100.1 MTU = 1420 [Peer] PublicKey = $(cat server_public.key) PresharedKey = $(cat server_psk.key) Endpoint = ${SERVER_PUBLIC_IP}:51820 AllowedIPs = 0.0.0.0/0, ::/0 PersistentKeepalive = 25 EOF # Δημιουργία QR code για mobile qrencode -t ansiutf8 < /etc/wireguard/client${i}.conf done # Firewall rules για WireGuard nft add rule inet firewall input udp dport 51820 accept # Ενεργοποίηση IP forwarding echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf echo "net.ipv6.conf.all.forwarding=1" >> /etc/sysctl.conf sysctl -p # Ενεργοποίηση service systemctl enable wg-quick@wg0 systemctl start wg-quick@wg0 # Monitoring script cat > /usr/local/bin/wireguard-monitor.sh << 'EOF' #!/bin/bash LOG_FILE="/var/log/wireguard-status.log" # Λήψη status status=$(wg show wg0) echo "=== WireGuard Status $(date) ===" >> $LOG_FILE echo "$status" >> $LOG_FILE echo "================================" >> $LOG_FILE # Ανίχνευση offline peers offline_peers=$(echo "$status" | grep -A2 "peer:" | grep -B1 "latest handshake" | grep -A1 "peer:" | grep -v "endpoint" | awk '/peer:/{peer=$2} /latest handshake:/{print peer, $3}' | awk '$2 == "" {print $1}') if [ -n "$offline_peers" ]; then echo "Offline peers detected: $offline_peers" >> $LOG_FILE # Μπορείτε να στείλετε notification εδώ fi EOF chmod +x /usr/local/bin/wireguard-monitor.sh # Cron job για monitoring echo "*/5 * * * * root /usr/local/bin/wireguard-monitor.sh" > /etc/cron.d/wireguard-monitor 6.5.2 WireGuard Web Interface Python Web UI για WireGuard Management: python #!/usr/bin/env python3 # wireguard-webui.py from flask import Flask, render_template, request, jsonify, send_file import subprocess import json import os import qrcode import io import sqlite3 from datetime import datetime app = Flask(__name__) WG_DIR = "/etc/wireguard" DB_PATH = "/var/lib/wireguard/wg.db" def init_database(): """Αρχικοποίηση βάσης για WireGuard peers""" conn = sqlite3.connect(DB_PATH) cursor = conn.cursor() cursor.execute(''' CREATE TABLE IF NOT EXISTS peers ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, public_key TEXT UNIQUE, private_key TEXT, preshared_key TEXT, ip_address TEXT, created_at DATETIME, last_seen DATETIME, is_active INTEGER DEFAULT 1, allowed_ips TEXT, description TEXT ) ''') cursor.execute(''' CREATE TABLE IF NOT EXISTS traffic_logs ( id INTEGER PRIMARY KEY AUTOINCREMENT, peer_id INTEGER, timestamp DATETIME, rx_bytes INTEGER, tx_bytes INTEGER, FOREIGN KEY (peer_id) REFERENCES peers(id) ) ''') conn.commit() conn.close() @app.route('/') def index(): """Κύρια σελίδα""" return render_template('index.html') @app.route('/api/status') def get_status(): """Λήψη WireGuard status""" try: result = subprocess.run(['wg', 'show', 'wg0'], capture_output=True, text=True) return jsonify({'status': 'success', 'data': result.stdout}) except Exception as e: return jsonify({'status': 'error', 'message': str(e)}) @app.route('/api/peers') def get_peers(): """Λήψη λίστας peers""" conn = sqlite3.connect(DB_PATH) cursor = conn.cursor() cursor.execute(''' SELECT id, name, ip_address, created_at, last_seen, is_active, description FROM peers ORDER BY created_at DESC ''') peers = [] for row in cursor.fetchall(): peer = { 'id': row[0], 'name': row[1], 'ip': row[2], 'created': row[3], 'last_seen': row[4], 'active': bool(row[5]), 'description': row[6] } peers.append(peer) conn.close() return jsonify({'status': 'success', 'peers': peers}) @app.route('/api/peers', methods=['POST']) def create_peer(): """Δημιουργία νέου peer""" data = request.json # Δημιουργία κλειδιών private_key = subprocess.run(['wg', 'genkey'], capture_output=True, text=True).stdout.strip() public_key = subprocess.run(['wg', 'pubkey'], input=private_key, capture_output=True, text=True).stdout.strip() preshared_key = subprocess.run(['wg', 'genpsk'], capture_output=True, text=True).stdout.strip() # Καθορισμός IP address conn = sqlite3.connect(DB_PATH) cursor = conn.cursor() cursor.execute('SELECT MAX(ip_address) FROM peers WHERE ip_address LIKE "10.10.0.%"') last_ip = cursor.fetchone()[0] if last_ip: last_num = int(last_ip.split('.')[-1]) new_ip = f"10.10.0.{last_num + 1}" else: new_ip = "10.10.0.2" # Εισαγωγή στη βάση cursor.execute(''' INSERT INTO peers (name, public_key, private_key, preshared_key, ip_address, created_at, allowed_ips, description) VALUES (?, ?, ?, ?, ?, datetime('now'), ?, ?) ''', (data['name'], public_key, private_key, preshared_key, new_ip, data.get('allowed_ips', '0.0.0.0/0'), data.get('description', ''))) peer_id = cursor.lastrowid # Προσθήκη στο WireGuard configuration config_path = f"{WG_DIR}/wg0.conf" with open(config_path, 'a') as f: f.write(f"\n# Peer: {data['name']}\n") f.write(f"[Peer]\n") f.write(f"PublicKey = {public_key}\n") f.write(f"PresharedKey = {preshared_key}\n") f.write(f"AllowedIPs = {new_ip}/32\n") f.write(f"PersistentKeepalive = 25\n") # Reload WireGuard subprocess.run(['wg', 'syncconf', 'wg0', f"{WG_DIR}/wg0.conf"]) conn.commit() conn.close() # Δημιουργία client configuration client_config = f"""[Interface] Address = {new_ip}/32 PrivateKey = {private_key} DNS = 192.168.100.1 MTU = 1420 [Peer] PublicKey = {get_server_public_key()} PresharedKey = {preshared_key} Endpoint = {data['endpoint']} AllowedIPs = 0.0.0.0/0, ::/0 PersistentKeepalive = 25""" return jsonify({ 'status': 'success', 'peer_id': peer_id, 'client_config': client_config }) @app.route('/api/peers//config') def get_peer_config(peer_id): """Λήψη client configuration""" conn = sqlite3.connect(DB_PATH) cursor = conn.cursor() cursor.execute(''' SELECT name, private_key, ip_address, preshared_key FROM peers WHERE id = ? ''', (peer_id,)) row = cursor.fetchone() if not row: return jsonify({'status': 'error', 'message': 'Peer not found'}) name, private_key, ip_address, preshared_key = row client_config = f"""[Interface] Address = {ip_address}/32 PrivateKey = {private_key} DNS = 192.168.100.1 MTU = 1420 [Peer] PublicKey = {get_server_public_key()} PresharedKey = {preshared_key} Endpoint = {request.host.split(':')[0]}:51820 AllowedIPs = 0.0.0.0/0, ::/0 PersistentKeepalive = 25""" conn.close() # Επιστροφή ως αρχείο return send_file( io.BytesIO(client_config.encode()), mimetype='text/plain', as_attachment=True, download_name=f"{name}.conf" ) @app.route('/api/peers//qrcode') def get_peer_qrcode(peer_id): """Δημιουργία QR code για mobile""" conn = sqlite3.connect(DB_PATH) cursor = conn.cursor() cursor.execute(''' SELECT name, private_key, ip_address, preshared_key FROM peers WHERE id = ? ''', (peer_id,)) row = cursor.fetchone() if not row: return jsonify({'status': 'error', 'message': 'Peer not found'}) name, private_key, ip_address, preshared_key = row client_config = f"""[Interface] Address = {ip_address}/32 PrivateKey = {private_key} DNS = 192.168.100.1 MTU = 1420 [Peer] PublicKey = {get_server_public_key()} PresharedKey = {preshared_key} Endpoint = {request.host.split(':')[0]}:51820 AllowedIPs = 0.0.0.0/0, ::/0 PersistentKeepalive = 25""" # Δημιουργία QR code qr = qrcode.QRCode(version=1, box_size=10, border=5) qr.add_data(client_config) qr.make(fit=True) img = qr.make_image(fill_color="black", back_color="white") # Μετατροπή σε bytes img_byte_arr = io.BytesIO() img.save(img_byte_arr, format='PNG') img_byte_arr.seek(0) conn.close() return send_file(img_byte_arr, mimetype='image/png') @app.route('/api/peers/', methods=['DELETE']) def delete_peer(peer_id): """Διαγραφή peer""" conn = sqlite3.connect(DB_PATH) cursor = conn.cursor() # Λήψη public key cursor.execute('SELECT public_key FROM peers WHERE id = ?', (peer_id,)) row = cursor.fetchone() if not row: return jsonify({'status': 'error', 'message': 'Peer not found'}) public_key = row[0] # Αφαίρεση από configuration file config_path = f"{WG_DIR}/wg0.conf" with open(config_path, 'r') as f: lines = f.readlines() # Αφαίρεση του peer από το αρχείο new_lines = [] skip = False for line in lines: if f"PublicKey = {public_key}" in line: skip = True continue if skip and line.strip() == "": skip = False continue if not skip: new_lines.append(line) with open(config_path, 'w') as f: f.writelines(new_lines) # Απενεργοποίηση στη βάση cursor.execute('UPDATE peers SET is_active = 0 WHERE id = ?', (peer_id,)) conn.commit() conn.close() # Reload WireGuard subprocess.run(['wg', 'syncconf', 'wg0', f"{WG_DIR}/wg0.conf"]) return jsonify({'status': 'success'}) def get_server_public_key(): """Λήψη δημόσιου κλειδιού server""" with open(f"{WG_DIR}/keys/server_public.key", 'r') as f: return f.read().strip() if __name__ == '__main__': init_database() app.run(host='0.0.0.0', port=5000, debug=True) 6.6 Service Discovery και Load Balancing 6.6.1 Consul για Dynamic Service Discovery Consul Configuration για Home Network: hcl # /etc/consul.d/consul.hcl datacenter = "cyberautonomy" domain = "consul" data_dir = "/opt/consul" client_addr = "0.0.0.0" bind_addr = "192.168.100.1" # Server mode (single server για home use) server = true bootstrap_expect = 1 ui = true # Service definitions service { name = "wiki" id = "wiki-1" address = "192.168.100.1" port = 8080 checks = [ { id = "wiki-http" name = "Wikipedia HTTP Check" http = "http://192.168.100.1:8080" interval = "10s" timeout = "1s" }, { id = "wiki-tcp" name = "Wikipedia TCP Check" tcp = "192.168.100.1:8080" interval = "10s" timeout = "1s" } ] tags = ["http", "knowledge", "primary"] } service { name = "maps" id = "maps-1" address = "192.168.100.1" port = 8081 checks = [ { http = "http://192.168.100.1:8081" interval = "10s" timeout = "1s" } ] tags = ["http", "maps", "primary"] } service { name = "search" id = "search-1" address = "192.168.100.1" port = 7700 checks = [ { http = "http://192.168.100.1:7700/health" interval = "10s" timeout = "1s" } ] tags = ["http", "search", "primary"] } # DNS configuration dns_config { allow_stale = true max_stale = "30s" node_ttl = "30s" service_ttl = { "*" = "30s" } } # Telemetry telemetry { prometheus_retention_time = "30s" disable_hostname = true } 6.6.2 Traefik με Consul Integration Traefik Configuration για Dynamic Routing: yaml # docker-compose.traefik.yml version: '3.8' services: traefik: image: traefik:v2.10 container_name: traefik ports: - "80:80" - "443:443" - "8080:8080" # Dashboard volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./traefik.yml:/etc/traefik/traefik.yml - ./config.yml:/etc/traefik/config.yml - ./letsencrypt:/letsencrypt networks: - cyber_network restart: unless-stopped consul: image: consul:1.15 container_name: consul volumes: - ./consul/config:/consul/config - consul_data:/consul/data ports: - "8500:8500" command: agent -server -bootstrap-expect=1 -ui -client=0.0.0.0 networks: - cyber_network restart: unless-stopped networks: cyber_network: external: true volumes: consul_data: Traefik Dynamic Configuration: yaml # traefik.yml api: dashboard: true insecure: true entryPoints: web: address: ":80" http: redirections: entryPoint: to: websecure scheme: https websecure: address: ":443" certificatesResolvers: letsencrypt: acme: email: admin@cyberautonomy.local storage: /letsencrypt/acme.json httpChallenge: entryPoint: web providers: docker: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false file: directory: /etc/traefik/config watch: true consulCatalog: endpoint: address: http://consul:8500 prefix: traefik exposedByDefault: false connectAware: true serviceName: traefik refreshInterval: 30s log: level: INFO filePath: /var/log/traefik.log accessLog: filePath: /var/log/access.log bufferingSize: 100 6.7 Network Monitoring και Εποπτεία 6.7.1 Ολοκληρωμένο Monitoring Stack Prometheus + Grafana + Alertmanager: yaml # docker-compose.monitoring.yml version: '3.8' services: prometheus: image: prom/prometheus:latest container_name: prometheus ports: - "9090:9090" volumes: - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml - prometheus_data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--storage.tsdb.retention.time=30d' - '--web.enable-lifecycle' networks: - monitoring_network restart: unless-stopped grafana: image: grafana/grafana:latest container_name: grafana ports: - "3000:3000" environment: - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD} - GF_INSTALL_PLUGINS=grafana-piechart-panel,grafana-clock-panel volumes: - grafana_data:/var/lib/grafana - ./monitoring/dashboards:/etc/grafana/provisioning/dashboards - ./monitoring/datasources:/etc/grafana/provisioning/datasources networks: - monitoring_network restart: unless-stopped alertmanager: image: prom/alertmanager:latest container_name: alertmanager ports: - "9093:9093" volumes: - ./monitoring/alertmanager.yml:/etc/alertmanager/alertmanager.yml networks: - monitoring_network restart: unless-stopped node-exporter: image: prom/node-exporter:latest container_name: node_exporter ports: - "9100:9100" volumes: - /proc:/host/proc:ro - /sys:/host/sys:ro - /:/rootfs:ro command: - '--path.procfs=/host/proc' - '--path.rootfs=/rootfs' - '--path.sysfs=/host/sys' - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)' networks: - monitoring_network restart: unless-stopped netdata: image: netdata/netdata:latest container_name: netdata ports: - "19999:19999" cap_add: - SYS_PTRACE security_opt: - apparmor:unconfined volumes: - /etc/passwd:/host/etc/passwd:ro - /etc/group:/host/etc/group:ro - /proc:/host/proc:ro - /sys:/host/sys:ro - /var/run/docker.sock:/var/run/docker.sock:ro networks: - monitoring_network restart: unless-stopped smokeping: image: linuxserver/smokeping:latest container_name: smokeping ports: - "8082:80" volumes: - ./monitoring/smokeping:/config - /etc/localtime:/etc/localtime:ro networks: - monitoring_network restart: unless-stopped networks: monitoring_network: driver: bridge volumes: prometheus_data: grafana_data: Προχωρημένο Prometheus Configuration: yaml # monitoring/prometheus.yml global: scrape_interval: 15s evaluation_interval: 15s rule_files: - "alerts.yml" alerting: alertmanagers: - static_configs: - targets: ['alertmanager:9093'] scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - job_name: 'node' static_configs: - targets: ['node-exporter:9100'] - job_name: 'netdata' static_configs: - targets: ['netdata:19999'] - job_name: 'wireguard' static_configs: - targets: ['192.168.100.1:9586'] # wg-exporter metrics_path: /metrics params: interface: ['wg0'] - job_name: 'services' static_configs: targets: - 'wiki:8080' - 'maps:8081' - 'search:7700' - 'traefik:8080' metrics_path: /metrics - job_name: 'network' static_configs: targets: ['192.168.100.1:9107'] # speedtest-exporter scrape_interval: 5m - job_name: 'blackbox' metrics_path: /probe params: module: [http_2xx] static_configs: - targets: - http://wiki.local - http://maps.local - http://portal.local relabel_configs: - source_labels: [__address__] target_label: __param_target - source_labels: [__param_target] target_label: instance - target_label: __address__ replacement: blackbox-exporter:9115 - job_name: 'snmp' static_configs: - targets: - 192.168.100.1 # Router/AP metrics_path: /snmp params: module: [if_mib] relabel_configs: - source_labels: [__address__] target_label: __param_target - source_labels: [__param_target] target_label: instance - target_label: __address__ replacement: snmp-exporter:9116 6.7.2 Προηγμένη Network Analysis με ntopng ntopng για Real-time Traffic Analysis: bash #!/bin/bash # setup-ntopng.sh # Εγκατάσταση ntopng wget https://packages.ntop.org/apt-stable/$(lsb_release -cs)/all/apt-ntop-stable.deb sudo dpkg -i apt-ntop-stable.deb sudo apt update sudo apt install -y ntopng nprobe redis-server # Ρύθμιση ntopng sudo tee /etc/ntopng/ntopng.conf << 'EOF' # Βασικές ρυθμίσεις -G=/var/run/ntopng.pid --community --dns-mode=1 --disable-login=1 --http-port=3001 --https-port=3002 --local-networks=192.168.100.0/24 --data-dir=/var/lib/ntopng --interface=eth0,wlan0 # Προηγμένες ρυθμίσεις --max-num-flows=131072 --max-num-hosts=65536 --zmq-encryption-key=changeme --zmq-topic=flow --zmq-export-port=5556 # Redis configuration --redis=127.0.0.1:6379 --redis-db-id=5 # Logging --log-dir=/var/log/ntopng --log-to-file --log-level=info # Security --admin-password=${NTOPNG_PASSWORD} EOF # Ρύθμιση nProbe για flow collection sudo tee /etc/nprobe/nprobe.conf << 'EOF' # nProbe configuration -i=eth0 -n=localhost:5556 --zmq=tcp://*:5556 --collector-port=2055 --override-timestamp=1 --verbose --dont-drop-privileges --print-interface-statistics=10 --tcp-reassembly=1 --max-num-pkts=8192 --max-num-flows=131072 --flow-log-format=json EOF # Ενεργοποίηση services sudo systemctl enable redis-server ntopng nprobe sudo systemctl start redis-server ntopng nprobe # Firewall rules nft add rule inet firewall input tcp dport 3001-3002 accept nft add rule inet firewall input udp dport 2055 accept echo "ntopng installed and configured" echo "Access: http://192.168.100.1:3001" echo "Admin password: ${NTOPNG_PASSWORD}" 6.8 Mesh Networking για Επεκτασιμότητα 6.8.1 Reticulum Mesh Network Setup Reticulum για Decentralized Communication: python #!/usr/bin/env python3 # reticulum-mesh.py import RNS import time import sqlite3 from datetime import datetime class CyberAutonomyMesh: def __init__(self, config_path="/etc/reticulum/config"): self.config_path = config_path self.identity = None self.destination = None self.init_reticulum() def init_reticulum(self): """Αρχικοποίηση Reticulum stack""" # Δημιουργία configuration config = { "reticulum": { "enable_transport": True, "shared_instance": True, "interface": { "enable": True, "mode": "Auto", "interface_enabled": True, "port": 37428, "outgoing": True, "device": "wlan0", "bitrate": 2000000, "channel": 6, "frequency": 2437000000, "bandwidth": 20000000, "spreading_factor": 8, "coding_rate": 5, "power": 17, "name": "CyberAutonomy Mesh", "type": "AutoInterface" } }, "storage": { "path": "/var/lib/reticulum" } } # Αρχικοποίηση Reticulum RNS.Reticulum(config) # Δημιουργία identity self.identity = RNS.Identity() # Δημιουργία destination self.destination = RNS.Destination( self.identity, RNS.Destination.IN, RNS.Destination.SINGLE, "cyberautonomy", "mesh" ) # Ορισμός handler για εισερχόμενες πληροφορίες self.destination.set_packet_callback(self.message_received) # Ανακοίνωση destination self.destination.announce() print(f"Mesh node initialized") print(f"Identity hash: {self.identity.hash}") print(f"Destination hash: {self.destination.hash}") def message_received(self, message, packet): """Χειρισμός εισερχόμενων μηνυμάτων""" try: data = message.decode('utf-8') print(f"Received message: {data}") # Αποθήκευση μηνύματος στη βάση self.store_message(data, packet) # Απάντηση (acknowledgment) response = f"ACK: {datetime.now().isoformat()}" packet.reply(response.encode('utf-8')) except Exception as e: print(f"Error processing message: {e}") def store_message(self, message, packet): """Αποθήκευση μηνύματος στη βάση""" conn = sqlite3.connect('/var/lib/reticulum/mesh.db') cursor = conn.cursor() cursor.execute(''' CREATE TABLE IF NOT EXISTS messages ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp DATETIME, source_hash TEXT, message TEXT, hops INTEGER, rssi REAL ) ''') cursor.execute(''' INSERT INTO messages (timestamp, source_hash, message, hops, rssi) VALUES (?, ?, ?, ?, ?) ''', ( datetime.now().isoformat(), packet.get_source_hash(), message, packet.hops, packet.rssi if hasattr(packet, 'rssi') else None )) conn.commit() conn.close() def send_message(self, destination_hash, message): """Αποστολή μηνύματος""" try: # Lookup destination destination = RNS.Destination.link_from_hash(destination_hash) if destination: # Αποστολή μηνύματος packet = RNS.Packet(destination, message.encode('utf-8')) packet.send() print(f"Message sent to {destination_hash}") return True else: print(f"Destination {destination_hash} not found") return False except Exception as e: print(f"Error sending message: {e}") return False def discover_nodes(self): """Ανακαλύψτε άλλους nodes στο mesh""" discovered = [] for destination_hash, destination in RNS.Transport.destinations.items(): if destination_hash != self.destination.hash: node_info = { 'hash': destination_hash, 'name': destination.name, 'type': destination.type, 'announced': destination.announced, 'hops': destination.hops if hasattr(destination, 'hops') else 0 } discovered.append(node_info) return discovered def start_web_interface(self, port=8085): """Εκκίνηση web interface για το mesh""" from flask import Flask, render_template, jsonify app = Flask(__name__) @app.route('/') def index(): return render_template('mesh_index.html') @app.route('/api/nodes') def get_nodes(): nodes = self.discover_nodes() return jsonify({'nodes': nodes}) @app.route('/api/messages') def get_messages(): conn = sqlite3.connect('/var/lib/reticulum/mesh.db') cursor = conn.cursor() cursor.execute(''' SELECT timestamp, source_hash, message, hops, rssi FROM messages ORDER BY timestamp DESC LIMIT 100 ''') messages = [] for row in cursor.fetchall(): messages.append({ 'timestamp': row[0], 'source': row[1][:8], 'message': row[2], 'hops': row[3], 'rssi': row[4] }) conn.close() return jsonify({'messages': messages}) @app.route('/api/send', methods=['POST']) def send_message(): data = request.json success = self.send_message(data['destination'], data['message']) return jsonify({'success': success}) print(f"Mesh web interface starting on port {port}") app.run(host='0.0.0.0', port=port) # Κυρίως εκτέλεση if __name__ == "__main__": mesh = CyberAutonomyMesh() # Εκτύπωση πληροφοριών print(f"\nLocal node information:") print(f" Identity: {mesh.identity.hash}") print(f" Destination: {mesh.destination.hash}") print(f" Name: {mesh.destination.name}") # Ανακαλύψτε άλλους nodes print(f"\nDiscovering nodes...") nodes = mesh.discover_nodes() print(f"Found {len(nodes)} nodes") for node in nodes: print(f" - {node['name']} ({node['hash'][:8]}) - {node['hops']} hops") # Εκκίνηση web interface mesh.start_web_interface() 6.8.2 BATMAN-adv για Layer 2 Mesh BATMAN-adv Configuration: bash #!/bin/bash # setup-batman-adv.sh # Εγκατάσταση apt update && apt install -y batctl alfred # Φόρτωση module modprobe batman-adv # Ρύθμιση interfaces MESH_INTERFACE="wlan1" # Δεύτερη wireless κάρτα για mesh PRIMARY_INTERFACE="wlan0" # Απενεργοποίηση interface ip link set $MESH_INTERFACE down # Ρύθμιση mode iw dev $MESH_INTERFACE set type ibss ip link set $MESH_INTERFACE up iw dev $MESH_INTERFACE ibss join CyberAutonomy-Mesh 2412 # Προσθήκη στο batman-adv batctl if add $MESH_INTERFACE ip link set up dev bat0 # Ρύθμιση IP address ip addr add 192.168.200.1/24 dev bat0 # Routing configuration batctl gw_mode server 100Mbps/100Mbps # Bridge με κύριο δίκτυο brctl addbr br-mesh brctl addif br-mesh bat0 brctl addif br-mesh $PRIMARY_INTERFACE ip link set up dev br-mesh # Firewall rules για mesh nft add rule inet firewall input iif bat0 accept nft add rule inet firewall forward iif bat0 oif $PRIMARY_INTERFACE accept nft add rule inet firewall forward iif $PRIMARY_INTERFACE oif bat0 accept # Alfred για service discovery alfred -i bat0 -m & batadv-vis -i bat0 -s & # Δημιουργία configuration για αυτόματη εκκίνηση cat > /etc/systemd/system/batman-adv.service << EOF [Unit] Description=B.A.T.M.A.N. Advanced Wants=network.target After=network.target [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/local/bin/batman-start.sh ExecStop=/usr/local/bin/batman-stop.sh [Install] WantedBy=multi-user.target EOF cat > /usr/local/bin/batman-start.sh << 'EOF' #!/bin/bash modprobe batman-adv ip link set wlan1 down iw dev wlan1 set type ibss ip link set wlan1 up iw dev wlan1 ibss join CyberAutonomy-Mesh 2412 batctl if add wlan1 ip link set up dev bat0 ip addr add 192.168.200.1/24 dev bat0 batctl gw_mode server 100Mbps/100Mbps alfred -i bat0 -m & batadv-vis -i bat0 -s & EOF chmod +x /usr/local/bin/batman-start.sh systemctl enable batman-adv systemctl start batman-adv 6.9 Σύνθετο Portal και User Interface 6.9.1 Ολοκληρωμένο Web Portal React-based Portal με Real-time Updates: javascript // portal/src/App.js import React, { useState, useEffect } from 'react'; import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom'; import './App.css'; // Components import Dashboard from './components/Dashboard'; import Services from './components/Services'; import Network from './components/Network'; import Files from './components/Files'; import Settings from './components/Settings'; // API client const API_BASE = 'http://portal.local/api'; function App() { const [systemStatus, setSystemStatus] = useState({}); const [services, setServices] = useState([]); const [networkStats, setNetworkStats] = useState({}); useEffect(() => { // Fetch initial data fetchSystemStatus(); fetchServices(); fetchNetworkStats(); // Set up WebSocket for real-time updates const ws = new WebSocket('ws://portal.local/ws'); ws.onmessage = (event) => { const data = JSON.parse(event.data); handleWebSocketMessage(data); }; // Polling for data updates const interval = setInterval(() => { fetchSystemStatus(); fetchServices(); fetchNetworkStats(); }, 10000); return () => { ws.close(); clearInterval(interval); }; }, []); const fetchSystemStatus = async () => { try { const response = await fetch(`${API_BASE}/status`); const data = await response.json(); setSystemStatus(data); } catch (error) { console.error('Error fetching system status:', error); } }; const fetchServices = async () => { try { const response = await fetch(`${API_BASE}/services`); const data = await response.json(); setServices(data.services); } catch (error) { console.error('Error fetching services:', error); } }; const fetchNetworkStats = async () => { try { const response = await fetch(`${API_BASE}/network/stats`); const data = await response.json(); setNetworkStats(data); } catch (error) { console.error('Error fetching network stats:', error); } }; const handleWebSocketMessage = (data) => { switch (data.type) { case 'service_update': setServices(prev => prev.map(s => s.name === data.service ? { ...s, status: data.status } : s )); break; case 'system_alert': showAlert(data.message, data.level); break; case 'network_traffic': setNetworkStats(prev => ({ ...prev, traffic: data.traffic })); break; } }; const showAlert = (message, level = 'info') => { // Implementation for showing alerts console.log(`${level.toUpperCase()}: ${message}`); }; return (
} /> { await fetch(`${API_BASE}/services/${service}/restart`, { method: 'POST' }); }} /> } /> } /> } /> } />

CyberAutonomy Server v1.0

Uptime: {systemStatus.uptime || '0 days'}

Last Updated: {new Date().toLocaleTimeString()}

); } export default App; 6.9.2 Real-time Monitoring Dashboard Dashboard Component με Charts: javascript // portal/src/components/Dashboard.js import React from 'react'; import { LineChart, Line, BarChart, Bar, PieChart, Pie, Cell, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts'; const Dashboard = ({ systemStatus, services, networkStats }) => { // Prepare data for charts const cpuData = systemStatus.cpu_history?.map((point, index) => ({ time: index * 5, usage: point })) || []; const memoryData = [ { name: 'Used', value: systemStatus.memory_used || 0 }, { name: 'Free', value: systemStatus.memory_free || 0 }, { name: 'Cached', value: systemStatus.memory_cached || 0 } ]; const serviceStatusData = services.map(service => ({ name: service.name, status: service.status === 'running' ? 1 : 0 })); const networkTrafficData = networkStats.traffic?.map((point, index) => ({ time: index * 10, in: point.rx / 1024, // KB/s out: point.tx / 1024 // KB/s })) || []; const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042']; return (

System Dashboard

CPU

{systemStatus.cpu_usage || 0}%

Memory

{((systemStatus.memory_used || 0) / 1024 / 1024).toFixed(1)} GB

Storage

{systemStatus.storage_used || 0}%

Network

{(networkStats.current_traffic || 0).toFixed(1)} Mbps

CPU Usage History

Memory Distribution

`${name}: ${(percent * 100).toFixed(0)}%`} outerRadius={80} fill="#8884d8" dataKey="value" > {memoryData.map((entry, index) => ( ))}

Network Traffic

Service Status

{services.map(service => (
{service.name} {service.uptime}
))}

Connected Devices

{(networkStats.devices || []).map(device => (
{device.hostname} {device.ip} {device.mac} {device.type}
↓ {(device.rx / 1024 / 1024).toFixed(2)} MB ↑ {(device.tx / 1024 / 1024).toFixed(2)} MB
))}
); }; export default Dashboard; Αυτή η ολοκληρωμένη ενότητα παρέχει μια εξαιρετικά προηγμένη και συμπαγή αρχιτεκτονική δικτύου για το αυτόνομο server. Κάθε στοιχείο έχει σχεδιαστεί για να λειτουργεί τόσο σε απομονωμένο όσο και σε συνδεδεμένο περιβάλλον, με έμφαση στην ασφάλεια, την απόδοση και την ευκολία χρήσης. Το σύστημα είναι πλήρως διαχειρίσιμο μέσω web interface και υποστηρίζει προηγμένα χαρακτηριστικά όπως mesh networking, VPN, service discovery και πραγματικό χρόνο monitoring.