一、相關概念:
socket=IP+PORT(server監聽在某個socket上作為client的通路入口
name resolve名稱解析:名稱轉換,背後有查詢過程,通過檔案或資料庫(FQDN<-->IP)
FQDN-->IP(正向解析);IP-->FQDN(反向)
nsswitch僅提供平台:libnss_files.so,libnss_dns.so
#vim /etc/nsswitch.conf
hosts: files dns(其中files是/etc/hosts檔案)
查詢:遞歸(隻發出一次請求,一定要要到答案,用于本地查詢);疊代(可發出多次請求,非本地,網際網路)
兩段式查詢:遞歸、疊代
stub resolver:是一軟體或程式,名稱解析器,由此程式發出的請求一定要遞歸,先找/etc/hosts如果沒有結果則找DNS服務解析)
IANA-->ICANN(internetcorporation for assigned names and numbers國際域名管理機構)
CDN(content deliverynetwork)
TLD(top level domain頂級域名):
組織域:.com .net .org .cc
國家域:.cn .tw .hk .iq .ir .jp
DNS:分布式資料庫,上級僅知道其直接下級,下級隻知道根的位置
DNS伺服器:接受本地伺服器的查詢請求(遞歸);外部用戶端請求,請求權威答案(肯定答案TTL,否定答案TTL,time to live生存時間);外部用戶端請求,請求非權威答案
DNS伺服器類型,4類:
1、主DNS伺服器(serialnumber(序列号,僅主DNS伺服器資料内容更改時才改變);refresh(定義每隔多長時間檢查主伺服器);retry(重試時間);expire(過期時間);nagative answer(否定答案的緩存時長TTL));
2、輔助DNS伺服器(或叫從DNS伺服器,向主DNS伺服器請求資料同步,采取pull拉取的機制;主可以有多個從,從也可以是其它從的從;若主挂掉從不會接替其工作,而是自殺(站在從的角度,主都不管了我管什麼);注意區域檔案中要定義type為slave,還要指定主伺服器masters );
3、緩存DNS伺服器(非權威答案);
4、轉發器
注:僅是管轄内的DNS伺服器傳回的答案是權威答案,例如.com管轄内的傳回的magedu.com為權威答案。
資料檔案中的每一個條目稱作一個資源記錄,格式為:
ZONENAME TTL IN RRT VALUE (其中TTL可省)
RRT(resource record type資源記錄類型):
SOA(start of authority起始授權,資料檔案中的第一條,正反向都定義)
NS(name server,zonename-->FQDN,除區域名稱外,其它都相同,正反向中都定義)
MX(mail exchanger,zonename-->FQDN,僅定義在正向中)
A(address,FQDN-->IPv4,僅正向,最常用)
AAAA(FQDN-->IPv6)
PTR(pointer,IP-->FQDN,僅定義在反向中)
CNAME(canonical name,别名,FQDN-->FQDN,正反向都可)
TXT
CHAOS
SRV
舉例:
ZONENAME TTL IN RRT VALUE(TTL可省)
magedu.com. 600 IN NS ns.magedu.com.
ns.magedu.com. 600 IN A 1.1.1.2(這兩組要成對出現)
ZONENAME TTL IN RRT PRI VALUE(僅定義資源類型為郵件時才需PRI,範圍0-99,數字越小級别越高)
magedu.com. 600 IN MX 10 mail.magedu.com.
mail.magedu.com. 600 IN A 1.1.1.3
ZONENAME TTL IN SOA FQDN ADMIN_MAILBOX (
SERIAL NUMBER
REFRESH
RETRY
EXPIRE
NAGATIVE TTL)
注:資料檔案中第一條必須是SOA記錄,它用來标明本區域多個DNS伺服器是如何完成資料同步的;格式如上,括号内各項表示的意義在伺服器類型-主DNS伺服器已介紹;時間機關:H,M,D,W分别是hour,minutes,day,week,不寫預設機關秒;郵箱格式不能寫@而要用點替代因為@在檔案中已表示為本區域;此檔案中的分号後的内容為注釋資訊,括号内的條目也可不用換行,用空格隔開。
@ 600 IN SOA ns1.magedu.com. admin.magedu.com.(
2015072101 ;serial number
1H ;refresh
5M ;retry
1W ;expire
1D );nagative ttl
Domain和zone:domain是邏輯概念,區域是實體存在的(正向解析區域,反向解析區域)
區域傳送類型:完全區域傳送(axfr,all transfer);增量區域傳送(inxfr,incremenatl transfer)
區域類型:主區域master;從區域slave;提示區域hint(定義根在什麼地方);轉發區域forward
二、實際操作:
本例環境:centos5.4, 2.6.18-164.el5
#yum list all | grep bind
#rpm -ql bind-libs
#rpm -ql bind-utils
#rpm -e bind-libs bind-utils(使用bind97主流版本,redhat6為bind)
#yum info bind97-devel.x86_64(建立開發環境才需安裝)
#yum info bind97-chroot.x86_64(為安全考慮可以将DNS程式放在某固定根下,進階用法)
#yum -y install bind97 bind97-libs bind97-utils
#rpm -ql bind97
/usr/sbin/*(指令位置,其中named二進制程式,named-checkconf檢查配置檔案,named-checkzone檢查區域資料檔案,rndc,rndc-confgen生成配置檔案)
/etc/rc.d/init.d/named {start|stop|status|restart|try-restart|reload|force-reload}
/etc/rndc.key(remote name domaincontroller,遠端工作的密鑰檔案,/etc/rndc.conf)
/var/named/*(資料檔案位置,其中named.ca辨別13個根節點,named.localhost預設正向資料檔案,named.empty預設反向資料檔案)
#rpm -ql bind97-utils(dig強大的測試工具,另有host,nslookup)
#vim /etc/named.conf
/etc/named.conf(主配置檔案,注意權限640,使用者名root,組named,此檔案中每個指令都分号結尾,否則文法錯誤 ,options全局配置,定義bind程序的工作屬性(最關鍵至少要配置directory,定義資料檔案目錄),zone區域的定義,區域可在主配置檔案中直接定義,或單獨定義但要在主配置檔案中包含進來(如include "/etc/named.rfc1912.zones";))
options {
listen-on port 53 { 192.168.1.222; };
directory “/var/named/”;(至少要有此項)
recursion yes;(此項沒有,預設也開啟遞歸,最好是用allow-recursion)
allow-recursion { 192.168.1.0/24; };(僅允許内部網絡遞歸)
allow-query { any; };(定義允許誰來查詢)
allow-transfer { 192.168.1.223; };(在主從配置中,為安全考慮,一般隻定義僅允許傳送資料給從伺服器,無主從架構寫none)
};
zone “ZONE NAME” IN {
type master|slave|hint|forward;
file “ZONEDATAFILE”;(可使用相對路徑,options中已指定)
masters “MASTER_IP”;(此項僅從DNS伺服器端有)
zone “.” IN {
type hint;
file “name.ca”;(記錄13個全球根伺服器位置)
zone “localhost” IN {
type master;
file “named.localhost”;(正向區域資料檔案)
zone “0.0.127.in-addr.arpa” IN {
file “named.loopback”;(反向區域資料檔案)
#named-checkconf(檢查配置檔案是否有文法錯誤,但不能判斷邏輯錯誤,如指定的區域檔案中無相應資料檔案,啟動服務時會報錯)
#named-checkzone “.” /var/named/named.ca
#named-checkzone “localhost” /var/named/named.localhost
#named-checkzone “0.0.127.in-addr.arpa” /var/named/named.loopback
#service named start(DNS啟動後,會将資料檔案加載到記憶體中,資料檔案也可放在資料庫中)
#tail /var/log/messages
#netstat -tunlp
#dig -t RRT NAME @SERVER
#dig -t NS . @a.root-servers.net.(指定伺服器檢視根區域的域名伺服器,-t指定資源記錄類型,answer section有查詢結果)
舉例:簡單配置DNS
#vim /etc/named.conf(定義主配置檔案)
directory “/var/named”;
zone “mageedu.com” IN {
file “mageedu.com.zone”;
zone “1.168.192.in-addr.arpa” {
file “192.168.1.zone”;
#cd /var/named
#cp -p named.localhost mageedu.com.zone(保留檔案屬性,權限640,屬主root,屬組named)
#vim mageedu.com.zone(定義正向資料檔案)
$TTL 600
@ IN SOA ns1.mageedu.com. admin.mageedu.com. ( ;注意分号表示注釋資訊,每個域名後記得要加點,@表示在主配置檔案已定義的正向區域mageedu.com,省略TTL值預設會繼承第一行定義的值
2015070101
1H
5M
2D
6H)
IN NS ns1 ;精簡寫法,也可寫為mageedu.com. 600 IN NS ns1.mageedu.com.
IN MX 10 mail
ns1 IN A 192.168.1.222
mail IN A 192.168.1.223
www IN A 192.168.1.222
ftp IN CNAME www
*.mageedu.com. IN A 192.168.1.222 ;泛域名解析,一般定義在錯誤頁面而非首頁
#cp -p mageedu.com.zone 192.168.1.zone
#vim 192.168.1.zone(定義反向資料檔案)
@ IN SOA 1.168.192.in-addr.arpa admin.mageedu.com. (
IN NS ns1.mageedu.com.
222 IN PTR ns1.mageedu.com.
223 IN PTR mail.mageedu.com.
#named-checkconf(檢主配置檔案是否有文法錯誤)
#named-checkzone “mageedu.com” /var/named/mageedu.com.zone(檢查區域檔案是否有文法錯誤)
#vim /etc/resolv.conf
nameserver 192.168.1.222(将域名伺服器改為本地設定的域名伺服器)
#service named restart
#dig -t NS mageedu.com
#dig -t SOA mageedu.com
#dig -x 192.168.1.222(反向查詢)
#host -t NS mageedu.com
#host -t A mail.mageedu.com
#host -t SOA mageedu.com
#nslookup(在linux中用互動模式中查詢)
>exit
>nslookup(在windows的指令行中,互動模式查詢)
>server 192.168.1.222(指定server)
>set q=NS(q=後跟RRT,設定查詢類型)
>mageedu.com
舉例:master-slave間區域傳送資料檔案
master-side: (在上例配置基礎上,添加從伺服器資訊,在主配置檔案中指定允許區域傳送的位址,資料檔案中添加從的相關記錄)
options {
allow-transfer { 192.168.1.225; };(此位址是從的位址)
#vim /var/named/mageedu.com.zone (正向資料檔案追加如下資訊)
IN NS ns2.mageedu.com.
ns2 IN A 192.168.1.225
#vim /var/named/192.168.1.zone(反向資料檔案追加如下資訊)
225 IN PTR ns2.mageedu.com.
slave-side:
#cp -p /etc/named.conf /etc/named.conf.bak
#chgrp named /etc/named.conf
}
type slave;
file “slaves/mageedu.com.zone”;
masters { 192.168.1.222; };
allow-transfer { none; };(上面概念提到過從可以是主的從,也可以是其它從的從,none其它任何伺服器都不能從此台伺服器擷取資料)
}:
zone “1.168.192.in-addr.arpa” IN {
file “slaves/192.168.1.zone”;
allow-transfer { none; };
#service named restart(配置好後兩端均重新開機服務)
#tail /var/log/messages(主從端都檢視日志,注意時間,serial版本号,區域傳輸類型axfr|ixfr)
在主端的資料檔案中再追加一條記錄,例如imap IN A 192.168.1.230,記得在SOA中更改serial版本号為2015070102,再重新開機服務,觀察主從兩邊日志變化情況。
注:若server-side資料檔案發生改變,一定要在相應的serial版本号上加1否則從擷取不到資料;
若開啟或重新開機服務時出現錯誤,如generating /etc/rndc.key,輸入指令再重新開機即可:
rndc-confgen -r /dev/urandom –a
舉例:rndc(為安全考慮,一般不開放rndc允許遠端控制)
#rndc -h(子指令)
#rndc -c RNDC_CONFIGFILE COMMAND(用戶端用此指令控制伺服器端,可檢視狀态,通知區域傳送,清空緩存等操作,status|notify ZONENAME|flush,通過#rndc -h可查詢看到)
server-side:
#rndc-confgen > /etc/rndc.conf(生成rndc配置檔案)
#vim -o /etc/rndc.conf /etc/named.conf(将rndc.conf檔案中的後半部分複制到named.conf中,并将注釋去掉,僅更改controls段中的位址,内容如下)
key "rndc-key" {
algorithm hmac-md5;
secret "LGt5qcw7Lk0BdvsHvm4C4w==";
controls {
inet 192.168.1.222 port 953
allow { 192.168.1.230; } keys { "rndc-key"; };
#netstat tulnp
#scp /etc/rndc.conf 192.168.1.220:/root/
client-side:
#cd /root
#vim rndc.conf(僅更改options段中default-server)
default-key "rndc-key";
default-server 192.168.1.222;
default-port 953;
#rndc -c rndc.conf COMMAND
子域授權:
<a href="http://www.mageedu.com/fin--%3Ewww.fin.magedu.com" target="_blank">www.mageedu.com/fin-->www.fin.mageedu.com</a>
<a href="http://www.mgaeedu.com/market--%3Ewww.market.mageedu.com" target="_blank">www.mgaeedu.com/market-->www.market.mageedu.com</a>
正向授權:
SUB_ZONE_NAME IN NS NSSERVER_SUB_ZONE_NAME
NSSERVER_SUB_ZONE_NAME IN A IP
子域和父域可以不在同一網段中;通過子域是查不到父域中的相關記錄,如果要想查詢到則要設定轉發forward,見下例
在上例master-slave的基礎上操作:
server-side(父域端)192.168.1.222
sub-side(子域端)192.168.1.228,準備一台伺服器,作為子域DNS伺服器(子域若隻在父域中有記錄而無具體資料查詢會失敗)
sub-side:先配置好子域端配置檔案及資料檔案(若有兩個子域一定要有對應的兩台伺服器及相關配置檔案存在,本例中隻建立fin.mageedu.com這一個實實在在存在的域,另一個僅在父域中寫出相應的記錄,注意僅有記錄是查詢不到的)
zone “fin.mageedu.com” IN {
file “fin.mageedu.com.zone”;
#cp named.localhost fin.mageedu.com.zone
@ IN SOA ns1.fin.mageedu.com. finadmin.mageedu.com. (
2015070101
1H
5M
2D
6H)
IN NS ns1
ns1 IN A 192.168.1.228
mail IN A 192.168.1.229
www IN A 192.168.1.228
#service named start
#netstat -tulnp
#dig -t NS fin.mageedu.com
#cd /var/named
#vim mageedu.com.zone(更改添加如下記錄)
……
2015070103 ;注意主配置檔案更改一定要改版本号serial否則從端擷取不到資料
fin IN NS ns1.fin
ns1.fin IN A 192.168.1.228
market IN NS ns1.market
ns1.market IN A 192.168.1.229
#tail /var/log/messages(主從都檢視日志,并且檢視從端資料檔案是否更新)
轉發配置:
forward only|first ;
forwarders { IP; };(指定轉發器是誰,誰負責解析查詢)
注:子域端解析不了的都轉發到指定的server;only轉發到指定server一定要要到答案,若要不到就結束不要了;first先轉發到指定server,若指定server不給答案,自己就去找根。
sub-side:
#vim /etc/named.conf(要麼在全局段配置;要麼在區域中配置)
options { (若轉發設定在全局段,則是所有子域中解析不到的都轉發到指定server)
forward { first; };
forwarders { 192.168.1.222; };
zone “mageedu.com” IN { (若轉發配置在區域,添加一區域,解析的資料此區域的才轉發,最好配置在區域中)
type forward;
forward first;
#dig -t NS mageedu.com(在子域中即可查詢父域中的資料)
清單配置:
内置的常用清單:none|any
例如allow-query { 192.168.1.220;172.16.0.0/16;127.0.0/8;10.0.0.0/8; ……}則可以将其歸類,模闆如下,acl段一定要放在主配置檔案的最前端且在options之外定義:
acl ACL_NAME {
network/netmask;
IP;
};
例如:
acl innet {
192.168.1.0/24;
172.16.0.0/8;
127.0.0.0/8;
allow-query { innet; };
DNS視圖:
實作智能解析,将一個域名解析成兩種;
一旦定義了視圖,所有的區域都必須要定義在視圖中;根區域定義在需要遞歸的視圖中
view VIEW_NAME {
{;
電信telecom、聯通unicom,兩個獨立的網絡,連接配接處的總帶寬100G;使用者通路網站,則直接在自己所屬的網絡中解析,不用經過連接配接處帶寬,前提線上的網站要在這兩個網絡中都有相關DNS資料檔案才可
準備兩個不同網段的用戶端,使之均能與DNS-server通信(此例中單獨拿出一台配置了兩個網卡的主機,兩個網卡配置位址均是兩個網段的網關,192.168.1.1和172.16.100.1,配置兩個網卡可以轉發,/etc/sysctl.conf中net.ipv4.ip_forward = 1):
DNS-server:192.168.1.222;
Client1:192.168.1.230
Client2:172.16.100.3
DNS-server-side:
acl innet {
view telecom {
match-clients { innet; };
zone “mageedu.com” IN {
type master;
file “telecom.mageedu.com.zone”;
view unicom {
match-clients { any; };
file “unicom.mageedu.com.zone”;
#cp named.localhost telecom.mageedu.com.zone
#cp named.localhost unicom.mageedu.com.zone
#vim telecom.mageedu.com.zone
@ IN SOA ns.mageedu.com. admin.mageedu.com. {
7D
1D)
ns IN A 192.168.1.222
#vim unicom.mageedu.com.zone
@ IN SOA ns.mageedu.com. admin.mageedu.com. {
mail IN A 172.16.100.2
www IN A 172.16.100.2
#dig -t A mail.magedu.com(在兩個用戶端都測試會得到不同的結果)
DNS日志功能:
channel(日志儲存位置,兩種方式:可通過file自定義儲存日志資訊檔案;通過syslog定義到/var/log/messages中)
category(類别,定義日志源共15種,日志是由哪個子系統産生的,如有查詢的、有區域傳送等)
注:每一個類别category可發往多個channel,每一channel隻接收一類category日志。
bind日志級别:dynamic,debug [level],info,notice,warning,error,critical;其中dynamic和debug[1|2|3]為bind日志所獨有,debug級别越高記錄越詳細;預設info級别。
15種類别:default,general,client,config,dispatch,dnssec,lame-servers,network,notify,queries,resolver,security,update,xfer-in,xfer-out;一般更新傳輸日志開啟 如update,xfer-in,xfer-out,查詢安全日志不要開啟security
Logging {
channel my_file {
file “log.msgs” version 3 size 10k;(每一日志達到10k則自動滾動,共記錄3個版本,也就是3個檔案)
severity dynamic;
print-time yes;(在日志檔案中記錄時間,什麼時候寫入的日志)
print-severity yes;(在日志檔案中記錄日志級别)
pirnt-category yes; (在日志檔案中記錄日志類别)
};
channel my_syslog {
syslog local0;
severity info;
category xfer-in { my_file; };
category update { my_syslog; };
logging {
channel querylog {
file “/var/log/named/bind-query.lgo” version 5 size 10M;
print-time yes;
print-serverity yes;
channel xfer-log {
file “/var/log/named/transfer.log” version 3 size 10k;
severity debug 3;
};
category queries { querylog; };
category xfer-out { xfer-log; };
queryperf(對DNS伺服器做壓力測試,一般若資料存于檔案,每秒1 萬以上個查詢很輕松,若資料放于資料庫中,每秒七八百就不錯了)
dnstop(監控DNS伺服器的工作狀态)
#tar xf bind-9.7.4.tar.gz
#cd bind-9.7.4/contrib/queryperf(僅編譯安裝queryperf工具)
#./configure
#make
#cp queryperf /bin
#queryperf -h
#queryperf -d test -s 192.168.1.222(注意最後一行Queries per second:後的值,把日志注釋掉再次查詢,性能會提高很多,響應速度極快)
#tar xf dnstop-20140915.tar.gz
#cd dnstop-20140915
#yum -y install libpcap-devel(依賴于此包,抓包工具packagecap)
#make install
#man dnstop
#dnstop -4 -Q -R eth0(-4,IPV4;-Q,count only DNS query messages;-R,count onlyDNS reply messages)
以上是學習《馬哥網絡視訊》做的筆記。
1、DNS系統的作用:正向解析(根據主機名稱或域名查找對應的IP位址);反向解析(根據IP位址查找對應的主機域名)。
DNS工作模式:遞歸查詢、疊代查詢。
全球共13台根DNS伺服器。
BIND(Berkeley InternetName Daemon)www.isc.org
軟體包:bind-9.3.3-7-el5.i386.rpm
注:DNS是網際網路的通信協定名稱,BIND是提供DNS服務的軟體。
服務名:named
端口号:53
主配置檔案:/etc/named.conf
儲存DNS解析記錄的資料檔案:/etc/named/下
主域名伺服器:特定DNS區域的官方伺服器,具有唯一性;負責維護該區域内所有域名到IP位址的映射記錄。
從域名伺服器:(輔助域名伺服器)資料檔案來源于主域名伺服器,供維護的域名到IP位址的映射記錄。
2、DNS伺服器配置:
》主配置檔案:#vi /etc/named.conf
options{
listen-on port 53 { 192.168.216.223; };
……
allow query { 192.168.216.0.24; }; (或any)
};
》區域配置檔案:#vi /etc/named.rfc1912.zones
zone "baidu.com" IN {
type master
file "baidu.localhost";
allow-update { none; };
}
zone "216.168.192.in-addr.arpa" IN {
type master;
file "baidu.empty";
》資料檔案:
正向資料檔案:#cp -p named.localhost baidu.localhost
#vi baidu.localhost
$TTL ID
@ IN SOA baidu.com. rname.invalid. {
0 ;serial
1D ;refresh
1H ;retry
1W ;expire
3H ;minimum
dns dns.baidu.com.
MX 5 mail.baidu.com.
dns A 192.168.216.223
www A 192.168.216.224
mail A 192.168.216.225
反向資料檔案:#cp -p named.empty baidu.empty
#vi baidu.empty
$TTL ID
0 ;serial
dns dns.baidu.com.
MX 5 mail.baidu.com.
223 PTR dns.baidu.com.
224 PTR www.baidu.com.
225 PTR mail.baidu.com.
3、主從DNS伺服器配置:
》主DNS主配置檔案:
listen-onport 53 { 192.168.216.223; };
allow-query { 192.168.216.0/24 };
allow-transfer { 192.168.216.224;};
……
主DNS區域檔案和資料檔案同上例。
》從DNS主配置檔案:
listen-on port 53 { 192.168.216.224; };
allow-query {192.168.216.224; };
從DNS區域檔案:
#vi /etc/named.rfc1912.zones
zone "baidu.com" IN {
type slave;
file "slaves/baidu.localhost";
allow-update {none;};
masters { 192.168.216.223;};
zone "216.168.192.in-addr-arpa" IN {
file "slaves/baidu.empty";
allow-update { none; };
master { 192.168.216.223;};
從DNS資料檔案從主DNS擷取
4、分離解析DNS伺服器:将相同的域名解析為不同的IP位址
實驗環境:三台虛拟機,其中一台雙網卡。
》主配置檔案:
listen-on port 53 { any; };
allow-query { any; };
注釋掉根伺服器有關設定;
view lan {
match-clients { 192.168.216.0/24; };
zone "." IN {
type hint;
file "named.ca";
include "/etc/named.lan";
view wan {
match-clients { any; };
include "/etc/named.wan";
》區域檔案:
#cp -p /etc/named.rfc1912.zones.bak /etc/named.lan
#cp -p /etc/named.rfc1912.zones.bak /etc/named.wan
#vi /etc/named.lan
type master;
file "baidu.1.lan";
aloow-update { none;};
file "baidu.2.lan";
#vi /etc/named.wan
file "baidu.1.wan";
zone "200.200.200.in-addr.arpa" IN {
file "baidu.2.wan";
》資料檔案:
#cp -p named.localhost baidu.1.lan
#vi baidu.1.lan
…… SOA baidu.com. ……
NS dns.baidu.com.
MX 5 mail.baid.com.
dns A 192.168.216.223
mail A 192.168.216.224
www A 192.168.216.225
* A 192.168.216.100
#cp -p named.empty baidu.2.lan
#vi baidu.2.lan
NS dns.baidu.com.
MX 5 mail.baidu.com.
223 PTR dns.baidu.com.
224 PTR mail.baidu.com.
225 PTR www.baidu.com.
* PTR xxx.baidu.com.
#cp -p named.localhost baidu.1.wan
#vi baidu.1.wan
dns A 200.200.200.1
mail A 200.200.200.2
www A 200.200.200.3
* A 200.200.200.100
#cp -p named.empty baidu.2.wan
#vi baidu.2.wan
1 PTR dns.baidu.com.
2 PTR mail.baidu.com.
3 PTR www.baidu.com.
本文轉自 chaijowin 51CTO部落格,原文連結:http://blog.51cto.com/jowin/1659467,如需轉載請自行聯系原作者