How can I automatically block a potentially malicious IP address on a pfSense firewall?

Article ID: 402
Category: Network Services
Applies to: 4.0.3
Updated: 2023-04-13

Requires: EventSentry NetFlow license, pfSense 2.4 or later, psexec, kitty_portable

Starting with EventSentry v4.0.3, EventSentry can log events when a potentially malicious IP address has been detected via NetFlow. This event can subsequently be used to trigger a process that remotely logs into the pfSense firewall to block the IP address. Note that other firewalls may support similar functionality, this is not covered in this article.

Before continuing, make sure that EventSentry is receiving and displaying NetFlow data in the web reports under Network -> NETFLOW -> History.

1. Enabling Malicious IP Detection
In the management console, navigate to Home -> Global Options and enable the "Get Threat Intel" check box on the "General" tab. If you have an AbuseIP subscription (recommended) then enter the API key as well. This first check box enables malicious IP detection in general and makes that data available in the web reports. Switch to the "NetFlow to EventLog" tab and then enable the "Alert on suspicious IP addresses" option, which will log alerts to the event log.

2. Install KiTTY
We will utilize this free app to log on to the pfSense firewall and issue the necessary commands to block an IP address. You can download KiTTY from here.

3. Enable SSH access on pfSense
SSH access needs to be enabled on the pfSense firewall in order to block IP addresses remotely. Log into the pfSense web portal and navigate to System -> Advanced, enable the "Enable Secure Shell" option and click save. Remain logged in.

4. Blocking Script
Create a script named block_ip.cmd on the machine where the EventSentry Network Services are running with the following content:

"C:\Tools\pfSense\kitty_portable.exe" -ssh admin@192.168.1.1 -pw DaWery5ecur3Pa$$w0rd -cmd "8 \n easyrule block wan %1 \n exit \n 0"

In this example both kitty_portable.exe and the script are located in the C:\Tools\pfSense directory. The IP address (192.168.1.1) and the password (TheVerySecurePassword) will need to be replaced with the connection info of your firewall.

5. Testing the Script
Since all SSH client require that the public key of the remote SSH server are acknowledged when connecting for the first time, it's important to run the script once under the context of the EventSentry Agent (LocalSystem by default). The easiest way to do do this is with the psexec utility. Run the following command to run the script under the context of the agent:

psexec -sid C:\Tools\pfsense\block_ip.cmd 10.254.254.254

SSH Public Key Prompt

Accept the public key from the remote host when prompted by clicking Yes. You should see a command window pop up for a few seconds and then disappear again. Running the "easyrule block" command for the first time will create a new alias in the firewall. To confirm this, switch to the pfSense web portal and navigate to Firewall -> Aliases and verify that a EasyRuleBlockHostsWAN rule as shown below exists. The test IP address 10.254.254.254 can be deleted later.

pfSense Alias

Running the psexec command again should not prompt you for the public key again.

6. Securing the Script
It is of utmost importance that all external scripts referenced by EventSentry are only accessible to authorized users, failure to do so could allow local non-admin users to elevate their access on the system:

  • READ ACCESS: Since the script contains credentials to the firewall make sure that only privileged users can read the contents of this file.
  • WRITE ACCESS: Since scripts are usually executed under the context of the LocalSystem user, only privileged users should have write access to the file.

7. Creating Actions
Now that you can semi-automatically block an IP address by running C:\Tools\pfsense\block_ip.cmd , it's time to link this script to the NetFlow alert that EventSentry generates. Since malicious IP addresses can be reported as both a source and destination address in event 820 we will need to create two actions to accommodate both scenarios.

EventSentry Network Services, Event ID 820:

A potentially malicious IP address was observed:

Source
IP Address: %1
Port: %2
Threat Confidence: %3/100
Threat Reports: %4
Threat Details: %5

Destination
IP Address: %6
Port: %7
Threat Confidence: %8/100
Threat Reports: %9
Threat Details: %10

Action #1
* First right-click on the Actions container and select "Add Action", you can also use the Ribbon. Specify a descriptive name (e.g. pfSense Block Source IP) and select Process as the action type and click OK.
* Specify the path to the script (C:\Tools\pfsense\block_ip.cmd) and specify the command line parameter as $STR1

Action #2
* First right-click on the Actions container and select "Add Action", you can also use the Ribbon. Specify a descriptive name (e.g. pfSense Block Destination IP) and select Process as the action type and click OK.
* Specify the path to the script (C:\Tools\pfsense\block_ip.cmd) and specify the command line parameter as $STR6

EventSentry Action

Note how the parameters $STR1 and $STR6 match the insertion strings %1 and %6 above.

8. Creating Event Log Filters
Finally we need to properly trigger the two actions created in the previous step. In most cases you'll want to create a new event log package and assign that to the host where the EventSentry Network Services are running.

Then, add a filter with the following properties:

Action: Block IP pfSense Source
Event Log: Application
Event Source: EventSentry Network Services
Event Category: NetFlow
Event ID: 820
Content Filter: Insertion String 3 more than 0

To cover the destination IP address as well, add another similar filter:

Action: Block IP pfSense Destination
Event Log: Application
Event Source: EventSentry Network Services
Event Category: NetFlow
Event ID: 820
Content Filter: Insertion String 8 more than 0

Filter for blocking IPs

The content filters in each filter ensure that the correct IP address is blocked, so not to block internal IP address for example. This may not be absolutely necessary since the IPs are only blocked on the WAN interface of the firewall by default anyways, but it is a cleaner solution regardless.