Skip to main content

Diameter Security

OmniDRA provides a comprehensive suite of Diameter security modules aligned with GSMA FS.19 (Diameter Interconnect Security, v10.0) and GSMA FS.21 (Interconnect Signalling Security Recommendations, v12.0). These modules protect the network against signalling-level attacks on Diameter interconnect interfaces.

Each module is independently configurable, can be enabled or disabled without affecting the others, and emits its own telemetry events for monitoring and alerting.

Architecture Overview

Processing Order

Inbound Diameter requests pass through the security modules in the following order. A message rejected at any stage is never forwarded to subsequent stages.

OrderModuleDirectionPurpose
1Rate LimiterInboundVolumetric flood protection
2Diameter FirewallInboundFS.19 protocol and content filtering
3AVP SanitizerInboundAVP validation and stripping
4Routing Engine-Standard Diameter routing
5Topology HidingOutboundNetwork topology concealment

Actions

All security modules support configurable actions when a violation is detected. Actions are configured per-module (and per-category for the Diameter Firewall).

ActionBehaviourDiameter Result
{:error, 3002}Respond with a Diameter error answerDIAMETER_UNABLE_TO_DELIVER
{:error, 3004}Respond with a Diameter error answerDIAMETER_TOO_BUSY
{:error, 3007}Respond with a Diameter error answerDIAMETER_APPLICATION_UNSUPPORTED
:dropSilently discard the messageNo response sent
:log_onlyLog the violation but allow the message throughMessage continues

Diameter Firewall

The Diameter Firewall implements the four filtering layers defined in GSMA FS.19 Section 3.3 and the protocol-agnostic packet categorisation from FS.21 Section 7. Messages are evaluated through each layer in order; a violation at any layer stops further processing.

Low-Layer Format Filtering

GSMA Reference: FS.19 Section 3.3.4, FS.21 Section 7.3.1

Low-layer filtering detects protocol-level violations and basic anti-spoofing attempts without needing to understand upper-layer application semantics. This layer catches malformed messages before they reach deeper inspection.

Checks performed:

CheckFS.19 ReferenceDescription
AVP DuplicationSection 3.3.4, 4.8.1Detects duplicate instances of AVPs that must appear at most once (e.g. Origin-Host, Origin-Realm). Prevents AVP doubling evasion attacks.
Session-Id OrderingSection 3.3.4Validates that Session-Id (AVP 263) is the first AVP in the message, per RFC 6733 Section 8.8.
Destination-Host in AnswersSection 3.3.4Rejects answer messages that contain a Destination-Host AVP, which is a protocol violation that may indicate filter evasion.
Mandatory AVP ValidationSection 3.3.5Validates that required AVPs are present for each command code (e.g. ULR must contain User-Name and Visited-PLMN-Id per 3GPP TS 29.272 Section 7.2.3).
low_layer: %{
enabled: true,
action: {:error, 3002},
# AVP codes that must not appear more than once (FS.19 Section 3.3.4)
# 264 = Origin-Host, 296 = Origin-Realm, 283 = Destination-Realm, 293 = Destination-Host
single_instance_avps: [264, 296, 283, 293],
# Session-Id must be the first AVP (RFC 6733 Section 8.8)
enforce_session_id_first: true,
# Answer messages must not contain Destination-Host (FS.19 Section 3.3.4)
reject_destination_host_in_answers: true,
# Mandatory AVPs per command code (3GPP TS 29.272)
# 1 = User-Name (IMSI), 1407 = Visited-PLMN-Id, 264 = Origin-Host, 296 = Origin-Realm
mandatory_avps: %{
316 => [1, 1407, 264, 296],
318 => [1, 1407, 264, 296]
}
}

Category 1 — Interface-Unauthorised Packet Filtering

GSMA Reference: FS.19 Section 3.3.5, FS.21 Section 7.2.1

Category 1 filtering ensures that only authorised Diameter Application IDs and Command Codes are accepted on each interconnect interface. This prevents external access to internal-only interfaces (e.g. blocking Sh commands over an S6a interface) and enforces that roaming partners only send message types covered by their roaming agreements.

The whitelist approach follows the FS.19 recommendation: block all Diameter messages except those explicitly required for a given interface.

Whitelists can be configured globally (applying to all peers) or per-peer, allowing different roaming partners to have different permitted message sets.

category_1: %{
enabled: true,
action: {:error, 3007},
whitelists: %{
# Per-peer whitelist — restrict this partner to ULR and AIR only (FS.19 Section 3.3.5)
"restricted-partner.roaming.com" => %{
16_777_251 => [316, 318]
},
# Default whitelist — standard S6a commands permitted for all other peers
all: %{
# S6a/S6d (FS.19 Section 3.3.5, Table 2)
16_777_251 => [316, 317, 318, 319, 320, 321, 323],
# S13 — ME Identity Check (FS.19 Section 3.3.5)
16_777_252 => [324],
# S6c — SMS via HSS (FS.19 Section 3.3.5.1)
16_777_312 => [8388647, 8388648],
# SGd — SMS via MME (FS.19 Section 3.3.5.2)
16_777_313 => [8388645, 8388646]
}
}
}

Common S6a/S6d Whitelist:

Command CodeNameDirectionReference
316Update-Location-Request/AnswerMME → HSS3GPP TS 29.272 §7.2.3
317Cancel-Location-Request/AnswerHSS → MME3GPP TS 29.272 §7.2.7
318Authentication-Information-Request/AnswerMME → HSS3GPP TS 29.272 §7.2.5
319Insert-Subscriber-Data-Request/AnswerHSS → MME3GPP TS 29.272 §7.2.9
320Delete-Subscriber-Data-Request/AnswerHSS → MME3GPP TS 29.272 §7.2.11
321Purge-UE-Request/AnswerMME → HSS3GPP TS 29.272 §7.2.13
323Notify-Request/AnswerMME → HSS3GPP TS 29.272 §7.2.15

Common Application IDs for roaming interconnect (FS.19 Section 3.3.5):

Application IDInterfaceReference
16777251S6a/S6d3GPP TS 29.272
16777252S133GPP TS 29.272
16777312S6c3GPP TS 29.338
16777313SGd3GPP TS 29.338
16777255SLg3GPP TS 29.172
16777267S93GPP TS 29.215

Category 2 — Home-Network Packet Filtering

GSMA Reference: FS.19 Section 3.3.6, FS.21 Section 7.2.2

Category 2 filtering protects home subscribers from being targeted by messages arriving from the interconnect. Messages on protected command codes are inspected for subscriber identity (IMSI in the User-Name AVP, MSISDN in AVP 701). If the identity matches a home subscriber prefix, the message is rejected — legitimate traffic for home subscribers should originate from within the home network, not from external peers.

This prevents attacks where an external entity sends location updates, subscriber data requests, or authentication queries targeting the operator's own subscribers.

# Top-level: define home subscriber prefixes
home_imsi_prefixes: ["31338", "31339"],
home_msisdn_prefixes: ["+1313"],

category_2: %{
enabled: true,
action: {:error, 3002},
# S6a command codes that carry subscriber identity (FS.19 Section 3.3.6, Table 12)
protected_command_codes: [316, 317, 318, 319, 320, 321, 323]
}

Category 3 — Plausible-Network Packet Filtering

GSMA Reference: FS.19 Section 3.3.7, FS.21 Section 7.2.3

Category 3 filtering detects implausible location changes by tracking the last-seen network for each subscriber (IMSI). When an Update-Location-Request arrives from a different visited network than the previous one, the time elapsed is compared against a configurable threshold. A realm change occurring faster than physically possible indicates a potential attack (e.g. spoofed location updates).

This module maintains stateful per-IMSI tracking using an ETS table with automatic cleanup of stale entries (entries older than 24 hours are removed periodically).

Checks performed:

CheckFS.19 ReferenceDescription
Previous Location CheckSection 3.3.7.1Compares the Origin-Realm of the current ULR with the last-seen Origin-Realm for that IMSI
Velocity/Time CheckSection 3.3.7.2Flags realm changes that occur within a configurable minimum time window
category_3: %{
enabled: true,
# Start with log_only to observe patterns before enforcing (FS.19 Section 3.3.7)
action: :log_only,
# Maximum plausible velocity in km/h (FS.19 Section 3.3.7.2)
max_velocity_kmh: 1200,
# Minimum seconds between ULRs from different realms for the same IMSI
min_time_between_updates_seconds: 2
}

Configuration

The Diameter Firewall is enabled at the top level, with each filtering layer configured independently. The config snippets shown above within each category section are combined under a single module_diameter_firewall key:

config :dra,
module_diameter_firewall: %{
enabled: true,
home_imsi_prefixes: ["31338", "31339"],
home_msisdn_prefixes: ["+1313"],
low_layer: %{ ... }, # See Low-Layer Format Filtering above
category_1: %{ ... }, # See Category 1 above
category_2: %{ ... }, # See Category 2 above
category_3: %{ ... } # See Category 3 above
}

Top-Level Parameters

ParameterTypeRequiredDefaultDescription
enabledBooleanYesfalseEnable or disable the entire Diameter Firewall module. When false, all messages pass through without inspection.
childrenListNo[]Processes started under the DRA supervisor when the module is enabled. For the firewall set to [DRA.Router.Modules.DiameterFirewall.LocationTracker], which is required for Category 3 stateful (velocity) tracking.
home_imsi_prefixesListNo[]List of IMSI prefix strings identifying home subscribers. Used by Category 2 filtering. Example: ["31338", "31339"].
home_msisdn_prefixesListNo[]List of MSISDN prefix strings identifying home subscribers. Used by Category 2 filtering. Example: ["+1313"].

Low-Layer Parameters

ParameterTypeRequiredDefaultDescription
enabledBooleanNotrueEnable or disable low-layer format filtering.
actionActionNo{:error, 3002}Action to take when a low-layer violation is detected.
single_instance_avpsListNo[264, 296, 283, 293]AVP codes that must not appear more than once in a message. Default covers Origin-Host (264), Origin-Realm (296), Destination-Realm (283), and Destination-Host (293).
enforce_session_id_firstBooleanNotrueReject messages where Session-Id is not the first AVP.
reject_destination_host_in_answersBooleanNotrueReject answer messages that contain a Destination-Host AVP.
mandatory_avpsMapNo%{}Map of command code to list of required AVP codes. Example: %{316 => [1, 1407, 264, 296]} requires User-Name, Visited-PLMN-Id, Origin-Host, and Origin-Realm in ULR messages.

Category 1 Parameters

ParameterTypeRequiredDefaultDescription
enabledBooleanNotrueEnable or disable Category 1 filtering.
actionActionNo{:error, 3007}Action to take when a Category 1 violation is detected. Default responds with DIAMETER_APPLICATION_UNSUPPORTED.
whitelistsMapYes-Map of peer hostname (or :all) to permitted Application ID / Command Code combinations. The :all key provides a default whitelist. Peer-specific entries take priority.

Category 2 Parameters

ParameterTypeRequiredDefaultDescription
enabledBooleanNotrueEnable or disable Category 2 filtering.
actionActionNo{:error, 3002}Action to take when a home subscriber is targeted from interconnect.
protected_command_codesListNo[]Command codes that trigger home subscriber identity checks. Typically the S6a command codes that carry subscriber identity.

Category 3 Parameters

ParameterTypeRequiredDefaultDescription
enabledBooleanNofalseEnable or disable Category 3 filtering. Requires the LocationTracker process to be running (started automatically by the supervisor when enabled).
actionActionNo:log_onlyAction to take when a location plausibility check fails. Recommended to start with :log_only to tune thresholds before enforcing.
max_velocity_kmhIntegerNo1200Maximum plausible velocity in km/h. Reserved for future geo-distance calculations.
min_time_between_updates_secondsIntegerNo2Minimum time in seconds between location updates from different realms for the same IMSI. Realm changes faster than this are flagged.

Telemetry Events

EventDescription
[:diameter, :firewall, :low_layer, :block]Low-layer format violation detected and blocked
[:diameter, :firewall, :category_1, :block]Category 1 violation detected and blocked
[:diameter, :firewall, :category_2, :block]Category 2 violation detected and blocked
[:diameter, :firewall, :category_3, :block]Category 3 violation detected and blocked
[:diameter, :firewall, :pass, :count]Message passed all firewall checks

All events include metadata: origin_host, application_id, command_code, application_name, command_name, and reason.


Topology Hiding

GSMA Reference: FS.19 Section 2.4, Section 3.4; FS.21 Section 3.6

The Topology Hiding module prevents internal network topology from being exposed to external peers. When Diameter messages traverse multiple internal nodes, they accumulate Route-Record AVPs and carry Origin-Host/Origin-Realm values that reveal internal hostnames, network structure, and node counts. This information can be used by attackers to map the internal network for targeted attacks.

Topology hiding operates on the outbound path — after routing decisions have been made, before messages are forwarded to the destination peer.

Features

FeatureFS.19 ReferenceDescription
Route-Record StrippingSection 2.4Removes all Route-Record AVPs (282) that reveal internal routing paths and node hostnames
Origin-Host RewritingSection 3.4Replaces the Origin-Host AVP with the DRA's own identity (or a custom value) on answer messages
Origin-Realm RewritingSection 3.4Optionally replaces the Origin-Realm AVP to hide internal realm structure
Per-Peer Control-Apply topology hiding selectively — only to external peers, or to all peers
module_topology_hiding: %{
enabled: true,
# Strip Route-Record AVPs revealing internal paths (FS.19 Section 2.4)
strip_route_records: true,
# Rewrite Origin-Host on answers to hide internal node names (FS.19 Section 3.4)
rewrite_origin_host: %{enabled: true, replacement: :self},
# Optionally hide internal realm structure
rewrite_origin_realm: %{enabled: false, replacement: :self},
# Apply to all external peers, or list specific hostnames
external_peers: :all
}

Parameters

ParameterTypeRequiredDefaultDescription
enabledBooleanYesfalseEnable or disable the Topology Hiding module.
strip_route_recordsBooleanNotrueRemove all Route-Record AVPs (code 282) from messages before forwarding to external peers.
rewrite_origin_hostMapNoSee belowControls Origin-Host rewriting on answer messages.
rewrite_origin_realmMapNoSee belowControls Origin-Realm rewriting on answer messages.
external_peers:all or ListNo:allPeers considered external. Topology hiding is only applied to messages destined for these peers. Use :all for interconnect deployments. Use a list of hostnames for selective application.

Rewrite Parameters (apply to both rewrite_origin_host and rewrite_origin_realm):

ParameterTypeRequiredDefaultDescription
enabledBooleanNovariesEnable rewriting for this AVP. Default is true for Origin-Host, false for Origin-Realm.
replacement:self or StringNo:selfReplacement value. :self uses the DRA's own identity from the diameter config (host.realm). A string value is used as-is.

Telemetry Events

EventDescription
[:diameter, :topology_hiding, :route_record, :stripped]Route-Record AVPs removed. Measurement includes count of AVPs stripped.
[:diameter, :topology_hiding, :origin_host, :rewritten]Origin-Host AVP rewritten
[:diameter, :topology_hiding, :origin_realm, :rewritten]Origin-Realm AVP rewritten

Rate Limiter

GSMA Reference: FS.19 Section 3.4 (Availability / DoS Protection)

The Rate Limiter enforces per-peer message rate limits to protect against volumetric attacks and message flooding. It operates as the first security check in the pipeline — before any message parsing or content inspection — to shed excess load as early as possible.

Rate limits are tracked per-peer using a sliding window counter. Each peer has an independent counter that resets every second.

module_rate_limiter: %{
enabled: true,
# Default limit for all peers (FS.19 Section 3.4)
default_max_requests_per_second: 1000,
default_action: {:error, 3004},
# Per-peer overrides
peer_limits: %{
"high-volume-partner.roaming.com" => %{max_requests_per_second: 5000, action: {:error, 3004}},
"restricted-peer.roaming.com" => %{max_requests_per_second: 100, action: :drop}
}
}

Parameters

ParameterTypeRequiredDefaultDescription
enabledBooleanYesfalseEnable or disable the Rate Limiter module.
childrenListNo[]Processes started under the DRA supervisor when enabled. Set to [DRA.Router.Modules.RateLimiter] so the per-peer rate-counter process runs.
default_max_requests_per_secondIntegerNo1000Default maximum requests per second allowed from any single peer.
default_actionActionNo{:error, 3004}Default action when a peer exceeds its rate limit. {:error, 3004} responds with DIAMETER_TOO_BUSY.
peer_limitsMapNo%{}Map of peer hostname to override configuration. Peers not listed use the defaults.

Per-Peer Override Parameters:

ParameterTypeRequiredDefaultDescription
max_requests_per_secondIntegerNoInherits defaultMaximum requests per second for this specific peer.
actionActionNoInherits defaultAction when this peer exceeds its rate limit.

Telemetry Events

EventDescription
[:diameter, :rate_limiter, :throttled]A message was rate limited. Measurements include current_rate and limit.
[:diameter, :rate_limiter, :allowed]A message was within rate limits.

AVP Sanitizer

GSMA Reference: FS.19 Section 3.3.4, 4.8.1, 4.8.2; FS.21 Section 3.6

The AVP Sanitizer validates and sanitizes Diameter AVPs at the interconnect boundary. It addresses the FS.21 Section 3.6 recommendations for handling protocol-level manipulation attacks that operate below the level of the FS.19 filtering categories.

Features

FeatureGSMA ReferenceDescription
Unknown Vendor AVP StrippingFS.21 Section 3.6Removes AVPs from non-whitelisted vendors. Prevents injection of proprietary AVPs that may trigger unintended behaviour in backend nodes.
Grouped AVP Nesting DepthFS.21 Section 3.6Enforces a maximum nesting depth for grouped AVPs. Prevents stack overflow attacks using deeply nested AVP structures.
module_avp_sanitizer: %{
enabled: true,
action: {:error, 3002},
# Only allow standard vendor AVPs on interconnect (FS.21 Section 3.6)
# 0 = IETF, 10415 = 3GPP, 13019 = ETSI, 5535 = 3GPP2
allowed_vendor_ids: [0, 10415, 13019, 5535],
strip_unknown_vendor_avps: true,
# Prevent stack overflow via deeply nested grouped AVPs (FS.21 Section 3.6)
max_avp_nesting_depth: 10
}

Parameters

ParameterTypeRequiredDefaultDescription
enabledBooleanYesfalseEnable or disable the AVP Sanitizer module.
actionActionNo{:error, 3002}Action to take when a nesting depth violation is detected. Vendor stripping silently removes offending AVPs without blocking the message.
allowed_vendor_idsListNo[0, 10415, 13019, 5535]List of vendor IDs permitted on interconnect. AVPs from other vendors are stripped.
strip_unknown_vendor_avpsBooleanNotrueEnable stripping of AVPs from vendors not in the allowed_vendor_ids list.
max_avp_nesting_depthIntegerNo10Maximum permitted depth of grouped AVP nesting. Messages exceeding this are subject to the configured action.

Common Vendor IDs:

Vendor IDOrganisationNotes
0IETFStandard Diameter AVPs defined in RFCs
104153GPPAll 3GPP-defined AVPs (S6a, Gx, Rx, etc.)
13019ETSIETSI-defined AVPs
55353GPP23GPP2-defined AVPs (CDMA interworking)

Telemetry Events

EventDescription
[:diameter, :avp_sanitizer, :unknown_vendor, :stripped]One or more AVPs from unknown vendors were stripped
[:diameter, :avp_sanitizer, :nesting_depth, :violation]A message exceeded the maximum AVP nesting depth
[:diameter, :avp_sanitizer, :pass, :count]Message passed all sanitization checks

Deployment Recommendations

When deploying the security modules for the first time, enable them incrementally to avoid disrupting live traffic:

  1. Rate Limiter — Start with generous limits and monitor traffic patterns. Tighten limits once baseline rates are understood.
  2. AVP Sanitizer — Low risk of false positives. Enable stripping and nesting checks.
  3. Diameter Firewall (Category 1) — Define whitelists based on roaming agreements. Start with known-good Application ID / Command Code combinations.
  4. Diameter Firewall (Low-Layer) — Enable protocol conformance checks.
  5. Diameter Firewall (Category 2) — Configure home IMSI/MSISDN prefixes.
  6. Topology Hiding — Enable Route-Record stripping first, then Origin-Host rewriting.
  7. Diameter Firewall (Category 3) — Enable with :log_only action to observe location patterns before enforcing.

Defence in Depth

These modules implement the defence in depth principle described in FS.19 Section 3.4. Each layer addresses a different class of attack:

Attack ClassPrimary DefenceSecondary Defence
Volumetric DoSRate LimiterDiameter Firewall (all categories)
Interface AbuseCategory 1AVP Sanitizer
Home Subscriber TargetingCategory 2Category 1 (interface restriction)
Location SpoofingCategory 3Category 2 (home sub check)
Topology DiscoveryTopology Hiding-
AVP InjectionAVP SanitizerLow-Layer Filtering
Protocol Evasion (AVP Doubling)Low-Layer FilteringAVP Sanitizer

GSMA Document Cross-Reference

Module / FeatureFS.19 v10.0FS.21 v12.0
Low-Layer Format FilteringSection 3.3.4Section 7.3.1
Category 1 FilteringSection 3.3.5, Annex B.3.3Section 7.2.1
Category 2 FilteringSection 3.3.6, Annex B.3.4Section 7.2.2, Section 16
Category 3 FilteringSection 3.3.7, Annex B.3.5Section 7.2.3
Topology HidingSection 2.4, Section 3.4Section 3.6
Rate LimitingSection 3.4-
AVP SanitizationSection 4.8.1, 4.8.2Section 3.6
Defence in DepthSection 3.4Section 3.15
Filtering Categories (Protocol-Agnostic)Annex ASection 7