Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detector Address filtering #62

Merged
merged 1 commit into from
Jan 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ name = "rust_dark_decoy"
crate-type = ["rlib", "staticlib"]

[dependencies]
toml = "0.5.8"
serde = "^1.0.0"
serde_derive = "^1.0.0"
lazycell = "^0.5"
libc = "~0.2"
aes-gcm = "0.8.0"
Expand Down
9 changes: 9 additions & 0 deletions application/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ covert_blocklist = [
]


# List of addresses to filter out traffic from the detector. The primary functionality
# of this is to prevent liveness testing from other stations in a conjure cluster from
# clogging up the logs with connection notifications. To accomplish this goal add all station
# ip addresses to this list when configuring station detectors.
detector_filter_list = [
"127.0.0.1",
"::1",
]

### ZMQ sockets to connect to and subscribe

## Registration API
Expand Down
27 changes: 26 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ extern crate tuntap; // https://github.com/ewust/tuntap.rs
extern crate zmq;
extern crate protobuf;
extern crate redis;
extern crate toml;
extern crate serde;
extern crate serde_derive;

use std::mem::transmute;
use std::collections::HashMap;
Expand All @@ -25,6 +28,9 @@ use radix::PrefixTree;
use std::io::BufReader;
use std::io::BufRead;
use std::fs::File;
use std::env;
use std::fs;
use serde_derive::Deserialize;

use std::ffi::CStr;
use std::os::raw::c_char;
Expand Down Expand Up @@ -70,6 +76,10 @@ pub struct PerCoreGlobal
// ZMQ socket for sending information to the dark decoy application
zmq_sock: zmq::Socket,

// Filter list of addresses to ignore traffic from. This primarily functions to prevent liveness
// testing from other stations in a conjure cluster from clogging up the logs with connection
// notifications.
filter_list: Vec<String>,
}

// Tracking of some pretty straightforward quantities
Expand Down Expand Up @@ -99,8 +109,15 @@ pub struct PerCoreStats
pub in_tree_this_period: u64,
}

const IP_LIST_PATH: &'static str = "/var/lib/dark-decoy.prefixes";
// Currently used to parse the Toml config. If this needs to play a larger role
// in the future this can be added to the PerCoreGlobal.
#[derive(Deserialize)]
struct StationConfig {
detector_filter_list: Vec<String>,
}

const IP_LIST_PATH: &'static str = "/var/lib/dark-decoy.prefixes";
const STATION_CONF_PATH: &'static str = "CJ_STATION_CONFIG";

impl PerCoreGlobal
{
Expand All @@ -115,6 +132,13 @@ impl PerCoreGlobal
let zmq_sock = zmq_ctx.socket(zmq::PUB).unwrap();
zmq_sock.connect(workers_socket_addr).expect("failed connecting to ZMQ");

// Parse toml station config to get filter list
let conf_path = env::var(STATION_CONF_PATH).unwrap();
let contents = fs::read_to_string(conf_path)
.expect("Something went wrong reading the station config file");
let value: StationConfig = toml::from_str(&contents)
.expect("Failed to parse toml station config");

PerCoreGlobal {
priv_key: priv_key,
lcore: the_lcore,
Expand All @@ -124,6 +148,7 @@ impl PerCoreGlobal
stats: PerCoreStats::new(),
ip_tree: PrefixTree::new(),
zmq_sock: zmq_sock,
filter_list: value.detector_filter_list,
}
}

Expand Down
100 changes: 53 additions & 47 deletions src/process_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ impl PerCoreGlobal
if self.flow_tracker.is_registered_dark_decoy(&dd_flow) {

// Handle packet destined for registered IP
match filter_station_traffic(flow.src_ip.to_string()) {
match self.filter_station_traffic(flow.src_ip.to_string()) {
// traffic was sent by another station, likely liveness testing.
None => {},

Expand Down Expand Up @@ -359,61 +359,67 @@ impl PerCoreGlobal
debug!("Validated UDP traffic from {}", flow)
}
}
} // impl PerCoreGlobal


/// Checks if the traffic seen is from a participating station byt checking the
/// source address. Returns Some if traffic is from anything other that a station.
///
/// This exists to prevent the detector from forwarding liveness check traffic
/// to the application wasting resources in the process.
///
/// Todo -> Move address list to some external config
///
/// # Examples
///
/// ```compile_fail
/// let flow_src_station = String::from("192.122.200.231");
/// let flow_src_client = String::from("128.138.89.172");
///
/// let station = filter_station_traffic(flow_src_station);
/// let client = filter_station_traffic(flow_src_client);
///
/// assert_eq!(None, station);
/// assert_eq!(Some(()), client);
/// ```
fn filter_station_traffic(src: String) -> Option<()> {

let station_addrs: [&str; 6] = [
"198.108.63.121", // artemis
"192.122.200.188", // windyheron
"192.122.200.253", // windyegret
"192.122.200.166", // decoy-tap
"192.122.200.231", // curveball
"2001:48a8:687f:2::2", // curveball
];

for addr in station_addrs.iter() {
if src == *addr {
return None
/// Checks if the traffic seen is from a participating station byt checking the
/// source address. Returns Some if traffic is from anything other that a station.
///
/// This exists to prevent the detector from forwarding liveness check traffic
/// to the application wasting resources in the process.
///
/// Todo -> Move address list to some external config
///
/// # Examples
///
/// ```compile_fail
/// let flow_src_station = String::from("192.122.200.231");
/// let flow_src_client = String::from("128.138.89.172");
///
/// let station = filter_station_traffic(flow_src_station);
/// let client = filter_station_traffic(flow_src_client);
///
/// assert_eq!(None, station);
/// assert_eq!(Some(()), client);
/// ```
fn filter_station_traffic(&mut self, src: String) -> Option<()> {

for addr in self.filter_list.iter() {
if src == *addr {
return None
}
}
}

Some(())
}
Some(())
}
} // impl PerCoreGlobal


#[cfg(test)]
mod tests {
use std::env;
use std::fs;
use toml;
use StationConfig;


#[test]
fn test_filter_station_traffic() {
let flow_src_station = String::from("192.122.200.231");
let flow_src_client = String::from("128.138.89.172");

let station = super::filter_station_traffic(flow_src_station);
let client = super::filter_station_traffic(flow_src_client);

assert_eq!(None, station);
assert_eq!(Some(()), client);

env::set_var("CJ_STATION_CONFIG", "./application/config.toml");

// --
let conf_path = env::var("CJ_STATION_CONFIG").unwrap();

let contents = fs::read_to_string(conf_path)
.expect("Something went wrong reading the file");

// let value = contents.parse::<Value>().unwrap();
let value: StationConfig = toml::from_str(&contents).unwrap();

let nets = value.detector_filter_list;

for net in nets.iter() {
println!("{}", net);
}
}
}