27/04/2021

How to block IP addresses in the Ubuntu firewall

Does this sound familiar:


	SMTP Server: Authentication failed for user hydra@somedomain.net ; connecting host 212.70.149.86
		
Hackers! They are trying to penetrate your system, you want to block them and preferrably in the firewall, so Domino doesn't even notice.

Can we do something about it? Definitely. Below I present to you (1) a simple agent that sends IP-addresses to Ubuntu's firewall, and (2) some configuration settings in the events4.nsf database.

The idea is to add an Event handler per server, in the Monitoring Configuration database, that triggers an agent in yet another database. Separate, so the design of the events4.nsf database isn't changed. I called mine dds.nsf, Domino Domain Security. It's based on the StdR5StatReport template, just like the Monitoring Results database you can find on your server.

Maybe it's better to show you the agent:


%REM
	Agent Block Intruder
	Created Feb 14, 2021 by Sjef Bosman/TCM
	Description: Block IP addresses on an Ubuntu server
%END REM
Option Public
Option Declare

Class IPBlocker
	Private blocked List As Boolean 
	Private n As Integer
	Private cmd As String
	
	Sub New
		cmd= |/bin/sudo firewall-cmd --add-rich-rule='rule family=ipv4 source address=|
	End Sub
	
	Sub block(ip As String)
		Dim r As Integer 
		If Not IsElement(blocked(ip)) Then
			Print "Blocking IP " ip
			r= Shell(cmd + ip + | reject' --permanent|)
			blocked(ip)= True
			n= n + 1 
		End If 
	End Sub
	
	Sub flush
		Dim r As Integer 
		If n>0 Then
			r= Shell(|/bin/sudo sudo firewall-cmd --reload|)
			Print "IP addresses blocked: " n
		End If
	End Sub
End Class

Sub Initialize
	Dim ns As New NotesSession
	Dim db As NotesDatabase
	Dim dc As NotesDocumentCollection
	Dim doc As NotesDocument
	Dim doc2 As NotesDocument
	Dim v As Variant
	Dim blocker As New IPBlocker 
	
	Set db= ns.Currentdatabase
	Set dc= db.Unprocesseddocuments
	Set doc= dc.Getfirstdocument()
	Do Until doc Is Nothing
		Select Case doc.ErrorCode(0)
		Case "SMTP Server0x336E":
			v= Split(doc.EventText(0), " ") ' last element is ip-address
			Call blocker.block(CStr(v(UBound(v))))
		End Select
		Set doc2= dc.Getnextdocument(doc)
		Call ns.Updateprocesseddoc(doc)
		Set doc= doc2
	Loop
	Call blocker.flush()
End Sub
    

Some explanation:

  • The class IPBlocker collects IP addresses and updates the firewall if not yet blocked during the execution of this agent
  • At the end, the firewall is told to update its internal tables
  • The main code walks through the unprocessed documents in the current database, checks if it's an intruder, gets the IP address and blocks it
  • The cmd variable/field isn't required, I needed it to fit the code on this page...
  • The Event document is to be created in the Monitoring Configuration database, as follows:

  • open the view Event Handlers/By Server
  • add a New Event Handler
  • Server(s) to monitor: Notify of the event on any server in the domain
  • Notification trigger: Any event that matches a criteria
  • Events must be this type: Mail
  • Events must be one of these severities: Fatal; Failure; Warning (high)
  • Events must have this text in the event message: Authentication failed
  • Notification Method: Log to a database
  • Database file name: dds.nsf
  • Log to the database on the same server where the event occured
  • Enablement: Enable this notification
  • Important: the Domino user ("notes") must have sudo rights without a password. Of course the agents should be signed by a user with sufficient rights to execute agents on the server.

    And the result:

    
    27/04/2021 18:33:49   SMTP Server: Authentication failed for user smtp@somedomain.net ; connecting host 103.99.0.23
    27/04/2021 18:33:50   SMTP Server: Authentication failed for user sodoff@somedomain.net ; connecting host 103.99.0.23
    27/04/2021 18:36:10   AMgr: Agent ('Block Intruder' in 'dds.nsf') printing: Blocking IP 103.99.0.23
    27/04/2021 18:36:12   AMgr: Agent ('Block Intruder' in 'dds.nsf') printing: IP addresses blocked:  1 	
    	

    It seems sensible to block complete IP-ranges, with some additional code in the IP-blocker class. The shell command is the following:

    
    	firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='45.0.0.0/8' reject"
    		
    Do try it!

    © 2020 Sjef Bosman · Consultant HCL Domino/Notes
    SIRET 442 133 252 00019 · tél. +33 475 252 805
    sjef@bosman.fr · sjef.bosman