TCP/IP

rfc1323导致的问题

\[rfc1323\]window7的Tcp1323Opts与linux的net.ipv4.tcptimestamps和NAT
最近遇到一个内网win7用户无法上部分网站的问题,同网段的其他机器都是正常,出问题的机器访问其他网站也是正常。网络结构简单,client\<-\>源地址转换NAT\<-\>网站。经过在server上抓包发现,server上有时会对client的syn包无响应。
通过我们测试,部分win7系统中的注册表中有Tcp1323Opts这个选项,会导致其在发包时加入时间戳,经过nat之后,如果前面相同的端口被使用过,且时间戳大于这个链接发出的syn中的时间戳,就会导致在服务器上忽略掉这个syn。表现为用户无法正常完成tcp3次握手。方法是在服务器上禁止

`` example
sysctl -w net.ipv4.tcp_timestamps=0


或者修改客户端的注册表Tcp1323Opts设置为0。 Tcp1323Opts
<http://technet.microsoft.com/en-us/library/cc938205.aspx>
这个问题最好是更改客户端的这个值,因为所有服务器上timestamps都是1.
Windows
XP包含几个可以动态地影响性能的注册表参数——其中有一个设置是用于处理RFC
1323的,即高性能的TCP扩展。 RFC
1323中所引用的TCP窗口是接收窗口——存储到达TCP片的缓存空间,除非(a)到达的数据包设置了Push标记然后它们被立即下发到应用程序中,或者(b)接收它的应用程序到缓存中取它的数据。
在TCP握手过程中,基于TCP连接的双方都会告诉对方它们的接收缓存大小。这是包含在TCP包头的Window
Size字段里的。这个字段的典型值是65,535(它是一个2字节长度的字段,65,535是它能表示的最大值)。这表明如果需要的话,发送握手数据包
的设备有65,535个字节空间可用于存储到达的数据。注意如果从一个TCP节点发来的初始通信在TCP握手数据包中使用了TCP
Window Scale选项,那么XP系统默认会使用Window
Scaling。这意味着如果你的XP设备是作为服务器(响应初始的TCP握手数据包)使用,你将会使用Window
Scaling。如果你的XP设备是一个客户端(比如,你用来连接一个HTTP服务器或邮件服务器),你就不会使用Window
Scaling。

Tcp1323Opts Key: TcpipParameters Value Type: REG<sub>DWORD</sub> —
number (flags) Valid Range: 0, 1, 2, 3 0 (disable RFC 1323 options)
(禁用RFC 1323选项) 1 (window scaling enabled only) (仅启用窗口缩放)
2 (timestamps enabled only) (仅启用时间戳) 3 (both options enabled)
(启用窗口缩放和时间戳)

默认:没有值。默认的行为是这样的:当初始化TCP连接时不使用时间戳(Timestamp)和窗口尺寸(Window
Scale)选项,但如果TCP节点在初始化通信时在SYN片中包含了它们,就使用时间戳和窗口尺寸(Window
Scale)选项。实际上windows xp
sp3默认设置成3了!这点很不靠谱,很不和谐,很不大众化!

<h2 id="子网掩码不对导致的网络连通问题">子网掩码不对导致的网络连通问题</h2>

子网掩码在数据传输中的作用:当主机A要把数据传送给主机B,主机A先通过自己的子网掩码计算出来主机A的网络ID;然后,在利用主机B的IP地址和自己的子网掩码,计算出来主机B的网络ID。如果,自己和主机B的网络ID相同,说明在一个网段,则直接传送,否则,说明在不同网段,要通过路由器传送。
cent.info: 10.2.3.77/255.255.255.0 10.2.3.78
该服务器的设置一直没有什么问题,直到有一天下面的服务器希望连接到10.2.3.77时,发现无法连通:
moodle.sw: 10.2.3.200/255.255.255.240 10.2.3.206
moodle.sw到10.2.3.78可通,但在traceroute时却不能再找到10.2.3.77,非常奇怪的问题,因为77和78在同一交换机上,不可能找不到。起先我怀疑是10.2.3.78的网关上有什么特殊设置,后来才发现问题并非如此。其实是cent.info的子网掩码设置错误,它把moodle.sw当作是在同一网段的地址,因此不会通过10.2.3.78网关送出。traceroute之所以无法显示10.2.3.78的下一跳,并非到不了,而是到了10.2.3.77以后,10.2.3.77的响应无法返回。两个问题的本质并不相同。

<h1 id="iptables <span class="tag" tag-name="iptables"><span class="smallcaps">iptables</span></span>">iptables <span class="tag" tag-name="iptables"><span class="smallcaps">iptables</span></span></h1>

<h2 id="NAT <span class="tag" tag-name="nat"><span class="smallcaps">nat</span></span>">NAT <span class="tag" tag-name="nat"><span class="smallcaps">nat</span></span></h2>

路由器通常不检查source
IP,因此,源端的内网IP地址也可以在互联网络上传播。假定有如下数据包:

example

source ip: 192.168.0.1, dest ip: 1.2.3.4


如果不作NAT处理,发送出去的数据包在源端为192.168.0.1(内网地址),目的服务器的响应包中会做如下设置:

example

source ip: 1.2.3.4, dest ip: 192.168.0.1


此时,目的IP地址为内网地址,路由器会直接将其抛弃。
更改源端IP地址称为SNAT,更改目的端IP地址称为DNAT。NAT机制包括:一对多、多对多、一对一及NAPT。不管哪一种机制,都是由SNAT与DNAT共同搭配组合而成。
NAT处理有两条走向: PACKET IN –\> PREROUTING CHAIN –\> ROUTING TABLE –\>
POSTROUTING CHAIN –\> PACKET OUT PACKET IN –\> PREROUTING CHAIN –\>
ROUTING TABLE –\> LOCAL PROCESS –\> ROUTING TABLE –\> OUTPUT CHAIN –\>
POSTROUTING CHAIN –\> PACKET OUT
其中,PREROUTING上可执行DNAT任务,POSTROUTING上可执行SNAT任务。如果要对本地进程的包执行DNAT任务,则必须在OUTPUT上执行,这也是之所以引入OUTPUT的原因。
写NAT规则时,只需写一个方向的规则就可以了,不管是SNAT还是DNAT,NAT机制都会自动帮我们判断另一个方向的响应封包。

<h3 id="一对多配置">一对多配置</h3>

为实现一对多配置,只要执行下面的操作即可:

example

iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/24 -j SNAT --to 10.0.1.200


-j SNAT –to 10.0.1.200
是一个整体,表示所有符合上述条件的包的源IP地址都会被改成10.0.1.200。如果公网IP地址是动态获取的,那么可以将规则写成下面的样子:

example

iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/24 -j MASQUERADE


<h3 id="多对多配置">多对多配置</h3>

一对多配置的缺点是,多外部服务器看来,所有内网机器都来自同一IP地址。一些服务可能会限制单个IP过多的连接。
多对多配置要求有多个连接的公网IP,设置方法如下:

example

iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/24 -j SNAT --to 10.0.1.200-10.0.1.205


<h3 id="一对一配置">一对一配置</h3>

一对一配置要同时配置封包进入的部分与出去的部分:
在NAT主机上配置,让10.0.1.201映射到192.168.0.1。

example

iptables -t nat -A PREROUTING -i eth0 -d 10.0.1.201 -j DNAT --to 192.168.0.1


如果考虑到让192.168.0.1主机能够主动向外部发送请求,那么还需添加下面的规则:

example

iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.1 -j SNAT --to 10.0.1.201


<h3 id="NAPT">NAPT</h3>

Network Address Port
Translation以Port为单位来执行NAT任务。下面的规则为后台的Web服务器提供了前端映射:

example

itpables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.0.1:80


如果Web服务器有对外连接的要求的话,那就还要添加出去的规则。与一对一配置相似。

<h1 id="mininet">mininet</h1>

<h2 id="生成文档">生成文档</h2>

make doc要用到可执行文件doxypy。
gentoo中用pip安装后,会得到/usr/local/bin/doxypy.py,直接执行make
doc会提示找不到文件,生成的文档没有内容。解决办法是创建名为doxypy的链接即可,让系统可搜索到该文件。

example

sudo ln -s /usr/local/bin/doxypy.py /usr/local/bin/doxypy


<h1 id="proxy设置 <span class="tag" tag-name="proxy"><span class="smallcaps">proxy</span></span>">proxy设置 <span class="tag" tag-name="proxy"><span class="smallcaps">proxy</span></span></h1>

bash

function proxy(){
echo -n "username:"
read -e username
echo -n "password:"
read -es password
export http_proxy="http://$username:$password@proxyserver:8080/"
export https_proxy=$http_proxy
export ftp_proxy=$http_proxy
export rsync_proxy=$http_proxy
export no_proxy="localhost,127.0.0.1,localaddress,.localdomain.com"
echo -e "\nProxy environment variable set."
}
function proxyoff(){
unset HTTP_PROXY
unset http_proxy
unset HTTPS_PROXY
unset https_proxy
unset FTP_PROXY
unset ftp_proxy
unset RSYNC_PROXY
unset rsync_proxy
echo -e "\nProxy environment variable removed."
}


<https://wiki.archlinux.org/index.php/Proxy_settings>

<h1 id="Tools">Tools</h1>

<h2 id="netcat <span class="tag" tag-name="netcat"><span class="smallcaps">netcat</span></span>">netcat <span class="tag" tag-name="netcat"><span class="smallcaps">netcat</span></span></h2>

  1. 结合tar来传递目录
example

tar zcfp – /path/to/directory | nc -w 3 127.0.0.1 1234 #发送方
nc -l -p 1234 | tar xvfpz - #接收方


  1. 访问syslogd
example

echo ‘<0>message’ | nc -w 1 -u loggerhost 514


  1. 端口扫描
example

echo EXIT | nc -w 1 127.0.0.1 20-250 500-600 5990-7000
nc -v -n -z -w 1 192.168.1.2 1-1000


  1. 访问网站
example

echo -e “GET http://www.google.com HTTP/1.0\n\n” | nc -w 5 www.google.com 80


  1. 只能点击一次的Web服务器
example

{ echo -ne "HTTP/1.0 200 OK\r\nContent-Length: $(wc -c


  1. HTTP代理
example

mkfifo backpipe
nc -l 12345 0backpipe


  1. 通过管道传递响应的Web服务器
example

while [ 1 ]; do cat out; done | nc -l 1234 -k -w 5
echo -e "HTTP/1.1 200 OK\nAccess-Control-Allow-Origin: *\n\n hello \n\n" > out


参考:http://en.wikipedia.org/wiki/Netcat

<h2 id="curl和wget的区别">curl和wget的区别</h2>

  1. curl是libcurl这个库支持的,wget是一个纯粹的命令行命令。
  2. curl支持更多的协议。curl supports FTP, FTPS, HTTP, HTTPS, SCP, SFTP,

TFTP, TELNET, DICT, LDAP, LDAPS, FILE, POP3, IMAP, SMTP and RTSP at
the time of this writing. Wget supports HTTP, HTTPS and FTP.

  1. curl

默认支持HTTP1.1(也支持1.0),而wget仅仅支持HTTP1.0规范。引用wget的man
page中的一段话吧,Please be aware that Wget needs to know the size
of the POST data in advance. It's not quite clear how to work around
this limitation inherent in HTTP/1.0. Although HTTP/1.1 introduces
chunked transfer that doesn't require knowing the request length in
advance, a client can't use chunked unless it knows it's talking to
an HTTP/1.1 server. And it can't know that until it receives a
response, which in turn requires the request to have been completed
– a chicken-and-egg problem.

  1. curl在指定要下载的链接时能够支持URL的序列或集合,而wget则不能这样.
  2. wget支持递归下载,而curl则没有这个功能。

<http://www.zhihu.com/question/19598302>

<h2 id="mtr">mtr</h2>

example

mtr -r -n -c 100 host


Loss% – 丢包率,单位是"%"; Snt – sent包的数量; Last – 最后一个包的延时;
Avg – 所有包的平均延时,同"ping"的"Avg"; Best –
延时最小的包,同"ping"的"Min"; Wrst –
Worst,延时最大的包,同"ping"的"Max"; StDev – Standard
Deviation,标准差,winmtr无该项。
如果StDev很大,表示各个包的延时的差别很大,网络不太稳定。不过由于中间点是路由器,一般路由器可能会对icmp包做限制或者优先丢弃,所以中间节点的StDev可以忽略不看。

<h2 id="iptraf">iptraf</h2>

监测网络流量。

<h2 id="iperf">iperf</h2>

iperf用于检测带宽。 服务器端启动服务:

example

iperf -s


然后在另一台机器上启动客户端去连接服务器:

example

iperf -c xxx.xxx.xxx.xxx -d


<h2 id="ntop">ntop</h2>

A network traffic probe similar to the UNIX top command. 带Web界面。

<h1 id="netcat">netcat</h1>

<h2 id="使用lsof代替Mac OS X中的netstat查看占用端口的程序">使用lsof代替Mac OS X中的netstat查看占用端口的程序</h2>

example

sudo lsof -nP -iTCP:端口号 -sTCP:LISTEN


-n 表示不显示主机名,-P 表示不显示端口俗称,不加 sudo
只能查看以当前用户运行的程序,可以后接管道符

example

sudo lsof -nP -iTCP -sTCP:LISTEN | grep Python


实际上只是为了看个程序名要图方便的话只需要 sudo lsof -i :端口号 \| grep
LISTEN不需要敲那么多,非常用端口连 grep 都能省了。 查看占用某端口的
PID:

example

sudo lsof -i :端口号| grep LISTEN | awk '{ print $2; }' | head -n 2 | grep -v PID


结束该进程:

example

sudo kill -9 $(sudo lsof -i :1091| grep LISTEN | awk '{ print $2; }' | head -n 2 | grep -v PID)


<h1 id="ppp">ppp</h1>

<h2 id="认证">认证</h2>

Linux的ppp包中pppd支持三种认证协议:

  1. PAP (Password Authentication Protocol)
  2. CHAP (Challenge Handshake Authentication Protocol)
  3. EAP (Extensible Authentication Protocol)

PAP由客户端发送明文密码,CHAP则先由服务器发送challenge,客户端则响应自己的名字和由密码计算得出的hash值。EAP支持CHAP模式,并包含了SRP-SHA1,能有效防御字典攻击。

<h1 id="Bluetooth">Bluetooth</h1>

<h2 id="Bluetooth Protocol">Bluetooth Protocol</h2>

Bluetooth协议栈分为controller stack和host stack,controller
stack一般由芯片来实现,host
stack一般由软件来实现,不过像headset(蓝牙耳机)中两者均由芯片来实现,这种系统又称为hostless系统。
HCI(Host Controller Interface)是host stack与controller
stack之间的标准通信接口。

<h2 id="术语">术语</h2>

  1. Bluetooth clock

蓝牙时钟,每一个蓝牙设备有一个内部系统时钟,用来决定收发器的时序和跳频。该时钟不会被调整或者关掉。该时钟可以作为一个28位计数器使用,其LSB位的计数周期是312.5us,即时钟频率为3.2kHz。

  1. Bluetooth device class

蓝牙设备分类,该参数用于指出设备类型,以及所支持的服务类型。在设备发现过程中,将接收到设备的类信息。

  1. Bluetooth service type

蓝牙服务类型。一个蓝牙设备提供给另外设备一项或者一项以上的服务。服务信息在蓝牙设备分类参数的服务类别(service
class)域中进行了定义。

<h1 id="ARP攻击">ARP攻击</h1>

<h2 id="ARP攻击的解决办法">ARP攻击的解决办法</h2>

  1. 关掉网卡的ARP功能。

很多情况下,我们只需要与网关通信,网络里面其他的机器很少通信。所以我们建立一个ip地址和mac地址的对应关系文件:/etc/ethers

example

cat /etc/ethers
192.168.1.254 00:14:78:8B:C4:54


然后执行 arp -f 的命令,即可绑定。

example

ifconfig ethx -arp


  1. 将MAC地址告诉网关
example

arping -U -I eth0 -s 192.168.1.17 192.168.1.254


<h2 id="ARP攻击时的主要现象:">ARP攻击时的主要现象:</h2>

  1. 网上银行、游戏及QQ账号的频繁丢失

一些人为了获取非法利益,利用ARP欺骗程序在网内进行非法活动,此类程序的主要目的在于破解账号登陆时的加密解密算法,通过截取局域网中的数据包,然后以分析数据通讯协

议的方法截获用户的信息。运行这类木马病毒,就可以获得整个局域网中上网用户账号的详细信息并盗取。

  1. 网速时快时慢,极其不稳定,但单机进行光纤数据测试时一切正常

当局域内的某台计算机被ARP的欺骗程序非法侵入后,它就会持续地向网内所有的计算机及网络设备发送大量的非法ARP欺骗数据包,
阻塞网络通道,造成网络设备的承载过重,导

致网络的通讯质量不稳定。

  1. 局域网内频繁性区域或整体掉线,重启计算机或网络设备后恢复正常

当带有ARP欺骗程序的计算机在网内进行通讯时,就会导致频繁掉线,出现此类问题后重启计算机或禁用网卡会暂时解决问题,但掉线情况还会发生。

<h2 id="arpoison">arpoison</h2>

主页:http://arpoison.net/ 防止arp攻击: : sudo arpoison -i eth0 -d
192.168.1.1 -s 192.168.1.101 -t ff:ff:ff:ff:ff:ff -r 00:1c:bf:03:9f:c7
攻击192.168.1.50的机器不让他上网 : sudo arpoison -i eth0 -d
192.168.1.50 -s 192.168.1.1 -t ff:ff:ff:ff:ff:ff -r 00:1c:bf:03:9f:c7

<h2 id="arp incomplete">arp incomplete</h2>

到路由器会首先为10.1.1.2创建一个incomplete entry,接下来的显示“rcvd rep
src 10.1.1.2 00e0.4c4d.50ab”表明路由器已收到10.1.1.2的正确arp
reply。这时路由器将此incomplete entry置换为正确的MAC地址。
路由器同样为10.1.1.2创建了一个incomplete
entry,然后路由器通过10.1.1.1的以太口网关对10.1.1.0/24网段进行arp
request广播,经过5次request后仍没有结果,此时再show
arp,可看到这个地址所对应的MAC地址显示为Incomplete。
<http://thinkinginmind.blog.51cto.com/849204/353073>

<h1 id="NetworkManager <span class="tag" tag-name="NetworkManager"><span class="smallcaps">NetworkManager</span></span>">NetworkManager <span class="tag" tag-name="NetworkManager"><span class="smallcaps">NetworkManager</span></span></h1>

在RedHat系的Linux中使用nmcli命令管理网络的教程
<http://www.kafan.cn/edu/88282256.html> 显示所有连接。

example

nmcli connection show -a


仅显示当前活动的连接。

example

nmcli device status


下列命令用来启动接口:

example

nmcli device connect eno16777736


以下命令可以添加一个静态IP地址的以太网连接:

example

nmcli connection add type ethernet con-name NAME_OF_CONNECTION ifname interface-name ip4 IP_ADDRESS gw4 GW_ADDRESS


使用下列命令设置DNS服务器:

example

nmcli connection modify NEW ipv4.dns "8.8.8.8 8.8.4.4"


查看新连接的配置信息:

example

nmcli -p connection show NEW


增加一个使用 DHCP 的新连接
增加新的连接,使用DHCP自动分配IP地址,网关,DNS等,你要做的就是将命令行后
ip/gw 地址部分去掉就行了,DHCP会自动分配这些参数。 例,在 eno 16777736
设备上配置一个 名为 NEW<sub>DHCP</sub> 的 DHCP 连接

example

nmcli connection add type ethernet con-name NEW_DHCP ifname eno16777736


ArchiLinux wiki <https://wiki.archlinux.org/index.php/NetworkManager>

networkmanager的dispatcher可用来处理在指定接口打开后要做的事情。比如在某网络连接打开后,自动连接VPN。
Use dispatcher to connect to a VPN after a network connection is
established

<h1 id="Wireshark">Wireshark</h1>

<h2 id="Sniffing with Wireshark as a Non-Root User">Sniffing with Wireshark as a Non-Root User</h2>

<http://packetlife.net/blog/2010/mar/19/sniffing-wireshark-non-root-user/>

bash

sudo apt-get install libcap2-bin
groupadd wireshark
usermod -a -G wireshark stretch
chgrp wireshark /usr/bin/dumpcap
chmod 750 /usr/bin/dumpcap
setcap cap_net_raw,cap_net_admin=eip /usr/bin/dumpcap
getcap /usr/bin/dumpcap

``