Friday, June 18, 2010

Mutiple SSL sites on single IP

ဒီေန႕ေတာင္ၾကည့္ ေျမာက္ၾကည့္နဲ႕ Myanmar Tutorials က Q&A တစ္ခုမွာ SSL website(https) တစ္ခုအတြက္ Dedicated IP တစ္ခုလိုတယ္လို႕ ေတြ႕လိုက္ပါတယ္။ သူေျပာတာ မွားတယ္လို႕ မဆိုလိုပါဘူး။ 2007 ေလာက္ကထိ ဒါ မွန္ပါတယ္။ SSL ရဲ့ အလုပ္လုပ္ပံုအရ socket တစ္ခု ( IP တစ္ခု ၊ Port တစ္ခု) မွာ SSL website တစ္ခုထက္ ပိုထားလို႕မရပါဘူး။ IP တစ္ခုမွာ SSL site ေတြ အမ်ားၾကီး Virtual Host လုပ္ခ်င္ရင္ မတူညီတယ့္ Port ေတြမွာ run မွရပါတယ္။ ဥပမာ abc.com ကို port 443 မွာ၊ def.net ကို port 444 မွာ အဲလိုမ်ိဳးေပါ့။ ဒီလိုၾကေတာ့လည္း အဆင္မေျပျပန္ပါဘူး။ ဘယ္သူမွ website ကိုအေနာက္က port number ၾကီးထဲ့႐ိုက္ျပီး ဖြင့္ၾကည့္ခ်င္မွာ မဟုတ္ဖူး။

ပံုမွန္ http site ေတြၾက IP တစ္ခုမွာ domain ေတြအမ်ားၾကီးကို VirtualHost အျဖစ္ထားလို႕ရျပီး ( shared web hosting လို႕ ေခၚပါတယ္) ၊ ဘာလို႕ HTTPS / SSL site ေတြၾကမွ ဒါမ်ိဳးမရ ရတာလည္း ? လူတစ္ေယာက္က သူ႕ browser မွာ abc.com လို႕ ေခၚလိုက္တယ္ဆိုပါေတာ့၊ သူ႕ browser ကေန ဒီ website ကို host လုပ္ထားတယ့္ Server ဆီကို http request လို႕ေခၚတယ္တယ့္ packet ပို႕လိုက္ပါတယ္။ ဒီ http request ထဲမွာ header field ပါပါတယ္။ ဘယ္ domain name ( abc.com) ကို request လုပ္တာလည္းဆိုတာ ဒီ header field ထဲမွာ ပါလာျပီးသားပါ။ ဒီ HTTP request header ကိုဖတ္ျပီး Server က ဒါ ဘယ္ domain ကိုလာတယ္၊ ဒါဆို ဘယ္ website ကိုေပးရမယ္ ဆိုတာခြဲျခားျပီး သိႏိုင္တယ္။

Https site ေတြမွာကေရာ ? HTTPs အလုပ္လုပ္ပံုအရ http traffic မသြားခင္မွာ User client ( browser ေပါ့ဗ်ာ) နဲ႕ Server ၾကားမွာ SSL tunnel ကို အရင္ တည္ေဆာက္ပါတယ္။ ဒါကို SSL session initialization လို႕သုံးပါတယ္။ ဒီမွာ နည္းနည္း ထပ္ေျပာရရင္ Browser နဲ႕ Server ရဲ့ port 443 ၾကားမွာ tunnel တည္ေဆာက္တာပါ။ ေနာက္ေတာ့ အျပန္အလွန္ပို႕သမွ် data အားလုံးကို rsa key ကိုသုံးျပီး Encrypt လုပ္ျပီး ပို႕ပါတယ္။ ၾကားထဲက sniff လုပ္လို႕မရေအာင္ေပါ့။ SSL request မွာက HTTP request header မွာလို domain name မပါလာပါဘူး။ အဲေတာ့ SSL tunnel အရင္ေဆာက္ျပီးလို႕ http request ေရာက္လာေတာ့မွ ဘယ္ domain ကို request တာလည္းဆိုတာ သိမယ္။ Server အေနနဲ႕ user client ( browser) နဲ႕ၾကားမွာ SSL tunnel ေဆာက္တုန္းက ( SSL session initialization မွာ) ဘယ္ domain ကို request လုပ္တာလည္းမသိေတာ့ ဘယ္ configuration ထဲက SSL key ကိုေပးရမမွန္း မသိပါဘူး။ Configuration ေတြထဲက ပထမဆုံးေတြ႕တယ့္ domain ရဲ့ SSL key ကို ေပးလိုက္ပါတယ္။ ေနာက္မွ ၾကည့္က်က္လုပ္မယ္ေပါ့။ အဲေတာ့ ဘာျဖစ္လည္း ဆိုေတာ့ ၊ User ဘက္မွာ SSL certificate error ဆိုတယ့္ warning ၾကီးတက္ပါတယ္။ ဒီ SSL cert က ဒီ domain အတြက္မဟုတ္ဖူး၊ လိမ္တာျဖစ္ႏိုင္တယ္ ဘာညာဆိုတယ့္ msg ၾကီး။ IE မွာဆို Continous Anyway (Not recommanded) ဆိုတာၾကီး ႏွိပ္မွ web site ေပၚလာတယ့္ အဆင့္ကို ေရာက္တယ္။ Firefox မွာဆို Certificate exception ထဲ့ရတယ္၊ I understand the risk ဘာညာျပီးေတာ့။ အဲေတာ့ ေတာ္႐ံု user က လန္႕ျပီး မသုံးေတာ့ဘူး။ Security အတြက္ https နဲ႕ဖြင့္ပါတယ္ဆို I understand the risk ဆိုျပီး အရင္ ဝန္ခံေနရေတာ့ ပုံမွန္ http သုံးတာကမွ ဟုတ္ေသးတယ္လို႕ စဥ္းစားစရာျဖစ္သြားတယ္။

ဘာလို႕ ဒီ ျပသနာက http မွာမျဖစ္ပဲ https မွာျဖစ္တာလည္းဆို က်ေနာ္အေပၚမွာ ေျပာသလို http reqeust header မွာတုန္းက domain name ပါေတာ့ server က ဘယ္ virtualhost ထဲက website ကို ျပန္ေပးရမလည္းသိတယ္။ https မွာက SSL session ေဆာက္ျပီးမွ http request ကလာတာ။ SSL session ေဆာက္တုန္းက ဘယ္ domain အတြက္မွန္းမသိေသးေတာ့ server က ေတြ႕ကရာ SSL key တစ္ခုေပးလိုက္တယ္ ( ဟုတ္ကဲ့ တကယ္က first vhost ရဲ့ key ပါ)။ တကယ္ request လုပ္တာက တျခား domain name လည္းျဖစ္ေနေရာ warning ေတြေပၚလာေရာ။ အဲေတာ့ Technically အရ IP တစ္ခု Port တစ္ခုမွာ SSL နဲ႕ website တစ္ခုပဲ ထားလို႕ရတယ္လို႕ ျဖစ္လာပါတယ္။ Server တစ္လုံးထဲမွာ SSL နဲ႕ website ႏွစ္ခုထားခ်င္ရင္ မတူညီတယ့္ IP ႏွစ္ခု ဒါမွမဟုတ္ IP တစ္ခုထဲဆို မတူညီတယ့္ port ႏွစ္ခုမွာ ထားမွ ရတယ္လို႕ျဖစ္လာေရာ။

E-commerce site ေတြ၊ Online payment system ေတြေခတ္စားလာတာနဲ႕ အမွ် bank account information ေတြ၊ Credit card information ေတြ online မွာ၊ website ေတြမွာ အသုံးျပဳတာမ်ားလာတာနဲ႕ အမွ် Website ေတြမွာ SSL နဲ႕ https အသုံးျပဳဖို႕ လိုအပ္မႈက ပိုပိုမ်ားလာပါတယ္။ ဒါဆို ဒီလို site ေတြကို site တစ္ခု IP တစ္ခုသာ ေပးေနရရင္ IPv4 exhaustion ကို ပိုျမန္ကုန္မွာေပါ့။ ေနာက္ေတာ့ SSL ရဲ့ လိုအပ္ခ်က္ေတြ အားနည္းခ်က္ေတြကို patch လုပ္ရင္း SSL v1 , v2 , v3 ေနာက္မွာ TLS လို႕ေခၚတယ့္ Transport Layer Security ကိုသုံးလာၾကတယ္။ Browser ေတြမွာ TLS 1.0 ၊ TLS 1.1 ဆိုျပီး checkbox ေလးေတြ ေတြ႕ဖူးမွာပါ။ အရင္က ျပသနာ SSL session request မွာ domain name header မပါတယ့္ ကိစၥ ၊ TLS မွာ ေျဖရွင္းႏိုင္ဖို႕ အလားအလာ ရွိလာတယ္။ 2006 မွာထင္တယ္ RFC 4366 ထြက္လာျပီး Server Name Indication လို႕ေခၚတယ့္ SNI support ၊ TLS မွာပါလာတယ္။ SNI အရ SSL session တည္ေဆာက္တယ့္ အခ်ိန္ ( TLS negotiation လို႕ သုံးပါတယ္) မွာ ကတည္းက domain name ကို ထဲ့ပို႕လိုက္ပါတယ္။ အဲေတာ့ Server ဘက္က ဘယ္ domain ရဲ့ SSL key ကို reply ရမလည္းဆိုတာ သိသြားပါတယ္။ User client ( browser) ေရာ ၊ Server ဘက္ကေရာ SNI support လုပ္ဖို႕ေတာ့ လိုပါတယ္။

TLS v1.1 ရဲ့ feature ဆိုေပမယ့္ TLS v1.0 မွာလည္း support လုပ္ေအာင္ လုပ္ထားပါတယ္။ Browser ေတာ္ေတာ္မ်ားမ်ားနဲ႕ ၊ User ေတာ္ေတာ္မ်ားမ်ားက အခုထိ TLS v1.0 ကိုပဲ support လုပ္ႏိုင္တယ့္ OS ကိုပဲသုံးေနၾကဆဲမို႕လို႕ပါ။ အခုေတာ့ X.509 v3 မွာ SSL certificate တစ္ခုက multiple domain name ကို support လုပ္ႏိုင္တာတို႕ ဘာတို႕ျဖစ္လာပါျပီ။ ဒါေၾကာင့္ HTTPs website တစ္ခုအတြက္ IP တစ္ခုလိုတယ္ဆိုတာ ဒီေန႕ေခတ္မွာ မရွိေတာ့ပါဘူး။ ဒီေန႕ က်ေနာ္တို႕ လက္ထက္ IT ေခတ္က အရာရာ ေပါေပါေလာေလာရေနလိုက္တာ restriction ဆိုတာမရွိေတာ့ သေလာက္ပါပဲ။ အရာရာ လြယ္ကူေစဖို႕ ေနာက္ၾကျပီး ေမြးခဲ့တယ့္ အေမ့ကို ေက်းဇူးတင္ပါတယ္ :D

Notes: SNI TLS သုံးဖို႕ Server က SNI support လုပ္ႏိုင္တယ့္ Web Server ျဖစ္ဖို႕လိုပါတယ္။ Apache 2.2.12 ကေနစျပီး SNI support က Apache Native support ျဖစ္သြားပါျပီ ။ အရင္ Version အေဟာင္းေတြမွာေတာ့ GnuTLS module ကို install လုပ္ရင္ရပါတယ္။ User ဘက္ကလည္း SNI support ရမွျဖစ္ပါတယ္။ ဒါမွ TLS negotiation request packet မွာ domain name header ထဲ့ပို႕မွာပါ။ Windows XP SP3 နဲ႕ အထက္၊ IE 7 နဲ႕ အထက္မွာရပါတယ္။ IE6 မွာလည္း XP SP3 ဆိုရင္ ရတယ္လို႕ေျပာပါတယ္။