Splunk Search

Concurrent Active VPN Sessions on a Timechart

stepheneardley
Explorer

I'm struggling to find a working solution to show cumulative active VPN sessions on a timechart with 20m data points. Using transaction and timechart doesn't really work as it only shows a count based on when the sessions connected and doesn't show persistence across subsequent time points.

Looking at the following examples;

User 1's connection and disconnect

Mar 18 09:09:30 host Mar 18 2020 09:09:30 host : %ASA-4-xxx: Group <xxx> User <User1> IP <123.123.123.123> IPv4 Address <123.123.123.123> IPv6 address <::> assigned to session

Mar 18 09:26:33 host Mar 18 2020 09:26:33 host : %ASA-4-xxx: Group = xxx, Username = User1, IP = 123.123.123.123, Session disconnected. Session Type: SSL. Duration: 17m:3s, Bytes xmt: 6403456, Bytes rcv: 1776534, Reason: User requested

User 2's connection and disconnect

Mar 18 09:09:30 host Mar 18 2020 09:09:30 host : %ASA-4-xxx: Group <xxx> User <User2> IP <123.123.123.123> IPv4 Address <123.123.123.123> IPv6 address <::> assigned to session

Mar 18 09:10:33 host Mar 18 2020 09:10:33 host : %ASA-4-xxx: Group = xxx, Username = User2, IP = 123.123.123.123, Session disconnected. Session Type: SSL. Duration: 1m:3s, Bytes xmt: 6403456, Bytes rcv: 1776534, Reason: User requested

I'd expect my chart to show;

08:40 - 0
09:00 - 2
09:20 - 1
09:40 - 0

Does anyone have a solution for this please?

0 Karma
1 Solution

to4kawa
SplunkTrust
SplunkTrust
|makeresults
| eval _raw="Mar 18 09:09:30 host Mar 18 2020 09:09:30 host : %ASA-4-xxx: Group <xxx> User <User1> IP <123.123.123.123> IPv4 Address <123.123.123.123> IPv6 address <::> assigned to session
Mar 18 09:26:33 host Mar 18 2020 09:26:33 host : %ASA-4-xxx: Group = xxx, Username = User1, IP = 123.123.123.123, Session disconnected. Session Type: SSL. Duration: 17m:3s, Bytes xmt: 6403456, Bytes rcv: 1776534, Reason: User requested
Mar 18 09:09:30 host Mar 18 2020 09:09:30 host : %ASA-4-xxx: Group <xxx> User <User2> IP <123.123.123.123> IPv4 Address <123.123.123.123> IPv6 address <::> assigned to session
Mar 18 09:10:33 host Mar 18 2020 09:10:33 host : %ASA-4-xxx: Group = xxx, Username = User2, IP = 123.123.123.123, Session disconnected. Session Type: SSL. Duration: 1m:3s, Bytes xmt: 6403456, Bytes rcv: 1776534, Reason: User requested"
| rex mode=sed "s/(?m)^\s+//g"
| multikv noheader=t
| stats count by _raw
| rename COMMENT as "this is sample, from here, the logic"
| rex "(?<time>\w{3} \d+ \d\d:\d\d:\d\d)"
| eval _time=strptime(time,"%B %d %T")
| sort 0 _time
| rex "(User|Username) (=|\<) ?(?<user>[^,\>]+)"
| rex "(?<status>assigned|disconnected)"
| eval time2=_time 
| bin span=20m time2
| eval time2=if(status="disconnected",NULL,time2)
| eval _time=coalesce(time2,_time)
| streamstats count(eval(status="assigned")) as session by user
| stats values(eval(if(status="assigned",round(_time),NULL))) as start  values(eval(if(status="disconnected",round(_time),NULL))) as end by user session
| eval timerange=mvrange(start,end,1200)
| mvexpand timerange
| rename timerange as _time
| timechart span=20m count(user)

For multiple login, try streamstats

View solution in original post

0 Karma

spodda01da
Explorer

Hi @stepheneardley,

I am also looking for something similar with concurrent VPN sessions of user. Will you be able to share some insight. I am trying the following ASA events:

May 6 21:42:15 10.90.101.17 :May 06 21:42:54 CDT: %ASA-svc-4-722051: Group <***> User IP IPv4 Address IPv6 address <::> assigned to session

May 6 10:31:32 10.90.101.17 :May 06 10:32:10 CDT: %ASA-svc-4-722037: Group <***> User IP SVC closing connection: Transport closing.

Thanks in advance,

0 Karma

chris_jepeway
New Member

This is working for us:

1. sourcetype=cisco:asa eventtype=cisco_vpn ( tag = start OR tag = end )
2. | transaction user src startswith=established endswith=terminated 
3. | concurrency duration=duration
4. | timechart concurrency span=5m

It relies on the Splunk Add-on for Cisco ASA, and I think that's what's doing the tagging, too.

You could of course just use text searches to get the ASA logs that have the established and terminated strings that transaction is relying on.

0 Karma

stepheneardley
Explorer

Definitely a much cleaner approach. I'll look into this when I get some time. Thank you for sharing.

0 Karma

chris_jepeway
New Member

Let me know how it works out for you, if you don't mind.

I'm pretty sure the transaction isn't strictly necessary, since one of the tag = end messages contains a duration in it. So, something instead like eval session_start = _time - duration | concurrent start=session_start duration=duration would probably get it more efficiently.

But the more general usefulness and applicability of transaction just...stuck with me, I suppose, and so I prefer it.

0 Karma

to4kawa
SplunkTrust
SplunkTrust
|makeresults
| eval _raw="Mar 18 09:09:30 host Mar 18 2020 09:09:30 host : %ASA-4-xxx: Group <xxx> User <User1> IP <123.123.123.123> IPv4 Address <123.123.123.123> IPv6 address <::> assigned to session
Mar 18 09:26:33 host Mar 18 2020 09:26:33 host : %ASA-4-xxx: Group = xxx, Username = User1, IP = 123.123.123.123, Session disconnected. Session Type: SSL. Duration: 17m:3s, Bytes xmt: 6403456, Bytes rcv: 1776534, Reason: User requested
Mar 18 09:09:30 host Mar 18 2020 09:09:30 host : %ASA-4-xxx: Group <xxx> User <User2> IP <123.123.123.123> IPv4 Address <123.123.123.123> IPv6 address <::> assigned to session
Mar 18 09:10:33 host Mar 18 2020 09:10:33 host : %ASA-4-xxx: Group = xxx, Username = User2, IP = 123.123.123.123, Session disconnected. Session Type: SSL. Duration: 1m:3s, Bytes xmt: 6403456, Bytes rcv: 1776534, Reason: User requested"
| rex mode=sed "s/(?m)^\s+//g"
| multikv noheader=t
| stats count by _raw
| rename COMMENT as "this is sample, from here, the logic"
| rex "(?<time>\w{3} \d+ \d\d:\d\d:\d\d)"
| eval _time=strptime(time,"%B %d %T")
| sort 0 _time
| rex "(User|Username) (=|\<) ?(?<user>[^,\>]+)"
| rex "(?<status>assigned|disconnected)"
| eval time2=_time 
| bin span=20m time2
| eval time2=if(status="disconnected",NULL,time2)
| eval _time=coalesce(time2,_time)
| streamstats count(eval(status="assigned")) as session by user
| stats values(eval(if(status="assigned",round(_time),NULL))) as start  values(eval(if(status="disconnected",round(_time),NULL))) as end by user session
| eval timerange=mvrange(start,end,1200)
| mvexpand timerange
| rename timerange as _time
| timechart span=20m count(user)

For multiple login, try streamstats

View solution in original post

0 Karma

sjbriggs
Explorer

Can you explain real quick what the 1200 in this line is doing:

eval timerange=mvrange(start,end,1200)

Is that assuming a 12 hour window?    Or is that the number of seconds in 20 minutes? 

0 Karma

to4kawa
SplunkTrust
SplunkTrust

>Or is that the number of seconds in 20 minutes? 

yes, 60(s)*20=1200

stepheneardley
Explorer

Thanks for the impressive query @to4kawa but it doesn't appear to work. Each of the syslog lines in your _raw evaluation aren't being treated as individual events. I'm running this search on an index containing many thousands of lines like the 4 example events I provided in the question.

0 Karma

to4kawa
SplunkTrust
SplunkTrust

If you search , try after no.10
If you understand my query, you can do it.

0 Karma

stepheneardley
Explorer

Figured it out. I eval'd null end values to current time which made them chart. Great solution!

0 Karma

stepheneardley
Explorer

Ahhh I see how you did it 🙂 This is awesome however timerange does not get calculated when a user has logged in and out multiple times. I'm not sure how to handle that.

Example

User---------Start---------------End

User1-------1584522000-----1584545193

----------------1584546000-----1584570799

0 Karma
.conf21 CFS Extended through 5/20!

Don't miss your chance
to share your Splunk
wisdom in-person or
virtually at .conf21!

Call for Speakers has
been extended through
Thursday, 5/20!