Erlang集群未公开特性:IP网段限制
Erlang集群二个节点之间的通讯是通过一个tcp长连接进行的,而且是全联通的,一旦cookie论证通过了,任何一个节点就获得全集群的访问权,可以参考Erlang分布的核心技术浅析
。erlang的这个授权模式特定搞的这么简单,但是在实际使用中还是有安全性的问题。我们退而求其次,来个IP网段限制,这个功能Erlang是有的只是没有文档化。
我们来看下代码:
inet_tcp_dist.erl:L157
do_accept( Kernel , AcceptPid , Socket , MyNode , Allowed , SetupTime ) -> |
{ AcceptPid , controller} -> |
Timer = dist_util:start_timer ( SetupTime ), |
dist_util:handshake_other_started ( HSData ); |
error_msg( "** Connection attempt from " |
"disallowed IP ~w ** ~n" , [ IP ]), |
case application:get_env (check_ip) of |
case inet:peername ( Socket ) of |
case inet:getif ( Socket ) of |
{ok, IFs } -> {ok, IFs , IP }; |
check_ip([{ OwnIP , _, Netmask }| IFs ], PeerIP ) -> |
case {mask( Netmask , PeerIP ), mask( Netmask , OwnIP )} of |
_ -> check_ip( IFs , PeerIP ) |
mask({ M1 , M2 , M3 , M4 }, { IP1 , IP2 , IP3 , IP4 }) -> |
这个功能可以用-kernel check_ip true打开。
接着我们来实验下,在其中一个终端开:
$ erl -kernel check_ip true -name x@127.0.0.1 |
Erlang R14B04 (erts-5.8.5) [ source ] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll: false ] |
Eshell V5.8.5 (abort with ^G) |
(x@127.0.0.1)1> dbg:tracer(). |
(x@127.0.0.1)2> dbg:p(all,c). |
{ok,[{matched, 'x@127.0.0.1' ,32}]} |
(x@127.0.0.1)3> dbg:tpl(inet_tcp_dist,check_ip, [{ '_' , [], [{return_trace}]}]). |
{ok,[{matched, 'x@127.0.0.1' ,2},{saved,1}]} |
(x@127.0.0.1)4> dbg:tpl(inet_tcp_dist,check_ip, [{ '_' , [], [{return_trace}]}])(<0.44.0>) call inet_tcp_dist:check_ip( |
(<0.44.0>) call inet_tcp_dist:check_ip([{{172,16,64,1},{172,16,64,255},{255,255,255,0}}, |
{{172,16,213,1},{172,16,213,255},{255,255,255,0}}, |
{{192,168,1,3},{192,168,1,255},{255,255,255,0}}, |
{{127,0,0,1},undefined,{255,0,0,0}}],{127,0,0,1}) |
(<0.44.0>) call inet_tcp_dist:check_ip([{{172,16,213,1},{172,16,213,255},{255,255,255,0}}, |
{{192,168,1,3},{192,168,1,255},{255,255,255,0}}, |
{{127,0,0,1},undefined,{255,0,0,0}}],{127,0,0,1}) |
(<0.44.0>) call inet_tcp_dist:check_ip([{{192,168,1,3},{192,168,1,255},{255,255,255,0}}, |
{{127,0,0,1},undefined,{255,0,0,0}}],{127,0,0,1}) |
(<0.44.0>) call inet_tcp_dist:check_ip([{{127,0,0,1},undefined,{255,0,0,0}}],{127,0,0,1}) |
(<0.44.0>) returned from inet_tcp_dist:check_ip/2 -> true |
(<0.44.0>) returned from inet_tcp_dist:check_ip/2 -> true |
(<0.44.0>) returned from inet_tcp_dist:check_ip/2 -> true |
(<0.44.0>) returned from inet_tcp_dist:check_ip/2 -> true |
(<0.44.0>) returned from inet_tcp_dist:check_ip/1 -> true |
在另外一个终端开:
Erlang R14B04 (erts-5.8.5) [ source ] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll: false ] |
Eshell V5.8.5 (abort with ^G) |
(y@127.0.0.1)1> net_adm: ping ( 'x@127.0.0.1' ). |
通过跟踪我们确诊这个功能被打开了,而且在作用。如果没通过IP限制,SASL下会得到如下提示:
** Connection attempt from disallowed IP ~w **。
祝大家玩得开心,集群得安全!
Recent Comments