自 2010 年末首次發布,OpenStack 已經成為了使用最為廣泛的 Infrastructure as a Service (IaaS)云平臺之一。OpenStack 是一個不斷成長的開源解決方案套件,由核心項目和孵化項目組成。各個項目之間是松耦合的關系,通過 Message Queue 和 REST API 進行通訊。考慮到性能等問題,OpenStack 官方默認的配置都是非加密的。在一些企業級的應用中,用戶對通訊的加密非常看重。本文簡單介紹如何通過配置,使 OpenStack 的 REST API 通訊以 SSL 加密方式進行。
開始之前
環境準備
一個 RHEL 6.5 的 Linux 操作系統運行在 RHEL6.5 之上的 OpenStack Icehouse 版本文中術語說明
REST:含狀態傳輸(英文:Representational State Transfer,簡稱REST),是目前主流的 web 服務實現方案之一。它是一種設計風格,以 URI 表示資源,并且支持資源的獲取、創建、修改和刪除。SSL:安全套接層(Secure Sockets Layer,SSL)是一種安全協議,目的是為互聯網通信,提供安全及數據完整性保障。OpenStack 通訊機制概述
本文假設讀者已經對 OpenStack 有了一定的了解,因此對 OpenStack 的發展及使用場景不再贅述。僅對與本文相關的通訊機制部分作一定的說明。
OpenStack 由多個相對獨立的項目組成,每個項目有獨立的代碼,并且能獨立運行。項目與項目之間協同工作,完成了一個基礎架構云平臺。由于各個項目獨立運行,因此,相互之間的通訊顯得格外重要。OpenStack 的各個項目之間,有兩種通訊方式,一種是基于 AMQP(Advanced Message Queuing Protocol )的消息隊列機制;一種是 REST 風格的 HTTP 請求。在空閑時間,各個項目之間相安無事。一旦某個項目發生了變化,首先會通過消息隊列將變化傳遞到相關的項目,之后被通知的項目再通過 HTTP 請求來獲得變化的具體內容。對于 OpenStack 中的某些較大項目,在項目內部又細分成幾個模塊,這幾個模塊之間的通訊可能就是消息隊列和 HTTP 請求并存。
OpenStack 各個項目本身都支持 SSL 加密認證。但是,如果對通訊都進行 SSL 加密,耗時必然會加大。因此,出于性能考慮,OpenStack 的默認配置都沒有使能 SSL。本文將簡要介紹如何將一個默認的 OpenStack 云環境,配置成 REST API 是 SSL 加密的云環境。本文之后部分所描述的 SSL 加密都是針對 OpenStack 各個項目的 REST API,本文之后部分的通訊都是指各個項目之間的 HTTP 請求通訊。
以 SSL 方式配置 Keystone 的 REST API
Keystone(OpenStack Identity Service)在 OpenStack 框架中,負責身份驗證和服務令牌等功能,它實現了 OpenStack 的 Identity API。Keystone 類似一個服務總線,或者說是整個 OpenStack 框架的注冊表, 其他服務通過 Keystone 來注冊其服務的 Endpoint(服務訪問的 URL),任何服務之間相互的調用,首先需要經過 Keystone 的身份驗證,來獲得目標服務的 endpoint 來找到目標服務。有關 Keystone 的更多信息,可以查看 Keystone 的 wiki。
因為 Keystone 會與所有其他的 OpenStack 項目通訊,先配置好 Keystone,可以在配置其他項目時把該項目與 Keystone 的通訊也配置成 SSL 加密方式。反之,如果先配置別的項目,在 Keystone 完成 SSL 配置之后,還需要再在各個項目中將 Keystone 部分的配置修改成 SSL 加密的方式。因此,本文首先對 Keystone 進行配置。
生成自簽名證書
SSL 通訊的核心是基于證書的,Keystone 比較方便的是,能生成一個用于測試的自簽名證書。執行以下命令:
# keystone-manage ssl_setup --keystone-user keystone --keystone-group keystone清單 1. 用 Keystone 命令生成用于測試的自簽名證書
執行完清單 1 的命令后,在/etc/keystone/ssl 路徑下會新增幾個證書文件。為了確保 Keystone 能正常讀取文件,修改文件的用戶組。
清單 2. 修改 Keystone 生成的證書文件所在的用戶組
# chown -R keystone:keystone /etc/keystone/ssl修改 Keystone 的 endpoint
Endpoint 的概念在后面還會多次出現,這里簡單說一下。endpoint,翻譯為“端點”,我們可以理解它是一個 OpenStack 項目暴露出來的訪問點,如果需要訪問一個項目,可以先獲取它的 endpoint,再從 endpoint 進行訪問。OpenStack 中,endpoint 是由 Keystone 進行管理的。這么做是合理的,因為 Keystone 與所有項目都進行通訊。在 Keystone 中包含一個 endpoint 模板,這個模板提供了所有存在的項目 endpoint 信息。一個 endpoint template 包含一個 URLs 列表,列表中的每個 URL 都對應一個項目實例的訪問地址,并且具有 public、internal 和 admin 這三種權限。public url 可以被全局訪問,internal url 只能被局域網訪問,admin url 被從常規的訪問中分離。
由于本文想將 Keystone 配置成 SSL 加密,因此需要讓所有的訪問者知道 Keystone 服務的入口已經改變了,可以通過修改 Keystone 的 endpoint 來實現這一目的。
清單 3. 獲取當前的 Keystone endpoint 列表
#keystone endpoint-list通過讀取 Keystone 的配置文件可以知道它的 public 端口是 5000,internal 和 admin 端口是 35357。通過端口號能從 endpoint list 中找到 Keystone 的 endpoint。由于 Keystone 在 V2 版本不提供修改 endpoint 的接口,在這里可以先創建一個新的 https 的 endpoint,再刪除之前的 endpoint。
清單 4. 創建 Keystone 的 SSL endpoint
# keystone endpoint-create --service keystone --region RegionOne --publicurl https://{keystoneHost}:5000/v2.0 --internalurl https://{keystoneHost}:35357/v2.0 --adminurl https://{keystoneHost}:35357/v2.0清單 4 中的{keystoneHost}是指 Keystone 所在的 host。這里要注意,一定要先添加 HTTPS 的 endpoint,再刪除舊的 HTTP 的 endpoint。否則會由于找不到 Keystone 服務的入口導致后繼的操作將無法進行。
添加完成之后,Keystone 相當于有兩個 endpoint 暴露出來了,在實際中究竟使用哪一個呢?答案是不確定。這就導致在添加完 HTTPS 的 endpoint 之后,Keystone 提供給自己的服務入口可能是 HTTPS 的,也可能是舊的 HTTP 的。在這里可以做個測試,執行清單 3 的命令,如果命令不能返回 endpoint 列表,則說明 Keystone 對外暴露的是 HTTPS 的 endpoint。反之,則說明 Keystone 對外暴露的仍然是舊的 HTTP 的 endpoint,此時,可以刪除該 endpoint,以確保 Keystone 對外暴露的是 HTTPS 的 endpoint。
清單 5. 刪除 Keystone 的 http endpoint
# keystone endpoint-delete {old endpoint id}清單 5 中,{old endpoint id}是通過清單 3 中的指令獲取的舊的 Keystone 的 endpoint 的 id。
此時,由于對外暴露的 Keystone 服務端口已經是 SSL 的,但是其本身還是以非 SSL 方式運行,所以 Keystone 服務已經無法使用了。我們需要將 Keystone 本身也修改成以 SSL 加密認證方式工作。
修改 Keystone 的 SSL 相關配置
由于已經通過清單 1 的命令生成了用于測試的自簽名證書,在本小節需要將其寫入 Keystone 的配置。打開 Keystone 的配置文件,修改如下配置項:
清單 6. 修改 Keystone 的 SSL 相關配置
# vi /etc/keystone/keystone.conf [ssl] enable = True certfile = /etc/keystone/ssl/certs/keystone.pem keyfile = /etc/keystone/ssl/private/keystonekey.pem ca_certs = /etc/keystone/ssl/certs/ca.pem為了使修改的配置生效,重啟 Keystone 服務。
清單 7. 重啟 Keystone 服務
# service openstack-keystone restart至此,Keystone 的 SSL 配置已經完成了,Keystone 對外的接口已經是 SSL 加密認證的,所有訪問的 url 都是 HTTPS 開頭的。為了使之后的命令能執行,需要更新 OpenStack cli 的認證 url。
清單 8. 更新 OpenStack cli 的認證 url
# export OS_AUTH_URL=https://{keystoneHost}:5000/v2.0如果之前沒有做,現在可以刪除之前的舊的 http 的 endpoint。
清單 9. 刪除 Keystone 的非 SSL endpoint
# keystone –-insecure endpoint-delete {old endpoint id}清單 9 中,{old endpoint id}是通過清單 3 中的指令獲取的舊的 Keystone 的 endpoint 的 id。
這里說明一下清單 9 中的參數 --insecure。 OpenStack 的 CLI 命令,實際上都是通過執行 curl 命令調用相應項目的 REST API 來實現。我們之前是用一個自簽名的證書來配置 Keystone 的 SSL 加密認證,這個證書是不被 curl 所認可的。加上 --insecure 參數可以讓 curl 忽略這個證書。另一方面,也可以將這個自簽名證書導入 curl,具體操作見參考資源,這樣就可以省去該參數。如果是通過別的工具,例如 Firefox 來訪問 OpenStack 的 REST API,僅需要在第一次訪問時接受證書,之后就可以正常訪問了。
以 SSL 方式配置 Nova 的 REST API
Nova(OpenStack Compute Service)在 OpenStack 框架中,負責虛機的管理,是整個 Infrastructure as a Service 系統中的最重要部分。有關 Nova 的更多信息,可以查看 Nova 的 wiki。但是在 SSL 配置中,Nova 的地位與其他項目一樣。因此,本文將不會逐個介紹如何對各個項目進行 SSL 配置,僅以 Nova 為例說明。
配置 Nova 以 SSL 加密方式連接 Keystone
前面已經將 Keystone 配置成 SSL 加密認證了。由于 OpenStack 所有的其他項目都需要通過 Keystone 進行用戶認證,而默認的配置,都是以非 SSL 方式連接 Keystone。所以,理論上此時除了 Keystone,OpenStack 的其他項目都已經無法使用了。所以,配置 Nova 的第一步,應將 Nova 中有關 Keystone 的部分修改成 SSL 加密的。
清單 10. 修改 Nova 配置以 SSL 方式連接 Keystone
# vi /etc/nova/API-paste.ini auth_uri = https://10.1.0.92:5000/v2.0 auth_protocol = https insecure = True這里的 insecure = True 與之前說明的 --insecure 參數是一個道理。 修改完之后,重啟 nova-API,以使配置生效。
清單 11. 重啟 nova-API
# service openstack-nova-API restart此時,Nova 已經可以使用了。可以使用以下命令檢驗之。
清單 12. 查看 nova 下所有 hypervisor
# nova --insecure hypervisor-list在檢驗時需要注意,由于 Nova 可能與其他項目也存在交互,例如調用 Nova 的某些命令,可能需要去 Neutron 取數據,而 Neutron 同樣也需要經過 Keystone 認證。但是,在目前的步驟,Neutron 還沒有被配置,所以,Neutron 中有關 Keystone 的配置仍然是非 SSL 的。這個時候 Neutron 的是無法通過 Keystone 認證的,數據也無法獲取,最終會導致 Nova 的相應命令執行失敗。因此,在目前的步驟下,檢驗 Nova 需要用一些只使用 Nova 內部數據的命令,例如清單 12。
生成自簽名證書
Nova 不像 Keystone,提供命令生成用于測試的自簽名證書。我們在這里使用前面 Keystone 的證書。首先將證書拷貝至 Nova 目錄下,然后修改證書所在的用戶組以供 Nova 使用。
清單 13. 將 Keystone 的證書拷貝至 Nova 目錄下
# mkdir /etc/nova/ssl # cp /etc/keystone/ssl/certs/keystone.pem /etc/nova/ssl/ # cp /etc/keystone/ssl/private/keystonekey.pem /etc/nova/ssl/ # chown -R nova:nova /etc/nova/ssl/修改 Nova 的 endpoint
endpoint 的概念之前已經介紹過了,這里直接調用清單 3 中的命令,獲取 endpoint 列表。從 Nova 的配置文件中可以知道它的 public,internal 和 admin 端口是 8774。
清單 14. 創建 Nova 的 SSL endpoint
# keystone --insecure endpoint-create --service nova --region RegionOne --publicurl "https://{novaHost}:8774/v2/%(tenant_id)s" --internalurl "https://{novaHost}:8774/v2/%(tenant_id)s" --adminurl "https://{novaHost}:8774/v2/%(tenant_id)s"創建完成之后,刪除之前的非 SSL endpoint 以避免混淆。相應的命令參見清單 9。此時,由于對外暴露的 Nova 服務端口已經是 SSL 的,但是其本身還是非 SSL 方式運行,所以 Nova 服務又無法使用了。我們需要將 Nova 本身也修改成以 SSL 加密認證方式工作。
修改 Nova 的 SSL 相關配置
直接修改 Nova 的配置文件,
清單 15. 修改 Nova 的 SSL 相關配置
# vi /etc/nova/nova.conf [DEFAULT] enabled_ssl_APIs=osAPI_compute ssl_cert_file=/etc/nova/ssl/keystone.pem ssl_key_file=/etc/nova/ssl/keystonekey.pem修改完配置之后,調用清單 11 的命令重啟 nova-API 以使配置生效。之后用清單 12 中的命令測試結果即可。如果想看具體的調用,可以加上 --debug 參數。可以發現,現在所有的 curl 命令都調用 https 的 url。
總結
OpenStack 在 Icehouse 版本共有 9 個核心項目,若干個孵化項目。隨著 OpenStack 的成長,項目數還會增加。出于性能考慮,OpenStack 所有的項目默認都是以非 SSL 方式工作,需要用戶手動修改配置以使能 SSL。在修改配置上,Keystone 由于其在整個架構中所處的特殊地位,而略有不同。其他的項目,如 Glance、Cinder、Neutron 等,雖然在配置文件中某些屬性可能不同,但是配置過程與 Nova 大致相同。讀者可以嘗試按照 Nova 的配置過程去配置其他的項目。