pub struct DomainMetadata {
    pub fqdn: String,
    pub ips: Option<Vec<IpAddr>>,
    pub smtp: Option<SmtpMetadata>,
    pub http_banner: Option<String>,
    pub geo_ip_lookups: Option<Vec<(IpAddr, String)>>,
    pub who_is_lookup: Option<String>,
}
Expand description

Container to store interesting FQDN metadata on domains that we resolve.

Whenever any domain enrichment occurs, the following struct is return to indicate the information that was derived.

N.B—there will be cases where a single domain can have multiple DomainMetadata instancees associated with it.

Fields§

§fqdn: String

The domain that is being enriched.

§ips: Option<Vec<IpAddr>>

Any IPv4 and IPv6 ips that were discovered during domain resolution.

§smtp: Option<SmtpMetadata>

Any SMTP message data (if any) that was returned by an SMTP server.

§http_banner: Option<String>

HTTP server banner data extracted.

§geo_ip_lookups: Option<Vec<(IpAddr, String)>>

IP addresses resolved through GeoIP lookup to City, Country, Continent.

§who_is_lookup: Option<String>

Block of text returned by the WhoIs registrar.

Implementations§

source§

impl DomainMetadata

source

pub fn new(fqdn: String) -> DomainMetadata

Create a new empty state for a particular FQDN.

source

pub async fn dns_resolvable(&self) -> Result<DomainMetadata, Error>

Asynchronous DNS resolution on a DomainMetadata instance.

Returns Ok(DomainMetadata) is the domain was resolved, otherwise returns Err(EnrichmentError).

N.B—also host lookups are done over port 80.

source

pub async fn mx_check(&self) -> Result<DomainMetadata, Error>

Asynchronous SMTP check. Attempts to establish an SMTP connection to the FQDN on port 25 and send a pre-defi ned email.

Currently returns Ok(DomainMetadata) always, which internally contains Option<SmtpMetadata>. To check if the SMTP relay worked, check that DomainMetadata.smtp is Some(v).

source

pub async fn http_banner(&self) -> Result<DomainMetadata, Error>

Asynchronous HTTP Banner fetch. Searches and parses server header from an HTTP request to gather the HTTP banner.

Note that a HEAD request is issued to minimise bandwidth. Also note that the internal HttpConnector sets the response buffer window to 1024 bytes, the CONNECT timeout to 5s and enforces HTTP scheme.

use twistrs::enrich::DomainMetadata;

#[tokio::main]
async fn main() {
    let domain_metadata = DomainMetadata::new(String::from("www.phishdeck.com"));
    println!("{:?}", domain_metadata.http_banner().await);
}
source

pub async fn geoip_lookup( &self, geoip: &Reader<Vec<u8>> ) -> Result<DomainMetadata, Error>

Asynchronous cached GeoIP lookup. Interface deviates from the usual enrichment interfaces and requires the callee to pass a maxminddb::Reader to perform the lookup through. Internally, the maxminddb call is blocking and may result in performance drops, however the lookups are in-memory.

The only reason you would want to do this, is to be able to get back a DomainMetadata to then process as you would with other enrichment methods. Internally the lookup will try to stitch together the City, Country & Continent that the IpAddr resolves to.

use maxminddb::Reader;
use twistrs::enrich::DomainMetadata;

#[tokio::main]
async fn main() {
    let reader = maxminddb::Reader::open_readfile("./data/MaxMind-DB/test-data/GeoIP2-City-Test.mmdb").unwrap();
    let domain_metadata = DomainMetadata::new(String::from("www.phishdeck.com"));
    println!("{:?}", domain_metadata.geoip_lookup(&reader).await);
}
Features

This function requires the geoip_lookup feature toggled.

source

pub async fn whois_lookup(&self) -> Result<DomainMetadata, Error>

Asyncrhonous WhoIs lookup using cached WhoIs server config. Note that the internal lookups are not async and so this should be considered a heavy/slow call.

use twistrs::enrich::DomainMetadata;

#[tokio::main]
async fn main() {
    let domain_metadata = DomainMetadata::new(String::from("www.phishdeck.com"));
    println!("{:?}", domain_metadata.whois_lookup().await);
}
Features

This function requires the whois_lookup feature toggled.

source

pub async fn all(&self) -> Result<Vec<DomainMetadata>, Error>

Performs all FQDN enrichment methods on a given FQDN. This is the only function that returns a Vec<DomainMetadata>.

Panics

Currently panics if any of the internal enrichment methods returns an Err.

Trait Implementations§

source§

impl Clone for DomainMetadata

source§

fn clone(&self) -> DomainMetadata

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for DomainMetadata

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for DomainMetadata

source§

fn default() -> DomainMetadata

Returns the “default value” for a type. Read more
source§

impl Serialize for DomainMetadata

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more