upgw-dns-redirect 节点
upgw-dns-redirect
节点承接upgw-input
节点流量,当 upgw-input
节点分析报文为 dns
报文后,交到 upgw-dns-redirect
节点,upgw-dns-redirect
节点处理如下:
区分域名是否在 dns redirect 配置中,如果不在,直接发到默认出口的
interface-output
。如果域名在 dns redirect 配置中,做进一步分析
若数据包从 USER 来且是 dns 请求包,保存
dns_pkt_key
后根据 dns redirect 配置修改报文目的 IP 和 MAC,然后送到指定接口的interface-output
.若数据包从 USER 来且是 dns 应答包,丢弃。
若数据包从 NETWORK 来,丢弃。
若数据包从 LBP 来且是 dns 请求包,丢弃。
若数据包从 LBP 来切实 dns 应答包,根据目的 ip 查询自学习 learning table,删除请求时保存的
dns_pkt_key
后,根据 learning table 重新封装报文为 GTPU 或者 IP 报文,然后发送到 learning table 中的接口的interface-output
。
处理流程
配置
命令行:
# 查看 node 信息
uranus> show node upgw-dns-redirect
node upgw-dns-redirect, type internal, state active, index 23
node function variants:
default only
next nodes:
next-index node-index Node Vectors
0 687 error-drop 0
1 685 interface-output 0
known previous nodes:
upgw-input (26)
dns 重定向配置
.short_help = "upgw dns redirect <add|del|clear> <doamin-name> [{<ip-addr> interface <interface-name> | [v4|v6|all]}]"
例子:
添加一条 ipv4 redirect server
upgw dns redirect add www.baidu.com 1.1.1.1 interface GigabitEthernet0/b/0
添加一条 ipv6 redirect server
upgw dns redirect add www.baidu.com 2222::222 interface GigabitEthernet0/b/0
删除一条 ipv4 redirect server
upgw dns redirect del www.baidu.com v4
删除一条 ipv6 redirect server
upgw dns redirect del www.baidu.com v6
删除域名下的 redirect server
upgw dns redirect del www.baidu.com all
清除所有的 dns_redirect
upgw dns redirect clear
dns 重定向查看
.short_help = show upgw dns redirect [domain_name]
查看指定 domain_name 的 dns 重定向信息
uranus> show upgw dns redirect www.baidu.com
www.baidu.com
*********************************************
ip4 redirect dns server: 1.1.1.1, lbp-inter GigabitEthernet0/b/0
ip6 redirect dns server: 2222::222, lbp-inter GigabitEthernet0/b/0
查看所有的 dns 重定向信息
show upgw dns redirect
Trace
如果域名未在 DNS 重定向列表中
DNS 请求
00:00:31:228731: upgw-dns-redirect
next_node_index 1
Dns request package, Domain_name www.1234.com and Send to 1 direct
DNS 回复
00:00:31:237570: upgw-dns-redirect
next_node_index 1
Dns reply package, Domain_name www.1234.com and Send to 1 direct
如果域名在DNS 重定向列表中
DNS 请求
00:00:33:156401: upgw-dns-redirect
next_node_index 1
Dns request package, Domain_name www.123.com and Rewrite package done
Rewrite Ethernet:
IP4: 52:54:00:c2:cb:3f -> 52:54:00:e8:a7:28
Rewrite IP:
UDP: 192.168.10.3 -> 192.168.200.1
tos 0x00, ttl 64, length 68, checksum 0x546b dscp CS0 ecn NON_ECN
fragment id 0xd2e8
UDP: 60675 -> 53
length 48, checksum 0x1230
DNS 回复
00:00:33:157193: upgw-dns-redirect
next_node_index 1
Dns reply package, Domain_name www.123.com and Rewrite package done
Rewrite Ethernet:
IP4: 52:54:00:aa:8d:48 -> 52:54:00:c2:cb:3f
Rewrite IP:
UDP: 192.168.10.4 -> 192.168.10.3
tos 0x00, ttl 64, length 73, checksum 0x6b93 dscp CS0 ecn NON_ECN
fragment id 0x39b9, flags DONT_FRAGMENT
UDP: 53 -> 60675
length 53, checksum 0x5259
基于 VPP 的 UPGW DNS 重定向功能介绍
DNS 协议
域名系统(Domain Name System 缩写 DNS,Domain Name 被译为域名)是因特网的一项核心服务,它作为可以将域名和 IP 地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的 IP 数串。
DNS 报文解析
DNS 分为查询请求和查询响应,请求和响应的报文结构基本相同。DNS 报文格式如图所示。
基础结构部分
DNS 报文的基础结构部分指的是报文首部,如图所示。
该部分中每个字段含义如下。
事务 ID:DNS 报文的 ID 标识。对于请求报文和其对应的应答报文,该字段的值是相同的。通过它可以区分 DNS 应答报文是对哪个请求进行响应的。
标志:DNS 报文中的标志字段。
问题计数:DNS 查询请求的数目。
回答资源记录数:DNS 响应的数目。
权威名称服务器计数:权威名称服务器的数目。
附加资源记录数:额外的记录数目(权威名称服务器对应 IP 地址的数目)。
基础结构部分中的标志字段又分为若干个字段,如图所示。
标志字段中每个字段的含义如下:
QR(Response):查询请求/响应的标志信息。查询请求时,值为 0;响应时,值为 1。
Opcode:操作码。其中,0 表示标准查询;1 表示反向查询;2 表示服务器状态请求。
AA(Authoritative):授权应答,该字段在响应报文中有效。值为 1 时,表示名称服务器是权威服务器;值为 0 时,表示不是权威服务器。
TC(Truncated):表示是否被截断。值为 1 时,表示响应已超过 512 字节并已被截断,只返回前 512 个字节。
RD(Recursion Desired):期望递归。该字段能在一个查询中设置,并在响应中返回。该标志告诉名称服务器必须处理这个查询,这种方式被称为一个递归查询。如果该位为 0,且被请求的名称服务器没有一个授权回答,它将返回一个能解答该查询的其他名称服务器列表。这种方式被称为迭代查询。
RA(Recursion Available):可用递归。该字段只出现在响应报文中。当值为 1 时,表示服务器支持递归查询。
Z:保留字段,在所有的请求和应答报文中,它的值必须为 0。
rcode(Reply code):返回码字段,表示响应的差错状态。当值为 0 时,表示没有错误;当值为 1 时,表示报文格式错误(Format error),服务器不能理解请求的报文;当值为 2 时,表示域名服务器失败(Server failure),因为服务器的原因导致没办法处理这个请求;当值为 3 时,表示名字错误(Name Error),只有对授权域名解析服务器有意义,指出解析的域名不存在;当值为 4 时,表示查询类型不支持(Not Implemented),即域名服务器不支持查询类型;当值为 5 时,表示拒绝(Refused),一般是服务器由于设置的策略拒绝给出应答,如服务器不希望对某些请求者给出应答。
UPGW 1.1.0 中 关于 dns_hearder_s 结构体如下
typedef struct dns_header_s {
uint16_t id; // 对应事务 ID
uint8_t rd : 1; // 对应 Recursion Desired
uint8_t tc : 1; // 对应 Truncated
uint8_t aa : 1; // 对应 Authoritative, 请求报文中无效,Wireshack 不解析
uint8_t opcode : 4; // 操作码
uint8_t qr : 1; // 对应 Response
uint8_t rcode : 4; // 返回码字段
uint8_t z : 3; // 保留字段,为 0
uint8_t ra : 1; // 可用递归
uint16_t qdcount; // Questions 问题计数
uint16_t ancount; // Answer RRs, DNS 响应的数目
uint16_t nscount; // Authnority RRs, 权威名称服务器的数目
uint16_t qrcount; // Additional RRs, 附加资源记录数
} __attribute__((__packed__)) dns_header_t;
问题部分
问题部分指的是报文格式中查询问题区域(Queries)部分。该部分是用来显示 DNS 查询请求的问题,通常只有一个问题。该部分包含正在进行的查询信息,包含查询名(被查询主机名字)、查询类型、查询类。问题部分格式如图所示。
该部分中每个字段含义如下:
查询名:一般为要查询的域名,有时也会是 IP 地址,用于反向查询。
查询类型:DNS 查询请求的资源类型。通常查询类型为 A 类型,表示由域名获取对应的 IP 地址。
查询类:地址类型,通常为互联网地址,值为 1。
资源记录部分
资源记录部分是指 DNS 报文格式中的最后三个字段,包括回答问题区域字段、权威名称服务器区域字段、附加信息区域字段。这三个字段均采用一种称为资源记录的格式,格式如图所示。
资源记录格式中每个字段含义如下:
域名:DNS 请求的域名。
类型:资源记录的类型,与问题部分中的查询类型值是一样的。
类:地址类型,与问题部分中的查询类值是一样的。
生存时间:以秒为单位,表示资源记录的生命周期,一般用于当地址解析程序取出资源记录后决定保存及使用缓存数据的时间。它同时也可以表明该资源记录的稳定程度,稳定的信息会被分配一个很大的值。
资源数据长度:资源数据的长度。
资源数据:表示按查询段要求返回的相关资源记录的数据。
资源记录部分只有在 DNS 响应包中才会出现。下面通过 DNS 响应包来进一步了解资源记录部分的字段信息。
DNS 重定向需求
DNS 重定向针对特定域名进行重定向,将请求发送到 edge dns 服务器;
当终端发出 DNS 请求时;在 UPGW 解析,如果是需要重定向的请求域名,则将请求发送到 edge dns;不再发送到终端发出 DNS 请求的目的 Server。
结构
存储 DNS 的域名和 DNS 服务器的映射关系,请求的域名为系统内唯一,不需要引入 UUID;
upgw_main_t
{
......
dns_redirect_entry_t *dns_redirect_entries; // dns_redirect_entry 列表
uword *dns_redirect_entry_index_by_domain_name; // dns_redirect_entry_index hash
dns_pkt_key_t *dns_pkt_keys; // dns_pkt_key 列表
uword *dns_pkt_key_by_unique_identify; // dns_pkt_key_index hash
}
typedef struct
{
u8 *domain_name; // 域名
u8 flags; // ipv4,ipv6,ipv4 && ipv6
ip4_address_t ip4_dns_redirect_server; // ipv4 dns server
ip6_address_t ip6_dns_redirect_server; // ipv6 dns server
u32 ip4_sw_if_index; // ipv4 dns server lbp 出口
u32 ip6_sw_if_index; // ipv6 dns server lbp 出口
} dns_redirect_entry_t;
typedef struct
{
uint16_t transaction_id; // dns 序号
ip46_address_t req_ip; // dns 请求者的 ip
} dns_pkt_unique_identify_t;
typedef struct
{
dns_pkt_unique_identify_t dns_pkg_unique_identify; //unique identify, src_ip + transaction_id 上个结构体
ip46_address_t resp_ip; // 原 dns 请求的目的 ip server 地址
f64 time_cycle; // 请求缓存存活时间
} dns_pkt_key_t;
upgw node init
存储dns_redirect_entry
和以domain_name
和entry
的Hash
;dns_redirect entry
有domain_name
和对应重定向服务器的ipv4
;dns_pkg_key_s
缓存dns
请求的源ip + port + mac
和目的 ip (dns 服务器);transaction_id
号,time_cycle
为请求保留时间。