本節介紹Erlang發行版如何使用TLS來得到額外的驗證和安全性。node
理論上,Erlang發行版可使用幾乎全部基於鏈接的協議做爲承載。可是,須要一個用於實現鏈接設置的協議特定部分的模塊。內核應用程序中的默認分發模塊是inet_tcp_dist。啓動分佈式的Erlang節點時,net_kernel使用此模塊設置偵聽端口和鏈接。shell
在SSL應用程序中,可使用一個額外的分發模塊inet_tls_dist做爲替代。全部分發鏈接將使用TLS,而且分佈式系統中的全部參與的Erlang節點必須使用此分發模塊。安全
安全級別取決於提供給TLS鏈接設置的參數。可是,始終使用Erlang節點cookie,由於它們可用於區分兩個不一樣的Erlang網絡。服務器
要經過TLS設置Erlang分發,請執行如下操做:cookie
如下各節描述了這些步驟。網絡
4.1 構建包括SSL應用程序在內的啓動腳本session
使用SASL應用程序中的systools實用程序來構建引導腳本。 有關systools的更多信息,請參見SASL文檔。 這僅僅是能夠作的一個例子。tcp
最簡單的啓動腳本可能僅包括內核和STDLIB應用程序。 這樣的腳本位於Erlang發行版的bin目錄中。 該腳本的源代碼位於發行版/ <OTP版本> /start_clean.rel下的Erlang安裝目錄下。分佈式
請執行下列操做:函數
下面顯示了添加了TLS的示例.rel文件:
{release, {"OTP APN 181 01","R15A"}, {erts, "5.9"},
[{kernel,"2.15"},
{stdlib,"1.18"},
{crypto, "2.0.3"},
{public_key, "0.12"},
{asn1, "4.0"},
{ssl, "5.0"}
]}.
版本號在您的系統中有所不一樣。 每當腳本中包含的應用程序之一升級時,請更改腳本。
請執行下列操做:
假設.rel文件存儲在當前目錄的文件start_ssl.rel中,則能夠以下構建啓動腳本:
1> systools:make_script("start_ssl",[]).
如今,當前目錄中有一個start_ssl.boot文件。
請執行下列操做:
$ erl -boot /home/me/ssl/start_ssl
Erlang (BEAM) emulator version 5.0
Eshell V5.0 (abort with ^G)
1> whereis(ssl_manager).
<0.41.0>
whereis函數調用驗證SSL應用程序已啓動。
做爲構建引導腳本的替代方法,您能夠在命令行上將路徑顯式添加到SSL ebin目錄。 這是經過命令行選項-pa完成的。 這能夠工做,由於不須要啓動SSL應用程序便可發佈發行版本,由於SSL應用程序的克隆已掛接到內核應用程序中。 所以,只要能夠訪問SSL應用程序代碼,就開始分發。 僅建議將-pa方法用於測試目的。
注意:SSL應用程序的克隆必須容許在創建發行版所需的早期引導階段使用SSL代碼。 可是,這使得沒法軟升級SSL應用程序。
4.2 指定net_kernel的分發模塊
TLS的分發模塊名爲inet_tls_dist,並在命令行上使用選項-proto_dist指定。 -proto_dist的參數是不帶後綴_dist的模塊名稱。 所以,此分發模塊在命令行上經過-proto_dist inet_tls指定。
擴展命令行給出如下內容:
$ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls
對於要開始的分發,還要給仿真器起一個名字:
$ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls -sname ssl_test
Erlang (BEAM) emulator version 5.0 [source]
Eshell V5.0 (abort with ^G)
(ssl_test@myhost)1>
可是,以這種方式啓動的節點拒絕與其餘節點通訊,由於沒有提供TLS參數(請參閱下一節)。
4.3 指定TLS選項
能夠將TLS分發選項寫入啓動節點時要查詢的文件。 而後,使用命令行參數-ssl_dist_optfile指定此文件名。
能夠在選項文件中指定任何可用的TLS選項,但請注意,採用fun()的選項必須使用語法fun Mod:Func/Arity,由於在查閱文件時沒法編譯功能主體。
不要篡改套接字選項列表,二進制文件,活動文件,數據包,nodelay和交付,由於它們由分發協議處理程序自己使用。 其餘原始套接字選項(例如packet_size)可能會嚴重干擾,所以請注意!
爲了使TLS起做用,必須爲服務器端至少指定一個公鑰和一個證書。 在如下示例中,PEM文件「 /home/me/ssl/erlserver.pem」包含服務器證書及其私鑰。
建立一個名爲「 /home/me/ssl/ssl_test@myhost.conf」的文件:
[{server,
[{certfile, "/home/me/ssl/erlserver.pem"},
{secure_renegotiate, true}]},
{client,
[{secure_renegotiate, true}]}].
而後像這樣啓動節點(命令中的換行符是爲了提升可讀性,鍵入時不該出如今換行符中):
$ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls
-ssl_dist_optfile "/home/me/ssl/ssl_test@myhost.conf"
-sname ssl_test
調用ssl:ssl_accept/3時,將使用{server,Opts}元組中的選項,而調用ssl:connect/4時,將使用{client,Opts}元組中的選項。
對於客戶端,在鏈接時會添加選項{server_name_indication,atom_to_list(TargetNode)}。這樣就可使用客戶端選項{verify,verify_peer},客戶端將驗證證書是否與您要鏈接的節點名稱匹配。僅當服務器證書的名稱爲atom_to_list(TargetNode)時,此方法纔有效。
對於服務器,也可使用選項{verify,verify_peer},而且服務器將僅接受具備服務器已知根證書信任的證書的客戶端鏈接。提供不可信證書的客戶將被拒絕。此選項最好與{fail_if_no_peer_cert,true}組合,不然若是客戶端不提供任何證書,則仍將被接受。
使用TLS做爲分發協議,以此方式啓動的節點能夠正常運行。
4.4 指定TLS選項(舊版)
與上一節同樣,PEM文件「 /home/me/ssl/erlserver.pem」包含服務器證書及其私鑰。
在erl命令行上,您能夠指定建立套接字時TLS分發添加的選項。
能夠經過在選項名稱中添加前綴server_或client_來指定如下列表中最簡單的TLS選項:
注意,由於在命令行上不接受funs,因此verify_fun須要以與相應的TLS選項不一樣的形式編寫。
服務器還能夠採用選項dhfile和fail_if_no_peer_cert(也帶有前綴)。
當發行版啓動到另外一個節點的鏈接時,將使用client_-prefixed選項。 接受來自遠程節點的鏈接時,將使用server_前綴選項。
原始套接字選項(例如數據包和大小)不能在命令行上指定。
用於指定TLS選項的命令行參數名爲-ssl_dist_opt,後跟一對SSL選項及其值。 參數-ssl_dist_opt能夠重複任意次。
如今,與上一節中的示例相同的示例命令行以下所示(命令中的換行符是爲了可讀性,鍵入時不該出如今換行符中):
$ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls
-ssl_dist_opt server_certfile "/home/me/ssl/erlserver.pem"
-ssl_dist_opt server_secure_renegotiate true client_secure_renegotiate true
-sname ssl_test
Erlang (BEAM) emulator version 5.0 [source]
Eshell V5.0 (abort with ^G)
(ssl_test@myhost)1>
4.5 設置環境以始終使用TLS(舊版)
指定Erlang參數的簡便方法是使用環境變量ERL_FLAGS。 能夠在該變量中指定使用TLS分發所需的全部標誌,而後將其解釋爲全部後續Erlang調用的命令行參數。
在Unix(Bourne)外殼程序中,它看起來可能以下所示(換行符是爲了提升可讀性,鍵入時不要出現換行符):
$ ERL_FLAGS="-boot /home/me/ssl/start_ssl -proto_dist inet_tls
-ssl_dist_opt server_certfile /home/me/ssl/erlserver.pem
-ssl_dist_opt server_secure_renegotiate true client_secure_renegotiate true"
$ export ERL_FLAGS
$ erl -sname ssl_test
Erlang (BEAM) emulator version 5.0 [source]
Eshell V5.0 (abort with ^G)
(ssl_test@myhost)1> init:get_arguments().
[{root,["/usr/local/erlang"]},
{progname,["erl "]},
{sname,["ssl_test"]},
{boot,["/home/me/ssl/start_ssl"]},
{proto_dist,["inet_tls"]},
{ssl_dist_opt,["server_certfile","/home/me/ssl/erlserver.pem"]},
{ssl_dist_opt,["server_secure_renegotiate","true",
"client_secure_renegotiate","true"]
{home,["/home/me"]}]
init:get_arguments()調用可驗證是否向模擬器提供了正確的參數。
4.6 在IPv6上使用TLS分發
能夠在IPv6而非IPv4上使用TLS分發。 爲此,在命令行或ERL_FLAGS環境變量中啓動Erlang時,傳遞選項-proto_dist inet6_tls而不是-proto_dist inet_tls。
使用此選項的示例命令行以下所示:
$ erl -boot /home/me/ssl/start_ssl -proto_dist inet6_tls
-ssl_dist_optfile "/home/me/ssl/ssl_test@myhost.conf"
-sname ssl_test
以這種方式啓動的節點將只能使用經過IPv6的TLS分發與其餘節點通訊。