|
![]() |
Usually, applications and security are developed
for a specific use. We propose here a security framework that allows
to dynamically deploy
applications and to configure security according to this deployment.
ProActive security mechanism provides a set of
security features from basic ones like communications authentication,
integrity, confidentiality to more high-level features including
migration security mechanism, hierarchical security policies,
dynamically negotiated policies. All theses features are expressed
inside the meta-level of the middleware and used transparently by
applications.
It is possible to attach security policies to
Runtimes, Virtual Nodes, Nodes and Active Objects. Policies are
expressed inside an XML descriptor.
A distributed or concurrent application built using ProActive is composed of a number of medium-grained entities called active objects. Each active object has one distinguished element, the root, which is the only entry point to the active object; all other objects inside the active object are called passive objects and cannot be referenced directly from objects which are outside this active object (see Figure 8); the absence of sharing is important with respect to security.
Figure 8: A typical object graph with active objects
The security is based on Public Key Infrastructure. Each entity owns a certificate and an private key generated from the certificate of a user.
Certificates are generated automatically by the security mechanism. The validity of a certificate is checked by validating its certificate chain. As shown in figure 2, before validating the certificate of an active object, application certificate and user certificate will be checked. If a valid path is found so object certificate is validated.
Figure 2 : Certificate chain
Figure 1 : Hierarchical security
When an interaction is happening, all participating entities' security policy are verified and combined to find the policy to enforce to the interaction.
The security architecture relies on two related abstractions for deploying Grid applications: Node and Virtual Node. A node gathers several objects in a logical entity. It provides an abstraction for the physical location of a set of activities. Objects are bound to a node at creation or after migration. In order to have a flexible deployment (eliminating from the source code machine names, creation protocols), the system relies on Virtual Nodes (VNs). A VN is identified as a name (a simple string), used in a program source, defined and configured in an descriptor. The user can attach policy to these virtual nodes. Virtual Nodes are used within application code to structure it. By example, an object which will be used as a server will be set inside a virtual node named Server_VN, client objects will be set inside Client_VN. The user expresses policy between server and client object inside a descriptor file. The correspondence between Virtual Nodes and Nodes, the mapping, is done at application starting time.
Grid programming is about deploying processes (activities) on various machines. In the end, the security policy that must be ensured for those processes depends upon many factors: first of all, the application policy that is needed, but also the machine locations, the security policies of their administrative domain, and the network being used to reach those machines.
Previous section defined the notions of Virtual Nodes, and Nodes.
Virtual Nodes are application abstractions, and nodes are only a
run-time entity
resulting from the deployment: a mapping of Virtual Nodes to processes
and hosts.
A first decisive feature
allows to define application-level security on those application-level
abstractions:
As such, virtual nodes are the support for intrinsic application level security. If, at design time, it appears that a process always requires a specific level of security (e.g. authenticated and encrypted communications at all time), then that process should be attached to a virtual node on which those security features are imposed. It is the designer responsibility to structure his/her application or components into virtual node abstractions compatible with the required security. Whatever deployment occurs, those security features will be maintained. We expect this usage to be rather occasional, for instance in very sensitive applications where even an intranet deployment calls for encrypted communications.
The second decisive feature deals with a major Grid aspect: deployment-specific security. The issue is actually twofold:
Domains are a standard way to structure (virtual) organizations involved in a Grid infrastructure; they are organized in a hierarchical manner. They are the logical concept allowing to express security policies in a hierarchical way.
This principle allows to deal with the two issues mentioned
above:
(1) the administrator of a domain can define specific policy rules
that must be obeyed by the applications running within the
domain. However, a general rule expressed inside a domain may prevent
the
deployment of a specific application. To solve this issue, a policy
rule can allow a well-defined entity to weaken it. As we are in a
hierarchical organization, allowing an entity to weaken a rule means
allowing all entities included to weaken the rule. The entity can be
identified by its certificate;
(2) a Grid user can, at the time he runs an application, specify
additional security based on the domains being deployed onto.
The Grid user can specify additional rules directly in his deployment descriptor for the domains he deploys onto. Note that those domains are actually dynamic as they can be obtained through external allocators, or even Web Services in an OGSA infrastructure [5]. Joker rules might be important in that case to cover all cases, and to provide a conservative security strategy for un-forecasted deployments.
Finally, as active objects are active and mobile entities, there is
a
need
to specify security at the level of such entities.
In open applications, e.g. several principals interacting in a
collaborative Grid application, a JVM (a process) launched by a given
principal can actually host an activity executing under another
principal. The principle above allows to keep specific security
privileges in such case.
Moreover, it can also serve as a basis to offer, in a secure manner,
hosting environments for mobile agents.
Figure 4: Hierarchical Security Entities
Figure 5: Syntax and attributes for policy rules
Prior to start application on a Grid, a user needs to acquire some resources (CPU time, disk storage, bandwidth) from the Grid. A Resource provider is an individual, a research institute, an organization who wants to offer some resources under a certain security policy to a restricted set of peoples. According to our definition, resource provider will set up one or more runtime where clients will be able do perform computation. Each runtime is set with its own policy. Theses runtimes could be worldwide distributed.
Prior to start application on a Grid, a user needs to acquire some resources (CPU time, disk storage, bandwidth) from the Grid. A Resource provider is an individual, a research institute, an organization who wants to offer some resources under a certain security policy to a restricted set of peoples. According to our definition, resource provider will set up one or more runtime where clients will be able do perform computation. Each runtime is set with its own policy. Theses runtimes could be worldwide distributed.
Security policies are able to control all the interactions that can occur when deploying and executing a multi-principals Grid application. With this goal in mind, interactions span over the creation of processes, to the monitoring of activities (Objects) within processes, including of course the communications. Here is a brief description of those interactions:
For instance, a domain is able to specify that it accepts
downloading of code from a given set of domains, provided
the transfers are authenticated and guaranteed not to be tampered with.
As a policy might leave open the integrity of communications, and also
because not allowing confidentiality can be a
domain (or even a country) policy, those 3 security attributes can be
specified in 3 modes: Required (+), Optional (?),
Disallowed (-)
For a given interaction, a tuple [+A,?I,-C] means that authentication
is required, integrity is accepted but not required, and
confidentiality is not allowed.
As a Grid operates in decentralized mode, without a central administrator controlling the correctness of all security policies, these policies must be combined, checked, and negotiated dynamically. The next two sections present that aspect.
As the proposed infrastructure takes into account different actors of the Grid (domain administrator, Grid user), even for a single-principal single-domain application, there are potentially several security policies activated. This section deals with the combination of those policies to obtain the final security tuples of a single entity. An important principle being that a sub-domain cannot weaken a super-domain's rule.
During execution, each activity (Active Object) is always included
in a Node (due to the Virtual Node mapping) and at least in one
Domain, the one used to launch a JVM ().
Figure 6
hierarchically represents the security rules that can be activated at
execution: from the top, hierarchical domains (
to
), the
virtual node policy (VN), and the Object
(O) policy. Of course, such policies can be inconsistent, and there
must be clear principles to combine the various sets of rules.
Figure 6: Hierarchical Security Levels
There are three main principles: (1) choosing the most specific rules within a given domain (as a single Grid actor is responsible for it), (2) an interaction is valid only if all levels accept it (absence of weakening of authorizations), (3) the security attributes retained are the most constrained based on a partial order (absence of weakening of security).
Domain[*] -> Domain[*] : Q,P : [+A,+I,+C]
Domain[CardPlus] -> Domain[CardPlus] : Q,P : [+A,?I,?C]
within the CardPlus domain, the second rule will be chosen (integrity and confidentiality will be optional). Of course, comparison of rules is only a partial order, and several incompatible most specific rules can exist within a single level (e.g. both ACCEPT and DENY most specific rules for the same interaction, or both +A and -A).
Between levels, an incompatibility can also occur, especially if a sub-level attempts to weaken the policy on a given interaction (e.g. a domain prohibits confidentiality [-C] while a sub-domain or the Virtual Node requires it [+C], a domain Di prohibits loading of code while Dj (j <= i) authorizes it). In all incompatible cases, the interaction is not authorized and an error is reported.
During execution, entities interact by pair with each other. Each entity, for each interaction (JVM creation, communication, migration, ...), will want to apply a security policy based on the resolution presented in the previous section. Before starting an interaction, a negotiation occurs between the two entities involved. Figure 7 shows the result of such negotiation. For example, if for a given interaction, entity A's policy is [+A,?I,?C], and B's policy is [+A,?I,-C], the negotiated policy will be [A,?I,-C]. If, for a result rule, one of the communication attributes is optional, the attribute is not activated.
Besides the interactions not being accepted by an entity, two other cases lead to an error: when an attribute is required by one, and disallowed by the other. In such cases, the interaction is not authorized and an error is reported. If a valid security policy is found between two entities, the interaction can occur. In the case that the agreed security policy includes confidentiality, the two entities negotiate a session key.
Figure 7: Result of security negotiations
In large scale Grid applications, migration of activities is an important issue. The migration of Active Objects must not weaken the security policy being applied.
When an active object migrates to a new location, three cases may happen :
Figure 3: Security layer detailed
Within descriptor, the tag <security> is
used to specify the policy for the deployed application. It will be the
policy for all Nodes and active that will be created.
the descriptor is:
1:<?xml version="1.0" encoding="UTF-8"?>
2:<ProActiveDescriptor xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="DescriptorSchema.xsd">
3: <security file="../../descriptors/applicationPolicy.xml"></security>
4: <componentDefinition>
5: <virtualNodesDefinition>
6: <virtualNode name="Locale" property="unique"/>
7: <virtualNode name="vm1" property="unique"/>
8: <virtualNode name="vm2" property="unique"/>
9: </virtualNodesDefinition>
10: </componentDefinition>
11: ....
50:<infrastructure>
51: <processes>
52: <processDefinition id="linuxJVM">
53: <jvmProcess class="org.objectweb.proactive.core.process.JVMNodeProcess">
54: <classpath>
....
74: </classpath>
75: <jvmParameters>
<parameter value="-Dproactive.runtime.security=/.../descriptors/jvm1-sec.xml" />
82: </jvmParameters>
83: </jvmProcess>
84: </processDefinition>
....
Inside the policy file, you can express policy
between entities (domain, runtime, node, active object).
The entity tag can be used to :
A policy file must begin with :
1:<?xml version="1.0" encoding="UTF-8"?>
2:<Policy>
next, application specific informations are given.
3: <ApplicationName>Garden</ApplicationName>
<ApplicationName> sets the application name. This allows to identify easily which application an entity belongs to.
4: <Certificate>/.../appli.cert</Certificate>
5: <PrivateKey>/.../appli.key</PrivateKey>
<Certificate> is the X509 certificate of the application, generated from a user certificate, and
<PrivateKey> the private key associated to the certificate.
6: <CertificationAuthority>
7: <Certificate>/.../ca.cert</Certificate>
8: </CertificationAuthority>
<CertificationAuthority> contains all trusted certificate authority. Each <Certificate> contains a certification authority certificate.
10: <Rules>
Then we can define policy rules. All rules are located within the <Rules>
A <Rule> is constructed according the following syntax :
11: <Rule>
<From> tag contains all entities from which the interaction is made. It is possible to specify many entities in order to match a specific fine-grained policy.
12: <From>
13: <Entity type="VN" name="vm2"/>
14: </From>
<Entity> is used to define an entity. the "type" parameter can be "VN", "certificate".
15: <To>
16: <Entity type="VN" name="Locale"/>
17: </To>
The <Communication> tag defines security policies to apply to requests and replies.
18: <Communication>
<Request> sets the policy associated a request. the "value" parameter can be :
19: <Request value="authorized">
20: <Attributes authentication="required" integrity="optional" confidentiality="optional"/>
21: </Request>
<Reply> tag has the same parameters that <Request>
22:<Reply value="authorized">
23: <Attributes authentication="required" integrity="required" confidentiality="required"/>
24:</Reply>
25:</Communication>
<Migration> allows or not migration from <from> entities to <To> entities. Values can be "denied" or "authorized".
26: <Migration>denied</Migration>
<OACreation> allows or not creation of active objects by
<From> entities onto <To> entities.
Values can be "denied" or "authorized".
27: <OACreation>denied</OACreation>
1:<?xml version="1.0" encoding="UTF-8"?>Note that the JVM that reads the deployment descriptor should be started with security policy. In order to start a secure JVM, you need to use the property proactive.runtime.security and give a path a security file descriptor.
2:<Policy>
3: <ApplicationName>Garden</ApplicationName>
4: <Certificate>/net/home/acontes/certif/appli.cert</Certificate>
5: <PrivateKey>/net/home/acontes/certif/appli.key</PrivateKey>
6: <CertificationAuthority>
7: <Certificate></Certificate>
8: </CertificationAuthority>
10: <Rules>
11: <Rule>
12: <From>
13: <Entity type="VN" name="vm2"/>
14: </From>
15: <To>
16: <Entity type="VN" name="Locale"/>
17: </To>
18: <Communication>
19: <Request value="authorized">
20: <Attributes authentication="required" integrity="required" confidentiality="required"/>
21: </Request>
22: <Reply value="authorized">
23: <Attributes authentication="required" integrity="required" confidentiality="required"/>
24: </Reply>
25: </Communication>
26: <Migration>denied</Migration>
27: <OACreation>denied</OACreation>
28:
29: </Rule>
30: <Rule>
31: <From>
32: <Entity type="certificate" name="certificateRuntime1.cert"/>
33: </From>
34: <To>
35: <Entity type="VN" name="Locale"/>
36: </To>
37: <Communication>
38: <Request value="authorized">
39: <Attributes authentication="required" integrity="required" confidentiality="required"/>
40: </Request>
41: <Reply value="authorized">
42: <Attributes authentication="required" integrity="required" confidentiality="required"/>
43: </Reply>
44: </Communication>
45: <Migration>denied</Migration>
46: <OACreation>denied</OACreation>
47:
48: </Rule>
...
90: <Rule>
91: <From>
92: <Entity type="DefaultVirtualNode" name="*"/>
93: </From>
94: <To>
95: <Entity type="DefaultVirtualNode" name="*"/>
96: </To>
97: <Communication>
98: <Request value="denied">
99: <Attributes authentication="optional" integrity="optional" confidentiality="optional"/>
100: </Request>
101: <Reply value="denied">
102: <Attributes authentication="optional" integrity="optional" confidentiality="optional"/>
103:
104: </Reply>
105: </Communication>
106: <Migration>denied</Migration>
107: <OACreation>authorized</OACreation>
108:
109: </Rule>
110:
111: </Rules>
112:</Policy>
How to
quickly generate certificate ?
under Linux :
openssl req -x509 -newkey rsa:1024 -keyout
application.key -out application.cert -outform PEM
openssl pkcs8 -topk8 -outform DER -nocrypt < application.key >!
application.key.der
rm application.key
mv application.key.der application.key
under windows : ?