Compiling NetXMS Agent on Alpine Linux

I needed to use the NetXMS agent on my Alpine Linux system which I am using as a utility linux server. The source-code download link for NetXMS v2.2.10 (latest at the time of this writing) is at https://www.netxms.org/download/releases/2.2/2.2.10/netxms-2.2.10.tar.gz

Here is the quick set of dependent packages and libraries I needed to install to be able to compile the NetXMS agent for my Alpine Linux box.

apk add --update alpine-sdk
apk add gcc glibc 
apk add g++ automake openssl-dev
apk add libcurl curl-dev
apk add libssh-dev
apk add mosquitto-libs mosquitto-dev
apk add cmake
apk add linux-headers

After installing the above, I could compile and install the NetXMS Agent component with:

tar -xzvf netxms-2.2.10.tar.gz
cd netxms-2.2.10
sh ./configure --with-agent
make
make install

After successful installation you can just modify your NetXMS Agent config at /etc/nxagentd.conf (or copy it over from one of your other linux boxes) and launch the agent as a daemon using:

nxagentd -D

Monitoring Windows RDP Sessions with Splunk

Install Splunk UF on Windows via Command Prompt/PowerShell:

This little one-liner can be used to install the Splunk Universal Forwarder (UF) on Windows Systems supporting powershell. Ofcourse you need administrative priviliges for the user running the powershell session and the installer MSI file needs to be accessible in the provided location (Network paths can also be used)

msiexec.exe /i \temp\splunkforwarder-7.2.0-x64.msi DEPLOYMENT_SERVER="<splunk-deployment-server>:8089" RECEIVING_INDEXER="<splunk-indexer>:9997" AGREETOLICENSE=Yes SPLUNKPASSWORD="PutYourPasswordHere" /L*v \temp\logfile.txt

Monitoring RDP Login Users with Source IP

Generally the Windows Security Logs have a decent bunch of information and can be monitored by default using the Splunk UF and the Splunk Add-On for Windows but there is a major pain when it comes to corelating Logon IDs with the actual Source IP Address of the incoming RDP connection and also differentiating local console sessions from RDP sessions. The better approach is to monitor the TerminalServices-LocalSessionManager -> Operational logs. To get it running, add the following stanza to your inputs.conf.

#$SPLUNKPATH/apps/Splunk_TA_windows/local/inputs.conf
[WinEventLog:Microsoft-Windows-TerminalServices-LocalSessionManager/Operational]
disabled = 0

Once you have logs rolling in for the above source, you can use the below search queries to show “completed” or “currently running” RDP sessions. I have yet to test whether it also logs “Local” console sessions but I think it does.

RDP Completed Sessions:

index=main source="wineventlog:microsoft-windows-terminalservices-localsessionmanager/operational" NOT Message="*arbitration*" NOT Message="Session *" host="<your-host-here>"
| eval Message = replace(Message,"[\n\r]+", " ")
| eval userstring = mvindex(User, -1)
| eval Domain = mvindex(split(userstring,"\\"),0)
| eval Domain=mvfilter(NOT match(Domain,"NOT_TRANSLATED") )
| eval User = mvindex(split(userstring,"\\"),1)
| transaction Session_ID, User, Source_Network_Address startswith=( ( Message="*logon succeeded*") OR (Message="*reconnection succeeded*") ) endswith=( ( Message="*logoff succeeded*") OR (Message="*Session has been disconnected*") )
| eval start_time = strftime(_time, "%Y-%m-%d %H:%M:%S")
| eval end_time = strftime(_time+duration, "%Y-%m-%d %H:%M:%S")
| table start_time, end_time, Session_ID, Domain, User, Source_Network_Address, duration
| rename Session_ID as "Session ID", Source_Network_Address as "Source Address", duration as "Duration", start_time as "Start Time", end_time as "End Time"

RDP Timeline: (Requires Timeline Visualization Addon)

index=main host="<your-host-here>" source="wineventlog:microsoft-windows-terminalservices-localsessionmanager/operational" NOT Message="*arbitration*" NOT Message="Session *" 
| eval Message = replace(Message,"[\n\r]+", " ") 
| eval userstring = mvindex(User, -1) 
| eval Domain = mvindex(split(userstring,"\\"),0) 
| eval Domain=mvfilter(NOT match(Domain,"NOT_TRANSLATED") ) 
| eval User = mvindex(split(userstring,"\\"),1) 
| transaction Session_ID, User, Source_Network_Address startswith=( ( Message="*logon succeeded*") OR (Message="*reconnection succeeded*") ) endswith=( ( Message="*logoff succeeded*") OR (Message="*Session has been disconnected*") ) 
| eval durationmilliseconds=duration*1000 
| eval usersession=User." (S#".Session_ID.")" 
| table _time usersession Source_Network_Address durationmilliseconds Session_ID

Happy Splunking!