Elixir分发安全和白名单允许的节点

时间:2016-01-19 04:23:08

标签: security elixir iptables

TL; DR

  • 如何将Node.connect到Elixir的节点列入白名单?
  • 还有其他任何安全建议吗?

设置

我已经开始修改Elixir(现在)两台不同的服务器。

例如,让我们说服务器的两个IP地址是:

  1. 198.51.100.0
  2. 203.0.113.0
  3. 首先,我向两台服务器上的iptables firewall添加了新规则,打开了端口4369(EPMD)和9000-9010之间的10个端口范围。我也只允许来自其他服务器的确切IP地址的传入连接。

    198.51.100.0的配置示例:

    -A INPUT -p tcp -m state --state NEW --dport 4369 -s 203.0.113.0 -j ACCEPT
    -A INPUT -p tcp -m state --state NEW --dport 9000:9010 -s 203.0.113.0 -j ACCEPT
    

    203.0.113.0的配置示例:

    -A INPUT -p tcp -m state --state NEW --dport 4369 -s 198.51.100.0 -j ACCEPT
    -A INPUT -p tcp -m state --state NEW --dport 9000:9010 -s 198.51.100.0 -j ACCEPT
    

    现在我可以在每台机器上打开iex个shell:

    198.51.100.0:

    $ iex --name one@198.51.100.0 --cookie secret --erl '-kernel inet_dist_listen_min 9000' --erl '-kernel inedist_listen_max 9010'
    

    203.0.113.0:

    $ iex --name two@203.0.113.0 --cookie secret --erl '-kernel inet_dist_listen_min 9000' --erl '-kernel inedist_listen_max 9010'
    

    我可以从节点1成功连接到节点2:

    iex(one@198.51.100.0)> Node.connect(:'two@203.0.113.0')
    true
    

    并列出节点2中的节点:

    iex(two@203.0.113.0)> Node.list
    [:"one@198.51.100.0"]
    

    我的问题:

    我已经读过:net_kernel.allow/1可用于将确切的允许连接列表列入白名单。但我似乎无法让它发挥作用:

    iex(one@198.51.100.0)> :net_kernel.allow([])
    :ok
    iex(one@198.51.100.0)> Node.connect(:'two@203.0.113.0')
    true
    

    我希望由于我已经允许列表中没有,因此不允许任何连接。有什么提示吗?

    更新

    我发现如果我将至少一个值传递给:net_kernel.allow,它似乎有效:

    iex(one@198.51.100.0)> :net_kernel.allow([:'127.0.0.0'])
    :ok
    iex(one@198.51.100.0)> Node.connect(:'two@203.0.113.0')
    false
    23:38:27.702 [error] ** Connection attempt with disallowed node :"two@203.0.113.0" **
    iex(one@198.51.100.0)> :net_kernel.allow([:'two@203.0.113.0'])
    :ok
    iex(one@198.51.100.0)> Node.connect(:'two@203.0.113.0')
    true
    

    这是诀窍吗?

2 个答案:

答案 0 :(得分:5)

白名单基于VM Cookie ~/.erlang.cookie。 然后只有授权的节点才能拥有好的cookie才能connect 对于安全部分,我在服务器和笔记本电脑之间设置了Tinc mesh VPN,这是我需要的所有安全性,同时提供了极大的灵活性。

答案 1 :(得分:2)

net_kernel是一个创建gen_server进程的模块。在该进程状态中,它有一些参数,例如allowed,它包含允许的节点列表,并在启动时由空列表启动。

有一个未记录的功能,如果给定的连接节点不是允许节点的成员但该列表为空,则允许节点连接。来自net_kernel.erl模块的此代码段说明了这一事实:

setup(Node,Type,From,State) ->
    Allowed = State#state.allowed,
    case lists:member(Node, Allowed) of
        false when Allowed =/= [] ->
            error_msg("** Connection attempt with "
                      "disallowed node ~w ** ~n", [Node]),
            {error, bad_node};
        _ ->
            %% set up connection to given node
    end.

另一个重要的注意事项是关于net_kernel:allow/1函数,它是一个仅附加函数。使用++运算符将新节点添加到以前的节点时,可以在源代码中检查此事实:

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;