Post

STUN

stun for nat detect

STUN

STUN探测类型

探测方式

根据 RFC 3489 / 5780:

维度含义
Primary IPA
Alternate IPB
Primary PortP1
Alternate PortP2

STUN Server 必须能从不同的 (IP, Port) 组合回应:

测试源 IP源 Port
Test IAP1
Test IIAP2
Test IIIBP1
Test IVBP2

客户端通过 是否能收到这些回应 判断:

  • NAT filtering behavior
  • NAT mapping behavior

STUN server

1
2
3
4
5
6
    stunserver \
    --mode full \
    --primaryinterface 128.34.56.78 \
    --altinterface     128.34.56.79 \
    --primaryport 3478 \
    --altport     3479   

STUN client

1
    stunclient --mode full 128.34.56.78

Mapping行为(NatBehavior)

决定:公网映射端口是否稳定、是否与对端有关

Behavior 枚举标准术语含义
DirectMapping无 NAT无地址/端口转换
EndpointIndependentMappingEIM同一内网 IP:Port → 同一公网 IP:Port(与对端无关)
AddressDependentMappingADM映射依赖对端 IP
AddressAndPortDependentMappingAPDM映射依赖对端 IP + Port

Filtering行为(FilterBehavior)

决定:外部“谁”能主动打进来

Filtering 枚举标准术语含义
DirectConnectionFiltering无过滤任意外部可直连
EndpointIndependentFilteringEIF任意端口,只要 IP 匹配即可
AddressDependentFilteringADF需 IP 匹配
AddressAndPortDependentFilteringAPDF需 IP + Port 都匹配

映射到四大NAT类型

Mapping(Behavior)FilteringNAT 类型
EndpointIndependentMappingEndpointIndependentFilteringFull Cone NAT
EndpointIndependentMappingAddressDependentFilteringRestricted Cone NAT
EndpointIndependentMappingAddressAndPortDependentFilteringPort Restricted Cone NAT
AddressDependentMapping任意Symmetric NAT
AddressAndPortDependentMapping任意Symmetric NAT
DirectMappingDirectConnectionFilteringOpen Internet(无 NAT)

只要 Mapping 不是 Endpoint Independent,一律判定为 Symmetric NAT
过滤方式在 Symmetric NAT 场景下已经“无实用价值”

Full Cone NAT

特征

  • 映射固定
  • 无过滤(任何外部都能打进)

Mapping = EndpointIndependentMapping
Filtering = EndpointIndependentFiltering

Restricted Cone NAT

特征

  • 映射固定
  • 只限制对端 IP,不限制端口

Mapping = EndpointIndependentMapping
Filtering = AddressDependentFiltering

Port Restricted Cone NAT

特征

  • 映射固定
  • 同时限制对端 IP + Port

Mapping = EndpointIndependentMapping
Filtering = AddressAndPortDependentFiltering

Symmetric NAT

特征

  • 映射随对端变化,映射依赖对端 IP + Port

Mapping = AddressDependentMapping
Mapping = AddressAndPortDependentMapping

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
enum NatType {
    Nat_OpenInternet,
    Nat_FullCone,
    Nat_RestrictedCone,
    Nat_PortRestrictedCone,
    Nat_Symmetric,
    Nat_Unknown
};

NatType DetectNatType(NatBehavior mapping, NatFiltering filtering)
{
    if (mapping == DirectMapping)
        return Nat_OpenInternet;

    if (mapping != EndpointIndependentMapping)
        return Nat_Symmetric;

    switch (filtering)
    {
        case EndpointIndependentFiltering:
            return Nat_FullCone;
        case AddressDependentFiltering:
            return Nat_RestrictedCone;
        case AddressAndPortDependentFiltering:
            return Nat_PortRestrictedCone;
        default:
            return Nat_Unknown;
    }
}

This post is licensed under CC BY 4.0 by the author.