- Why brick was created
- Preparation
- Presentation
- High-level overview
- Improvements
- Upstream feature requests
- References
This demo is intended to answer that question by covering:
- brief history of dealing with account abuse
- current functionality provided by this application
- future improvements, pending approval of time and resources
- Boot throwaway Ubuntu Linux 18.04 LTS desktop VM older or newer versions may work, but have not received as much testing
- Install
git
sudo apt-get update && sudo apt-get install -y git
- Clone remote repo
cd $HOME/Desktop
git clone https://github.com/atc0005/brick
- Note: Depending on project development timing, this might actually be a different repo path
- Run demo scripts 1-4
contrib/demo/scripts/01-install-docker.sh
contrib/demo/scripts/02-install-dependencies.sh
contrib/demo/scripts/03-install-demo-tooling.sh
contrib/demo/scripts/04-setup-env.sh
- Shutdown VM
- Take snapshot
- Boot VM
- Run
go version
to ensure thatgo
is properly registered inPATH
- Run demo script 5
contrib/demo/scripts/05-deploy.sh
- Reset demo environment
- run
contrib/demo/scripts/06-reset-env.sh
- this is even for the first part of the demo to ensure we are working from a consistent state throughout the demo
- this does not modify existing copies of the config files in the
/usr/local/etc/brick/
directory
- run
- Open a web browser directly within the demo VM or on the VM host
- Navigate to the IP Address of the VM +
:1080
- e.g.,
http://192.168.92.136:1080/
orhttp://localhost:1080/
- e.g.,
- Enable automatic refresh of mailbox contents
-
Add
brick
repo path to workspace -
Add
/var/log/brick
path to workspace -
Add
/usr/local/etc/brick
path to workspace -
Add
/var/cache/brick
path to workspace -
Add
/usr/local/ezproxy
path to workspace -
Install extensions
Even Better TOML
(tamasfe.even-better-toml
)
-
Configure settings
{ "workbench.startupEditor": "newUntitledFile", "telemetry.enableTelemetry": false, "telemetry.enableCrashReporter": false, "workbench.activityBar.visible": true, "editor.minimap.enabled": false }
-
Open
/usr/local/etc/brick/config.toml
-
Open
/usr/local/etc/brick/users.brick-ignored.txt
-
Open
/usr/local/etc/brick/ips.brick-ignored.txt
We're going to make changes to these latter files in a bit and having them open already during the demo should help speed things up.
Configure brick
:
- Open
/usr/local/etc/brick/config.toml
- Set
ignore_lookup_errors
totrue
- Retrieve webhook URL from Microsoft Teams Connector
- assumption: We will use an existing "testing" channel
- Set
msteams.webhook_url
to the webhook URL retrieved from the test Microsoft Teams channel - Comment out
msteams.webhook_url
line- this disables Microsoft Teams notifications for now
- Set
ezproxy.terminate_sessions
totrue
- TODO: Decide if this will be enabled initially, or as a follow-up item
- Configure email settings
email.server
tolocalhost
email.port
to25
email.client_identity
tobrick
- a production system should set this to the fully-qualified hostname of the sending system
- a production system should also have a Forward-confirmed reverse DNS (FCrDNS configuration to enable the most reliable delivery possible
email.sender_address
tobrick@example.org
email.recipient_addresses
to["help@example.org"]
email.rate_limit
to3
email.retries
to2
email.retry_delay
to2
- Comment out
email.server
- this disables email notifications for now
Configure guake
for demo:
- create labeled tabs
Deploy
Splunk (Payload)
syslog entries
disabled user entries
reported user entries
- aka, "action" entries
fail2ban log
- Configure 100% height/width
- Disable transparency
- Enable 9000 lines scroll-back (hopefully not needed)
- Clear screen in each
guake
tab, tail log files, pipe throughccze -A
Deploy
- none
Splunk (Payload)
- No log file; stage
curl
commandcd $HOME/Desktop/brick/contrib/tests
curl -X POST -H "Content-Type: application/json" -d @splunk-sanitized-payload-formatted.json http://localhost:8000/api/v1/users/disable
- No log file; stage
syslog entries
clear && tail -f /var/log/brick/syslog.log | ccze -A
disabled user entries
clear && tail -f /var/cache/brick/users.brick-disabled.txt | ccze -A
reported user entries
clear && tail -f /var/log/brick/users.brick-reported.log | ccze -A
fail2ban log
clear && tail -f /var/log/fail2ban.log | ccze -A
email log
clear && tail -f /var/log/mail.log | ccze -A
- Start slideshow
- Step through each slide, checking for notes in the presenter's Notes box
- Make sure to pause momentarily for questions
- On the Demonstration slide, switch back to this document (offscreen)
- Start with payload tab
- Mention that this emulates receiving a Splunk alert
- We have permission from NetSec to run the search every 5 minutes
- Splunk alerts will continue to trigger for every Username/IP pair associated with the thresholds we have defined for the Splunk alerts.
- We may have to adjust those thresholds to get the desired behavior over time.
- Switch to syslog entries tab
- syslog entries are automatically forwarded to sawmill1 and on to Graylog where they are searchable
- Mention the periodic stats output showing how many notification messages
were generated vs what was actually set
- At this point Teams should have all zeros; we haven't enabled Teams notifications yet
- Switch to disabled user entries tab
- Emphasize format and fields recorded
- comment
Username
Source IP
(aka,User IP
)Alert name
(1:1 with name shown inSplunk Alerts
panel)Alert sender IP
(aka,Distributed IT Splunk search head
)- Useful if we have someone intentionally (or otherwise) attempt to spoof a Splunk alert payload
- Note: Splunk does not appear to support providing any sort of authentication token/key to prove its identity, so we'll need to use host-level firewall rules to help control abuse
- SearchID (should be 1:1 with value recorded in Splunk's logs if we ever need to dig that deep)
username::deny
format- matches existing
users.disabled.txt
file format which we maintain by hand - plan for disabled user files
- keep one file for manual entries
- add another to be automatically maintained by
brick
- matches existing
- comment
- Emphasize format and fields recorded
- Switch to reported user entries
- Mention that the entries come in pairs
- an alert was received
- this is what we did about it
- Mention that there is no guarantee that they'll be in order (though they
often will be)
- use
SearchID
to match up report/action pairs
- use
- Mention that we'll come back to this tab later to show additional entry types
- Mention that the entries come in pairs
- Switch to fail2ban log tab
- Note
bantime
value - Note
found
line - Note
Ban
line - Mention that we'll come back in a moment
- Note
- Open web browser
- Navigate to
http://localhost:1080/
- Show the fail2ban alert email
- mention that GeoIP functionality would be available for non-private IPs
- mention that we can customize the alerts to use Redmine "include" pages to allow a standardized "what do I do with this alert?" guide
- Navigate to
- Switch back to
Splunk (Payload)
tab- Submit another payload for the same username
- Mention that this simulates a repeat alert in case the Splunk
Agent/Forwarder on the EZproxy server gets "stuck" after the initial
alert and finally unsticks sending in queued entries after the
"cooldown" timer on the Splunk "search head" expires, which from
brick
's perspective is a duplicate disable request
- Switch to the
syslog entries
tab- Note "already disabled" wording
- Switch to the
disabled user entries
tab- Note that there is still only one entry
- this is as expected
- Note that there is still only one entry
- Switch to the
reported user entries
tab- Note the new pair of entries
- Report: same format as before
- Action: same "DISABLE" prefix as before, but …
- The log entries explicitly notes that the user account has already been disabled, but had it not, it would be again due to XYZ alert (should be a different SearchID than the original disable action)
- The IP Address could be different and often would be different for cases where a compromised account is shared. We want to disable ALL IPs associated with a compromised account (note that we'll return to that shortly; (we're going to demo the "ignored users/ips" support, but don't mention that just yet)
- Note the new pair of entries
- Switch to the
fail2ban log
tab- Note that it recognizes the "duplicate" report
- The current configuration doesn't do this, but fail2ban offers the ability to reset unban timers for each additional match
- We don't do that on purpose; we want to ban the IP of the original disable request only long enough to terminate the matching user session as other legitimate users may be coming from that IP.
- Note that once the fail2ban timer expires for the original IP, other users from that IP Address will be allowed to connect to EZproxy again. The disabled account will stay disabled.
- Note that it recognizes the "duplicate" report
Use the same test username as before.
- Enable Teams webhook in
/usr/local/etc/brick/config.toml
- Uncomment webhook URL entry added earlier
- Reset demo environment
- Submit two payloads
- Switch to Teams channel
- First message indicates payload receipt
- Second message indicates errors (if any), actions taken
- Switch to the
syslog entries
tab- point out Teams notifications details
- Switch to the disabled
user entries
tab- show that there is still only one entry
- Switch to the
reported user entries
tab- Show familiar entries
- Switch to the
fail2ban log
tab- Show familiar entries
- Switch to the MailDev container
- Accessible within demo VM or externally on NAT network
- Step through all notifications
Do not reset demo environment; we need to have the prior entries/settings as-is.
- Modify the
contrib/tests/splunk-sanitized-payload-formatted.json
file- Replace test account IP Address with
123.123.123.123
- Replace test account IP Address with
- Switch to
Splunk (Payload)
tab- Submit payload
- Switch to
syslog entries
tab - Switch to
disabled user entries
tab- Note that the user account won't be disabled twice
- Switch to the
reported user entries
tab- Note that the "already disabled" message is present as before, but now we see a different IP Address than when the user was first banned
- Switch to the
fail2ban log
tab- Mention that the new IP associated with the disabled user account has
been banned
- This will cause the associated session to timeout
- Mention that the new IP associated with the disabled user account has
been banned
- Modify the
contrib/tests/splunk-sanitized-payload-formatted.json
file- Replace earlier test account with mine
- Replace test IP Address with
4.4.4.4
- Add my user account to the ignored user file
/usr/local/etc/brick/users.brick-ignored.txt
- Should already be open in VS Code from earlier prep step
- Submit the updated payload
- Switch to the syslog entries tab
- Note the Ignored entry there
- Switch to the disabled user entries tab
- show that no new entries were added
- Switch to the reported user entries tab
- show that an IGNORED entry was added along with sufficient details explaining why
- "ignored" user accounts are "protected" from disable actions (see next)
- Switch to the fail2ban log tab
- show that no new bans are present
- Note: Other requests from Splunk tied to the same IP for other usernames won't disable this account, but they will be temporarily banned due to the shared IP Address. Once the IP is unbanned, non-disabled accounts can use EZproxy as before
- Switch to Microsoft Teams a. Show the notification pair
- Modify the
contrib/tests/splunk-sanitized-payload-formatted.json
file- Replace my account with another team member's
- Add IP Address to the ignored IP Address file
- IP:
10.10.10.10
- arbitrary, just writing it out here for reference
- File:
/usr/local/etc/brick/ips.brick-ignored.txt
- Note: should already be open in VS Code from earlier prep step
- IP:
- Switch to the payload tab
- Submit payload
- Switch to the syslog entries tab
- Note ignored entry there
- Switch to the disabled user entries tab
- show that no new entries were added
- Switch to the reported user entries tab
- show that an IGNORED entry was added along with sufficient details explaining why
- Switch to the fail2ban log tab
- show that no new bans are present
- Note: all non-disabled user accounts associated with the ignored IP entry are "protected" or ignored
- Switch to Microsoft Teams
- Show the notification pair
See Overview doc for additional details.
-
Email notifications directly from
brick
- analogue to Teams notifications
-
Support for automatic sessions termination
- using official
ezproxy
binary - using unsupported
kill
subcommand of officialezproxy
binary
- using official
- Additional endpoints
- list disabled user accounts
- user accounts disabled by this application (
users.brick-disabled.txt
) - user accounts disabled manually (
users.disabled.txt
)
- user accounts disabled by this application (
- list log messages associated with disabled user accounts
- list disabled user accounts
Many of these improvements are likely on hold pending investment of time/support from leadership.
- "Warning-only" behavior based on specific fields or alert name prefixes
- Disable for high-confidence alerts
- Warning for anything else
- LDAP
- Use LDAP package to add disabled users to a Library-specific AD group
- Update EZproxy (test instance first) to deny login access to users in this AD group
- Refactoring to allow
brick
to take general actions from Splunk, Graylog or another alert- restart a service
- force a user account to logout & ban them
- submit API request to Service Now to indicate problems with a system
- submit API requests to Redmine to add, create or update tickets
- Refactoring to allow
brick
to receive payloads from other services (and take specific actions, perhaps branching paths based on the notification source or endpoint used (most likely)- GitHub
- Office 365
- Our own services/tooling
- e.g., RSS or Atom feed updates monitoring by another could result in a
payload submission to
brick
which kicks off a pipeline
- e.g., RSS or Atom feed updates monitoring by another could result in a
payload submission to
The following enhancement requests would help regardless of whether we use
brick
:
- Add support for dynamically denying access to specified IPs
- without restarting EZproxy
- Add (official) support to terminate active user sessions via API or other
external control
- without restarting EZproxy
- Note: This support is available as of right now (learned this after the May 2020 demo), but OCLC Support has indicated it isn't official and could go away without notice.
These are references intended for the audience to review just after a demo wraps up.
-
"Brick" image
-
Splunk
-
EZproxy
-
Fail2ban
-
Brick