How Sniffnet's IP Blacklist Feature Enhances Security: A Technical Deep Dive

The IP blacklist feature in Sniffnet allows users to load a custom list of hostile IP addresses at runtime, automatically flagging matching traffic in real-time and triggering immediate notifications without relying on external services.

Sniffnet is an open-source network monitoring application developed by GyulyVGC that analyzes traffic locally through a Rust-powered GUI. The IP blacklist feature provides a critical security layer by enabling deterministic detection of communications from known malicious sources. This capability operates entirely offline, giving users full control over threat definitions while eliminating privacy risks associated with cloud-based lookups.

How the IP Blacklist Works in Sniffnet

Loading the Blacklist from User Settings

The configuration flow begins in src/gui/types/settings.rs, where the Settings struct maintains an ip_blacklist field storing the filesystem path to the user's blacklist file. When the GUI initializes, it retrieves this path from the configuration and initiates the asynchronous loading process. The actual instantiation occurs in src/gui/sniffer.rs (lines 664-677), where the application creates an IpBlacklist instance and populates it from the specified file path.

The IpBlacklist Data Structure

Defined in src/networking/types/ip_blacklist.rs, the IpBlacklist struct encapsulates an Arc<HashSet<IpAddr>> wrapped in a thread-safe reference counter for concurrent access. The from_file constructor reads the user-provided text file line-by-line, parsing each entry into a strongly-typed IpAddr, and stores valid addresses in the HashSet for O(1) lookup performance. A loading flag tracks the initialization state to prevent race conditions during the asynchronous file read.

Real-Time Packet Inspection

During live capture, every packet passes through the modify_or_insert_in_map function in src/networking/manage_packets.rs. This function extracts the remote address using get_address_to_lookup and queries the IpBlacklist via the contains method. When a match occurs, the code immediately sets info.is_blacklisted = true, marking the specific traffic flow as originating from a hostile source before it enters the reporting pipeline.

Security Benefits of User-Controlled Blacklisting

Deterministic Threat Detection

Unlike cloud-based threat intelligence services that require network connectivity and may compromise privacy, Sniffnet's blacklist operates entirely locally using the user-defined static list. This approach eliminates false positives from shared intelligence feeds and ensures that security decisions remain deterministic—the same input always produces the same security classification without external dependencies.

Immediate Alert Notifications

When blacklisted traffic is detected, the notify_and_log function in src/notifications/notify_and_log.rs (lines 93-144) generates a BlacklistedTransmitted notification event. All UI text related to these alerts is localized through src/translations/translations_5.rs, ensuring consistent user experience across languages. The system logs the incident, optionally transmits remote push notifications, and plays the user-configured alert sound, creating an immediate feedback loop for security teams.

Focused Traffic Analysis

The feature integrates with Sniffnet's reporting infrastructure through SearchParameters in src/report/types/search_parameters.rs. Users can activate the only_blacklisted flag to filter the entire dataset, displaying exclusively connections flagged as hostile. This capability helps security auditors isolate suspicious flows from high-volume benign traffic, streamlining incident response workflows.

Implementation Details and Code Examples

Creating a Blacklist File

Users define hostile addresses in a plain text file with one IP per line:


# file: my_blacklist.txt

8.8.8.8
1.2.3.255
2001:db8::1234
fe80::99

Loading the Blacklist in Rust

The GUI loads and initializes the blacklist asynchronously from the settings path:

// Example from src/gui/sniffer.rs, lines 664-677
let blacklist_path = conf.settings.ip_blacklist.clone();
sniffer.ip_blacklist = IpBlacklist::default();
sniffer.ip_blacklist.start_loading();
sniffer.ip_blacklist = IpBlacklist::from_file(blacklist_path).await;

Checking Addresses During Packet Processing

The packet handler performs O(1) lookups against the HashSet during live capture:

// Inside modify_or_insert_in_map in src/networking/manage_packets.rs
let address_to_lookup = get_address_to_lookup(key, traffic_direction);
if ip_blacklist.contains(&address_to_lookup) {
    info.is_blacklisted = true;
}

Generating Security Notifications

The notification system creates structured alerts for blacklisted traffic:

// Inside notify_and_log in src/notifications/notify_and_log.rs
if notifications.ip_blacklist_notification.is_active {
    let notification = LoggedNotification::BlacklistedTransmitted(BlacklistedTransmitted {
        id: logged_notifications.tot(),
        ip,
        host,
        data_info_host,
        timestamp: get_formatted_timestamp(timestamp),
    });
    logged_notifications.push(&notification);
}

Filtering the UI for Blacklisted Traffic

Users can isolate suspicious connections programmatically using search parameters:

// Using SearchParameters in src/report/types/search_parameters.rs
let mut search_params = SearchParameters::default();
search_params.only_blacklisted = true;

Summary

  • The IP blacklist feature loads user-defined hostile addresses from a local file into an Arc<HashSet<IpAddr>> for thread-safe, concurrent access.
  • Real-time detection occurs in modify_or_insert_in_map, which marks packets as blacklisted during live capture with O(1) lookup complexity.
  • Immediate notifications are generated through BlacklistedTransmitted events in notify_and_log, supporting sound alerts, remote pushes, and localized UI strings from translations_5.rs.
  • Privacy-preserving operation requires no external services, keeping threat intelligence entirely under user control and eliminating network dependencies.
  • Focused analysis is enabled through SearchParameters::only_blacklisted filtering in the GUI, allowing security teams to view exclusively flagged traffic.

Frequently Asked Questions

What file format does Sniffnet use for the blacklist?

Sniffnet expects a plain text file containing one IP address per line. The parser in src/networking/types/ip_blacklist.rs reads the file line-by-line using standard IP parsing, supporting both IPv4 and IPv6 formats. The from_file method validates each line as an IpAddr before insertion into the HashSet.

How does Sniffnet handle the blacklist during high-traffic scenarios?

The implementation uses an Arc<HashSet<IpAddr>> wrapped in a thread-safe atomic reference counter, enabling lock-free concurrent reads during packet processing. The HashSet provides O(1) lookup complexity, ensuring that checking thousands of packets per second against large blacklists introduces minimal performance overhead to the capture pipeline.

Can Sniffnet automatically download or update blacklists from the internet?

No, Sniffnet's blacklist feature is strictly offline and user-controlled. The Settings::ip_blacklist field only stores a local filesystem path, and the IpBlacklist::from_file method performs no network operations. Users must manually provide and update the blacklist file, ensuring complete privacy and preventing automatic dependencies on external threat intelligence feeds.

Where are blacklisted traffic notifications stored?

When the ip_blacklist_notification setting is active, the notify_and_log function in src/notifications/notify_and_log.rs pushes BlacklistedTransmitted events into the logged_notifications collection. These entries persist in the application's internal logs with timestamps, and can trigger immediate sound alerts or remote push notifications based on user preferences configured in the GUI settings.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →