引言
此文檔是對(duì)發(fā)往Docker容器內(nèi)的數(shù)據(jù)包源地址被修改的研究做的實(shí)踐記錄。
實(shí)踐環(huán)境一
Centos7.2+Docker1.12.6
關(guān)閉firewalld:
systemctl stop firewalld
設(shè)置selinux為Permissive模式:
setenforce 0
/etc/docker/daemon.json內(nèi)容:
{
"userland-proxy": true
}
創(chuàng)建名為python的容器:
docker run -itd --name python --network bridge -p 8000:9999/udp --entrypoint bash python:2.7.15
容器內(nèi)接收udp數(shù)據(jù)包的程序內(nèi)容為:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 綁定端口:
s.bind(('0.0.0.0', 9999))
print 'Bind UDP on 9999...'
while 1:
# 接收數(shù)據(jù):
data, addr = s.recvfrom(1024)
print 'addr: {0}, data: {1}'.format(addr, data)
路由信息:
一搏讶、通過另一臺(tái)主機(jī)向當(dāng)前主機(jī)發(fā)送數(shù)據(jù)包
1.192.168.84.75主機(jī)上運(yùn)行接收udp數(shù)據(jù)包的程序系吩,運(yùn)行配置基于實(shí)踐環(huán)境,在192.168.84.79主機(jī)上通過 echo mac | nc -s 192.168.84.79 -p 42731 -u 192.168.84.75 8000(產(chǎn)生數(shù)據(jù)包的源地址科盛、源端口與目的地址、目的端口為:192.168.84.79.42731 > 192.168.84.75.8000) 向192.168.84.75發(fā)送數(shù)據(jù)包榨崩。
對(duì)192.168.84.79主機(jī)的網(wǎng)卡進(jìn)行抓包處理:
tcpdump -i eno16777984 udp port 8000 -nn -vv
tcpdump: listening on eno16777984, link-type EN10MB (Ethernet), capture size 262144 bytes
13:33:15.227775 IP (tos 0x0, ttl 64, id 58746, offset 0, flags [DF], proto UDP (17), length 32)
192.168.84.79.42731 > 192.168.84.75.8000: [bad udp cksum 0x2a09 -> 0x3f53!] UDP, length 4
分別對(duì)192.168.84.75主機(jī)的lo胳施、物理網(wǎng)卡(eno16777984)焦辅、docker0以及容器的網(wǎng)卡進(jìn)行抓包處理:
tcpdump -i lo -nn -vv
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
無內(nèi)容
tcpdump -i eno16777984 udp port 8000 -nn -vv
tcpdump: listening on eno16777984, link-type EN10MB (Ethernet), capture size 262144 bytes
13:33:25.690285 IP (tos 0x0, ttl 64, id 58746, offset 0, flags [DF], proto UDP (17), length 32)
192.168.84.79.42731 > 192.168.84.75.8000: [udp sum ok] UDP, length 4
tcpdump -i docker0 -nn -vv
tcpdump: listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
13:33:25.690319 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
13:33:25.690354 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
13:33:25.690362 IP (tos 0x0, ttl 63, id 58746, offset 0, flags [DF], proto UDP (17), length 32)
192.168.84.79.42731 > 172.17.0.2.9999: [udp sum ok] UDP, length 4
tcpdump -i vethc4d778f -nn -vv
tcpdump: listening on vethc4d778f, link-type EN10MB (Ethernet), capture size 262144 bytes
13:33:25.690332 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
13:33:25.690354 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
13:33:25.690364 IP (tos 0x0, ttl 63, id 58746, offset 0, flags [DF], proto UDP (17), length 32)
192.168.84.79.42731 > 172.17.0.2.9999: [udp sum ok] UDP, length 4
由上述的時(shí)間可知數(shù)據(jù)包先經(jīng)過84.79主機(jī)的網(wǎng)卡,然后數(shù)據(jù)包被發(fā)往84.75主機(jī),在84.75主機(jī)上經(jīng)過的設(shè)備依次為:主機(jī)網(wǎng)卡(eno16777984 )---> docker0 ---> 容器網(wǎng)卡(vethc4d778f)
數(shù)據(jù)包發(fā)送前與發(fā)送后84.75主機(jī)的nat表的對(duì)比:
發(fā)送前執(zhí)行 iptables -t nat -nvL > pre
發(fā)送后執(zhí)行 iptables -t nat -nvL > now
然后通過diff命令對(duì)比兩個(gè)文件的內(nèi)容:
-
在84.79主機(jī)上執(zhí)行 echo mac | nc -s 127.0.0.1 -p 42731 -u 192.168.84.75 8000 例嘱,報(bào)錯(cuò)誤信息Ncat: Invalid argument.
二狡逢、本機(jī)上通過網(wǎng)卡ip地址發(fā)送數(shù)據(jù)包
- 在192.168.84.75主機(jī)上執(zhí)行 echo mac | nc -s 192.168.84.75 -p 34191 -u 192.168.84.75 8000
分別lo、物理網(wǎng)卡(eno16777984)拼卵、docker0以及容器的網(wǎng)卡進(jìn)行抓包處理:
tcpdump -i lo -nn -vv
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
無內(nèi)容
tcpdump -i eno16777984 udp port 8000 -nn -vv
tcpdump: listening on eno16777984, link-type EN10MB (Ethernet), capture size 262144 bytes
無內(nèi)容
tcpdump -i docker0 -nn -vv
tcpdump: listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
13:37:07.072740 IP (tos 0x0, ttl 64, id 64295, offset 0, flags [DF], proto UDP (17), length 32)
192.168.84.75.34191 > 172.17.0.2.9999: [bad udp cksum 0xc124 -> 0xc1c4!] UDP, length 4
13:37:12.075322 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
13:37:12.075355 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
tcpdump -i vethc4d778f -nn -vv
tcpdump: listening on vethc4d778f, link-type EN10MB (Ethernet), capture size 262144 bytes
13:37:07.072758 IP (tos 0x0, ttl 64, id 64295, offset 0, flags [DF], proto UDP (17), length 32)
192.168.84.75.34191 > 172.17.0.2.9999: [bad udp cksum 0xc124 -> 0xc1c4!] UDP, length 4
13:37:12.075332 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
13:37:12.075355 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
可知數(shù)據(jù)包僅經(jīng)過docker0然后去往容器設(shè)備vethc4d778f奢浑,并沒有經(jīng)過綁定192.168.84.75 IP的網(wǎng)卡eno16777984
數(shù)據(jù)包發(fā)送前與發(fā)送后84.75主機(jī)的nat表的對(duì)比:
-
echo mac | nc -s 127.0.0.1 -p 34191 -u 192.168.84.75 8000 Ncat: Invalid argument.
三、本機(jī)上通過127.0.0.1地址發(fā)送數(shù)據(jù)包
- 在192.168.84.75主機(jī)上執(zhí)行 echo mac | nc -s 127.0.0.1 -p 33089 -u 127.0.0.1 8000
分別對(duì)主機(jī)的lo沃疮、物理網(wǎng)卡(eno16777984)盒让、docker0以及容器的網(wǎng)卡進(jìn)行抓包處理:
tcpdump -i lo -nn -vv
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
13:41:30.463055 IP (tos 0x0, ttl 64, id 54997, offset 0, flags [DF], proto UDP (17), length 32)
127.0.0.1.33089 > 127.0.0.1.8000: [bad udp cksum 0xfe1f -> 0x90e6!] UDP, length 4
tcpdump -i eno16777984 udp port 8000 -nn -vv
tcpdump: listening on eno16777984, link-type EN10MB (Ethernet), capture size 262144 bytes
無內(nèi)容
tcpdump -i docker0 -nn -vv
tcpdump: listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
13:41:30.463419 IP (tos 0x0, ttl 64, id 35536, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.33987 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0x2b72!] UDP, length 4
13:41:35.467315 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
13:41:35.467348 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
tcpdump -i vethc4d778f -nn -vv
tcpdump: listening on vethc4d778f, link-type EN10MB (Ethernet), capture size 262144 bytes
13:41:30.463430 IP (tos 0x0, ttl 64, id 35536, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.33987 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0x2b72!] UDP, length 4
13:41:35.467325 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
13:41:35.467348 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
可知數(shù)據(jù)包在主機(jī)上經(jīng)過的設(shè)備次序?yàn)椋簂o ---> docker0 ---> vethc4d778f
數(shù)據(jù)包發(fā)送前與發(fā)送后主機(jī)nat表的對(duì)比如下:
- echo mac | nc -s 192.168.84.75 -p 33089 -u 127.0.0.1 8000(程序能夠收到數(shù)據(jù)包)
lo設(shè)備、docker0與容器網(wǎng)卡抓包結(jié)果:
tcpdump -i lo -nn -vv
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
13:46:14.238701 IP (tos 0x0, ttl 64, id 54998, offset 0, flags [DF], proto UDP (17), length 32)
192.168.84.75.33089 > 127.0.0.1.8000: [bad udp cksum 0x9412 -> 0xfaf3!] UDP, length 4
tcpdump -i docker0 -nn -vv
tcpdump: listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
13:46:14.238980 IP (tos 0x0, ttl 64, id 35537, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.36234 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0x22ab!] UDP, length 4
13:46:19.243339 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
13:46:19.243377 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
tcpdump -i vethc4d778f -nn -vv
tcpdump: listening on vethc4d778f, link-type EN10MB (Ethernet), capture size 262144 bytes
13:46:14.238992 IP (tos 0x0, ttl 64, id 35537, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.36234 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0x22ab!] UDP, length 4
13:46:19.243350 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
13:46:19.243377 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
程序輸出結(jié)果:addr: ('172.17.0.1', 36234), data: mac
四跛十、通過容器ip地址發(fā)送數(shù)據(jù)包
-
192.168.84.75主機(jī)上容器python的ip地址為172.17.0.2泉手,可通過下面方式獲得:
在主機(jī)上執(zhí)行 echo mac | nc -s 172.17.0.1 -p 42883 -u 172.17.0.2 9999分別對(duì)192.168.84.75主機(jī)的lo、物理網(wǎng)卡(eno16777984)偶器、docker0以及容器的網(wǎng)卡進(jìn)行抓包處理:
tcpdump -i lo -nn -vv
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
無內(nèi)容
tcpdump -i eno16777984 udp port 9999 -nn -vv
tcpdump: listening on eno16777984, link-type EN10MB (Ethernet), capture size 262144 bytes
無內(nèi)容
tcpdump -i docker0 -nn -vv
tcpdump: listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
13:49:05.123460 IP (tos 0x0, ttl 64, id 35538, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.42883 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0x08b2!] UDP, length 4
13:49:10.139337 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
13:49:10.139376 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
tcpdump -i vethc4d778f -nn -vv
tcpdump: listening on vethc4d778f, link-type EN10MB (Ethernet), capture size 262144 bytes
13:49:05.123479 IP (tos 0x0, ttl 64, id 35538, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.42883 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0x08b2!] UDP, length 4
13:49:10.139347 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
13:49:10.139376 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
數(shù)據(jù)包經(jīng)過的設(shè)備依次為:docker0 ---> vethc4d778f
數(shù)據(jù)包發(fā)送前與發(fā)送后主機(jī)nat對(duì)比:
- echo mac | nc -s 172.17.0.2 -p 42883 -u 172.17.0.2 9999
libnsock mksock_bind_addr(): Bind to 172.17.0.2:42883 failed (IOD #1): Cannot assign requested address (99)
docker0與容器網(wǎng)卡抓包結(jié)果:
tcpdump -i docker0 -nn -vv(數(shù)據(jù)包的源地址、源端口已經(jīng)被修改)
tcpdump: listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
13:51:26.388949 IP (tos 0x0, ttl 64, id 35539, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.54670 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0xdaa6!] UDP, length 4
13:51:31.403315 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
13:51:31.403347 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
tcpdump -i vethc4d778f -nn -vv
tcpdump: listening on vethc4d778f, link-type EN10MB (Ethernet), capture size 262144 bytes
13:51:26.388966 IP (tos 0x0, ttl 64, id 35539, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.54670 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0xdaa6!] UDP, length 4
13:51:31.403325 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
13:51:31.403347 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
程序結(jié)果:addr: ('172.17.0.1', 54670), data: mac
-
echo mac | nc -s 127.0.0.1 -p 42883 -u 172.17.0.2 9999 Ncat: Invalid argument.
實(shí)踐環(huán)境二
Centos7.2 + Docker1.12.6
關(guān)閉firewalld:
systemctl stop firewalld
設(shè)置selinux為Permissive模式:
setenforce 0
/etc/docker/daemon.json內(nèi)容:
{
"userland-proxy": false
}
創(chuàng)建名為python的容器:
docker run -itd --name python --network bridge -p 8000:9999/udp --entrypoint bash python:2.7.15
容器內(nèi)接收udp數(shù)據(jù)包的程序內(nèi)容為:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 綁定端口:
s.bind(('0.0.0.0', 9999))
print 'Bind UDP on 9999...'
while 1:
# 接收數(shù)據(jù):
data, addr = s.recvfrom(1024)
print 'addr: {0}, data: {1}'.format(addr, data)
路由信息:-
docker-proxy進(jìn)程消失
-
dockerd進(jìn)程監(jiān)聽8000端口
- nat表的POSTROUTING鏈多了一條源地址偽裝的規(guī)則
-A POSTROUTING -o docker0 -m addrtype --src-type LOCAL -j MASQUERADE
(將源地址類型為LOCAL且從docker0設(shè)備流出的數(shù)據(jù)包的源地址偽裝成docker0設(shè)備的地址)
一检眯、通過另一臺(tái)主機(jī)向當(dāng)前主機(jī)發(fā)送數(shù)據(jù)包
- 192.168.84.75主機(jī)上運(yùn)行接收udp數(shù)據(jù)包的程序,運(yùn)行配置基于實(shí)踐環(huán)境昆淡,在192.168.84.79主機(jī)上通過 echo mac | nc -s 192.168.84.79 -p 55902 -u 192.168.84.75 8000 發(fā)送數(shù)據(jù)包锰瘸。
對(duì)192.168.84.79主機(jī)的網(wǎng)卡進(jìn)行抓包處理:
tcpdump -i eno16777984 udp port 8000 -nn -vv
tcpdump: listening on eno16777984, link-type EN10MB (Ethernet), capture size 262144 bytes
13:57:35.975290 IP (tos 0x0, ttl 64, id 58747, offset 0, flags [DF], proto UDP (17), length 32)
192.168.84.79.55902 > 192.168.84.75.8000: [bad udp cksum 0x2a09 -> 0x0be0!] UDP, length 4
分別對(duì)192.168.84.75主機(jī)的lo、物理網(wǎng)卡(eno16777984)昂灵、docker0以及容器的網(wǎng)卡進(jìn)行抓包處理:
tcpdump -i lo -nn -vv
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
無內(nèi)容
tcpdump -i eno16777984 udp port 8000 -nn -vv
tcpdump: listening on eno16777984, link-type EN10MB (Ethernet), capture size 262144 bytes
13:57:46.437799 IP (tos 0x0, ttl 64, id 58747, offset 0, flags [DF], proto UDP (17), length 32)
192.168.84.79.55902 > 192.168.84.75.8000: [udp sum ok] UDP, length 4
tcpdump -i docker0 -nn -vv
tcpdump: listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
13:57:46.437850 IP (tos 0x0, ttl 63, id 58747, offset 0, flags [DF], proto UDP (17), length 32)
192.168.84.79.55902 > 172.17.0.2.9999: [udp sum ok] UDP, length 4
13:57:51.451317 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
13:57:51.451355 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
tcpdump -i vethcbcc4e9 -nn -vv
tcpdump: listening on vethcbcc4e9, link-type EN10MB (Ethernet), capture size 262144 bytes
13:57:46.437863 IP (tos 0x0, ttl 63, id 58747, offset 0, flags [DF], proto UDP (17), length 32)
192.168.84.79.55902 > 172.17.0.2.9999: [udp sum ok] UDP, length 4
13:57:51.451327 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
13:57:51.451355 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
數(shù)據(jù)包流經(jīng)設(shè)備的順序依次為:eno16777984(84.79) ---> eno16777984(84.75) ---> docker0 ---> vethcbcc4e9
數(shù)據(jù)包發(fā)送前與發(fā)送后主機(jī)nat表對(duì)比:
-
192.168.84.79主機(jī)上執(zhí)行 echo mac | nc -s 127.0.0.1 -p 55902 -u 192.168.84.75 8000 Ncat: Invalid argument.
二、本機(jī)上通過網(wǎng)卡ip地址發(fā)送數(shù)據(jù)包
- 在192.168.84.75主機(jī)上執(zhí)行 echo mac | nc -s 192.168.84.75 -p 41003 -u 192.168.84.75 8000
分別lo設(shè)備镶柱、物理網(wǎng)卡(eno16777984)旷档、docker0以及容器網(wǎng)卡進(jìn)行抓包處理:
tcpdump -i lo -nn -vv
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
tcpdump -i eno16777984 udp port 8000 -nn -vv
tcpdump: listening on eno16777984, link-type EN10MB (Ethernet), capture size 262144 bytes
tcpdump -i docker0 -nn -vv
tcpdump: listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:03:41.089945 IP (tos 0x0, ttl 64, id 64296, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.41003 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0x100a!] UDP, length 4
14:03:46.091328 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
14:03:46.091387 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
tcpdump -i vethcbcc4e9 -nn -vv
tcpdump: listening on vethcbcc4e9, link-type EN10MB (Ethernet), capture size 262144 bytes
14:03:41.089961 IP (tos 0x0, ttl 64, id 64296, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.41003 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0x100a!] UDP, length 4
14:03:46.091343 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
14:03:46.091387 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
可知僵蛛,數(shù)據(jù)包僅經(jīng)過docker0與容器設(shè)備vethcbcc4e9
數(shù)據(jù)包發(fā)送前與發(fā)送后主機(jī)nat表對(duì)比:
- echo mac | nc -s 127.0.0.1 -p 41003 -u 192.168.84.75 8000
docker0與容器網(wǎng)卡抓包結(jié)果:
tcpdump -i docker0 -nn -vv(數(shù)據(jù)包的源地址已經(jīng)被修改)
tcpdump: listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:06:19.694983 IP (tos 0x0, ttl 64, id 64297, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.41003 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0x100a!] UDP, length 4
14:06:24.699338 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
14:06:24.699375 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
tcpdump -i vethcbcc4e9 -nn -vv
tcpdump: listening on vethcbcc4e9, link-type EN10MB (Ethernet), capture size 262144 bytes
14:06:19.695000 IP (tos 0x0, ttl 64, id 64297, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.41003 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0x100a!] UDP, length 4
14:06:24.699348 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
14:06:24.699375 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
程序結(jié)果:addr: ('172.17.0.1', 41003), data: mac
三阴幌、本機(jī)上通過127.0.0.1發(fā)送數(shù)據(jù)包
- 在192.168.84.75主機(jī)上執(zhí)行 echo mac | nc -s 127.0.0.1 -p 44818 -u 127.0.0.1 8000
分別主機(jī)的lo設(shè)備勺阐、物理網(wǎng)卡(eno16777984)卷中、docker0以及容器網(wǎng)卡進(jìn)行抓包處理:
tcpdump -i lo -nn -vv
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
tcpdump -i eno16777984 udp port 8000 -nn -vv
tcpdump: listening on eno16777984, link-type EN10MB (Ethernet), capture size 262144 bytes
tcpdump -i docker0 -nn -vv
tcpdump: listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:08:58.946048 IP (tos 0x0, ttl 64, id 54997, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.44818 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0x0123!] UDP, length 4
14:09:03.947336 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
14:09:03.947379 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
tcpdump -i vethcbcc4e9 -nn -vv
tcpdump: listening on vethcbcc4e9, link-type EN10MB (Ethernet), capture size 262144 bytes
14:08:58.946065 IP (tos 0x0, ttl 64, id 54997, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.44818 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0x0123!] UDP, length 4
14:09:03.947349 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
14:09:03.947379 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
數(shù)據(jù)包經(jīng)過的設(shè)備依次為:docker0 ---> vethcbcc4e9
數(shù)據(jù)包發(fā)送前與發(fā)送后nat表規(guī)則對(duì)比:
四、通過容器ip地址發(fā)送數(shù)據(jù)包
-
192.168.84.75主機(jī)上容器python的ip地址為172.17.0.2蒿赢,可通過下面方式獲得:
在主機(jī)上執(zhí)行 echo mac | nc -s 172.17.0.1 -p 54877 -u 172.17.0.2 9999润樱,分別對(duì)主機(jī)的lo、物理網(wǎng)卡(eno16777984)羡棵、docker0以及容器網(wǎng)卡進(jìn)行抓包處理:
tcpdump -i lo -nn -vv
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
無內(nèi)容
tcpdump -i eno16777984 udp port 9999 -nn -vv
tcpdump: listening on eno16777984, link-type EN10MB (Ethernet), capture size 262144 bytes
無內(nèi)容
tcpdump -i docker0 -nn -vv
tcpdump: listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:10:58.373599 IP (tos 0x0, ttl 64, id 35536, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.54877 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0xd9d7!] UDP, length 4
14:11:03.387315 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
14:11:03.387349 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
tcpdump -i vethcbcc4e9 -nn -vv
tcpdump: listening on vethcbcc4e9, link-type EN10MB (Ethernet), capture size 262144 bytes
14:10:58.373617 IP (tos 0x0, ttl 64, id 35536, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.54877 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0xd9d7!] UDP, length 4
14:11:03.387325 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
14:11:03.387349 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
數(shù)據(jù)包經(jīng)過的設(shè)備依次為:docker0 ---> vethcbcc4e9
數(shù)據(jù)包發(fā)送前與發(fā)送后主機(jī)nat對(duì)比:
- echo mac | nc -s 172.17.0.2 -p 54877 -u 172.17.0.2 9999
libnsock mksock_bind_addr(): Bind to 172.17.0.2:54877 failed (IOD #1): Cannot assign requested address (99)
docker0與容器網(wǎng)卡抓包結(jié)果:
tcpdump -i docker0 -nn -vv
tcpdump: listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:13:04.045159 IP (tos 0x0, ttl 64, id 35537, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.35950 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0x23c7!] UDP, length 4
14:13:09.051330 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
14:13:09.051367 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
tcpdump -i vethcbcc4e9 -nn -vv
tcpdump: listening on vethcbcc4e9, link-type EN10MB (Ethernet), capture size 262144 bytes
14:13:04.045176 IP (tos 0x0, ttl 64, id 35537, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.35950 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0x23c7!] UDP, length 4
14:13:09.051340 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
14:13:09.051367 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
程序結(jié)果:addr: ('172.17.0.1', 35950), data: mac
- echo mac | nc -s 127.0.0.1 -p 54877 -u 172.17.0.2 9999
docker0與容器網(wǎng)卡抓包結(jié)果:
tcpdump -i docker0 -nn -vv(數(shù)據(jù)包的源地址被規(guī)則 -A POSTROUTING -o docker0 -m addrtype --src-type LOCAL -j MASQUERADE 修改為docker0地址172.17.0.1)
tcpdump: listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:15:08.717851 IP (tos 0x0, ttl 64, id 35538, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.54877 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0xd9d7!] UDP, length 4
14:15:13.723315 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
14:15:13.723350 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
tcpdump -i vethcbcc4e9 -nn -vv
tcpdump: listening on vethcbcc4e9, link-type EN10MB (Ethernet), capture size 262144 bytes
14:15:08.717868 IP (tos 0x0, ttl 64, id 35538, offset 0, flags [DF], proto UDP (17), length 32)
172.17.0.1.54877 > 172.17.0.2.9999: [bad udp cksum 0x5843 -> 0xd9d7!] UDP, length 4
14:15:13.723326 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
14:15:13.723350 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
程序結(jié)果:addr: ('172.17.0.1', 54877), data: mac
-
去除POSTROUTING鏈的規(guī)則 -A POSTROUTING -o docker0 -m addrtype --src-type LOCAL -j MASQUERADE
執(zhí)行 echo mac | nc -s 127.0.0.1 -p 54877 -u 172.17.0.2 9999
docker0與容器網(wǎng)卡抓包結(jié)果:
tcpdump -i docker0 -nn -vv
tcpdump: listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:17:35.597021 IP (tos 0x0, ttl 64, id 35539, offset 0, flags [DF], proto UDP (17), length 32)
127.0.0.1.54877 > 172.17.0.2.9999: [bad udp cksum 0x2b32 -> 0x06e9!] UDP, length 4
14:17:40.603314 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
14:17:40.603346 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
tcpdump -i vethcbcc4e9 -nn -vv
tcpdump: listening on vethcbcc4e9, link-type EN10MB (Ethernet), capture size 262144 bytes
14:17:35.597050 IP (tos 0x0, ttl 64, id 35539, offset 0, flags [DF], proto UDP (17), length 32)
127.0.0.1.54877 > 172.17.0.2.9999: [bad udp cksum 0x2b32 -> 0x06e9!] UDP, length 4
14:17:40.603323 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
14:17:40.603346 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
程序結(jié)果:空纤控,即程序沒有接收到數(shù)據(jù)包
-
添加將udp協(xié)議挂捻、源地址類型為LOCAL的數(shù)據(jù)包的源地址修改為主機(jī)地址192.168.84.75
執(zhí)行 echo mac | nc -s 127.0.0.1 -p 54877 -u 172.17.0.2 9999
docker0與容器網(wǎng)卡veth1a4e47a抓包結(jié)果:
tcpdump -i docker0 -nn -vv
tcpdump: listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:20:10.098644 IP (tos 0x0, ttl 64, id 35540, offset 0, flags [DF], proto UDP (17), length 32)
192.168.84.75.54877 > 172.17.0.2.9999: [bad udp cksum 0xc124 -> 0x70f6!] UDP, length 4
14:20:15.115338 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
14:20:15.115377 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
tcpdump -i vethcbcc4e9 -nn -vv
tcpdump: listening on vethcbcc4e9, link-type EN10MB (Ethernet), capture size 262144 bytes
14:20:10.098661 IP (tos 0x0, ttl 64, id 35540, offset 0, flags [DF], proto UDP (17), length 32)
192.168.84.75.54877 > 172.17.0.2.9999: [bad udp cksum 0xc124 -> 0x70f6!] UDP, length 4
14:20:15.115350 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 172.17.0.2 tell 172.17.0.1, length 28
14:20:15.115377 ARP, Ethernet (len 6), IPv4 (len 4), Reply 172.17.0.2 is-at 02:42:ac:11:00:02, length 28
程序結(jié)果:addr: ('192.168.84.75', 54877), data: mac
總結(jié)
Centos7中更改數(shù)據(jù)包源地址的操作即SNAT可以在INPUT鏈與POSTROUTING鏈兩個(gè)地方操作。Docker在INPUT鏈中沒有定義SNAT規(guī)則船万,全部的SNAT操作均定義在POSTROUTING鏈中刻撒。所以對(duì)Docker數(shù)據(jù)包的SNAT的研究只需關(guān)注POSTROUTING鏈即可骨田。我們自己產(chǎn)品對(duì)docker的使用屬于上述實(shí)驗(yàn)一的范圍,即是將userland設(shè)置為true声怔,包括以下幾種情況:
如果機(jī)器的iptables規(guī)則沒有做額外的配置态贤,通過外主機(jī)向本機(jī)訪問或在本機(jī)上通過ip地址訪問,數(shù)據(jù)包的源地址不會(huì)被修改
本機(jī)上通過127.0.0.1訪問的數(shù)據(jù)包的源地址會(huì)被docker-proxy進(jìn)程修改醋火,因此本機(jī)訪問若想要數(shù)據(jù)包的源地址不被修改悠汽,需使用本機(jī)ip地址訪問
通過上面實(shí)踐可發(fā)現(xiàn),源地址為127.0.0.1的數(shù)據(jù)包在多數(shù)場景下不能成功發(fā)送出去芥驳,能夠發(fā)送出去且能被容器內(nèi)程序接收到的數(shù)據(jù)包在容器網(wǎng)卡或docker0那一層其源地址127.0.0.1已經(jīng)被修改了柿冲;即容器內(nèi)程序接收到的數(shù)據(jù)包的源地址不可能是127.0.0.1。源地址為127.0.0.1的數(shù)據(jù)包在傳輸過程中意義不大兆旬,因?yàn)闊o法根據(jù)源地址127.0.0.1找到發(fā)包的設(shè)備
數(shù)據(jù)包在主機(jī)與主機(jī)或主機(jī)與容器之間傳輸時(shí)假抄,數(shù)據(jù)包的源地址多數(shù)情況下會(huì)發(fā)生改變,如果某功能是以數(shù)據(jù)包源IP地址作為來源主機(jī)的判斷是不可靠的丽猬;因?yàn)榭赡苋〉臄?shù)據(jù)包是處于中間狀態(tài)的包宿饱,這類包的源IP地址可能已被修改,這樣就會(huì)導(dǎo)致來源主機(jī)判斷的錯(cuò)誤脚祟。