diff --git a/baseTemplate/static/baseTemplate/custom-js/system-status.js b/baseTemplate/static/baseTemplate/custom-js/system-status.js index b3403aa99..d32b31dbd 100644 --- a/baseTemplate/static/baseTemplate/custom-js/system-status.js +++ b/baseTemplate/static/baseTemplate/custom-js/system-status.js @@ -1011,8 +1011,84 @@ app.controller('dashboardStatsController', function ($scope, $http, $timeout) { }; $scope.blockIPAddress = function(ipAddress) { - if (!$scope.blockingIP) { - $scope.blockingIP = ipAddress; + try { + console.log('========================================'); + console.log('=== blockIPAddress CALLED ==='); + console.log('========================================'); + console.log('blockIPAddress called with:', ipAddress); + console.log('ipAddress type:', typeof ipAddress); + console.log('ipAddress value:', ipAddress); + console.log('$scope:', $scope); + console.log('$scope.blockIPAddress:', typeof $scope.blockIPAddress); + + // Validate IP address parameter + if (!ipAddress) { + console.error('No IP address provided:', ipAddress); + if (typeof PNotify !== 'undefined') { + new PNotify({ + title: 'Error', + text: 'No IP address provided', + type: 'error', + delay: 5000 + }); + } + return; + } + + // Ensure it's a string and trim it + ipAddress = String(ipAddress).trim(); + + // Validate after trimming + if (!ipAddress || ipAddress === '' || ipAddress === 'undefined' || ipAddress === 'null') { + console.error('IP address is empty or invalid after trim:', ipAddress); + if (typeof PNotify !== 'undefined') { + new PNotify({ + title: 'Error', + text: 'Invalid IP address provided: ' + ipAddress, + type: 'error', + delay: 5000 + }); + } + return; + } + + // Basic IP format validation + var ipPattern = /^(\d{1,3}\.){3}\d{1,3}(\/\d{1,2})?$/; + if (!ipPattern.test(ipAddress)) { + console.error('IP address format is invalid:', ipAddress); + if (typeof PNotify !== 'undefined') { + new PNotify({ + title: 'Error', + text: 'Invalid IP address format: ' + ipAddress, + type: 'error', + delay: 5000 + }); + } + return; + } + + // Prevent duplicate requests + if ($scope.blockingIP === ipAddress) { + console.log('Already processing IP:', ipAddress); + return; // Already processing this IP + } + + // Check if already blocked + if ($scope.blockedIPs && $scope.blockedIPs[ipAddress]) { + console.log('IP already blocked:', ipAddress); + if (typeof PNotify !== 'undefined') { + new PNotify({ + title: 'Info', + text: `IP address ${ipAddress} is already banned`, + type: 'info', + delay: 3000 + }); + } + return; + } + + // Set blocking flag to prevent duplicate requests + $scope.blockingIP = ipAddress; // Use the new Banned IPs system instead of the old blockIPAddress var data = { @@ -1027,48 +1103,265 @@ app.controller('dashboardStatsController', function ($scope, $http, $timeout) { } }; + console.log('Sending ban IP request:', data); + console.log('CSRF Token:', getCookie('csrftoken')); + console.log('Config:', config); + $http.post('/firewall/addBannedIP', data, config).then(function (response) { + console.log('=== addBannedIP SUCCESS ==='); + console.log('Full response:', response); + console.log('response.data:', response.data); + console.log('response.data type:', typeof response.data); + console.log('response.status:', response.status); + + // Reset blocking flag $scope.blockingIP = null; - if (response.data && response.data.status === 1) { + + // Apply scope changes + if (!$scope.$$phase && !$scope.$root.$$phase) { + $scope.$apply(); + } + + // Handle both JSON string and object responses + var responseData = response.data; + if (typeof responseData === 'string') { + try { + responseData = JSON.parse(responseData); + console.log('Parsed responseData from string:', responseData); + } catch (e) { + console.error('Failed to parse response as JSON:', e); + console.error('Raw response string:', responseData); + // Try to extract error from string + if (responseData.includes('error')) { + if (typeof PNotify !== 'undefined') { + new PNotify({ + title: 'Error', + text: 'Failed to block IP address: ' + responseData, + type: 'error', + delay: 5000 + }); + } + return; + } + } + } + + console.log('Final responseData:', responseData); + console.log('responseData.status:', responseData ? responseData.status : 'undefined'); + console.log('responseData.message:', responseData ? responseData.message : 'undefined'); + console.log('responseData.error_message:', responseData ? responseData.error_message : 'undefined'); + + // Check for success (status === 1 or status === '1') + if (responseData && (responseData.status === 1 || responseData.status === '1')) { // Mark IP as blocked + if (!$scope.blockedIPs) { + $scope.blockedIPs = {}; + } $scope.blockedIPs[ipAddress] = true; // Show success notification - new PNotify({ - title: 'IP Address Banned', - text: `IP address ${ipAddress} has been permanently banned and added to the firewall. You can manage it in the Firewall > Banned IPs section.`, - type: 'success', - delay: 5000 - }); + if (typeof PNotify !== 'undefined') { + new PNotify({ + title: 'IP Address Banned', + text: `IP address ${ipAddress} has been permanently banned and added to the firewall. You can manage it in the Firewall > Banned IPs section.`, + type: 'success', + delay: 5000 + }); + } // Refresh security analysis to update alerts - $scope.analyzeSSHSecurity(); + if ($scope.analyzeSSHSecurity) { + $scope.analyzeSSHSecurity(); + } + + // Apply scope changes + if (!$scope.$$phase && !$scope.$root.$$phase) { + $scope.$apply(); + } } else { // Show error notification + var errorMsg = 'Failed to block IP address'; + if (responseData && responseData.error_message) { + errorMsg = responseData.error_message; + } else if (responseData && responseData.error) { + errorMsg = responseData.error; + } else if (responseData && responseData.message) { + errorMsg = responseData.message; + } else if (responseData) { + errorMsg = JSON.stringify(responseData); + } + console.error('Ban IP failed:', errorMsg); + if (typeof PNotify !== 'undefined') { + new PNotify({ + title: 'Error', + text: errorMsg, + type: 'error', + delay: 5000 + }); + } + } + }, function (err) { + $scope.blockingIP = null; + console.error('addBannedIP error:', err); + console.error('Error status:', err.status); + console.error('Error statusText:', err.statusText); + console.error('Error data:', err.data); + + // Prevent showing duplicate error notifications + if ($scope.lastErrorIP === ipAddress && $scope.lastErrorTime && (Date.now() - $scope.lastErrorTime) < 2000) { + console.log('Skipping duplicate error notification for IP:', ipAddress); + return; + } + + $scope.lastErrorIP = ipAddress; + $scope.lastErrorTime = Date.now(); + + var errorMessage = 'Failed to block IP address'; + if (err.data) { + var errData = err.data; + if (typeof errData === 'string') { + try { + errData = JSON.parse(errData); + } catch (e) { + errorMessage = errData || errorMessage; + } + } + if (errData && typeof errData === 'object') { + if (errData.error_message) { + errorMessage = errData.error_message; + } else if (errData.error) { + errorMessage = errData.error; + } else if (errData.message) { + errorMessage = errData.message; + } + } + } else if (err.statusText) { + errorMessage = err.statusText; + } else if (err.status) { + errorMessage = `HTTP ${err.status}: ${err.statusText || 'Unknown error'}`; + } + + console.error('Final error message:', errorMessage); + + if (typeof PNotify !== 'undefined') { new PNotify({ title: 'Error', - text: response.data && response.data.error ? response.data.error : 'Failed to block IP address', + text: errorMessage, type: 'error', delay: 5000 }); } - }, function (err) { - $scope.blockingIP = null; - var errorMessage = 'Failed to block IP address'; - if (err.data && err.data.error) { - errorMessage = err.data.error; - } else if (err.data && err.data.message) { - errorMessage = err.data.message; + }); + } catch (e) { + console.error('========================================'); + console.error('=== ERROR in blockIPAddress ==='); + console.error('========================================'); + console.error('Error:', e); + console.error('Error message:', e.message); + console.error('Error stack:', e.stack); + $scope.blockingIP = null; + if (typeof PNotify !== 'undefined') { + new PNotify({ + title: 'Error', + text: 'An error occurred while trying to ban the IP address: ' + (e.message || String(e)), + type: 'error', + delay: 5000 + }); + } + } + }; + + // Ban IP from SSH Logs + $scope.banIPFromSSHLog = function(ipAddress) { + if (!ipAddress) { + new PNotify({ + title: 'Error', + text: 'No IP address provided', + type: 'error', + delay: 5000 + }); + return; + } + + if ($scope.blockingIP === ipAddress) { + return; // Already processing + } + + if ($scope.blockedIPs[ipAddress]) { + new PNotify({ + title: 'Info', + text: `IP address ${ipAddress} is already banned`, + type: 'info', + delay: 3000 + }); + return; + } + + $scope.blockingIP = ipAddress; + + // Use the Banned IPs system + var data = { + ip: ipAddress, + reason: 'Suspicious activity detected from SSH logs', + duration: 'permanent' + }; + + var config = { + headers: { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post('/firewall/addBannedIP', data, config).then(function (response) { + $scope.blockingIP = null; + if (response.data && response.data.status === 1) { + // Mark IP as blocked + $scope.blockedIPs[ipAddress] = true; + + // Show success notification + new PNotify({ + title: 'IP Address Banned', + text: `IP address ${ipAddress} has been permanently banned and added to the firewall. You can manage it in the Firewall > Banned IPs section.`, + type: 'success', + delay: 5000 + }); + + // Refresh SSH logs to update the UI + $scope.refreshSSHLogs(); + } else { + // Show error notification + var errorMsg = 'Failed to ban IP address'; + if (response.data && response.data.error_message) { + errorMsg = response.data.error_message; + } else if (response.data && response.data.error) { + errorMsg = response.data.error; } new PNotify({ title: 'Error', - text: errorMessage, + text: errorMsg, type: 'error', delay: 5000 }); + } + }, function (err) { + $scope.blockingIP = null; + var errorMessage = 'Failed to ban IP address'; + if (err.data && err.data.error_message) { + errorMessage = err.data.error_message; + } else if (err.data && err.data.error) { + errorMessage = err.data.error; + } else if (err.data && err.data.message) { + errorMessage = err.data.message; + } + + new PNotify({ + title: 'Error', + text: errorMessage, + type: 'error', + delay: 5000 }); - } + }); }; // Initial fetch diff --git a/baseTemplate/templates/baseTemplate/homePage.html b/baseTemplate/templates/baseTemplate/homePage.html index 2a3b3ba88..6fe4418c5 100644 --- a/baseTemplate/templates/baseTemplate/homePage.html +++ b/baseTemplate/templates/baseTemplate/homePage.html @@ -972,22 +972,23 @@ Recommendation:

{$ alert.recommendation $}

- -
- Manage in Firewall - Blocked @@ -1015,12 +1016,43 @@ TIMESTAMP MESSAGE + IP ADDRESS + ACTIONS {$ log.timestamp $} {$ log.message $} + + + {$ log.ip_address $} + + - + + + + + + + Banned + + - + diff --git a/firewall/firewallManager.py b/firewall/firewallManager.py index cc2883520..a50d43339 100644 --- a/firewall/firewallManager.py +++ b/firewall/firewallManager.py @@ -2014,7 +2014,7 @@ class FirewallManager: try: admin = Administrator.objects.get(pk=userID) if admin.acl.adminStatus != 1: - return ACLManager.loadError() + return ACLManager.loadErrorJson('status', 0) ip = data.get('ip', '').strip() reason = data.get('reason', '').strip() @@ -2095,23 +2095,32 @@ class FirewallManager: command = f'chmod 644 {banned_ips_file} && chown root:root {banned_ips_file}' ProcessUtilities.executioner(command, None, True) - # Apply firewall rule to block the IP + # Apply firewall rule to block the IP using ProcessUtilities (handles sudo) try: - # Add iptables rule to block the IP - if '/' in ip: - # CIDR notation - subprocess.run(['iptables', '-A', 'INPUT', '-s', ip, '-j', 'DROP'], check=True) - else: - # Single IP - subprocess.run(['iptables', '-A', 'INPUT', '-s', ip, '-j', 'DROP'], check=True) + # Check if rule already exists to avoid duplicate rules + check_command = f"iptables -C INPUT -s {ip} -j DROP 2>&1" + check_result = ProcessUtilities.executioner(check_command, None, True) - logging.CyberCPLogFileWriter.writeToFile(f'Banned IP {ip} with reason: {reason}') - except subprocess.CalledProcessError as e: - logging.CyberCPLogFileWriter.writeToFile(f'Failed to add iptables rule for {ip}: {str(e)}') + # If rule doesn't exist (check returns non-zero), add it + if check_result != 0: + # Add iptables rule to block the IP using ProcessUtilities (handles sudo) + command = f"iptables -A INPUT -s {ip} -j DROP" + result = ProcessUtilities.executioner(command, None, True) + + if result == 0: + logging.CyberCPLogFileWriter.writeToFile(f'Successfully added iptables rule to ban IP {ip} with reason: {reason}') + else: + logging.CyberCPLogFileWriter.writeToFile(f'Warning: Failed to add iptables rule for {ip} (exit code: {result}), but IP was added to banned list') + # Don't fail the entire operation - IP is still in banned list + else: + logging.CyberCPLogFileWriter.writeToFile(f'IPTables rule already exists for {ip}, skipping') + except Exception as e: + logging.CyberCPLogFileWriter.writeToFile(f'Error adding iptables rule for {ip}: {str(e)}, but IP was added to banned list') + # Don't fail the entire operation - IP is still in banned list final_dic = {'status': 1, 'message': f'IP address {ip} has been banned successfully'} final_json = json.dumps(final_dic) - return HttpResponse(final_json) + return HttpResponse(final_json, content_type='application/json') except BaseException as msg: final_dic = {'status': 0, 'error_message': str(msg)}