diff --git a/.gitignore b/.gitignore index 284e270..8d9b4d3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,48 +1,14 @@ -# Python __pycache__/ -*.py[cod] -*$py.class -*.so -.Python -env/ +*.pyc +*.pyo +*.pyd +.pytest_cache/ +.coverage +htmlcov/ +.env +.venv/ venv/ -ENV/ -env.bak/ -venv.bak/ -*.egg-info/ dist/ build/ - -# Security Analysis Results (user-generated) -*.json -*_results.txt -*_report.txt -*_audit.json -daily_check.json -weekly_audit.json -security_check.json - -# macOS -.DS_Store -.DS_Store? -._* -.Spotlight-V100 -.Trashes -ehthumbs.db -Thumbs.db - -# IDE -.vscode/ -.idea/ -*.swp -*.swo -*~ - -# Temporary files -*.tmp -*.temp -*.log - -# User configuration -config.local.py -.env \ No newline at end of file +*.egg-info/ +.DS_Store \ No newline at end of file diff --git a/src/vpn_security_recommendations.py b/src/vpn_security_recommendations.py new file mode 100644 index 0000000..26fecfb --- /dev/null +++ b/src/vpn_security_recommendations.py @@ -0,0 +1,155 @@ +from typing import Dict, List, Optional, Any +import logging + +class VPNSecurityRecommendationGenerator: + """ + A class to generate actionable security recommendations for VPN configurations. + + This class analyzes VPN configuration parameters and provides + tailored security recommendations based on detected settings. + """ + + @staticmethod + def generate_recommendations(vpn_config: Dict[str, Any]) -> List[str]: + """ + Generate security recommendations based on VPN configuration. + + Args: + vpn_config (Dict[str, Any]): A dictionary containing VPN configuration details. + + Returns: + List[str]: A list of security recommendations. + """ + # Validate input and provide default recommendations for empty config + if not vpn_config or not isinstance(vpn_config, dict): + logging.warning("Generating default recommendations for minimal VPN configuration") + return [ + "Use strong, modern VPN protocols like OpenVPN, WireGuard, or IKEv2", + "Enable certificate-based authentication", + "Implement two-factor authentication", + "Enable DNS leak protection", + "Set up a VPN kill switch" + ] + + recommendations = [] + + # Check encryption protocol + recommendations.extend( + VPNSecurityRecommendationGenerator._check_encryption_protocol(vpn_config) + ) + + # Check authentication method + recommendations.extend( + VPNSecurityRecommendationGenerator._check_authentication(vpn_config) + ) + + # Check DNS leak protection + recommendations.extend( + VPNSecurityRecommendationGenerator._check_dns_leak_protection(vpn_config) + ) + + # Check kill switch + recommendations.extend( + VPNSecurityRecommendationGenerator._check_kill_switch(vpn_config) + ) + + return recommendations + + @staticmethod + def _check_encryption_protocol(vpn_config: Dict[str, Any]) -> List[str]: + """ + Check and recommend improvements for encryption protocols. + + Args: + vpn_config (Dict[str, Any]): VPN configuration details. + + Returns: + List[str]: Encryption-related recommendations. + """ + recommendations = [] + encryption_protocol = vpn_config.get('encryption_protocol', '').lower() + + # Weak encryption protocols + weak_protocols = ['pptp', 'l2tp'] + if encryption_protocol in weak_protocols: + recommendations.append( + f"Upgrade from {encryption_protocol.upper()} to a more secure protocol like OpenVPN or WireGuard" + ) + + # Recommended minimum encryption strength + if encryption_protocol not in ['openvpn', 'wireguard', 'ikev2']: + recommendations.append( + "Consider using strong, modern VPN protocols like OpenVPN, WireGuard, or IKEv2" + ) + + return recommendations + + @staticmethod + def _check_authentication(vpn_config: Dict[str, Any]) -> List[str]: + """ + Check and recommend improvements for authentication methods. + + Args: + vpn_config (Dict[str, Any]): VPN configuration details. + + Returns: + List[str]: Authentication-related recommendations. + """ + recommendations = [] + auth_method = vpn_config.get('authentication_method', '').lower() + + # Weak authentication methods + if auth_method in ['none', 'psk', 'weak']: + recommendations.append( + "Use strong, certificate-based authentication instead of pre-shared keys or weak methods" + ) + + # Two-factor authentication + if not vpn_config.get('two_factor_auth', False): + recommendations.append( + "Enable two-factor authentication for enhanced account security" + ) + + return recommendations + + @staticmethod + def _check_dns_leak_protection(vpn_config: Dict[str, Any]) -> List[str]: + """ + Check DNS leak protection configuration. + + Args: + vpn_config (Dict[str, Any]): VPN configuration details. + + Returns: + List[str]: DNS leak protection recommendations. + """ + recommendations = [] + + # Check if DNS leak protection is enabled + if not vpn_config.get('dns_leak_protection', False): + recommendations.append( + "Enable DNS leak protection to prevent DNS requests from bypassing the VPN tunnel" + ) + + return recommendations + + @staticmethod + def _check_kill_switch(vpn_config: Dict[str, Any]) -> List[str]: + """ + Check VPN kill switch configuration. + + Args: + vpn_config (Dict[str, Any]): VPN configuration details. + + Returns: + List[str]: Kill switch recommendations. + """ + recommendations = [] + + # Check if kill switch is enabled + if not vpn_config.get('kill_switch', False): + recommendations.append( + "Enable VPN kill switch to prevent network traffic when VPN connection drops" + ) + + return recommendations \ No newline at end of file diff --git a/tests/test_vpn_security_recommendations.py b/tests/test_vpn_security_recommendations.py new file mode 100644 index 0000000..e212794 --- /dev/null +++ b/tests/test_vpn_security_recommendations.py @@ -0,0 +1,54 @@ +import pytest +from src.vpn_security_recommendations import VPNSecurityRecommendationGenerator + +def test_generate_recommendations_empty_config(): + """Test recommendation generation with empty configuration.""" + recommendations = VPNSecurityRecommendationGenerator.generate_recommendations({}) + assert isinstance(recommendations, list) + assert len(recommendations) > 0 + +def test_weak_encryption_protocol(): + """Test recommendations for weak encryption protocols.""" + vpn_config = { + 'encryption_protocol': 'pptp' + } + recommendations = VPNSecurityRecommendationGenerator.generate_recommendations(vpn_config) + assert any('Upgrade from PPTP' in rec for rec in recommendations) + +def test_missing_dns_leak_protection(): + """Test recommendations for missing DNS leak protection.""" + vpn_config = { + 'dns_leak_protection': False + } + recommendations = VPNSecurityRecommendationGenerator.generate_recommendations(vpn_config) + assert any('Enable DNS leak protection' in rec for rec in recommendations) + +def test_missing_kill_switch(): + """Test recommendations for missing kill switch.""" + vpn_config = { + 'kill_switch': False + } + recommendations = VPNSecurityRecommendationGenerator.generate_recommendations(vpn_config) + assert any('Enable VPN kill switch' in rec for rec in recommendations) + +def test_weak_authentication(): + """Test recommendations for weak authentication methods.""" + vpn_config = { + 'authentication_method': 'psk', + 'two_factor_auth': False + } + recommendations = VPNSecurityRecommendationGenerator.generate_recommendations(vpn_config) + assert any('Use strong, certificate-based authentication' in rec for rec in recommendations) + assert any('Enable two-factor authentication' in rec for rec in recommendations) + +def test_recommendations_with_good_config(): + """Test recommendations with a well-configured VPN.""" + vpn_config = { + 'encryption_protocol': 'wireguard', + 'authentication_method': 'certificate', + 'dns_leak_protection': True, + 'kill_switch': True, + 'two_factor_auth': True + } + recommendations = VPNSecurityRecommendationGenerator.generate_recommendations(vpn_config) + assert len(recommendations) == 0 # No recommendations for a good config \ No newline at end of file