Have you ever wondered who plugged a USB device into your Linux server while you weren’t around? I used to dismiss that question — until I audited a production server and discovered that someone had connected an unknown USB device at 2 AM without anyone knowing.
USB forensics is often overlooked in security checklists, even though it’s an extremely dangerous attack vector. BadUSB, HID injection, data exfiltration via USB — all of these leave traces in the kernel log if you know how to read them. In this article, I’ll compare the different investigation approaches, then dive straight into usbrip — the dedicated tool for this job.
Three Ways to Investigate USB Connection History on Linux
Method 1: Reading System Logs Directly
Linux records every USB event in syslog or the journal. You can do a raw grep:
# With systemd journal
journalctl | grep -i usb
# With classic syslog
grep -i usb /var/log/syslog
# Check dmesg right when USB is connected
dmesg | grep -i usb | tail -50
Typical output looks like this:
Jun 20 02:14:33 server kernel: usb 1-1.2: new high-speed USB device number 5 using xhci_hcd
Jun 20 02:14:33 server kernel: usb 1-1.2: New USB device found, idVendor=0930, idProduct=6545
Jun 20 02:14:33 server kernel: usb 1-1.2: Product: DataTraveler 3.0
Jun 20 02:14:33 server kernel: usb 1-1.2: SerialNumber: 001B12345678
Method 2: Using udev Rules with a Custom Script
Create a udev rule to automatically log every USB connection:
sudo nano /etc/udev/rules.d/99-usb-log.rules
ACTION=="add", SUBSYSTEM=="usb", RUN+="/usr/local/bin/log-usb.sh"
#!/bin/bash
# /usr/local/bin/log-usb.sh
echo "$(date) | VID=$ID_VENDOR_ID | PID=$ID_MODEL_ID | Serial=$ID_SERIAL | Model=$ID_MODEL" \
>> /var/log/usb-connections.log
Method 3: Using usbrip — The Dedicated Tool
usbrip is a Python tool written specifically for USB forensics. It parses kernel logs, organizes them into structured data, supports JSON/HTML output, and includes built-in violation detection based on a whitelist — something the other two methods lack.
# View USB history in a clean format
usbrip events history
# Compare against whitelist
usbrip events violations -a auth.json
Comparing the Pros and Cons of Each Method
Raw system logs: Nothing to install, but the output is messy and hard to read for serious investigations. You’ll spend hours sifting through plain text with no structured data and no automatic violation detection.
udev + script: Good for real-time monitoring from the point of setup onward, but there’s no historical data from before setup. You have to write your own detection code — error-prone and hard to maintain.
usbrip: Takes a few minutes to set up, but everything is much simpler afterward. Most importantly, it can read historical logs — essential when investigating an incident that happened in the past. Built-in JSON/HTML export for reporting.
Which Method Should You Choose?
I typically use a combination: usbrip for forensic investigation, udev rules for real-time alerts.
- Investigating a past incident → usbrip, because it reads historical logs
- Want an immediate alert when an unknown USB is plugged in → udev + script
- Just need a quick one-time check → grep syslog is enough
After auditing security on 10+ servers, I noticed most share the same fundamental gaps — including no USB device tracking. Most sysadmins focus on network security while physical access is left completely unmonitored. usbrip addresses this without much effort.
Installing and Using usbrip
Installation
usbrip requires Python 3.6+:
# Ubuntu/Debian
sudo apt install python3-pip
# Install usbrip
sudo pip3 install usbrip
# Verify
usbrip --version
Or install from source:
git clone https://github.com/snovvcrash/usbrip.git
cd usbrip
sudo pip3 install -r requirements.txt
sudo python3 setup.py install
Viewing USB Connection History
# View full history
usbrip events history
# Filter by specific date
usbrip events history --date 2026-06-20
# Export to JSON for further analysis
usbrip events history -q --json /tmp/usb-history.json
Output is displayed as a color-coded table, much clearer than grepping syslog:
Connected | Host | VID | PID | Manufact | Product | Serial
--------------+----------+------+------+----------+---------------+------------------
2026-06-20 | server01 | 0930 | 6545 | Kingston | DataTraveler | 001B12345678
02:14:33 | | | | | 3.0 |
Creating a Whitelist of Authorized Devices
This is the most important step for violation detection. You define which USB devices are allowed to connect:
# Auto-generate auth list from current history
sudo usbrip events gen_auth /etc/usbrip/auth.json
# Or create manually
mkdir -p /etc/usbrip
cat > /etc/usbrip/auth.json << 'EOF'
{
"authorized": [
{
"vid": "0930",
"pid": "6545",
"prod": "DataTraveler 3.0",
"manufact": "Kingston",
"serial": "001B12345678"
},
{
"vid": "046d",
"pid": "c52b",
"prod": "USB Receiver",
"manufact": "Logitech",
"serial": null
}
]
}
EOF
Set serial: null for mice and keyboards — devices that typically don’t have a serial number.
Detecting Unauthorized Devices
# Check violations against whitelist
usbrip events violations -a /etc/usbrip/auth.json
# Verbose output — more detailed information
usbrip events violations -a /etc/usbrip/auth.json -v
# Export violations to JSON file
usbrip events violations -a /etc/usbrip/auth.json -q --json /tmp/violations.json
If unauthorized devices are found, usbrip highlights them in red and displays full details: connection time, VID/PID, device name, and serial number.
Automation: Scheduled Runs and Alerts
For real-world production value, automate this with crontab:
#!/bin/bash
# /usr/local/bin/usb-check.sh
AUTH_FILE="/etc/usbrip/auth.json"
REPORT="/tmp/usb-violations-$(date +%Y%m%d).json"
EMAIL="[email protected]"
usbrip events violations -a "$AUTH_FILE" -q --json "$REPORT" 2>/dev/null
# Send email if violations detected
if [ -s "$REPORT" ]; then
echo "WARNING: Unauthorized USB device detected on $(hostname)" | \
mail -s "[SECURITY ALERT] USB Violation" -A "$REPORT" "$EMAIL"
fi
# Add to crontab — runs daily at 8 AM
sudo crontab -e
# Add this line:
0 8 * * * /usr/local/bin/usb-check.sh
Storing History Independent of System Logs
This is a useful usbrip feature that many people overlook. System logs rotate after 7-30 days, but usbrip’s storage doesn’t:
# Create storage from current logs
sudo usbrip storage create history
# Update storage with new events
sudo usbrip storage update history
# Read from storage (faster than parsing logs)
usbrip storage open history
A Few Notes for Real-World Deployment
Log rotation is your biggest enemy: On many servers, syslog rotates after 7 days. If an incident happened two weeks ago, the evidence is gone. Increase journald retention to keep logs longer:
sudo nano /etc/systemd/journald.conf
# Add or modify:
MaxRetentionSec=90day
SystemMaxUse=500M
sudo systemctl restart systemd-journald
usbrip is not a SIEM: It only tracks USB events. To find out what a USB device was actually used for — where it was mounted, which files were copied — you need to combine it with auditd. usbrip tells you which device connected and when, while auditd tells you what happened afterward.
Root is required for some commands: gen_auth and storage create require sudo. Regular read commands run fine as a normal user if you have log read permissions.
USB forensics isn’t something you need every day, but when you do need it, you need it fast. Install usbrip now, build a whitelist, set up crontab — it takes less than 30 minutes. When you actually need to investigate, you won’t be starting from scratch.

