Home > Erlang探索 > Erlang如何限制节点对集群的访问之net_kernel:allow

Erlang如何限制节点对集群的访问之net_kernel:allow

October 24th, 2011

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: Erlang如何限制节点对集群的访问之net_kernel:allow

默认情况下Erlang的集群访问是全授权的,只要cookie认证过了后,新加入的节点可以访问集群里面的任何机器,这给运维带来很大风险。目前erlang有二种方法可以限制 1. IP网段限制,参看这里 2. 节点名称限制。这个是通过net_kernel:allow来实现的,参看:

allow/1
Limits access to the specified set of nodes. Any access attempts made from (or to) nodes not in Nodes will be rejected.

Returns error if any element in Nodes is not an atom.

我们假设集群有节点x,y,z, foo:
1. 有个节点叫foo, 它只允许来自x,y节点的请求,其他的节点访问被拒;
2. z只能访问x,其他拒

我们来试验下:

$ erl -name foo@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)
(foo@127.0.0.1)1> net_kernel:allow(['x@127.0.0.1', 'y@127.0.0.1']).
ok
(foo@127.0.0.1)2> 

在其他终端运行:

$ erl -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> net_adm:ping('foo@127.0.0.1').
pong
(x@127.0.0.1)2> 

$ erl -name y@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)
(y@127.0.0.1)1> net_adm:ping('foo@127.0.0.1').
pong
(y@127.0.0.1)2> 

$ erl -name z@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)
(z@127.0.0.1)1> net_adm:ping('foo@127.0.0.1').
pang
(z@127.0.0.1)2> net_adm:ping('y@127.0.0.1').
pong
(z@127.0.0.1)3> net_kernel:disconnect('y@127.0.0.1').
true
(z@127.0.0.1)4> net_kernel:allow(['x@127.0.0.1']).
ok
(z@127.0.0.1)5> net_adm:ping('y@127.0.0.1').         

=ERROR REPORT==== 24-Oct-2011::01:23:34 ===
** Connection attempt with disallowed node 'y@127.0.0.1' ** 
pang

同时我们会在foo的终端上看到:

=ERROR REPORT==== 24-Oct-2011::01:08:20 ===
** Connection attempt from disallowed node 'z@127.0.0.1' ** 
(foo@127.0.0.1)2>

看代码:

...
%% dist_util.erl
%%                                                                                                                           
%% check if connecting node is allowed to connect                                                                            
%% with allow-node-scheme                                                                                                    
%%                                                                                                                           
is_allowed(#hs_data{other_node = Node,
                    allowed = Allowed} = HSData) ->
    case lists:member(Node, Allowed) of
        false when Allowed =/= [] ->
            send_status(HSData, not_allowed),
            error_msg("** Connection attempt from "
                      "disallowed node ~w ** ~n", [Node]),
            ?shutdown(Node);
        _ -> true
    end.
...

可以知道如果Allowed空的话,代表不做任何限制,否则net_kernel:allow限制主动和被动连接的节点。

祝玩得开心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索 Tags:
  1. 宋枭
    March 7th, 2014 at 15:27 | #1

    mac的节点 怎么一直都不能连接上ubuntu ,试了各种方法,霸爷求教

    Yu Feng Reply:

    cookie一样吗,otp版本一样吗,网络联通吗,epmd端口通吗?可以wireshark抓包看看

    宋枭 Reply:

    都一样的,第二天一试却能联通了,可以没有保留现场,未能查出原因

  2. wind
    October 9th, 2014 at 10:43 | #2

    我先在节点z上面调用 net_kernel:allow([‘x@127.0.0.1’]),
    之后,y,foo都连不上z了。
    现在我再把z上面调用net_kernel:allow([]),
    为什么y和foo还是不能联上z呢?

    Yu Feng Reply:

    你可以用wireshark抓包确认下。

    suexcxine Reply:

    net_kernel:allow是追加列表,没有办法清空,见代码
    参考net_kernel.erl代码
    handle_call({allow, Nodes}, From, State) ->
    case all_atoms(Nodes) of
    true ->
    Allowed = State#state.allowed,
    async_reply({reply,ok,State#state{allowed = Allowed ++ Nodes}},
    From);
    false ->
    async_reply({reply,error,State}, From)
    end;

Comments are closed.