diff --git a/README.md b/README.md index 5369247..5181825 100644 --- a/README.md +++ b/README.md @@ -68,36 +68,6 @@ This firewall uses a **threshold-based detection approach**: python3 test_attacks.py 127.0.0.1 ``` -## 🏃 Running on Windows - -This program uses `netsh` to manage firewall rules, which requires administrative privileges. - -1. **Open as Administrator:** Right-click on **Command Prompt** or **Windows PowerShell** and select **"Run as administrator"**. - -2. **Navigate to Folder:** Change to the project directory: - ```sh - cd path\to\simple_firewall - ``` - -3. **(Optional) Activate Virtual Environment:** If you use a virtual environment: - ```sh - .\venv\Scripts\activate - ``` - -4. **Install Requirements:** Install the main requirements and the Windows-specific ones: - ```sh - pip install -r requirements.txt - pip install -r requirements-windows.txt - ``` - -5. **Run the Program:** - ```sh - python main.py -i "Your Interface Name" - - # Example: - python main.py -i "Ethernet" - ``` - ## Usage ### Basic Commands diff --git a/requirements-windows.txt b/requirements-windows.txt deleted file mode 100644 index 37a3830..0000000 --- a/requirements-windows.txt +++ /dev/null @@ -1,8 +0,0 @@ -# This file lists Python packages required *only* for running -# this project on Windows, which are not in the main requirements.txt. - -# psutil (used for Windows-specific interface detection) is -# already listed in the main requirements.txt as a core -# dependency for all platforms. - -# Future Windows-only dependencies can be added here. \ No newline at end of file diff --git a/src/firewall/blocking.py b/src/firewall/blocking.py index 7662572..4fad861 100644 --- a/src/firewall/blocking.py +++ b/src/firewall/blocking.py @@ -157,7 +157,7 @@ def _unblock_ip_macos(self, ip: str) -> bool: return result.returncode == 0 def _block_ip_windows(self, ip: str) -> bool: - """Block IP using Windows Firewall (netsh)""" + """Block IP using Windows Firewall""" rule_name = f"SimpleFirewall_Block_{ip.replace('.', '_')}" cmd = [ 'netsh', 'advfirewall', 'firewall', 'add', 'rule', @@ -166,38 +166,18 @@ def _block_ip_windows(self, ip: str) -> bool: 'action=block', f'remoteip={ip}' ] - try: - result = subprocess.run(cmd, capture_output=True, text=True) - if result.returncode == 0: - self.logger.debug(f"netsh add rule stdout: {result.stdout.strip()}") - return True - else: - self.logger.error(f"netsh add rule failed: rc={result.returncode} stdout={result.stdout.strip()} stderr={result.stderr.strip()}") - return False - except Exception as e: - self.logger.error(f"Exception when running netsh add rule: {e}") - return False - + result = subprocess.run(cmd, capture_output=True, text=True) + return result.returncode == 0 + def _unblock_ip_windows(self, ip: str) -> bool: - """Unblock IP using Windows Firewall (netsh)""" + """Unblock IP using Windows Firewall""" rule_name = f"SimpleFirewall_Block_{ip.replace('.', '_')}" cmd = [ 'netsh', 'advfirewall', 'firewall', 'delete', 'rule', f'name={rule_name}' ] - try: - result = subprocess.run(cmd, capture_output=True, text=True) - if result.returncode == 0: - self.logger.debug(f"netsh delete rule stdout: {result.stdout.strip()}") - return True - else: - # Sometimes netsh returns 1 when rule not found; log and return False - self.logger.error(f"netsh delete rule failed: rc={result.returncode} stdout={result.stdout.strip()} stderr={result.stderr.strip()}") - return False - except Exception as e: - self.logger.error(f"Exception when running netsh delete rule: {e}") - return False - + result = subprocess.run(cmd, capture_output=True, text=True) + return result.returncode == 0 def get_blocked_ips(self) -> Dict[str, str]: """Get currently blocked IPs with their block times""" diff --git a/src/network/interface.py b/src/network/interface.py index 528c33c..0c840df 100644 --- a/src/network/interface.py +++ b/src/network/interface.py @@ -1,115 +1,88 @@ -# src/network/interface.py """Network interface detection and management""" import netifaces -import platform from typing import Optional, List -# Use psutil on Windows to get friendly interface names -try: - import psutil -except Exception: - psutil = None - class NetworkInterface: """Handles network interface detection and management""" - + def __init__(self, interface: str = None): - self._platform = platform.system().lower() self.interface = interface or self._get_default_interface() - + def _get_default_interface(self) -> str: - """Get the default network interface (Windows-friendly names when available)""" + """Get the default network interface""" try: - # On Windows prefer psutil names (friendly names) - if self._platform == 'windows' and psutil is not None: - # psutil returns a mapping of friendly names - names = [name for name in psutil.net_if_addrs().keys() - if not name.startswith(('Loopback', 'loopback', 'vEthernet'))] - # Prefer "Ethernet" or "Wi-Fi" heuristically - for n in names: - if n.lower().startswith('ether') or 'ethernet' in n.lower(): - return n - for n in names: - if 'wi' in n.lower() or 'wifi' in n.lower() or 'wi-fi' in n.lower(): - return n - return names[0] if names else 'Ethernet' - else: - interfaces = netifaces.interfaces() - - # Filter out loopback and virtual interfaces - physical_interfaces = [ - iface for iface in interfaces - if not iface.startswith(('lo', 'docker', 'veth', 'br-')) - ] - - # Prefer ethernet interfaces, then wireless - for iface in physical_interfaces: - if iface.startswith(('eth', 'en')): - return iface - - for iface in physical_interfaces: - if iface.startswith(('wl', 'wlan')): - return iface - - # Fallback to first available interface - return physical_interfaces[0] if physical_interfaces else 'eth0' - + interfaces = netifaces.interfaces() + + # Filter out loopback and virtual interfaces + physical_interfaces = [ + iface for iface in interfaces + if not iface.startswith(('lo', 'docker', 'veth', 'br-')) + ] + + # Prefer ethernet interfaces, then wireless + for iface in physical_interfaces: + if iface.startswith(('eth', 'en')): + return iface + + for iface in physical_interfaces: + if iface.startswith(('wl', 'wlan')): + return iface + + # Fallback to first available interface + return physical_interfaces[0] if physical_interfaces else 'eth0' + except Exception: - return '' - + return 'eth0' + def get_interface_info(self) -> dict: """Get information about the current interface""" try: - addrs = netifaces.ifaddresses(self.interface) if self.interface else {} + addrs = netifaces.ifaddresses(self.interface) info = { 'name': self.interface, 'ipv4': [], 'ipv6': [], 'mac': None } - + # Get IPv4 addresses - if addrs and netifaces.AF_INET in addrs: + if netifaces.AF_INET in addrs: for addr in addrs[netifaces.AF_INET]: info['ipv4'].append({ 'addr': addr.get('addr'), 'netmask': addr.get('netmask'), 'broadcast': addr.get('broadcast') }) - + # Get IPv6 addresses - if addrs and netifaces.AF_INET6 in addrs: + if netifaces.AF_INET6 in addrs: for addr in addrs[netifaces.AF_INET6]: info['ipv6'].append({ 'addr': addr.get('addr'), 'netmask': addr.get('netmask') }) - + # Get MAC address - if addrs and netifaces.AF_LINK in addrs: + if netifaces.AF_LINK in addrs: info['mac'] = addrs[netifaces.AF_LINK][0].get('addr') - + return info - + except Exception as e: return {'name': self.interface, 'error': str(e)} - + def list_all_interfaces(self) -> List[str]: - """List all available network interfaces (friendly names preferred on Windows)""" + """List all available network interfaces""" try: - if self._platform == 'windows' and psutil is not None: - return list(psutil.net_if_addrs().keys()) return netifaces.interfaces() except Exception: return [] - + def is_interface_up(self) -> bool: """Check if the interface is up and running""" try: - if self._platform == 'windows' and psutil is not None: - return self.interface in psutil.net_if_stats() return self.interface in netifaces.interfaces() except Exception: - return False + return False \ No newline at end of file