2012年3月9日星期五

Bash长行换行问题

发现Bash命令行里面敲的字符超过一行的话,后面的字符不会从下一行开始,而是从提示符开始覆盖。这样覆盖一行后,再输入才会换行。初步锁定问题在PS1变量上,PS1是:
\e[35m\u@\h \w$ \e[0m
如果没有颜色的PS1就没有问题。

后来搜索到解决办法了,要用\[\]把非打印字符括起来,这样Bash就不会糊涂不知道光标在哪里了。其实Bash的手册里面有介绍\[\]在提示符中的作用。

2012年3月1日星期四

SSH登录太慢

从CentOS 6.2用ssh连接Solaris 10很慢,加上-v参数后看到:
debug1: Authentications that can continue: gssapi-keyex,gssapi-with-mic,publickey,password,keyboard-interactive
debug1: Next authentication method: gssapi-keyex
debug1: No valid Key exchange context
debug1: Next authentication method: gssapi-with-mic
debug1: An invalid name was supplied
Cannot determine realm for numeric host address
debug1: An invalid name was supplied
Cannot determine realm for numeric host address
debug1: An invalid name was supplied
debug1: An invalid name was supplied
debug1: Next authentication method: publickey
......
是两个GSSAPI的认证等待失败导致登录很慢。看了Solaris上的sshd_config(4)GSSAPIAuthentication默认打开,CentOS上的ssh_config(5)GSSAPIAuthentication默认也是关闭,但是/etc/ssh/ssh_config中却打开了该选项,这导致ssh尝试了GSSAPI认证。

解决办法很多,要么在服务器端的sshd_config中关掉该选项,要么在客户机的~/.ssh/config或者ssh_config中关掉,或者用ssh -o GSSAPIAuthentication=no来登录。真是:*nix is like a box of chocolate, you never know what you are gonna get.

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为宿主机,*为虚拟机