DiscoverySpiNodeAuthenticator implementation

classic Classic list List threaded Threaded
5 messages Options
djm132 djm132
Reply | Threaded
Open this post in threaded view
|

DiscoverySpiNodeAuthenticator implementation

Hi,

I need to implement token-based security authenticator. The best place I've found so far is to extend discovery SPI  

TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();

discoSpi.setAuthenticator(new TokenAuthenticator());
igniteConfig.setDiscoverySpi(discoSpi);

Then I've implemented simple TokenAuthenticator as a proof-of-concept:

public class TokenAuthenticator implements DiscoverySpiNodeAuthenticator, Serializable {

    @Override
    public boolean isGlobalNodeAuthentication() {
        return true;
    }

    public SecurityContext authenticateNode(ClusterNode node, SecurityCredentials cred) {
        // Local node trusted
        if (node.isLocal()) {
            return new DummySecurityContext();
        }

        // Remote nodes blocked
        return null;
    }
}

There is no examples on how to create security context, so there is a dummy class which returns true on all 3 methods and null for subject().

Everything is ok after launching first instance (#1) on localhost.
But then I need to check if second localhost instance (#2) blocked.

#1 instance shows in log

2016/05/23 11:18:53.393 [none] WARN Authentication failed [nodeId=9bd41203-4e2b-4bb0-81f3-1a740d2f7c36, addrs=…

which seems correct. But the #2 shown long exception log:

org.apache.ignite.IgniteCheckedException: Failed to start SPI: TcpDiscoverySpi [addrRslvr=null, sockTimeout=5000, ackTimeout=5000, reconCnt=10, maxAckTimeout=600000, forceSrvMode=false, clientReconnectDisabled=false]
        at org.apache.ignite.internal.managers.GridManagerAdapter.startSpi(GridManagerAdapter.java:258)
        at org.apache.ignite.internal.managers.discovery.GridDiscoveryManager.start(GridDiscoveryManager.java:660)
        at org.apache.ignite.internal.IgniteKernal.startManager(IgniteKernal.java:1505)
        at org.apache.ignite.internal.IgniteKernal.start(IgniteKernal.java:917)
        at org.apache.ignite.internal.IgnitionEx$IgniteNamedInstance.start0(IgnitionEx.java:1688)
        at org.apache.ignite.internal.IgnitionEx$IgniteNamedInstance.start(IgnitionEx.java:1547)
        at org.apache.ignite.internal.IgnitionEx.start0(IgnitionEx.java:1003)
        at org.apache.ignite.internal.IgnitionEx.start(IgnitionEx.java:534)
        at org.apache.ignite.internal.IgnitionEx.start(IgnitionEx.java:515)
        at org.apache.ignite.Ignition.start(Ignition.java:322)
        at dmp.grid.engine.Engine.start(Engine.java:120)
        at dmp.grid.Node.run(Node.java:45)
        at dmp.grid.Node.main(Node.java:32)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293)
        at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.ignite.spi.IgniteSpiException: Authentication failed [nodeId=c156015b-9292-4d5a-9fd1-71d4dddc376a, addr=0.0.0.0]
        at org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi.authenticationFailedError(TcpDiscoverySpi.java:1636)
        at org.apache.ignite.spi.discovery.tcp.ServerImpl.joinTopology(ServerImpl.java:878)
        at org.apache.ignite.spi.discovery.tcp.ServerImpl.spiStart(ServerImpl.java:329)
        at org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi.spiStart(TcpDiscoverySpi.java:1835)
        at org.apache.ignite.internal.managers.GridManagerAdapter.startSpi(GridManagerAdapter.java:255)
        ... 18 common frames omitted
       
        ….
       
       
        1) Is there any example of correct implementation of DiscoverySpiNodeAuthenticator (not found in sources).
        2) Is returning null for blocking remote is the correct way to do it ?
        3) How valid SecurityContext created and used ?
        4) How to get rid of exceptions ?

The reason of token authenticator is to split environments in one sub-net and create several closed rings of nodes based on the same token.

Thanks.

Michael.
vkulichenko vkulichenko
Reply | Threaded
Open this post in threaded view
|

Re: DiscoverySpiNodeAuthenticator implementation

Hi,

To add security capabilities to the Ignite cluster you need to implement GridSecurityProcessor and provide it as a plugin. The blog [1] provides a good example of how this can be done.

Also GridGain provides the implementation as a part of their commercial offering. See [2] for details if you're interested.

[1] http://smartkey.co.uk/development/securing-an-apache-ignite-cluster/
[2] https://gridgain.readme.io/docs/security-and-audit

-Val
djm132 djm132
Reply | Threaded
Open this post in threaded view
|

Re: DiscoverySpiNodeAuthenticator implementation

I've tried the code from http://smartkey.co.uk/development/securing-an-apache-ignite-cluster/ too. The second (blocked) node just throw exception as in my example with DiscoverySpiNodeAuthenticator:

2016/05/23 17:28:08.062 [main] ERROR Failed to start manager: GridManagerAdapter [enabled=true, name=o.a.i.i.managers.discovery.GridDiscoveryManager]
org.apache.ignite.IgniteCheckedException: Failed to start SPI: TcpDiscoverySpi [addrRslvr=null, sockTimeout=5000, ackTimeout=5000, reconCnt=10, maxAckTimeout=600000, forceSrvMode=false, clientReconnectDisabled=false]
        at org.apache.ignite.internal.managers.GridManagerAdapter.startSpi(GridManagerAdapter.java:258)
        at org.apache.ignite.internal.managers.discovery.GridDiscoveryManager.start(GridDiscoveryManager.java:677)
        at org.apache.ignite.internal.IgniteKernal.startManager(IgniteKernal.java:1531)
        at org.apache.ignite.internal.IgniteKernal.start(IgniteKernal.java:897)
        at org.apache.ignite.internal.IgnitionEx$IgniteNamedInstance.start0(IgnitionEx.java:1736)
        at org.apache.ignite.internal.IgnitionEx$IgniteNamedInstance.start(IgnitionEx.java:1589)
        at org.apache.ignite.internal.IgnitionEx.start0(IgnitionEx.java:1042)
        at org.apache.ignite.internal.IgnitionEx.start(IgnitionEx.java:569)
        at org.apache.ignite.internal.IgnitionEx.start(IgnitionEx.java:516)
        at org.apache.ignite.Ignition.start(Ignition.java:322)
        at dmp.grid.engine.Engine.start(Engine.java:120)
        at dmp.grid.Node.run(Node.java:45)
        at dmp.grid.Node.main(Node.java:32)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293)
        at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.ignite.spi.IgniteSpiException: Access denied
        at org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi.checkFailedError(TcpDiscoverySpi.java:1644)
        at org.apache.ignite.spi.discovery.tcp.ServerImpl.joinTopology(ServerImpl.java:885)
        at org.apache.ignite.spi.discovery.tcp.ServerImpl.spiStart(ServerImpl.java:334)
        at org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi.spiStart(TcpDiscoverySpi.java:1832)
        at org.apache.ignite.internal.managers.GridManagerAdapter.startSpi(GridManagerAdapter.java:255)
        ... 18 common frames omitted

Expected behaviour is the continue to work in standalone mode in this case. Here is the code with blocks any other nodes from connecting to current one (

public class TokenSecurityProcessor implements DiscoverySpiNodeAuthenticator, GridSecurityProcessor, IgnitePlugin {
    ...
    @Override
    public IgniteNodeValidationResult validateNode(ClusterNode node) {
        return new IgniteNodeValidationResult(node.id(), "Access denied", "Access denied");
    }
}
djm132 djm132
Reply | Threaded
Open this post in threaded view
|

Re: DiscoverySpiNodeAuthenticator implementation

So what to do with this exception ?
vkulichenko vkulichenko
Reply | Threaded
Open this post in threaded view
|

Re: DiscoverySpiNodeAuthenticator implementation

Why did you implement validateNode() method? It's not a security concept, it's just a generic way that can be used by components to check the node validity (e.g., to avoid misconfiguration). Looks like in your case it always return result which is the reason of the failure (for valid node it should be null). As I said earlier, you need to implement GridSecurityProcessor. It's main method is authenticateNode(..).

-Val