DNS需求分析
需求:由于 IP 地址具有不方便记忆并且不能显示地址组织的名称和性质等缺点,人们设计出了域名,并通过域名解析协议(DNS,Domain Name System)来将域名和 IP 地址相互映射,使人更方便地访问互联网,而不用去记住能够被机器直接读取的 IP 地址数串。
功能:将域名映射成 IP 地址称为正向解析,将 IP 地址映射成域名称为反向解析。
端口:DNS 协议可以使用 UDP 或者 TCP 进行传输,使用的端口号都为 53。当DNS响应报文长度大于512 字节,就会使用TCP传输,在DNS服务器主备间同步数据时,也会使用TCP传输。
DNS查找顺序:
浏览器缓存> 本地操作系统缓存> DNS服务器(路由缓存>互联网 DNS缓存服务器)
浏览器缓存: 只存下浏览器自己访问过的域名.
本地操作系统缓存: 在/etc/hosts本地映射文件里设置的转换,但是hosts设置的IP地址是静态的,如果宿主机地址发生改变,对应的hosts也要改写.
DNS 服务器: 包括路由缓存和互联网DNS服务器
DNS请求报文:
DNS回复报文:
OVN验证DNS功能
#创建lr
ovn-nbctl lr-add lr
ovn-nbctl lrp-add lr lrp fe:fe:fe:fe:fe:aa 192.168.0.1/24
#创建ls,连接上lr
ovn-nbctl ls-add ls
ovn-nbctl lsp-add ls lsp
ovn-nbctl lsp-set-type lsp router
ovn-nbctl lsp-set-addresses lsp fe:fe:fe:fe:fe:aa
ovn-nbctl lsp-set-options lsp router-port=lrp
#创建vm口动态从dhcp获取ip,同时要制定ip范围和保留ip段
ovn-nbctl lsp-add ls ls-vm
ovn-nbctl lsp-set-addresses ls-vm "fe:fe:fe:fe:fe:cc 192.168.0.10"
#在worker节点创建vm
ip netns add vm
ovs-vsctl add-port br-int vm -- set interface vm type=internal
ip link set vm address fe:fe:fe:fe:fe:cc
ip link set vm netns vm
ip netns exec vm ip link set vm up
ovs-vsctl set Interface vm external_ids:iface-id=ls-vm
#配置dns,uuid为创建DNS records返回的值
ovn-nbctl create DNS records="www.baidu.com=100.0.0.1"
ovn-nbctl set logical_switch ls dns_records=60e10efc-b62b-4088-b975-51788a24da0c
#查看北向数据库
ovn-nbctl show
switch 48f1921d-42f6-44e8-95a7-801c0bdc4e02 (ls)
port lsp
type: router
addresses: ["fe:fe:fe:fe:fe:aa"]
router-port: lrp
port ls-vm
addresses: ["fe:fe:fe:fe:fe:cc 192.168.0.10"]
router e9e827bd-b3aa-47b9-8378-c9cc5d814309 (lr)
port lrp
mac: "fe:fe:fe:fe:fe:aa"
networks: ["192.168.0.1/24"]
#dig探测域名
ip netns exec vm dig www.baidu.com
; <<>> DiG 9.9.4-RedHat-9.9.4-51.el7_4.1 <<>> www.baidu.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56543
;; flags: qr rd ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.baidu.com. IN A
;; ADDITIONAL SECTION:
www. 3600 IN A 10.0.0.1
;; Query time: 2 msec
;; SERVER: 114.114.114.114#53(114.114.114.114)
;; WHEN: Thu Sep 30 14:30:28 CST 2021
;; MSG SIZE rcvd: 51
#查看Logical Flow
ovn-sbctl lflow-list ls
Datapath: "ls" (c33e860d-fd6b-4091-98ed-41a45d838bec) Pipeline: ingress
table=0 (ls_in_port_sec_l2 ), priority=100 , match=(eth.src[40]), action=(drop;)
table=0 (ls_in_port_sec_l2 ), priority=100 , match=(vlan.present), action=(drop;)
table=0 (ls_in_port_sec_l2 ), priority=50 , match=(inport == "ls-vm"), action=(next;)
table=0 (ls_in_port_sec_l2 ), priority=50 , match=(inport == "lsp"), action=(next;)
table=1 (ls_in_port_sec_ip ), priority=0 , match=(1), action=(next;)
table=2 (ls_in_port_sec_nd ), priority=0 , match=(1), action=(next;)
table=3 (ls_in_lookup_fdb ), priority=0 , match=(1), action=(next;)
table=4 (ls_in_put_fdb ), priority=0 , match=(1), action=(next;)
table=5 (ls_in_pre_acl ), priority=110 , match=(eth.dst == $svc_monitor_mac), action=(next;)
table=5 (ls_in_pre_acl ), priority=0 , match=(1), action=(next;)
table=6 (ls_in_pre_lb ), priority=110 , match=(eth.dst == $svc_monitor_mac), action=(next;)
table=6 (ls_in_pre_lb ), priority=110 , match=(eth.mcast), action=(next;)
table=6 (ls_in_pre_lb ), priority=110 , match=(ip && inport == "lsp"), action=(next;)
table=6 (ls_in_pre_lb ), priority=110 , match=(nd || nd_rs || nd_ra || mldv1 || mldv2), action=(next;)
table=6 (ls_in_pre_lb ), priority=0 , match=(1), action=(next;)
table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[2] == 1 && ip4 && sctp), action=(reg1 = ip4.dst; reg2[0..15] = sctp.dst; ct_lb;)
table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[2] == 1 && ip4 && tcp), action=(reg1 = ip4.dst; reg2[0..15] = tcp.dst; ct_lb;)
table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[2] == 1 && ip4 && udp), action=(reg1 = ip4.dst; reg2[0..15] = udp.dst; ct_lb;)
table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[2] == 1 && ip6 && sctp), action=(xxreg1 = ip6.dst; reg2[0..15] = sctp.dst; ct_lb;)
table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[2] == 1 && ip6 && tcp), action=(xxreg1 = ip6.dst; reg2[0..15] = tcp.dst; ct_lb;)
table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[2] == 1 && ip6 && udp), action=(xxreg1 = ip6.dst; reg2[0..15] = udp.dst; ct_lb;)
table=7 (ls_in_pre_stateful ), priority=110 , match=(reg0[2] == 1), action=(ct_lb;)
table=7 (ls_in_pre_stateful ), priority=100 , match=(reg0[0] == 1), action=(ct_next;)
table=7 (ls_in_pre_stateful ), priority=0 , match=(1), action=(next;)
table=8 (ls_in_acl_hint ), priority=65535, match=(1), action=(next;)
table=9 (ls_in_acl ), priority=65535, match=(1), action=(next;)
table=10(ls_in_qos_mark ), priority=0 , match=(1), action=(next;)
table=11(ls_in_qos_meter ), priority=0 , match=(1), action=(next;)
table=12(ls_in_lb ), priority=0 , match=(1), action=(next;)
table=13(ls_in_acl_after_lb ), priority=0 , match=(1), action=(next;)
table=14(ls_in_stateful ), priority=100 , match=(reg0[1] == 1 && reg0[13] == 0), action=(ct_commit { ct_label.blocked = 0; }; next;)
table=14(ls_in_stateful ), priority=100 , match=(reg0[1] == 1 && reg0[13] == 1), action=(ct_commit { ct_label.blocked = 0; ct_label.label = reg3; }; next;)
table=14(ls_in_stateful ), priority=0 , match=(1), action=(next;)
table=15(ls_in_pre_hairpin ), priority=0 , match=(1), action=(next;)
table=16(ls_in_nat_hairpin ), priority=0 , match=(1), action=(next;)
table=17(ls_in_hairpin ), priority=0 , match=(1), action=(next;)
table=18(ls_in_arp_rsp ), priority=100 , match=(arp.tpa == 192.168.0.10 && arp.op == 1 && inport == "ls-vm"), action=(next;)
table=18(ls_in_arp_rsp ), priority=50 , match=(arp.tpa == 192.168.0.10 && arp.op == 1), action=(eth.dst = eth.src; eth.src = fe:fe:fe:fe:fe:cc; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = fe:fe:fe:fe:fe:cc; arp.tpa = arp.spa; arp.spa = 192.168.0.10; outport = inport; flags.loopback = 1; output;)
table=18(ls_in_arp_rsp ), priority=0 , match=(1), action=(next;)
table=19(ls_in_dhcp_options ), priority=0 , match=(1), action=(next;)
table=20(ls_in_dhcp_response), priority=0 , match=(1), action=(next;)
table=21(ls_in_dns_lookup ), priority=100 , match=(udp.dst == 53), action=(reg0[4] = dns_lookup(); next;)
table=21(ls_in_dns_lookup ), priority=0 , match=(1), action=(next;)
table=22(ls_in_dns_response ), priority=100 , match=(udp.dst == 53 && reg0[4]), action=(eth.dst <-> eth.src; ip4.src <-> ip4.dst; udp.dst = udp.src; udp.src = 53; outport = inport; flags.loopback = 1; output;)
table=22(ls_in_dns_response ), priority=100 , match=(udp.dst == 53 && reg0[4]), action=(eth.dst <-> eth.src; ip6.src <-> ip6.dst; udp.dst = udp.src; udp.src = 53; outport = inport; flags.loopback = 1; output;)
table=22(ls_in_dns_response ), priority=0 , match=(1), action=(next;)
table=23(ls_in_external_port), priority=0 , match=(1), action=(next;)
table=24(ls_in_l2_lkup ), priority=110 , match=(eth.dst == $svc_monitor_mac), action=(handle_svc_check(inport);)
table=24(ls_in_l2_lkup ), priority=80 , match=(flags[1] == 0 && arp.op == 1 && arp.tpa == 192.168.0.1), action=(clone {outport = "lsp"; output; }; outport = "_MC_flood_l2"; output;)
table=24(ls_in_l2_lkup ), priority=80 , match=(flags[1] == 0 && nd_ns && nd.target == fe80::fcfe:feff:fefe:feaa), action=(clone {outport = "lsp"; output; }; outport = "_MC_flood_l2"; output;)
table=24(ls_in_l2_lkup ), priority=75 , match=(eth.src == {fe:fe:fe:fe:fe:aa} && (arp.op == 1 || nd_ns)), action=(outport = "_MC_flood_l2"; output;)
table=24(ls_in_l2_lkup ), priority=70 , match=(eth.mcast), action=(outport = "_MC_flood"; output;)
table=24(ls_in_l2_lkup ), priority=50 , match=(eth.dst == fe:fe:fe:fe:fe:aa), action=(outport = "lsp"; output;)
table=24(ls_in_l2_lkup ), priority=50 , match=(eth.dst == fe:fe:fe:fe:fe:cc), action=(outport = "ls-vm"; output;)
table=24(ls_in_l2_lkup ), priority=0 , match=(1), action=(outport = get_fdb(eth.dst); next;)
table=25(ls_in_l2_unknown ), priority=50 , match=(outport == "none"), action=(drop;)
table=25(ls_in_l2_unknown ), priority=0 , match=(1), action=(output;)
Datapath: "ls" (c33e860d-fd6b-4091-98ed-41a45d838bec) Pipeline: egress
table=0 (ls_out_pre_lb ), priority=110 , match=(eth.mcast), action=(next;)
table=0 (ls_out_pre_lb ), priority=110 , match=(eth.src == $svc_monitor_mac), action=(next;)
table=0 (ls_out_pre_lb ), priority=110 , match=(ip && outport == "lsp"), action=(next;)
table=0 (ls_out_pre_lb ), priority=110 , match=(nd || nd_rs || nd_ra || mldv1 || mldv2), action=(next;)
table=0 (ls_out_pre_lb ), priority=0 , match=(1), action=(next;)
table=1 (ls_out_pre_acl ), priority=110 , match=(eth.src == $svc_monitor_mac), action=(next;)
table=1 (ls_out_pre_acl ), priority=0 , match=(1), action=(next;)
table=2 (ls_out_pre_stateful), priority=110 , match=(reg0[2] == 1), action=(ct_lb;)
table=2 (ls_out_pre_stateful), priority=100 , match=(reg0[0] == 1), action=(ct_next;)
table=2 (ls_out_pre_stateful), priority=0 , match=(1), action=(next;)
table=3 (ls_out_acl_hint ), priority=65535, match=(1), action=(next;)
table=4 (ls_out_acl ), priority=65535, match=(1), action=(next;)
table=4 (ls_out_acl ), priority=34000, match=(outport == "ls-vm" && eth.src == fe:fe:fe:fe:fe:aa && ip4.src == 192.168.0.1 && udp && udp.src == 67 && udp.dst == 68), action=(next;)
table=5 (ls_out_qos_mark ), priority=0 , match=(1), action=(next;)
table=6 (ls_out_qos_meter ), priority=0 , match=(1), action=(next;)
table=7 (ls_out_stateful ), priority=100 , match=(reg0[1] == 1 && reg0[13] == 0), action=(ct_commit { ct_label.blocked = 0; }; next;)
table=7 (ls_out_stateful ), priority=100 , match=(reg0[1] == 1 && reg0[13] == 1), action=(ct_commit { ct_label.blocked = 0; ct_label.label = reg3; }; next;)
table=7 (ls_out_stateful ), priority=0 , match=(1), action=(next;)
table=8 (ls_out_port_sec_ip ), priority=0 , match=(1), action=(next;)
table=9 (ls_out_port_sec_l2 ), priority=100 , match=(eth.mcast), action=(output;)
table=9 (ls_out_port_sec_l2 ), priority=50 , match=(outport == "ls-vm"), action=(output;)
table=9 (ls_out_port_sec_l2 ), priority=50 , match=(outport == "lsp"), action=(output;)
可以看到在table21里仅匹配目的端口53后进行dns_lookup,到table22里对dns报文进行修改,将目的mac修改为dns request的源mac,源ip为dns request的目的ip,udp源端口改成53,出接口改为dns request的入接口,返回dns response。缺点是不能做到vpc隔离和dns二级代理。
在vm口抓包,可以看到dns reponse回包www.baidu.com对应的ip为100.0.0.1
ip netns exec vm tcpdump -i vm -nn -vv -e
08:28:16.708619 fe:fe:fe:fe:fe:cc > fe:fe:fe:fe:fe:aa, ethertype IPv4 (0x0800), length 73: (tos 0x0, ttl 64, id 61033, offset 0, flags [DF], proto UDP (17), length 59)
192.168.0.6.41123 > 10.96.0.10.53: [bad udp cksum 0xcb50 -> 0xb07d!] 10033+ A? www.baidu.com. (31)
08:28:16.709210 fe:fe:fe:fe:fe:aa > fe:fe:fe:fe:fe:cc, ethertype IPv4 (0x0800), length 102: (tos 0x0, ttl 64, id 61033, offset 0, flags [DF], proto UDP (17), length 88)
10.96.0.10.53 > 192.168.0.6.41123: [no cksum] 10033- q: A? www.baidu.com. 1/0/0 www.baidu.com. A 100.0.0.1 (60)