Splunk Search

Concurrent Active VPN Sessions on a Timechart

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

Ultra Champion
|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

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

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

Explorer

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

0 Karma

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

Ultra Champion
|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

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

Ultra Champion

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

0 Karma

Explorer

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

0 Karma

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