簡(jiǎn)介
這個(gè)章節(jié)上接上一份文檔,包含了Consul集群的安全和網(wǎng)絡(luò)設(shè)置吩抓,這里假設(shè)用戶已經(jīng)完成了上一章節(jié)中數(shù)據(jù)中心的部署先誉。
Gossip加密
Consul內(nèi)部針對(duì)兩套不同的子系統(tǒng)使用不同的通信加密方式:Gossip加密
和TLS
,TLS
用于保護(hù)代理間的RPC調(diào)用娄周,代理間的Gossip通信
是通過UDP
完成的没卸,使用對(duì)稱密鑰
保護(hù)安全羹奉,這個(gè)章節(jié)我們僅討論Gossip加密
。
Gossip加密密鑰
要啟用Gossip加密
约计,需要在啟動(dòng)Consul服務(wù)時(shí)添加加密密鑰诀拭,用戶可以在配置文件中增加encrypt
參數(shù),密鑰大小為16字節(jié)煤蚌,使用Base64編碼耕挨,用戶可以使用Consul命令行生成密鑰:
$ consul keygen
cg8StVXbQJ0gPvMd9o7yrg==
在新集群上生效
如果用戶想在新集群上啟用Gossip加密
,可以將密鑰參數(shù)添加到配置文件尉桩,并在啟動(dòng)時(shí)通過-config-dir
參數(shù)指定文件:
{
"data_dir": "/opt/consul",
"log_level": "INFO",
"node_name": "bulldog",
"server": true,
"encrypt": "JY34uTPZyfUE+6tinMYEVw=="
}
$ consul agent -config-dir=/etc/consul.d/
==> Starting Consul agent...
==> Starting Consul agent RPC...
==> Consul agent running!
Node name: 'Armons-MacBook-Air.local'
Datacenter: 'dc1'
Server: false (bootstrap: false)
Client Addr: 127.0.0.1 (HTTP: 8500, HTTPS: -1, DNS: 8600, RPC: 8400)
Cluster Addr: 10.1.10.12 (LAN: 8301, WAN: 8302)
Gossip encrypt: true, RPC-TLS: false, TLS-Incoming: false
...
如果正確配置了加密筒占,輸出中將包含Gossip encrypt: true
,這里需要注意的是魄健,集群中的所有節(jié)點(diǎn)必須使用一份共同的加密密鑰赋铝,使用WAN連接的多個(gè)數(shù)據(jù)中心之間也需要保持統(tǒng)一插勤。
在現(xiàn)有集群上生效
Gossip加密
也可以在現(xiàn)有集群上啟用沽瘦,需要額外幾個(gè)步驟:
- 使用
consul keygen
生成密鑰:
$ consul keygen
JY34uTPZyfUE+6tinMYEVw==
- 設(shè)置加密密鑰,將配置文件中的
crypto_verify_incoming
和crypto_verify_outgoing
參數(shù)設(shè)置為false
农尖,然后滾動(dòng)更新
Consul集群析恋,執(zhí)行完此步驟后,代理可以解密Gossip加密
數(shù)據(jù)盛卡,但此時(shí)發(fā)送的數(shù)據(jù)還未加密助隧。這里的滾動(dòng)更新
可以通過依次重新啟動(dòng)Consul節(jié)點(diǎn)來完成,consul reload
或者kill -HUP <process_id>
不足以改變Gossip
配置滑沧。
{
"data_dir": "/opt/consul",
"log_level": "INFO",
"node_name": "bulldog",
"server": true,
"encrypt": "JY34uTPZyfUE+6tinMYEVw==",
"encrypt_verify_incoming": false,
"encrypt_verify_outgoing": false
}
- 將
encrypt_verify_outgoing
設(shè)置更新為true
并村,然后滾動(dòng)更新
Consul集群,現(xiàn)在代理將發(fā)送加密的Gossip數(shù)據(jù)滓技,并允許接收未加密的數(shù)據(jù):
{
"data_dir": "/opt/consul",
"log_level": "INFO",
"node_name": "bulldog",
"server": true,
"encrypt": "JY34uTPZyfUE+6tinMYEVw==",
"encrypt_verify_incoming": false,
"encrypt_verify_outgoing": true
}
- 最后將
crypto_verify_incoming
更新為true
哩牍,滾動(dòng)更新
Consul集群,在驗(yàn)證完上一步全部生效之后令漂,才能執(zhí)行此步:
{
"data_dir": "/opt/consul",
"log_level": "INFO",
"node_name": "bulldog",
"server": true,
"encrypt": "JY34uTPZyfUE+6tinMYEVw==",
"encrypt_verify_incoming": true,
"encrypt_verify_outgoing": true
}
現(xiàn)在所有代理都將嚴(yán)格執(zhí)行加密Gossip協(xié)議
膝昆,此處需要注意的是encrypt_verify_incoming
和encrypt_verify_outgoing
這兩個(gè)參數(shù)默認(rèn)都是true
丸边。
使用TLS加密保護(hù)Agent端通信安全
在生產(chǎn)環(huán)境中使用TLS加密
來保護(hù)數(shù)據(jù)中心安全是非常必要的步驟,TLS配置
也是我們安全模型的先決條件荚孵。正確配置TLS是一個(gè)非常復(fù)雜的過程妹窖,尤其考慮到部署的范圍會(huì)非常大。本章將會(huì)介紹可用于生產(chǎn)的RPC通信
和一致性通信(consensus communication)
的TLS配置收叶,同時(shí)用戶也需要保障HTTP請(qǐng)求
的安全骄呼。
Consul支持使用TLS對(duì)服務(wù)端和客戶端進(jìn)行鑒權(quán),啟用TLS需要所有服務(wù)端都具有單個(gè)證書頒發(fā)機(jī)構(gòu)簽名的證書判没,同時(shí)客戶端也應(yīng)該具有相同認(rèn)證的證書谒麦。
先決條件
本章節(jié)中介紹的證書生成及分發(fā)步驟僅適用于新的Consul集群,在啟動(dòng)Consul服務(wù)之前,應(yīng)完成所有的配置工作翅帜;如果需要在已有的數(shù)據(jù)中心上啟用TLS加密
翔冀,需要將此章節(jié)內(nèi)容結(jié)合其他操作,這個(gè)會(huì)在后續(xù)再做介紹耻蛇。
分發(fā)客戶端證書
分發(fā)客戶端證書有兩種方法,手動(dòng)加密
或自動(dòng)加密
胞此,Consul在1.5.2版本
中引入了自動(dòng)加密方式臣咖,減輕了運(yùn)維人員手動(dòng)生成和分發(fā)客戶端正式的步驟。這個(gè)方法使用Connect CA
命名生成客戶端證書漱牵,然后Consul會(huì)將證書自動(dòng)分發(fā)給所有客戶端夺蛇,這對(duì)于有許多客戶端的大型數(shù)據(jù)中心非常有效。
如果需要使用第三方CA或需要對(duì)證書管理進(jìn)行更細(xì)粒度的控制酣胀,建議使用手動(dòng)加密
方式刁赦。有關(guān)將OpenSSL
作為第三方CA的示例,將在后續(xù)再做介紹闻镶。
初始化內(nèi)置證書
為Consul配置TLS的第一步就是生成證書甚脉,為了防止未經(jīng)授權(quán)的數(shù)據(jù)中心訪問,Consul要求所有證書均由同一證書頒發(fā)機(jī)構(gòu)簽名铆农。這里應(yīng)該是一個(gè)私有證書牺氨,而不是公共證書,因?yàn)槭褂迷撟C書簽名的憑證都能與本數(shù)據(jù)中心進(jìn)行通信墩剖。
有多種工具可以管理證書猴凹,比如Value
中的PKI
,這里為了簡(jiǎn)化操作岭皂,我們使用Consul內(nèi)置的TLS助手
來創(chuàng)建證書郊霎。整個(gè)數(shù)據(jù)中心僅需創(chuàng)建一個(gè)證書,創(chuàng)建證書的節(jié)點(diǎn)應(yīng)保持穩(wěn)定蒲障,最好不要是Consul代理或者云服務(wù)器歹篓,創(chuàng)建指令如下:
$ consul tls ca create
==> Saved consul-agent-ca.pem
==> Saved consul-agent-ca-key.pem
CA證書:consul-agent-ca.pem
包含驗(yàn)證Consul證書所需的公共密鑰瘫证,必須分發(fā)給運(yùn)行Consul代理的各個(gè)節(jié)點(diǎn)
CA密鑰:consul-agent-ca-key.pem
將用于簽署訪問Consul節(jié)點(diǎn)的證書,必須保持私有庄撮,擁有此密鑰背捌,任何人都可以受信訪問Consul服務(wù)器,并可以生成新的證書洞斯,獲得所有Consul數(shù)據(jù)(包括ACL令牌)的訪問權(quán)限毡庆。
創(chuàng)建服務(wù)端證書
使用下述命令創(chuàng)建服務(wù)端證書
$ consul tls cert create -server
==> WARNING: Server Certificates grants authority to become a
server and access all state in the cluster including root keys
and all ACL tokens. Do not distribute them to production hosts
that are not server nodes. Store them as securely as CA keys.
==> Using consul-agent-ca.pem and consul-agent-ca-key.pem
==> Saved dc1-server-consul-0.pem
==> Saved dc1-server-consul-0-key.pem
在同一個(gè)節(jié)點(diǎn)重復(fù)這個(gè)操作,直到每臺(tái)服務(wù)器都有一個(gè)單獨(dú)的證書烙如。該命令可以反復(fù)調(diào)用么抗,它會(huì)自動(dòng)增加證書和密鑰序列。
為了對(duì)Consul服務(wù)端進(jìn)行身份驗(yàn)證亚铁,服務(wù)端會(huì)提供一種特殊的證書蝇刀,證書的名稱中包含server.dc1.consul
。如果用戶啟用verify_server_hostname
徘溢,那么只有能提供此證書的代理才能作為服務(wù)端吞琐。假設(shè)沒有設(shè)置verify_server_hostname = true
,攻擊者可能會(huì)破壞Consul客戶端代理然爆,并將其作為服務(wù)端重新啟動(dòng)站粟,然后就能訪問數(shù)據(jù)中心的所有數(shù)據(jù),這就是服務(wù)端證書很特殊的原因曾雕,并且僅服務(wù)端需要配置它們奴烙。
分發(fā)服務(wù)端證書
生成服務(wù)端證書后,用戶需要將它們分發(fā)到Consul服務(wù)器剖张,并修改配置文件切诀,指定證書的目錄地址。
用戶需要將下述文件復(fù)制到Consul服務(wù)端機(jī)器:
-
consul-agent-ca.pem
:CA公共證書 -
dc1-server-consul-0.pem
:dc1數(shù)據(jù)中心Consul服務(wù)器節(jié)點(diǎn)公共證書 -
dc1-server-consul-0-key.pem
:dc1數(shù)據(jù)中心Consul服務(wù)器節(jié)點(diǎn)私鑰
重復(fù)上述過程修械,直到所有服務(wù)端機(jī)器都具有這三個(gè)文件趾牧。
自動(dòng)加密方式
服務(wù)端配置
在上述章節(jié)中检盼,用戶創(chuàng)建了服務(wù)端證書并成功分發(fā)了它們肯污,要使用自動(dòng)加密
來分發(fā)客戶端證書,用戶需要啟用auto_encrypt
功能吨枉,使用以下選項(xiàng)配置服務(wù)器:
{
"verify_incoming": true,
"verify_outgoing": true,
"verify_server_hostname": true,
"ca_file": "consul-agent-ca.pem",
"cert_file": "dc1-server-consul-0.pem",
"key_file": "dc1-server-consul-0-key.pem",
"auto_encrypt": {
"allow_tls": true
}
}
注意蹦渣,除了verify_xxx
設(shè)置之外,還需要啟用allow_tls
配置貌亭,verify_xxx
設(shè)置確保服務(wù)端和客戶端之間的所有通信都進(jìn)行了鑒權(quán)柬唯,啟用auto_encrypt
會(huì)默認(rèn)啟用verify_outgoing
。
客戶端配置
客戶端配置如下所示:
{
"verify_incoming": false,
"verify_outgoing": true,
"verify_server_hostname": true,
"ca_file": "consul-agent-ca.pem",
"auto_encrypt": {
"tls": true
}
}
注意圃庭,此方法將證書存儲(chǔ)在內(nèi)存中锄奢,并沒有持久化保存失晴。
手動(dòng)加密方式
服務(wù)端配置
使用以下選項(xiàng)配置服務(wù)端:
{
"verify_incoming": true,
"verify_outgoing": true,
"verify_server_hostname": true,
"ca_file": "consul-agent-ca.pem",
"cert_file": "dc1-server-consul-0.pem",
"key_file": "dc1-server-consul-0-key.pem"
}
通過verify_outgoing
和verify_server_hostname
配置項(xiàng),TLS可用于服務(wù)端鑒權(quán)拘央,也可以選擇使用verify_incoming
對(duì)客戶端進(jìn)行鑒權(quán)涂屁。
設(shè)置客戶端
要對(duì)客戶端通信進(jìn)行加密,需要將CA證書灰伟、客戶端證書及其私鑰分發(fā)給每個(gè)客戶端拆又,下面描述具體步驟。
生成客戶端證書
在Consul集群節(jié)點(diǎn)上栏账,使用consul tls cert create -client
命令生成客戶端證書:
$ consul tls cert create -client
==> Using consul-agent-ca.pem and consul-agent-ca-key.pem
==> Saved dc1-client-consul-0.pem
==> Saved dc1-client-consul-0-key.pem
客戶端證書應(yīng)該也要由CA簽名帖族,但是它沒有服務(wù)端證書的特征,這意味著如果啟用了verify_server_hostname
配置挡爵,它們不能作為服務(wù)端啟動(dòng)竖般,創(chuàng)建完服務(wù)端證書之后,即可以分發(fā)到Consul集群每個(gè)客戶端中茶鹃。
客戶端配置
配置客戶端代理:
{
"verify_incoming": true,
"verify_outgoing": true,
"verify_server_hostname": true,
"ca_file": "consul-agent-ca.pem",
"cert_file": "dc1-client-consul-0.pem",
"key_file": "dc1-client-consul-0-key.pem"
}
啟動(dòng)Consul
現(xiàn)在捻激,用戶已經(jīng)配置好了服務(wù)端和客戶端,可以開啟Consul服務(wù)了
# systemctl start consul
使用ACL增強(qiáng)Consul安全性
Consul使用訪問控制列表(ACLs)
來保護(hù)UI
前计、API
胞谭、CLI
、服務(wù)通信
和代理通信
男杈,當(dāng)用戶希望保護(hù)集群安全時(shí)丈屹,應(yīng)該優(yōu)先配置ACL。ACL的核心理念是將規(guī)則
分組為策略
伶棒,然后將一個(gè)或多個(gè)策略與令牌
相關(guān)聯(lián)旺垒。
初始化ACL系統(tǒng)
用戶需要通過兩個(gè)步驟初始化ACL系統(tǒng):
- 啟用
ACLs
- 創(chuàng)建引導(dǎo)令牌
在代理中啟用ACLs
在代理的配置文件中添加ACL參數(shù),然后重新啟動(dòng)Consul服務(wù)可以啟用ACL肤无,為了正確啟用ACL配置先蒋,用戶需要將相同的參數(shù)應(yīng)用于數(shù)據(jù)中心的每個(gè)服務(wù)端和客戶端。如果希望減少Consul客戶端的重啟次數(shù)宛渐,可以在添加令牌時(shí)一同啟用ACL竞漾。
## agent.hcl
acl = {
enabled = true
default_policy = "deny"
enable_token_persistence = true
}
注意:這里需要注意的是令牌持久化在1.4.3版本中才引入,用戶在使用HTTP API時(shí)無法持久化令牌窥翩。
在此示例中业岁,默認(rèn)策略配置為deny
,這意味著處于白名單模式寇蚊,這里還啟用了持久化令牌(token persistence)
笔时,這樣令牌會(huì)保留在磁盤上,并在代理重啟時(shí)重新加載仗岸。
注意:如果要在現(xiàn)有數(shù)據(jù)中心上引導(dǎo)ACL允耿,首先配置 default_policy = allow 在代理上啟用ACL借笙。默認(rèn)策略配置為allow將啟用ACL,打開所有權(quán)限较锡,從而在創(chuàng)建并使用令牌后提澎,集群也可以正常工作,這有助于減少停機(jī)時(shí)間念链。
創(chuàng)建引導(dǎo)令牌
使用acl bootstrap
命令創(chuàng)建引導(dǎo)令牌:
consul acl bootstrap
輸出內(nèi)容包含了令牌的重要信息:global-management
和SecretID
盼忌。
注意:默認(rèn)情況下,Consul賦予引導(dǎo)令牌 global-management 策略掂墓,這個(gè)令牌擁有特權(quán)谦纱,不受任何限制。在緊急情況下君编,擁有一個(gè)不受限的令牌時(shí)非常重要的跨嘉,但是只應(yīng)少量管理員擁有此令牌。SecretID是一個(gè)UUID吃嘿,在使用Consul命令行或HTTP API時(shí)用于標(biāo)識(shí)令牌祠乃。
將CONSUL_HTTP_TOKEN
環(huán)境變量設(shè)置為引導(dǎo)令牌:
export CONSUL_HTTP_TOKEN=<your_token_here>
接下來的所有示例,都以服務(wù)器consul-server-one
為例兑燥。
將代理中應(yīng)用令牌
在代理中應(yīng)用令牌分為三個(gè)步驟:
- 創(chuàng)建代理策略亮瓷;
- 使用新創(chuàng)建的策略創(chuàng)建令牌;
- 將令牌添加到代理降瞳。
創(chuàng)建代理策略
我們建議將代理策略配置為具有寫權(quán)限的配置嘱支,包括在目錄中自注冊(cè)、更新節(jié)點(diǎn)級(jí)別的健康檢查挣饥、以及對(duì)代理中的配置文件具有寫訪問權(quán)限等除师。
# consul-server-one-policy.hcl
node "consul-server-one" {
policy = "write"
}
創(chuàng)建代理策略時(shí),需要先查看節(jié)點(diǎn)規(guī)則扔枫,只有可以使用Consul命令行對(duì)其進(jìn)行初始化汛聚。(同樣也可以使用HTTP API)
$ consul acl policy create \
-name consul-server-one \
-rules @consul-server-one-policy.hcl
命令行輸出將包含策略信息,對(duì)Consul數(shù)據(jù)中心中的所有服務(wù)端和客戶端都重復(fù)此過程短荐,每個(gè)代理都有對(duì)應(yīng)自己節(jié)點(diǎn)名稱相應(yīng)的策略倚舀。
創(chuàng)建代理Token
創(chuàng)建完代理策略
之后,就要為所有代理創(chuàng)建單獨(dú)的令牌搓侄,執(zhí)行consul acl token create
命令:
$ consul acl token create -description "consul-server-one agent token" -policy-name consul-server-one
這條命令返回令牌信息
瞄桨,令牌信息
包括描述
和策略
信息,對(duì)每個(gè)代理都重復(fù)此過程讶踪,運(yùn)維人員需要將這些令牌保存在安全的地方,這里我們推薦使用Vault
泊交。
代理添加Token
最后乳讥,使用set-agent-token
子命令配置令牌:
consul acl set-agent-token agent "<agent token here>"
用戶需要在每個(gè)代理中都執(zhí)行此操作柱查,此外還需要將CONSUL_HTTP_TOKEN
環(huán)境變量設(shè)置為引導(dǎo)令牌或使用API配置。
至此云石,每個(gè)具有令牌的代理都可以再次向Consul讀寫信息唉工,但只能用于與節(jié)點(diǎn)相關(guān)的操作,對(duì)服務(wù)的操作尚不能運(yùn)行汹忠。
在服務(wù)中添加令牌
服務(wù)令牌的創(chuàng)建和應(yīng)用過程類似于代理:
- 創(chuàng)建一個(gè)策略淋硝;
- 使用該策略創(chuàng)建令牌;
- 將令牌添加到服務(wù)宽菜。
下面是一個(gè)需要配置令牌的服務(wù)示例,這個(gè)服務(wù)定義在某個(gè)客戶端服務(wù)器的配置目錄中:
{
"service": {
"name": "dashboard",
"port": 9002,
"check": {
"id": "dashboard-check",
"http": "http://localhost:9002/health",
"method": "GET",
"interval": "1s",
"timeout": "1s"
}
}
}
首先铅乡,創(chuàng)建一個(gè)僅向dashboard
服務(wù)授予寫權(quán)限的策略:
# dashboard-policy.hcl
service "dashboard" {
policy = "write"
}
使用策略定義來初始化策略:
consul acl policy create -name "dashboard-service" -rules @dashboard-policy.hcl
接下來继谚,使用該策略創(chuàng)建一個(gè)token:
consul acl token create -description "Token for Dashboard Service" \
-policy-name dashboard-service
與之前一樣,該命令會(huì)返回有關(guān)令牌的信息阵幸,需要將它們妥善保管花履,最后將令牌添加到服務(wù)定義中:
{
"service": {
"name": "dashboard",
"port": 9002,
"token": "57c5d69a-5f19-469b-0543-12a487eecc66",
"check": {
"id": "dashboard-check",
"http": "http://localhost:9002/health",
"method": "GET",
"interval": "1s",
"timeout": "1s"
}
}
}
如果服務(wù)正在運(yùn)行中,需要重新啟動(dòng)它生效挚赊。與代理令牌不同诡壁,沒有HTTP API接口可以在服務(wù)中設(shè)置令牌,如果該服務(wù)之前是通過配置文件注冊(cè)的荠割,還必須在配置文件中設(shè)置令牌欢峰;如果之前是使用HTTP API注冊(cè)服務(wù)的,用戶可以在header中使用X-Consul-Token
傳遞令牌涨共。
Consul KV令牌
為Consul KV
創(chuàng)建令牌的步驟與前幾類令牌相似纽帖,與它們不同的是,Consul KV有許多不同的使用場(chǎng)景:
- 服務(wù)可能需要訪問KV集中的配置數(shù)據(jù)举反;
- 用戶存儲(chǔ)Session分布式鎖信息懊直;
- 運(yùn)維人員需要權(quán)限更新配置值;
KV集
的規(guī)則有四個(gè)政策級(jí)別:deny
火鼻、write
室囊、read
和list
。
根據(jù)使用場(chǎng)景不同魁索,令牌的使用方式也會(huì)有所差異融撞。對(duì)于服務(wù),用戶需要將令牌添加到HTTP客戶端粗蔚;對(duì)于運(yùn)維人員尝偎,需要在執(zhí)行命令行或API時(shí)添加令牌。
遞歸讀取
key_prefix "redis/" {
policy = "read"
}
上述示例中,用戶允許讀取任何前綴是redis/
的鍵致扯,如果用戶發(fā)出指令consul kv get -recurse redis/ -token=<your token>
肤寝,可以獲得一列redis/
為前綴的鍵的列表。
配置這種類型的策略有利于運(yùn)維人員遞歸讀取
KV集中存儲(chǔ)的配置參數(shù)抖僵,同樣配置寫權(quán)限可以更新前綴為redis/
的所有鍵鲤看。
某一鍵值的寫權(quán)限
key "dashboard-app" {
policy = "write"
}
上述示例中,用戶賦予dashboard-app
鍵讀寫權(quán)限耍群,允許使用get
义桂、delete
和put
操作。
某一鍵值的讀權(quán)限
key "counting-app" {
policy = "read"
}
上述示例中蹈垢,用戶賦予counting-app
鍵讀權(quán)限慷吊,允許使用get
操作。
Consul UI令牌
在建立ACL系統(tǒng)
后耘婚,用戶在界面訪問也受到了限制罢浇,如果在代理上未設(shè)置默認(rèn)令牌,則將匿名令牌授予UI訪問權(quán)限沐祷,這樣所有的操作都會(huì)被拒絕嚷闭,包括查看節(jié)點(diǎn)和服務(wù)。
運(yùn)維人員可以創(chuàng)建并分發(fā)token給用戶赖临,重新啟用UI功能胞锰,用戶可以在 ACL
頁(yè)面添加獲取的token:
在操作完之后,用戶可以在頁(yè)面看到添加的令牌:
瀏覽器會(huì)存儲(chǔ)用戶添加的令牌兢榨,運(yùn)維人員可以分配不同權(quán)限的令牌給不同的用戶嗅榕。
下述是一個(gè)策略的示例,該策略允許用戶對(duì)
Services
吵聪、Nodes
凌那、Key/Value
和Intentions
界面進(jìn)行訪問,同時(shí)還需要配置acl = read
才能查看策略和令牌吟逝,否則無法訪問界面的ACL
部分:
# operator-ui.hcl
service_prefix "" {
policy = "read"
}
key_prefix "" {
policy = "read"
}
node_prefix "" {
policy = "read"
}
管理ACL策略
本章節(jié)內(nèi)容主要面向運(yùn)維人員帽蝶,關(guān)注創(chuàng)建和管理ACL令牌,其中包括一些建議块攒,如何找到完成操作所需的最低權(quán)限励稳。 在整篇指南中,我們將提供一些示例囱井,用戶可以根據(jù)自己的環(huán)境進(jìn)行調(diào)整驹尼,閱讀完本章節(jié)后,用戶將對(duì)如何有效管理ACL策略和令牌有更好的了解庞呕。
我們希望運(yùn)維人員在生產(chǎn)環(huán)境中自動(dòng)執(zhí)行策略和令牌生成過程新翎。 此外,如果用戶使用了容器編排器(container orchestrator)
,雖然本指南中的概念仍然適用料祠,但整個(gè)過程還是將有所不同骆捧。 如果用戶使用的是官方的Consul-Kubernetes Helm圖
表來部署Consul澎羞,請(qǐng)使用相關(guān)的鑒權(quán)方法文檔(authentication method documentation)
髓绽。
先決條件
在本指南中,我們提供的是一些抽象并高級(jí)的建議妆绞,并不會(huì)按部就班地用命令描述令牌生成過程顺呕,這里假定所有的代理上都設(shè)置了default_policy
為deny
。
安全性和可用性
本章節(jié)中的示例描述了括饶,如何創(chuàng)建可用于完成同一任務(wù)的多個(gè)策略株茶。 例如,使用完全匹配資源(exact match resourc)
規(guī)則是最安全的图焰,它授予完成任務(wù)所需的最少權(quán)限启盛,通常,創(chuàng)建具有最小權(quán)限的策略和令牌將導(dǎo)致更多的策略定義技羔。為了簡(jiǎn)化過程僵闯,前綴資源(prefix resources)
規(guī)則可以應(yīng)用于零到多個(gè)對(duì)象,這樣創(chuàng)建令牌的過程會(huì)相對(duì)簡(jiǎn)單藤滥,但是權(quán)限的作用域半徑會(huì)擴(kuò)大鳖粟。
發(fā)現(xiàn)所需的權(quán)限
在引導(dǎo)完ACL系統(tǒng)并使用令牌配置Consul代理后,用戶還需要?jiǎng)?chuàng)建令牌來完成數(shù)據(jù)中心內(nèi)的所有其他任務(wù)拙绊,包括注冊(cè)服務(wù)等向图。
在發(fā)現(xiàn)令牌所需的最低權(quán)限之前,先要了解令牌的基本組成部分标沪。規(guī)則(rule)
對(duì)應(yīng)一份特定的權(quán)限榄攀,是令牌的基本單位,不同的規(guī)則組合在一起形成策略(policy)
金句。規(guī)則有兩個(gè)主要部分:資源(resource)
和策略配置(policy disposition)
檩赢,資源是規(guī)則適用的對(duì)象,策略配置表示權(quán)限趴梢。下面的示例適用于任何名為web
的服務(wù)漠畜,策略配置為讀(read)
權(quán)限:
service "web" {
policy = "read"
}
為了發(fā)現(xiàn)特定操作所需的最低權(quán)限,我們給出三條建議:
首先坞靶,關(guān)注環(huán)境中需要保護(hù)的數(shù)據(jù)憔狞,確保敏感數(shù)據(jù)具有特定且受限制的策略,由于可以組合使用策略來創(chuàng)建令牌彰阴,因此通常會(huì)為敏感數(shù)據(jù)創(chuàng)建更多策略瘾敢。敏感數(shù)據(jù)可以是鍵值存儲(chǔ)(key-value store)
中的特定應(yīng)用程序或一組值。
其次,參考Consul文檔中的規(guī)則(rule)
頁(yè)面和API
頁(yè)面簇抵,以了解任何給定操作所需的權(quán)限庆杜。
規(guī)則文檔介紹了所有規(guī)則資源,對(duì)于啟用了ACL的任何運(yùn)行數(shù)據(jù)中心碟摆,以下四種資源類型都是至關(guān)重要的:
規(guī)則 | 描述 |
---|---|
acl |
acl規(guī)則 授予acl權(quán)限晃财,包括創(chuàng)建、更新或查看令牌和策略 |
node典蜕、node_prefix |
node規(guī)則 授予節(jié)點(diǎn)層注冊(cè)的權(quán)限断盛,包括向數(shù)據(jù)中心和目錄添加代理 |
service、service_prefix |
service規(guī)則 授予服務(wù)層注冊(cè)的權(quán)限愉舔,包括向目錄中添加服務(wù) |
operator | 授予數(shù)據(jù)中心操作的權(quán)限钢猛,包括與Raft 進(jìn)行交互 |
在API
頁(yè)面上,每個(gè)端點(diǎn)都有一個(gè)對(duì)應(yīng)包含所需ACL的表轩缤。如下圖所示命迈,節(jié)點(diǎn)健康檢查端點(diǎn)需要對(duì)應(yīng)節(jié)點(diǎn)node
和service
的讀
權(quán)限。
最后火的,在生產(chǎn)中使用令牌之前壶愤,應(yīng)測(cè)試它是否具有正確的權(quán)限,如果使用的令牌缺少權(quán)限卫玖,那么Consul將發(fā)出錯(cuò)誤響應(yīng)公你。
$ consul operator raft list-peers
Error getting peers: Failed to retrieve raft configuration:
Unexpected response code: 403 (rpc error making call: Permission denied)
根據(jù)數(shù)據(jù)的操作和類型,用戶會(huì)看到404
或403
假瞬。
操作示例:排列顯示Consul代理
要查看數(shù)據(jù)中心中的所有Consul代理陕靠,可以使用consul members
命令行指令:
$ consul members
Node Address Status Type Build Protocol DC Segment
server.one 18.220.91.175:8302 alive server 1.6.0 2 dc1 <all>
client.one 18.223.155.113:8302 alive client 1.6.0 2 dc1 <all>
client.two 18.220.91.175:8302 alive client 1.6.0 2 dc1 <all>
client.three 18.223.155.113:8302 alive client 1.6.0 2 dc1 <all>
為了使此命令可以成功執(zhí)行,用戶至少需要為數(shù)據(jù)中心的每個(gè)代理配置讀權(quán)限脱茉。根據(jù)用戶對(duì)應(yīng)的威脅模型(threat model)
剪芥,可以配置以下任一策略。
如果用戶的生產(chǎn)環(huán)境是動(dòng)態(tài)的琴许,并且規(guī)模很大税肪,則可能需要考慮創(chuàng)建一種適用于所有代理策略,以減少運(yùn)營(yíng)團(tuán)隊(duì)的工作量:
agent_prefix "" {
policy = "read"
}
注意榜田,""
表示此規(guī)則應(yīng)用于數(shù)據(jù)中心中的所有代理益兄,針對(duì)上面的示例,此規(guī)則將適用于server.one
箭券、client.one
净捅、client.two
和client.three
。
如果用戶的生產(chǎn)環(huán)境是靜態(tài)的辩块,并需要最大程度保證安全性蛔六,則需要為每個(gè)代理都創(chuàng)建一個(gè)單獨(dú)的規(guī)則荆永。每次將新代理添加到數(shù)據(jù)中心時(shí),都需要?jiǎng)?chuàng)建一個(gè)新令牌国章。
agent "server.one" {
policy = "read"
}
agent "client.one" {
policy = "read"
}
agent "client.two" {
policy = "read"
}
agent "client.three" {
policy = "read"
}
安全訪問控制:Operator-Only Access
最安全的訪問控制策略是將使用acl="write"
策略的令牌僅授予一到幾個(gè)受信的運(yùn)維人員具钥,擁有acl="write
策略令牌的人操作幾乎不受限,因?yàn)樗麄兛梢允褂闷渌Y源和策略生成令牌液兽,操作人員負(fù)責(zé)創(chuàng)建所有其他策略和令牌骂删,對(duì)數(shù)據(jù)中心進(jìn)行權(quán)限管控,我們稱這種實(shí)現(xiàn)方式為operator-only
實(shí)現(xiàn)抵碟,此實(shí)現(xiàn)類型最復(fù)雜桃漾,也最安全坏匪。
對(duì)于此控制策略拟逮,運(yùn)維人員負(fù)責(zé)管理以下策略和令牌:
-
服務(wù)(service)
和連接(connect proxy)
注冊(cè) -
意向(intention)
管理 -
代理(agent)
管理 -
API
、命令行
和UI
訪問
Operator-Only Access 示例
在下面的示例中适滓,運(yùn)維人員保留服務(wù)令牌管理的責(zé)任敦迄,但將啟用連接(Connect-enabled)的服務(wù)之間的訪問控制委托給安全團(tuán)隊(duì)。
首先凭迹,運(yùn)維人員會(huì)為安全團(tuán)隊(duì)單獨(dú)創(chuàng)建一個(gè)對(duì)intention
管理權(quán)限的令牌罚屋,開發(fā)人員將獲得單獨(dú)的令牌,他們能夠注冊(cè)自己的應(yīng)用程序嗅绸,而無需管理intention
脾猛。安全團(tuán)隊(duì)令牌中策略對(duì)應(yīng)的服務(wù)都必須包含intention
配置策略。
service "wordpress" {
policy = "read"
intentions = "write"
}
這使安全團(tuán)隊(duì)可以創(chuàng)建一個(gè)intention
鱼鸠,使wordpress
服務(wù)可以打開與上游mysql
服務(wù)的新連接:
$ consul intention create wordpress mysql
當(dāng)default_policy
配置為deny
時(shí)猛拴,負(fù)責(zé)管理intention
的安全團(tuán)隊(duì)需要可以創(chuàng)建intention
,因?yàn)槟J(rèn)從ACL配置繼承的權(quán)限為deny all
蚀狰。
在實(shí)現(xiàn)中愉昆,開發(fā)人員負(fù)責(zé)為服務(wù)請(qǐng)求令牌,對(duì)于啟用了連接的服務(wù)麻蹋,運(yùn)維人員需要?jiǎng)?chuàng)建一個(gè)策略跛溉,為該服務(wù)和代理提供寫
權(quán)限,并為所有服務(wù)和節(jié)點(diǎn)提供讀
權(quán)限扮授,以發(fā)現(xiàn)其他上游依賴項(xiàng)芳室。
service "mysql" {
policy = "write"
}
service "mysql-sidecar-proxy" {
policy = "write"
}
service_prefix "" {
policy = "read"
}
node_prefix "" {
policy = "read"
}
有了令牌,開發(fā)人員即可以使用register
命令在Consul中注冊(cè)服務(wù)刹勃。
$ consul services register mysql
上面的示例說明了如何在安全范圍內(nèi)創(chuàng)建策略堪侯。第一個(gè)示例,使用完全匹配資源
規(guī)則是最安全的深夯,它僅授予完成任務(wù)所需的最少權(quán)限抖格,通常诺苹,創(chuàng)建最小權(quán)限的策略和令牌需要定義很多策略,但是這有助于保證最安全的環(huán)境雹拄。相反收奔,前綴規(guī)則可以應(yīng)用于0到多個(gè)對(duì)象。運(yùn)維人員需要權(quán)限操作的復(fù)雜性與系統(tǒng)的安全性滓玖,這不僅適用于代理坪哄,也適用于其他所有規(guī)則。
操作數(shù)據(jù)中心所需的權(quán)限
下表是常見操作所需的最低權(quán)限势篡,創(chuàng)建特定策略時(shí)翩肌,用戶可以使用完全匹配規(guī)則
。
命令行指令 | 所需權(quán)限 |
---|---|
consul reload | agent_prefix "": policy = "write" |
consul monitor | agent_prefix "": policy = "read" |
consul leave | agent_prefix "": policy = "write" |
consul members | node_prefix "": policy = "read" |
consul acl | acl = "write" |
consul catalog services | service_prefix "": policy = "read" |
consul catalog nodes | node_prefix "": policy = "read" |
consul services register | service_prefix "": policy = "write" |
consul services register (Connect proxy) | service_prefix "": policy = "write", node_prefix "": policy = "read" |
consul connect intention | service_prefix "": intention = "write" |
consul kv get | key_prefix "": policy = "read" |
consul kv put | key_prefix "": policy = "write" |
排除ACL系統(tǒng)故障
Consul提供了一套可靠的API禁悠,可用于檢查數(shù)據(jù)中心的運(yùn)行狀況念祭。 在本章節(jié)中,用戶將了解幾個(gè)Consul命令行指令碍侦,可用于排除令牌和策略問題的故障粱坤。 此外,用戶還將了解在緊急情況下瓷产,如何對(duì)ACL系統(tǒng)進(jìn)行重置站玄。
先決條件
本章節(jié)中的內(nèi)容假定現(xiàn)有的數(shù)據(jù)中心運(yùn)行的Consul 1.4或者更高版本,這里還需要確北舻可以正常執(zhí)行Consul命令行指令株旷,可以是Consul代理,或者是遠(yuǎn)程控制數(shù)據(jù)中心的本地二進(jìn)制文件尔邓。
本章節(jié)中的所有命令都需要一個(gè)有效的令牌晾剖,為方便起見,我們建議使用引導(dǎo)令牌铃拇,因?yàn)樗鼪]有權(quán)限限制钞瀑。
Consul Members指令
在使用令牌配置代理時(shí),用戶可以使用consul members
命令來檢查它們是否具有加入數(shù)據(jù)中心所需的權(quán)限慷荔。
如果一個(gè)代理(服務(wù)端或客戶端)沒有在列表中出現(xiàn)雕什,那么該代理上的ACL沒有正確配置,或者令牌沒有正確的權(quán)限显晶,列表中僅顯示有權(quán)限再目錄中注冊(cè)的代理贷岸。
$ consul members
Node Address Status Type Build Protocol DC Segment
server-1 172.17.0.2:8301 alive server 1.4.4 2 dc1 <all>
server-2 172.17.0.3:8301 alive server 1.4.4 2 dc1 <all>
server-3 172.17.0.4:8301 alive server 1.4.4 2 dc1 <all>
對(duì)列出的各個(gè)節(jié)點(diǎn)使用consul acl
命令可幫助解決令牌權(quán)限問題。
Consul Catalog指令
consul catalog nodes -detailed
指令會(huì)顯示節(jié)點(diǎn)的詳細(xì)信息磷雇,其中包括標(biāo)記地址(TaggedAddresse)
偿警,如果任一代理的標(biāo)記地址為空,則該代理的ACL配置不正確唯笙。用戶可以通過查看所有服務(wù)器上的Consul日志來進(jìn)行調(diào)試螟蒸,如果正確啟用了ACL盒使,則可以關(guān)注代理的令牌。
$ consul catalog nodes -detailed
Node ID Address DC TaggedAddresses
server-1 a82c7db3-fdc3 192.168.1.191 kc lan=192.168.1.191, wan=192.168.1.190
server-2 a82c7db3-fdc3 192.168.1.192 kc lan=192.168.1.192, wan=192.168.1.190
server-3 a82c7db3-fdc3 192.168.1.193 kc lan=192.168.1.193, wan=192.168.1.190
對(duì)列出的各個(gè)節(jié)點(diǎn)使用consul acl
命令可幫助解決令牌權(quán)限問題七嫌。
Consul ACL指令
一旦確認(rèn)問題不是由于配置錯(cuò)誤引起的少办,就可以使用以下命令來幫助解決令牌或策略問題。
Consul ACL Policy List 指令
consul acl policy list
命令將輸出所有可用策略诵原。 用戶首次設(shè)置令牌時(shí)英妓,應(yīng)使用執(zhí)行此命令來確保策略列表及其規(guī)則符合預(yù)期。 在下面的示例中有兩個(gè)策略绍赛; Consul創(chuàng)建的全局管理(global-management)
策略蔓纠,用戶創(chuàng)建的名為server-one-policy
的策略。
$ consul acl policy list
global-management:
ID: 00000000-0000-0000-0000-000000000001
Description: Builtin Policy that grants unlimited access
Datacenters:
server-one-policy:
ID: 0bcee22c-6602-9dd6-b147-964958069426
Description: policy for server one
Datacenters:
用戶可以使用consul acl policy read -id <policy_id>
指令來關(guān)注單個(gè)策略吗蚌,在下面的示例中腿倚,server-one-policy
策略有節(jié)點(diǎn)consul-server-one
的寫權(quán)限。
$ consul acl policy read -id 0bcee22c-6602-9dd6-b147-964958069426
ID: 0bcee22c-6602-9dd6-b147-964958069426
Name: server-one-policy
Description: policy for server one
Datacenters:
Rules:
node "consul-server-one" {
policy = "write"
}
Consul ACL Token List指令
consul acl token list
命令將列出所有令牌褪测,應(yīng)確保此列表僅包含正在使用的令牌猴誊,這對(duì)確保數(shù)據(jù)中心的安全性非常重要,應(yīng)該經(jīng)常檢查它。由于令牌不會(huì)過期雷酪,因此運(yùn)維人員應(yīng)當(dāng)刪除
未使用的令牌思瘟。
在下面的示例中,有三個(gè)令牌:第一個(gè)令牌是Consul在引導(dǎo)過程中創(chuàng)建的罚攀,通常稱為引導(dǎo)令牌;第二個(gè)令牌是用戶生成的,并且是通過server-one-policy
策略創(chuàng)建的畏吓;第三個(gè)令牌也由Consul創(chuàng)建,但它沒有任何權(quán)限卫漫。
$ consul acl token list
AccessorID: cf827c04-fb7d-ea75-da64-84e1dd2d5dfe
Description: Master Token
Local: false
Create Time: 2019-05-20 11:08:27.253096 -0500 CDT
Legacy: false
Policies:
00000000-0000-0000-0000-000000000001 - global-management
AccessorID: 5d3c3a03-e627-a749-444c-2984101190c0
Description: token for server one
Local: false
Create Time: 2019-10-17 11:46:27.106158 -0500 CDT
Legacy: false
Policies:
0bcee22c-6602-9dd6-b147-964958069426 - server-one-policy
AccessorID: 00000000-0000-0000-0000-000000000002
Description: Anonymous Token
Local: false
Create Time: 2019-05-20 11:08:27.253959 -0500 CDT
Legacy: false
consul acl token read -id <token_id>
命令用來提供指定令牌的信息菲饼,應(yīng)確保令牌的權(quán)限是符合預(yù)期的,在下面的示例中列赎,返回信息與consul acl token list
命令相似:
$ consul acl token read -id 5d3c3a03-e627-a749-444c-2984101190c0
AccessorID: 5d3c3a03-e627-a749-444c-2984101190c0
SecretID: 547a969c-5dff-f9a8-6b84-fb1d23f9a5cb
Description: token for server one
Local: false
Create Time: 2019-10-17 11:46:27.106158 -0500 CDT
Policies:
0bcee22c-6602-9dd6-b147-964958069426 - server-one-policy
當(dāng)使用consul catalog
指令或consul members
指令返回意外結(jié)果時(shí)宏悦,先使用consul acl token read
指令。
重置ACL系統(tǒng)
如果遇到無法解決的問題包吝,或者引導(dǎo)令牌放錯(cuò)了位置饼煞,用戶可以通過更新索引來重置ACL系統(tǒng)。 首先诗越,通過crul
任何節(jié)點(diǎn)上的/v1/status/leader
端點(diǎn)來找到領(lǐng)導(dǎo)者砖瞧,ACL重置操作必須在領(lǐng)導(dǎo)者機(jī)器上運(yùn)行。
$ curl 172.17.0.1:8500/v1/status/leader
"172.17.0.3:8300"%
在此示例中嚷狞,領(lǐng)導(dǎo)者的IP地址為172.17.0.3
块促,我們?cè)谠摲?wù)器執(zhí)行如下命令荣堰,重新運(yùn)行bootstrap
命令獲取索引號(hào):
$ consul acl bootstrap
Failed ACL bootstrapping: Unexpected response code: 403 (Permission denied: ACL bootstrap no longer allowed (reset index: 13))
將重置索引寫入重置文件,此處重置索引為13
:
$ echo 13 >> <data-directory>/acl-bootstrap-reset
重置ACL系統(tǒng)后竭翠,用戶可以重新創(chuàng)建引導(dǎo)令牌持隧。
DNS緩存
DNS
是Consul的主要接口之一,使用DNS可以將Consul集成到現(xiàn)有基礎(chǔ)架構(gòu)之中逃片,而無需進(jìn)行任何高度集成(high-touch integration)
屡拨。
默認(rèn)情況下,Consul返回DNS結(jié)果褥实,TTL
值為0呀狼,這樣可以防止任何緩存。這樣做的好處是损离,每次查詢DNS都會(huì)重新計(jì)算哥艇,因此可以得到最及時(shí)的信息;但是僻澎,這增加了每次查詢的延遲貌踏,并可能耗盡群集的查詢吞吐量。Consul提供了許多可調(diào)參數(shù)窟勃,用來自定義DNS查詢的處理方式祖乳。
在本章節(jié)中,我們將討論一些參數(shù)秉氧,用于調(diào)整非及時(shí)讀染炖ァ(stale reads)
,負(fù)響應(yīng)緩存(negative response caching)
和TTL值
汁咏,所有DNS配置都必須在代理的配置文件集合中設(shè)置亚斋。
非及時(shí)讀取(stale reads)
非及時(shí)讀取
可用于減少延遲并增加DNS查詢的吞吐攘滩,用于控制DNS查詢非及時(shí)讀取的設(shè)置為:
- dns_config.allow_statle:設(shè)置為
true
帅刊,激活非及時(shí)讀取漂问; - dns_config.max_statle:過時(shí)數(shù)據(jù)的最大時(shí)間赖瞒。
通過這兩個(gè)設(shè)置,用戶可以啟用或禁止非及時(shí)讀取
级解,下面我們將討論兩者的優(yōu)缺點(diǎn)冒黑。
允許非及時(shí)讀取
從Consul0.7.1
開始,allow_stale
參數(shù)默認(rèn)情況下處于啟用狀態(tài)勤哗,max_stale
默認(rèn)閾值為大致10年抡爹,使用這種配置,即使Consul集群長(zhǎng)期沒有領(lǐng)導(dǎo)者芒划,也可以繼續(xù)提供DNS查詢服務(wù)冬竟。
{
"dns_config": {
"allow_stale": true,
"max_stale": "87600h"
}
}
注意欧穴,上述的示例是默認(rèn)配置,用戶無需顯式配置它泵殴。
啟用非及時(shí)讀取
機(jī)制時(shí)涮帘,所有Consul服務(wù)都可以提供查詢服務(wù),只是非領(lǐng)導(dǎo)節(jié)點(diǎn)的返回值可能是過期數(shù)據(jù)笑诅。如果對(duì)數(shù)據(jù)的及時(shí)性有足夠容忍度调缨,用戶就可以水平擴(kuò)展伸縮性,所有Consul服務(wù)器都能處理請(qǐng)求吆你,增加Consul集群的服務(wù)器數(shù)量即能提高吞吐量弦叶。
防止非及時(shí)讀取
如果用戶想要讀取及時(shí)數(shù)據(jù),或者限制數(shù)據(jù)的過期時(shí)間妇多,可以將allow_stale
設(shè)置為false
伤哺,或者將max_stale
閾值調(diào)低。當(dāng)把allow_stale
設(shè)置為false
時(shí)者祖,所有的讀取服務(wù)都由單個(gè)領(lǐng)導(dǎo)者節(jié)點(diǎn)提供立莉,讀取服務(wù)的結(jié)果將保持高度一致,但是會(huì)受到單個(gè)節(jié)點(diǎn)吞吐量的限制七问。
{
"dns_config": {
"allow_stale": false
}
}
負(fù)響應(yīng)緩存(negative response caching)
一些DNS客戶端會(huì)緩存負(fù)響應(yīng)(negative responses)
結(jié)果蜓耻,即有些服務(wù)本身是存在,但是沒有健康檢查端點(diǎn)烂瘫,Consul返回了not found
樣式媒熊,這樣會(huì)導(dǎo)致服務(wù)長(zhǎng)時(shí)間不可用,類似宕機(jī)狀態(tài)坟比。
配置SOA
在Consul1.3.0
及更高的版本中,用戶可以調(diào)整SOA響應(yīng)
配置來修改分析器的負(fù)TTL緩存嚷往,具體的配置為soa.min_ttl
屬性:
{
"dns_config": {
"soa": {
"min_ttl": 60
}
}
}
一個(gè)常見的示例是Windows將負(fù)響應(yīng)緩存時(shí)間默認(rèn)設(shè)為15分鐘葛账,DNS轉(zhuǎn)發(fā)器(DNS forwarders)
也會(huì)緩存負(fù)響應(yīng),效果相同皮仁。為了避免上述問題的發(fā)生籍琳,用戶需要檢查客戶端與Consul通路上任何操作系統(tǒng)和DNS轉(zhuǎn)發(fā)器的默認(rèn)緩存值,并適當(dāng)修改贷祈、通常情況下趋急,簡(jiǎn)單的做法就是在服務(wù)恢復(fù)可用前,先關(guān)閉負(fù)響應(yīng)緩存配置势誊。
TTL值
用戶可以設(shè)置TTL
值將DNS結(jié)果緩存在Consul下游呜达,較高的TTL值會(huì)減少查詢Consul服務(wù)的次數(shù),并加速客戶端查詢速度粟耻,但結(jié)果會(huì)越來越陳舊查近。默認(rèn)情況下眉踱,TTL設(shè)置為0,不會(huì)有任何緩存霜威。
{
"dns_config": {
"service_ttl": {
"*": "0s"
},
"node_ttl": "0s"
}
}
啟用緩存
為了啟用查詢節(jié)點(diǎn)的緩存(例如foo.node.consul
)谈喳,我們可以設(shè)置dns_config.node_ttl
,當(dāng)設(shè)置為10s
時(shí)戈泼,所有節(jié)點(diǎn)提供10秒TTL緩存時(shí)間婿禽。
用戶還可以以更細(xì)的粒度指定服務(wù)的TTL時(shí)間。默認(rèn)情況下大猛,用戶可以使用通配符TTL
扭倾,為所有服務(wù)設(shè)置TTL;前綴匹配的優(yōu)先級(jí)低于嚴(yán)格匹配胎署,例如my-service-x
優(yōu)先級(jí)高于my-service- *
吆录。執(zhí)行通配符匹配時(shí),會(huì)優(yōu)先匹配最長(zhǎng)路徑琼牧,my-service- *
優(yōu)先級(jí)高于my-*
和*
恢筝,*
為默認(rèn)的匹配值,如果找不到任何匹配項(xiàng)巨坊,那么TTL值為0撬槽。
TTL配置大致如下所示:
{
"dns_config": {
"service_ttl": {
"*": "5s",
"web": "30s",
"db*": "10s",
"db-master": "3s"
}
}
}
預(yù)查詢
預(yù)查詢(prepared queries)
提供了對(duì)TTL的額外控制,它們可以與查詢語句一起定義TTL趾撵,在更新查詢定義時(shí)可以及時(shí)更改侄柔。如果預(yù)查詢未配置TTL,則會(huì)使用TTL特定配置占调,如果未配置任何TTL暂题,則TTL默認(rèn)值為0。
轉(zhuǎn)發(fā)DNS
默認(rèn)情況下究珊,系統(tǒng)通過53端口
提供DNS服務(wù)薪者,大多數(shù)操作系統(tǒng)都需要提升權(quán)限。我們可以使用DNS服務(wù)器或端口重定向?qū)⒉樵冋?qǐng)求轉(zhuǎn)發(fā)到非特權(quán)端口上運(yùn)行的Consul剿涮,而不是使用root賬戶運(yùn)行Consul言津。
在本章節(jié)中,我們將從以下幾個(gè)方面演示轉(zhuǎn)發(fā):
- BIND
- dnsmasq
- Unbound
- systemd-resolved
- iptables
- maxOS
配置轉(zhuǎn)發(fā)后取试,我們將演示如何測(cè)試配置悬槽,最后我們還將提供一些故障指南。
BIND 設(shè)置
注意瞬浓,在此示例中初婆,BIND
和Consul運(yùn)行在同一臺(tái)計(jì)算機(jī)上,首先用戶必須禁用DNSSEC
,這樣Consul和BIND
可以互相通信烟逊,配置示例如下:
options {
listen-on port 53 { 127.0.0.1; };
listen-on-v6 port 53 { ::1; };
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
memstatistics-file "/var/named/data/named_mem_stats.txt";
allow-query { localhost; };
recursion yes;
dnssec-enable no;
dnssec-validation no;
/* Path to ISC DLV key */
bindkeys-file "/etc/named.iscdlv.key";
managed-keys-directory "/var/named/dynamic";
};
include "/etc/named/consul.conf";
區(qū)域(Zone)文件
然后在consul.conf
文件中為Consul管理記錄(managed records)
配置一個(gè)區(qū)域(zone)
:
zone "consul" IN {
type forward;
forward only;
forwarders { 127.0.0.1 port 8600; };
};
這里我們假設(shè)Consul使用默認(rèn)配置運(yùn)行渣窜,并在8600端口
提供DNS服務(wù)。
Dnsmasq 設(shè)置
Dnsmasq
通常通過dnsmasq.conf
或/etc/dnsmasq.d
目錄中的一系列配置文件來配置:
# Enable forward lookup of the 'consul' domain:
server=/consul/127.0.0.1#8600
# Uncomment and modify as appropriate to enable reverse DNS lookups for
# common netblocks found in RFC 1918, 5735, and 6598:
#rev-server=0.0.0.0/8,127.0.0.1#8600
#rev-server=10.0.0.0/8,127.0.0.1#8600
#rev-server=100.64.0.0/10,127.0.0.1#8600
#rev-server=127.0.0.1/8,127.0.0.1#8600
#rev-server=169.254.0.0/16,127.0.0.1#8600
#rev-server=172.16.0.0/12,127.0.0.1#8600
#rev-server=192.168.0.0/16,127.0.0.1#8600
#rev-server=224.0.0.0/4,127.0.0.1#8600
#rev-server=240.0.0.0/4,127.0.0.1#8600
創(chuàng)建完配置后宪躯,重新啟動(dòng)dnsmasq
服務(wù)乔宿,dnsmasq
中還有一些重要配置:
# Accept DNS queries only from hosts whose address is on a local subnet.
#local-service
# Don't poll /etc/resolv.conf for changes.
#no-poll
# Don't read /etc/resolv.conf. Get upstream servers only from the command
# line or the dnsmasq configuration file (see the "server" directive below).
#no-resolv
# Specify IP address(es) of other DNS servers for queries not handled
# directly by consul. There is normally one 'server' entry set for every
# 'nameserver' parameter found in '/etc/resolv.conf'. See dnsmasq(8)'s
# 'server' configuration option for details.
#server=1.2.3.4
#server=208.67.222.222
#server=8.8.8.8
# Set the size of dnsmasq's cache. The default is 150 names. Setting the
# cache size to zero disables caching.
#cache-size=65536
Unbound 設(shè)置
我們通常通過unbound.conf
或/etc/unbound/unbound.conf.d
目錄中一系列文件來配置Unbound
:
#Allow insecure queries to local resolvers
server:
do-not-query-localhost: no
domain-insecure: "consul"
#Add consul as a stub-zone
stub-zone:
name: "consul"
stub-addr: 127.0.0.1@8600
用戶必須在/etc/unbound/unbound.conf
文件底部添加以下內(nèi)容,才能包含新配置:
include: "/etc/unbound/unbound.conf.d/*.conf"
systemd-resolved 設(shè)置
systemd-resolved
通常使用/etc/systemd/resolved.conf
配置访雪,在resolved.conf
文件中添加以下內(nèi)容:
DNS=127.0.0.1
Domains=~consul
這個(gè)配置的主要限制是DNS字段不能包含端口详瑞,要使此功能生效,必須將Consul配置為監(jiān)聽53端口臣缀,而不是8600端口坝橡,或者可以使用iptables
命令將53端口映射到8600,指令如下:
[root@localhost ~]# iptables -t nat -A OUTPUT -d localhost -p udp -m udp --dport 53 -j REDIRECT --to-ports 8600
[root@localhost ~]# iptables -t nat -A OUTPUT -d localhost -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 8600
綁定53端口需要以特權(quán)用戶身份運(yùn)行精置,如果用戶使用Consul docker鏡像计寇,則需要在環(huán)境變量中增加CONSUL_ALLOW_PRIVILEGED_PORTS=yes
,允許Consul使用端口脂倦。
iptables設(shè)置
設(shè)置iptables
時(shí)番宁,iptables
規(guī)則必須與Consul實(shí)例設(shè)置在同一主機(jī)上,中繼機(jī)(relay hosts)
不應(yīng)位于同一主機(jī)上赖阻,否則重定向會(huì)攔截流量蝶押。
在支持配置iptables
的Linux系統(tǒng)上,傳入的請(qǐng)求和對(duì)本地主機(jī)的請(qǐng)求可以使用iptables
轉(zhuǎn)發(fā)到同一臺(tái)主機(jī)上的其他端口火欧,而無需其他輔助服務(wù)棋电。由于Consul默認(rèn)情況下僅解析.consul TLD
,因此苇侵,如果希望iptables
還能解析其他域名赶盔,如何使用recursors
選項(xiàng)尤為重要。recursors
不應(yīng)包含local host
榆浓,否則重定向只會(huì)攔截該請(qǐng)求招刨。
iptables
方法適用于以下場(chǎng)景,在系統(tǒng)中已經(jīng)有外部的DNS服務(wù)當(dāng)做recursor
使用或者將現(xiàn)有的DNS服務(wù)當(dāng)做查詢端點(diǎn)哀军,將consul域名下的請(qǐng)求轉(zhuǎn)發(fā)到Consul服務(wù)器。在這兩種情況下打却,用戶需要在不增加Consul主機(jī)開銷的情況下杉适,查詢Consul服務(wù)。
[root@localhost ~]# iptables -t nat -A PREROUTING -p udp -m udp --dport 53 -j REDIRECT --to-ports 8600
[root@localhost ~]# iptables -t nat -A PREROUTING -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 8600
[root@localhost ~]# iptables -t nat -A OUTPUT -d localhost -p udp -m udp --dport 53 -j REDIRECT --to-ports 8600
[root@localhost ~]# iptables -t nat -A OUTPUT -d localhost -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 8600
macOS 設(shè)置
在macOS系統(tǒng)上柳击,用戶可以使用macOS系統(tǒng)解析器將所有.consul請(qǐng)求指向Consul猿推。用戶只需在/etc/resolver/
中添加一個(gè)解析器條目指向Consul。該功能的文檔可通過man5 resolver
命令獲得。創(chuàng)建一個(gè)新文件/etc/resolver/consul
(用戶需要使用sudo /root
權(quán)限)蹬叭,并將下述內(nèi)容寫入文件:
nameserver 127.0.0.1
port 8600
這告訴macOS解析程序所有的.consul TLD
請(qǐng)求都轉(zhuǎn)發(fā)到127.0.0.1
的8600
端口藕咏。
測(cè)試
首先對(duì)Consul執(zhí)行DNS查詢,確保記錄存在:
[root@localhost ~]# dig @localhost -p 8600 primary.redis.service.dc-1.consul. A
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.23.rc1.32.amzn1 <<>> @localhost primary.redis.service.dc-1.consul. A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11536
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;primary.redis.service.dc-1.consul. IN A
;; ANSWER SECTION:
primary.redis.service.dc-1.consul. 0 IN A 172.31.3.234
;; Query time: 4 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Apr 9 17:36:12 2014
;; MSG SIZE rcvd: 76
然后對(duì)BIND
實(shí)例執(zhí)行相同的查詢秽五,確保獲得相同的結(jié)果:
[root@localhost ~]# dig @localhost -p 53 primary.redis.service.dc-1.consul. A
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.23.rc1.32.amzn1 <<>> @localhost primary.redis.service.dc-1.consul. A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11536
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;primary.redis.service.dc-1.consul. IN A
;; ANSWER SECTION:
primary.redis.service.dc-1.consul. 0 IN A 172.31.3.234
;; Query time: 4 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Apr 9 17:36:12 2014
;; MSG SIZE rcvd: 76
如果需要的話孽查,使用相同的方法驗(yàn)證反向DNS(reverse DNS)
:
[root@localhost ~]# dig @127.0.0.1 -p 8600 133.139.16.172.in-addr.arpa. PTR
; <<>> DiG 9.10.3-P3 <<>> @127.0.0.1 -p 8600 133.139.16.172.in-addr.arpa. PTR
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3713
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;133.139.16.172.in-addr.arpa. IN PTR
;; ANSWER SECTION:
133.139.16.172.in-addr.arpa. 0 IN PTR consul1.node.dc1.consul.
;; Query time: 3 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Sun Jan 31 04:25:39 UTC 2016
;; MSG SIZE rcvd: 109
[root@localhost ~]# dig @127.0.0.1 +short -x 172.16.139.133
consul1.node.dc1.consul.
故障排除
如果用戶沒從DNS服務(wù)器(如BIND
,Dnsmasq
)處獲得答案坦喘,那么也可以從Consul處獲得答案盲再,但最好的選擇還是打開DNS服務(wù)器的查詢?nèi)罩玖私庠斍椋瑢?duì)于BIND
:
[root@localhost ~]# rndc querylog
[root@localhost ~]# tail -f /var/log/messages
日志可能會(huì)顯示如下錯(cuò)誤:
error (no valid RRSIG) resolving
error (no valid DS) resolving
這表示沒有正確禁用DNSSEC
.
如果看到有關(guān)網(wǎng)絡(luò)連接的錯(cuò)誤瓣铣,可以驗(yàn)證運(yùn)行BIND
和Consul
的服務(wù)器之間是否有防火墻
或路由
問題答朋。
對(duì)于Dnsmasq
,需要日志查詢配置項(xiàng)和USR1
信號(hào)棠笑。