2012年2月24日星期五

Iptables的nat表

Iptables的nat表,看其名字,乃是Network Address Translation的缩写。我用过nat表的几次都是路由器在不同网段之间转发报文需要做NAT。现在碰到如下的情况:
笔记本电脑是配置成一个网桥的,两个网卡配置在一个网段,只需开启内核的转发和Proxy ARP两边网络即可打通,无需用iptables做NAT。

现在要用Dell作透明代理,要把192.168.2.5这边发出的所有对80端口的访问,转到Dell的3128端口。一般是用下面的一条iptables规则:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128
可是这里没有地址转换,是不是不应该用nat表?经过研究,其实nat表不一定必须要做NAT。iptables的手册里面写着:
nat:
This table is consulted when a packet that creates a new connection is encountered. It consists of three built-ins: PREROUTING (for altering packets as soon as they come in), OUTPUT (for altering locally-generated packets before routing), and POSTROUTING (for altering packets as they are about to go out).
例如PREROUTING链,在数据包进入的时候就要穿越,所以上面的iptables规则自然是可以用在网桥上的。
iptables的报文处理顺序
用iptables,一定要搞清楚报文处理顺序了,这样就能真正理解其用法了。推荐Linux Home Networking上的上图。

Squid+Nginx地址结尾的斜杠问题

前面用Squid(3.1)作反向代理,端口在3128;后面是Nginx(0.8.54),端口在8080。Squid的配置如下:
http_port 3128 vhost
cache_peer 10.146.18.213 parent 8080 0 originserver
对于HTML文件,工作正常。但是对目录,如果在访问地址后面有"/",访问正常;但是如果去掉"/",则URL会由
http://cache.fatduck.org:3128/dvorak
变成:
http://cache.fatduck.org:8080/dvorak/
相当于浏览器是从Nginx而不是从Squid得到了应答。而在生产环境中,Nginx的监听端口8080可能是被防火墙阻止的,这样没有"/"的话,这个请求就得不到应答,难于看到问题。
没有"/"时的HTTP报头
我的理解是Squid转给了Nginx,Nginx对目录请求自动在后面加了"/",这样301之后就不返回请求给Squid了。解决办法是让配置Nginx,让它在目录后面显式地增加"/":
if (-d $request_filename) {
        rewrite ^(.*[^/])$ $1/ break;
}
之后的报头就没有301了:
解决问题后的HTTP报头
这样URL不会变,还是http://cache.fatduck.org:3128/dvorak,甚至连最后的"/"都没有,尽管我们在Nginx里面重写URL加了"/"。

2012年2月22日星期三

用ping来traceroute

那天看TCP/IP Illustrated第一卷的第8章Traceroute,突然想到用ping就可以来做traceroute
for i in {1..30}; do  ping -t $i -c 1 google.com; done | grep "Time to live exceeded"
这只是一个演示traceroute原理的例子,不过是我灵机一动的原创哦。之前发在commandlinefu了,又在这里发一下。

其实这个和traceroute还是有区别的。比如ping发送的是ICMP echo request,而traceroute默认发送的是UDP报文。

2012年2月18日星期六

DHCP的租期

前几天DHCP出现问题,顺便研究了下DHCP的租期。
ChinaUnicom客户端的DHCP信息
北京联通的WLAN免费试用不错,SSID就是不加密的那个ChinaUnicom。不过被我发现,这个服务的DHCP租期竟然达10天。就是说如果连接的设备下线后,从连接开始到10天这个IP才会释放到IP池里面供别的设备使用。如果NAT为私有地址的话,那么IP池可以设置很大,没有关系。但只这个服务给用户的是因特网地址,上面的111.195.89.234即是。这样就很浪费IP地址的。

DHCP租期过短的话,局域网内Renew包和客户端租期的过期就会过多;DHCP租期过长的话,地址浪费就会过多。这篇2007年的论文研究了DHCP的租期,自称是对DHCP使用最大规模的研究(we present the largest known study of DHCP utilization)。论文研究发现,指数方式动态调整DHCP的租期,可以比较有效地提高IP地址利用率,并同时减少DHCP的Renew和Expire。具体策略是客户端每次续租的时候把租期翻倍,最高到一个固定值(the lease time a client receives doubles each time it renews a lease, up to a maximum possible lease time).

2012-02-21更新:发现每次连接ChinaUnicom ,得到的IP地址都会变化;说明它的DHCP服务器不保留客户端的租期信息,每次都重新分配IP地址。

Virtualbox的Bridge模式联网

VitualBox里的虚拟机用Bridge模式来联网,宿主机连接到无线路由器上网。无线路由器设置了MAC地址过滤,要把宿主机无线网卡的MAC地址加到路由器里,宿主机才能上网。而虚拟机网卡的MAC地址是不需要加进路由器的许可列表的,虚拟机依然可以上网。在这种模式下,相当于宿主机的无线网卡,替虚拟机的网卡从路由器又租用了一个IP地址给虚拟机用。在路由器上可以看到宿主机和虚拟机的MAC地址及租用IP。不过不需要将虚拟机MAC地址加入许可列表是比较特殊的一点。
路由器上看到的:X61为宿主机,*为虚拟机

2012年2月13日星期一

DHCP的问题

打开Windows下的CentOS虚拟机,ifup得不到DHCP地址了。CentOS是在VirtualBox里面用Bridge模式连网的,这种情况下虚拟机会和宿主机从同一个DHCPD(办公室路由器)获得地址。

DHCP超时失败前,屏幕上出现了ping几个地址失败的消息。在/etc目录下用grep没有找到这个地址,很奇怪。/etc/resolv.conf里面有两行nameserver,我把这两行删除后DHCP就成功了。

后来在/var/lib/dhclient/dhclient-eth1.leases里面找到了ping过的几个地址。这个文件里面有几个租约历史,有的还未过期。原来dhclient.conf(5)里面有解释:
The DHCP client may decide after some period of time (see PROTOCOL TIMING) that it is not going to succeed in contacting a server. At that time, it consults its own database of old leases and tests each one that has not yet timed out by pinging the listed router for that lease to see if that lease could work.
原来如果DHCP失败,dhclient会尝试曾经租约过但是还未过期的地址。不过只有在DHCP失败的情况下才会尝试,这也就是为什么是在出现ping的消息后ifup命令也马上回到了命令提示符。

本来我以为是resolv.conf中过期的内容导致DHCP失败,但后来却未能复现这样的判定,resolv.conf中加入错误的信息后DHCP还是可以成功的。那么,目前能得出的最可信的结论,就是办公室的无线路由器,或者Windows电脑正好出问题了,让CentOS虚拟机没能获得地址。在写这篇文章之前,我电脑就一度连不上网,这或许可以提高前面推测的可信性。

在此记录这个小小的“灵异事件”,以供日后参考。

2012年2月7日星期二

Openswan的证书认证

Openswan支持证书认证的IPSec。用OpenSSL生成CA、用户证书,然后在Windows下导入证书后连接,在服务器日志/var/log/secure中发现错误:
could not open host cert with nick name '/etc/pki/CA/private/cakey.pem' in NSS DB
Google搜索发现要把证书导入到NSS数据库中。这是Openswan 2.6.23之后改变的,要用Mozilla的Network Seurity Services管理证书。看了openswan-doc提供的README.nss,发现这个变动又引入了一堆新东西,而且不是那么容易搞定的,就暂时放弃了,还是用Preshared Key就够了。

2012年2月2日星期四

让APT不自动安装推荐包

Ubuntu里面apt-get会自动安装推荐包。如果要禁用掉自动安装推荐包,可以用apt-get--no-install-recommends参数,永久禁用可以在/etc/apt/apt.conf里面加入
APT::Install-Recommends "false";
Aptitude可以在其设置里面禁用此功能,Synaptic也可在其设置中禁用该功能。