Network Assets¶
This document describes the four network infrastructure asset types in the open-asset-model: FQDN, IPAddress, Netblock, and AutonomousSystem. These asset types represent the fundamental building blocks of network topology and addressing used in network reconnaissance and attack surface mapping. This page focuses on their structure, implementation, and network-specific relationships.
For information about registration records associated with network assets (DomainRecord, AutnumRecord, IPNetRecord), see 3.6. For details on the Asset interface these types implement, see 2.1. For the complete relationship validation system, see 4.
Network Asset Type Overview¶
The network domain defines four asset types that model Internet infrastructure:
| Asset Type | Purpose | Key Format | Primary Use Case |
|---|---|---|---|
FQDN |
Fully Qualified Domain Name | Domain name string | DNS hierarchy, hostnames |
IPAddress |
IP address (v4 or v6) | IP address string | Network endpoints, routing |
Netblock |
IP address range in CIDR notation | CIDR string (e.g., "192.168.1.0/24") | IP allocation, ownership |
AutonomousSystem |
AS number representing routing domain | AS number as string | BGP routing, ISP identification |
Sources: , , ,
Asset Type: FQDN¶
The FQDN asset type represents fully qualified domain names in the DNS hierarchy. It is the most relationship-rich asset type in the network domain, supporting DNS record relationships, port-based service connections, hierarchical node relationships, and domain registration links.
FQDN Relationships¶
graph TB
FQDN["FQDN"]
subgraph "DNS Record Relationships"
BasicDNS["BasicDNSRelation<br/>A, AAAA, CNAME, NS"]
PrefDNS["PrefDNSRelation<br/>MX records"]
SRV["SRVDNSRelation<br/>Service records"]
end
subgraph "Destination Types"
FQDN2["FQDN<br/>(dns_record)"]
IP["IPAddress<br/>(dns_record)"]
Service["Service<br/>(port)"]
DomainRec["DomainRecord<br/>(registration)"]
end
FQDN -->|"dns_record"| BasicDNS
FQDN -->|"dns_record"| PrefDNS
FQDN -->|"dns_record"| SRV
FQDN -->|"port (PortRelation)"| Service
FQDN -->|"node (SimpleRelation)"| FQDN2
FQDN -->|"registration (SimpleRelation)"| DomainRec
BasicDNS -.->|"resolves to"| FQDN2
BasicDNS -.->|"resolves to"| IP
PrefDNS -.->|"mail server"| FQDN2
SRV -.->|"service target"| FQDN2
The fqdnRels map in defines four relationship labels for FQDN assets:
| Label | Relation Type(s) | Destination Type(s) | Purpose |
|---|---|---|---|
dns_record |
BasicDNSRelation, PrefDNSRelation, SRVDNSRelation |
FQDN, IPAddress |
DNS resolution (A, AAAA, CNAME, NS, MX, SRV) |
port |
PortRelation |
Service |
Services listening on the FQDN |
node |
SimpleRelation |
FQDN |
DNS hierarchy (subdomains) |
registration |
SimpleRelation |
DomainRecord |
WHOIS/RDAP registration data |
Key Implementation Detail: The dns_record label supports three distinct RelationType values, each corresponding to different DNS record types. BasicDNSRelation handles standard records (A, AAAA, CNAME, NS), PrefDNSRelation adds preference/priority for MX records, and SRVDNSRelation includes priority, weight, and port for service records.
Sources:
Asset Type: IPAddress¶
The IPAddress asset type represents individual IPv4 or IPv6 addresses. It supports connections to services via ports and PTR record reverse DNS lookups.
IPAddress Relationships¶
graph LR
IP["IPAddress"]
Service["Service"]
FQDN["FQDN"]
IP -->|"port<br/>(PortRelation)"| Service
IP -->|"ptr_record<br/>(SimpleRelation)"| FQDN
The ipRels map in defines two relationship labels:
| Label | Relation Type | Destination Type | Purpose |
|---|---|---|---|
port |
PortRelation |
Service |
Services listening on the IP address |
ptr_record |
SimpleRelation |
FQDN |
Reverse DNS (PTR) records |
Contrast with FQDN: While FQDN assets support forward DNS relationships (dns_record) that can resolve to IP addresses, IPAddress assets support reverse DNS relationships (ptr_record) that point back to FQDNs. Both asset types share the port relationship for connecting to services.
Sources:
Asset Type: Netblock¶
The Netblock asset type represents CIDR-notated IP address ranges. It models IP address allocation and ownership, connecting address blocks to their constituent IP addresses and registration records.
Netblock Structure¶
// From network/netblock.go
type Netblock struct {
CIDR netip.Prefix `json:"cidr"`
Type string `json:"type"`
}
The struct uses Go's netip.Prefix type for type-safe CIDR representation. The Type field distinguishes between "IPv4" and "IPv6" address blocks.
Sources:
Netblock Interface Implementation¶
graph TB
Asset["Asset Interface<br/>(asset.go)"]
Netblock["Netblock Struct<br/>(network/netblock.go)"]
subgraph "Interface Methods"
Key["Key() string<br/>Returns CIDR.String()"]
AssetType["AssetType() AssetType<br/>Returns model.Netblock"]
JSON["JSON() ([]byte, error)<br/>Marshals to JSON"]
end
Asset -.->|"implements"| Netblock
Netblock -->|"line 29-31"| Key
Netblock -->|"line 34-36"| AssetType
Netblock -->|"line 39-41"| JSON
Key -->|"returns"| CIDRString["nb.CIDR.String()"]
The Key() method at returns the CIDR notation as a string (e.g., "192.168.1.0/24"), which serves as the unique identifier for the asset. The AssetType() method at returns the model.Netblock constant. The JSON() method at uses standard json.Marshal() serialization.
Sources:
Netblock Relationships¶
graph TB
Netblock["Netblock"]
IPAddress["IPAddress"]
IPNetRecord["IPNetRecord"]
Netblock -->|"contains<br/>(SimpleRelation)"| IPAddress
Netblock -->|"registration<br/>(SimpleRelation)"| IPNetRecord
The netblockRels map in defines two relationship labels:
| Label | Relation Type | Destination Type | Purpose |
|---|---|---|---|
contains |
SimpleRelation |
IPAddress |
Individual IP addresses within the CIDR block |
registration |
SimpleRelation |
IPNetRecord |
WHOIS/RDAP registration for the netblock |
The contains relationship enables modeling the hierarchical relationship between address blocks and individual addresses, supporting queries like "which IP addresses are contained in this netblock?"
Sources:
Netblock JSON Serialization¶
Example JSON output from a Netblock instance:
The test suite at verifies serialization for both IPv4 and IPv6 netblocks, ensuring the CIDR field serializes correctly using netip.Prefix's string representation.
Sources:
Asset Type: AutonomousSystem¶
The AutonomousSystem asset type represents an autonomous system number (ASN) used in BGP routing. It models the organizational units that control IP routing on the Internet, such as ISPs, cloud providers, and large enterprises.
AutonomousSystem Structure¶
The struct contains a single field: the AS number (e.g., 64496 for a private ASN, or 15169 for Google's public ASN).
Sources:
AutonomousSystem Interface Implementation¶
| Method | Implementation | Line Reference |
|---|---|---|
Key() |
Returns strconv.Itoa(a.Number) |
|
AssetType() |
Returns model.AutonomousSystem |
|
JSON() |
Returns json.Marshal(a) |
The Key() method converts the integer AS number to a string for use as the asset's unique identifier. This ensures that ASN 64496 has the key "64496".
Sources:
AutonomousSystem Relationships¶
graph LR
AS["AutonomousSystem"]
Netblock["Netblock"]
AutnumRecord["AutnumRecord"]
AS -->|"announces<br/>(SimpleRelation)"| Netblock
AS -->|"registration<br/>(SimpleRelation)"| AutnumRecord
The autonomousSystemRels map in defines two relationship labels:
| Label | Relation Type | Destination Type | Purpose |
|---|---|---|---|
announces |
SimpleRelation |
Netblock |
IP address blocks announced by the AS via BGP |
registration |
SimpleRelation |
AutnumRecord |
WHOIS/RDAP registration for the AS number |
The announces relationship models BGP announcements, enabling queries like "which netblocks does AS 15169 announce?" This is critical for attack surface mapping, as it reveals the IP space controlled by an organization.
Sources:
AutonomousSystem JSON Serialization¶
Example JSON output:
The test at verifies this serialization format.
Sources:
Network Asset Relationship Graph¶
The following diagram shows how all four network asset types interconnect, including cross-domain relationships to registration records and services:
graph TB
subgraph "Network Assets"
FQDN["FQDN"]
IP["IPAddress"]
Netblock["Netblock"]
AS["AutonomousSystem"]
end
subgraph "Registration Assets"
DomainRec["DomainRecord"]
IPNetRec["IPNetRecord"]
AutnumRec["AutnumRecord"]
end
subgraph "Digital Assets"
Service["Service"]
end
AS -->|"announces"| Netblock
AS -->|"registration"| AutnumRec
Netblock -->|"contains"| IP
Netblock -->|"registration"| IPNetRec
FQDN -->|"dns_record (Basic)"| IP
FQDN -->|"dns_record (Basic/Pref/SRV)"| FQDN
FQDN -->|"node"| FQDN
FQDN -->|"port"| Service
FQDN -->|"registration"| DomainRec
IP -->|"ptr_record"| FQDN
IP -->|"port"| Service
Key Observations:
- Hierarchical Structure:
AutonomousSystem→Netblock→IPAddressforms a three-level hierarchy of network address space - DNS Bidirectionality: FQDNs resolve to IP addresses (dns_record), while IP addresses reverse-resolve to FQDNs (ptr_record)
- Registration Linkage: All three network primitive types (AS, Netblock, FQDN) link to corresponding registration record types for ownership data
- Service Connectivity: Both FQDN and IPAddress assets connect to Service assets via PortRelation
- Self-Referential FQDN: FQDNs can reference other FQDNs through both dns_record (CNAME, NS, MX, SRV) and node (subdomain hierarchy) relationships
Sources: , , ,
Interface Compliance Testing Pattern¶
All network asset implementations follow a consistent testing pattern that verifies interface compliance at compile time:
// From network/netblock_test.go
var _ model.Asset = Netblock{} // Value receiver
var _ model.Asset = (*Netblock)(nil) // Pointer receiver
// From network/autonomous_system_test.go
var _ model.Asset = AutonomousSystem{} // Value receiver
var _ model.Asset = (*AutonomousSystem)(nil) // Pointer receiver
This pattern uses Go's blank identifier assignment to verify that both value and pointer receivers satisfy the Asset interface. If the type does not implement all required methods, this code will fail at compile time, preventing interface violations from reaching runtime.
The tests also verify method behavior: - Key() correctness: , - AssetType() returns correct constant: , - JSON() serialization format: ,
Sources: ,
Implementation Summary¶
All network asset types share common implementation patterns:
| Pattern | Implementation Detail | Example |
|---|---|---|
| Struct Simplicity | Minimal fields, focused on identity | Netblock: 2 fields, AS: 1 field |
| Type-Safe Keys | Leverage Go stdlib types for validation | netip.Prefix for Netblock CIDR |
| String-Based Keys | Key() returns string representation | AS.Key() uses strconv.Itoa() |
| Standard JSON | Use json.Marshal() without custom logic |
No custom MarshalJSON methods |
| Relationship Clarity | Clear semantic labels in relation maps | "announces", "contains", "ptr_record" |
This consistency simplifies client code: all network assets can be handled polymorphically through the Asset interface, with type-specific behavior expressed through the relationship taxonomy rather than custom methods.
Sources: ,