Tag: linux

apache rewrite 与linux软链的一个小问题

一个项目是apache+resin的架构,有一条 rewrite 规则是这样的:

RewriteRule ^/flashinfo/vinfo/([a-z0-9A-Z_]+).xml$ /video/videolist.htm?sid=$1 [PT,L]

其中,\.htm 交给resin处理

<LocationMatch (.*)\.htm>
SetHandler caucho-request
</LocationMatch>

理论上,访问 /flashinfo/vinfo/V5OJEFN7C.xml 文件,是会代理访问到 /video/videolist.htm?sid=V5OJEFN7C 的。

但事实上,却403了,如下:

$curl -I -H host:so.v.test.com http://127.0.0.1/flashinfo/vinfo/V5OJEFN7C.xml
HTTP/1.1 403 Forbidden
Date: Tue, 09 Feb 2010 07:29:30 GMT
Server: Apache/2.2.11 (Unix) Resin/3.0.26
Content-Type: text/html; charset=iso-8859-1

让我看看rewrite后的访问是否正常:

$curl -I -H host:so.v.test.com http://127.0.0.1/video/videolist.htm?sid=V5OJEFN7C
HTTP/1.1 200 OK
Date: Tue, 09 Feb 2010 07:33:23 GMT
Server: Apache/2.2.11 (Unix) Resin/3.0.26
Cache-Control: max-age=600
Expires: Tue, 09 Feb 2010 07:43:23 GMT
Content-Type: text/html

究竟什么原因呢??我看了一下,应该是这样的:

原因在于,在DocumentRoot下,有一个错误的软链video.

$ls -alh| grep video
lrwxrwxrwx  1 root root   29 02-09 15:29 video -&gt; /data/videopage

而/data/videopage这个目录是不存在的,所以video是一个错误的软链,rewrite 后的地址是 /video/videolist.htm?sid=$1 ,这样就爆403了。

真奇怪,其实apache 根本不用管我有没有video 这个目录的,因为都是转发到resin 去处理的了。既然想不通,就先记下。。。

我还做了两个测试:

1,让 video 成为一个正确的软链,curl 测试结果,200 。

2,把 video 删去,不存在这个软链,curl 测试结果,200。

————————————

结论:apache rewrite 后的地址,如 /data/dopost.jsp?sid=$1 这种,如果data 是一个错误的软链,尽管动态程序/data/dopost.jsp?sid=$1是正确的,apache 的 rewrite 都会不成功,返回 403 。如果 data 是一个正确的软链或者压根不存在,apache 正确地rewrite 。

当squid遇上502 bad gateway

测试环境:

192.168.1.1 (squid) , 192.168.1.2 (nginx proxy) , 192.168.1.3 (nginx web)

squid 作为最外层的代理;nginx proxy 作为第二层代理,通过upstream访问后台;nginx web 真正的数据后台web server。

测试开始:

$curl -I -H host:blog.lazybug.me http://192.168.1.1/test.html
 
HTTP/1.0 200 OK
Server: nginx/0.8.32
Date: Mon, 08 Feb 2010 18:11:48 GMT
Content-Type: text/html; charset=GBK
Expires: Mon, 08 Feb 2010 18:12:58 GMT
Cache-Control: max-age=70
X-Cache: MISS from proxy.lazybug.me
X-Cache-Lookup: HIT from proxy.lazybug.me:80
Via: 192.168.1.3.nginx, 1.1 proxy.lazybug.me:80 (squid/2.7.STABLE7)
Connection: close

此时, user -> squid -> nginx proxy -> nginx web

此时,这个页面已经被缓存住,往后的访问都是TCP_MEM_HIT的了。等到页面过期后,我把nginx web 后台弄挂,我在这里是直接把nginx proxy的upstream给改了,改为 192.168.1.4。此时,访问nginx proxy

$curl -I -H host:blog.lazybug.me http://192.168.1.2/test.html
 
HTTP/1.1 502 Bad Gateway
Server: nginx/0.8.32
Date: Mon, 08 Feb 2010 18:28:06 GMT
Content-Type: text/html
Content-Length: 173
Connection: keep-alive

因为根本没有192.168.1.4这个ip,肯定bad gateway了。

但此时访问squid

$curl -I -H host:blog.lazybug.me http://192.168.1.1/test.html
 
HTTP/1.0 200 OK
Server: nginx/0.8.32
Date: Mon, 08 Feb 2010 18:11:48 GMT
Content-Type: text/html; charset=GBK
Expires: Mon, 08 Feb 2010 18:12:58 GMT
Cache-Control: max-age=70
Age: 1004
Content-Length: 0
X-Cache: HIT from proxy.lazybug.me
X-Cache-Lookup: HIT from proxy.lazybug.me:80
Via: 192.168.51.3.nginx, 1.1 proxy.lazybug.me:80 (squid/2.7.STABLE7)
Connection: close

squid 仍然返回200,不过并不是立刻返回,而是经过了几秒才返回,因为此时squid认为请求页面过期,正在尝试去后端取新数据,但此时,后端返回一个502 bad gateway,那它的工作机制就是,返回旧的缓存数据给用户。

看一下squid的access.log,写着TCP_REFRESH_FAIL_HIT。查一下手册,如下:

An expired copy of the requested object was in the cache. Squid attempted to make an If-Modified-Since request, but it failed. The old (stale) object was delivered to the client.

如果 squid 没有缓存到页面,而出现502,squid 会不会返回200呢??测试下

清缓存:
squidclient -p 80 -m purge http://blog.lazybug.me/test.html

然后再次访问:

$curl -I -H host:blog.lazybug.me http://192.168.1.1/test.html
 
HTTP/1.0 502 Bad Gateway
Server: nginx/0.8.32
Date: Tue, 09 Feb 2010 18:17:13 GMT
Content-Type: text/html
Content-Length: 173
X-Cache: MISS from proxy.lazybug.me
X-Cache-Lookup: HIT from proxy.lazybug.me:80
Via: 1.1 proxy.lazybug.me:80 (squid/2.7.STABLE7)
Connection: close

呵呵,不出所料。

———————————————————————

结论:squid 作为前端代理,而后端502的话,如果squid已经缓存住的页面,那squid就返回用户旧的数据,如果squid没有缓存住的话,很遗憾,还是会502的。

关于nginx的last-modified返回头

squid 不能缓存cache-control在65秒以下的页面,详见ayou同学的这篇文章:http://sudone.com/linux/squid_cache_65s.html

根据文章所说,如果想实现65秒以下的缓存呢,用last-modified头吧。

今天遇到了一个比较郁闷的事,就是架设在squid后的一台nginx,随意访问一个静态页面,死活不出last-modified头。也没作什么特殊的配置,我自己新装一个nginx,测试之。

$curl -I 127.0.0.1
HTTP/1.1 200 OK
Server: nginx/0.8.32
Date: Thu, 28 Jan 2010 14:57:11 GMT
Content-Type: text/html
Content-Length: 151
Last-Modified: Thu, 28 Jan 2010 03:07:20 GMT
Connection: keep-alive
Accept-Ranges: bytes

很正常嘛,不作任何配置时默认是会有last-modified的。

后来还是经ayou同学的提醒,因为使用了ssi。。。

使用了ssi,nginx 就假设你这个页面动态的,谁知道你include的页面上次修改时间啊,当然也就不给你返回last-modified头了。

另外,使用nginx的 http_sub_module时,也不会出这个头的。在测试机上试试,加了个ssi on

$curl -I http://127.0.0.1
HTTP/1.1 200 OK
Server: nginx/0.8.32
Date: Thu, 28 Jan 2010 14:57:32 GMT
Content-Type: text/html
Connection: keep-alive

果然是ssi。。。

mark 一下,以前就试过了,今天竟然忘了!!

linux系统管理技术手册(中文版)阅读

封面写着linus大神倾力推荐。

扫了一下目录,觉得还OK,都是些比较基础的内容,不错不错,查漏补缺一下,巩固一下基础。

定一下计划,牛年内把这本书看完!!

网易微博上线测试~~

t.163.com 正式上线内测啦!!

其实就是走模仿twitter路线的产品,暂时就那么几个最简单的twitter功能,不过感觉还是不错的,除了那个丑陋的logo。。。

我也算是内测前接触微博的那批人,很应该抢一个有趣一点的个性地址的,结果傻了,竟然想不到。。。最后就用了个 t.163.com/freebsd 。。。

昨天也就给公司内部的人注册玩玩,刚开放,n 多人注册,然后不断地follow,已转眼下来,已follow了100人,被follow了70下。刚开放时,公司内部就喧闹起来了。。。所有的群都静了,微博像个闹市般热了起来。。。

今天就冷清多了,这个热退得还真快,哈哈。看着看着,有点空虚的感觉了。。。删一些人,只关注一下技术的就算了。。。

多对不同的ssh keys登录同一个用户

先做一个简单的介绍。像我这种系统管理员,远程登录服务器嘛,肯定要用到ssh的。现在,有一点经验的sa都会要求你用ssh key来登录服务器,而不是account和password来登录。为什么呢??

使用用户名和密码去登录服务器,你与服务器之间的通讯数据,并没有加密的,如果你被某人盯上了,他搭一个代理,在你和服务器之间担当一个中间人的角色,那么,你和服务器通讯的所有数据,都会流经他的代理,由于数据并没有加密,这个时候,他就能获取所有你往服务器发送的数据,及服务器返回给你的数据了。

使用ssh key登录有什么不同呢?整个连接过程是这样的,ssh key 生成的时候是一对的,一个叫public key,一个叫private key,就是一对key pair了。ssh 登录服务器时,我就拿着private key,服务器就拿着public key,咱们配对吧,配上了,就让我登录,配不上,就拒绝我了。配上后,我们之间的通讯都加密了,即使真有中间人监听,他拿到的也只是加密后的数据。

废话真多,说正题。

如果,我是A,他是B,我们都拥有自己的ssh key。但现在我们想以同一个用户C的身份登录,是否可以实现呢??

只要把我们的public key append 到C用户的pubilc key 就行了,服务器寻找用户的public key,在/etc/ssh/sshd_config 里配置,默认是/home/C/.ssh/authorized_keys .

cat /home/A/.ssh/authorized_keys >> /home/C/.ssh/authorized_keys

cat /home/B/.ssh/authorized_keys >> /home/C/.ssh/authorized_keys

然后A 就 ssh C@ip 就可以用C用户来登录了,B也同样可以。

其实这个东西,我也是今天才知道的啊@@我一直以为一个人只可以用一对key pair和一个用户名登录,今天一个同事提出可以这样做,我才尝试了一下。我真是火星了!!