minor updates to dev and user guide
[aaa.git] / docs / user-guide.rst
1 .. _aaa-user-guide:
2
3 Authentication, Authorization and Accounting (AAA) Services
4 ===========================================================
5
6 Overview
7 --------
8
9 Authentication, Authorization and Accounting (AAA) is a term for a
10 framework controlling access to resources, enforcing policies to use
11 those resources and auditing their usage. These processes are the
12 fundamental building blocks for effective network management and security.
13
14 Authentication provides a way of identifying a user, typically by
15 having the user enter a valid user name and valid password before access
16 is granted. The process of authentication is based on each user having a unique
17 set of criteria for gaining access. The AAA framework compares a user's
18 authentication credentials with other user credentials stored in a database.
19 If the credentials match, the user is granted access to the network.
20 If the credentials don't match, authentication fails and access is denied.
21
22 Authorization is the process of finding out what an authenticated user is
23 allowed to do within the system, which tasks can do, which API can call, etc.
24 The authorization process determines whether the user has the authority
25 to perform such actions.
26
27 Accounting is the process of logging the activity of an authenticated user,
28 for example, the amount of data a user has sent and/or received during a
29 session, which APIs called, etc.
30
31 Terms And Definitions
32 ^^^^^^^^^^^^^^^^^^^^^
33
34 AAA
35     Authentication, Authorization and Accounting.
36
37 Token
38     A claim of access to a group of resources on the controller.
39
40 Domain
41     A group of resources, direct or indirect, physical, logical, or
42     virtual, for the purpose of access control.
43
44 User
45     A person who either owns or has access to a resource or group of
46     resources on the controller.
47
48 Role
49     Opaque representation of a set of permissions, which is merely a
50     unique string as admin or guest.
51
52 Credential
53     Proof of identity such as user name and password, OTP, biometrics, or
54     others.
55
56 Client
57     A service or application that requires access to the controller.
58
59 Claim
60     A data set of validated assertions regarding a user, e.g. the role,
61     domain, name, etc.
62
63 Grant
64     It is the entity associating a user with his role and domain.
65
66 IdP
67     Identity Provider.
68
69 TLS
70     Transport Layer Security
71
72 CLI
73     Command Line Interface
74
75 Security Framework for AAA services
76 -----------------------------------
77
78 Since Boron release, the OpenDaylight's AAA services are based on the
79 `Apache Shiro <https://shiro.apache.org/>`_ Java Security Framework. The main
80 configuration file for AAA is located at “etc/shiro.ini” relative to the
81 OpenDaylight Karaf home directory.
82
83
84 How to enable AAA
85 -----------------
86
87 AAA is enabled through installing the odl-aaa-shiro feature. The vast majority
88 of OpenDaylight's northbound APIs (and all RESTCONF APIs) are protected by AAA
89 by default when installing the +odl-restconf+ feature, since the odl-aaa-shiro
90 is automatically installed as part of them. In the cases that APIs are *not*
91 protected by AAA, this will be noted in the per-project release notes.
92
93 How to disable AAA
94 ------------------
95
96 Edit the “etc/opendaylight/datastore/initial/config/aaa-app-config.xml” file and replace the following:
97
98 ::
99
100     /** = authcBasic
101
102 with
103
104 ::
105
106     /** = anon
107
108 Then restart the Karaf process.
109
110 AAA Realms
111 ----------
112
113 AAA plugin utilizes the Shiro Realms to support pluggable authentication &
114 authorization schemes. There are two parent types of realms:
115
116 -  AuthenticatingRealm
117
118    -  Provides no Authorization capability.
119
120    -  Users authenticated through this type of realm are treated
121       equally.
122
123 -  AuthorizingRealm
124
125    -  AuthorizingRealm is a more sophisticated AuthenticatingRealm,
126       which provides the additional mechanisms to distinguish users
127       based on roles.
128
129    -  Useful for applications in which roles determine allowed
130       capabilities.
131
132 OpenDaylight contains five implementations:
133
134 -  TokenAuthRealm
135
136    -  An AuthorizingRealm built to bridge the Shiro-based AAA service
137       with the h2-based AAA implementation.
138
139    -  Exposes a RESTful web service to manipulate IdM policy on a
140       per-node basis. If identical AAA policy is desired across a
141       cluster, the backing data store must be synchronized using an out
142       of band method.
143
144    -  A python script located at “etc/idmtool” is included to help
145       manipulate data contained in the TokenAuthRealm.
146
147    -  Enabled out of the box. This is the realm configured by default.
148
149 -  ODLJndiLdapRealm
150
151    -  An AuthorizingRealm built to extract identity information from IdM
152       data contained on an LDAP server.
153
154    -  Extracts group information from LDAP, which is translated into
155       OpenDaylight roles.
156
157    -  Useful when federating against an existing LDAP server, in which
158       only certain types of users should have certain access privileges.
159
160    -  Disabled out of the box.
161
162 -  ODLJndiLdapRealmAuthNOnly
163
164    -  The same as ODLJndiLdapRealm, except without role extraction.
165       Thus, all LDAP users have equal authentication and authorization
166       rights.
167
168    -  Disabled out of the box.
169
170 -  ODLActiveDirectoryRealm
171
172    - Wraps the generic ActiveDirectoryRealm provided by Shiro. This allows for
173      enhanced logging as well as isolation of all realms in a single package,
174      which enables easier import by consuming servlets.
175
176 -  KeystoneAuthRealm
177
178    - This realm authenticates OpenDaylight users against the OpenStack’s
179      Keystone server.
180
181    - Disabled out of the box.
182
183 .. note::
184
185     More than one Realm implementation can be specified. Realms are attempted
186     in order until authentication succeeds or all realm sources are exhausted.
187     Edit the **securityManager.realms = $tokenAuthRealm** property in shiro.ini
188     and add all the realms needed separated by commas.
189
190 TokenAuthRealm
191 ^^^^^^^^^^^^^^
192
193 How it works
194 ~~~~~~~~~~~~
195
196 The TokenAuthRealm is the default Authorization Realm deployed in OpenDaylight.
197 TokenAuthRealm uses a direct authentication mechanism as shown in the following
198 picture:
199
200 .. figure:: ./images/aaa/direct-authentication.png
201    :alt: TokenAuthRealm direct authentication mechanism
202
203    TokenAuthRealm direct authentication mechanism
204
205 A user presents some credentials (e.g., username/password) directly to the
206 OpenDaylight controller token endpoint /oauth2/token and receives an access
207 token, which then can be used to access protected resources on the controller.
208
209 Configuring TokenAuthRealm
210 ~~~~~~~~~~~~~~~~~~~~~~~~~~
211
212 The TokenAuthRealm stores IdM data in an h2 database on each node. Thus,
213 configuration of a cluster currently requires configuring the desired IdM policy
214 on each node. There are two supported methods to manipulate the TokenAuthRealm
215 IdM configuration:
216
217 -  idmtool configuration tool
218
219 -  RESTful Web Service configuration
220
221 **Idmtool**
222 ###########
223
224 A utility script located at “etc/idmtool” is used to manipulate the
225 TokenAuthRealm IdM policy. idmtool assumes a single domain, the default one
226 (sdn), since multiple domains are not supported in the Boron release. General
227 usage information for idmtool is derived through issuing the following command:
228
229 ::
230
231     $ python etc/idmtool -h
232     usage: idmtool [-h] [--target-host TARGET_HOST]
233                    user
234                    {list-users,add-user,change-password,delete-user,list-domains,list-roles,add-role,delete-role,add-grant,get-grants,delete-grant}
235                    ...
236
237     positional arguments:
238       user                  username for BSC node
239       {list-users,add-user,change-password,delete-user,list-domains,list-roles,add-role,delete-role,add-grant,get-grants,delete-grant}
240                             sub-command help
241         list-users          list all users
242         add-user            add a user
243         change-password     change a password
244         delete-user         delete a user
245         list-domains        list all domains
246         list-roles          list all roles
247         add-role            add a role
248         delete-role         delete a role
249         add-grant           add a grant
250         get-grants          get grants for userid on sdn
251         delete-grant        delete a grant
252
253     optional arguments:
254       -h, --help            show this help message and exit
255       --target-host TARGET_HOST
256                             target host node
257
258 Add a user
259 ''''''''''
260
261 ::
262
263     python etc/idmtool admin add-user newUser
264     Password:
265     Enter new password:
266     Re-enter password:
267     add_user(admin)
268
269     command succeeded!
270
271     json:
272     {
273         "description": "",
274         "domainid": "sdn",
275         "email": "",
276         "enabled": true,
277         "name": "newUser",
278         "password": "**********",
279         "salt": "**********",
280         "userid": "newUser@sdn"
281     }
282
283 .. note::
284
285     AAA redacts the password and salt fields for security purposes.
286
287 Delete a user
288 '''''''''''''
289
290 ::
291
292     $ python etc/idmtool admin delete-user newUser@sdn
293     Password:
294     delete_user(newUser@sdn)
295
296     command succeeded!
297
298 List all users
299 ''''''''''''''
300
301 ::
302
303     $ python etc/idmtool admin list-users
304     Password:
305     list_users
306
307     command succeeded!
308
309     json:
310     {
311         "users": [
312             {
313                 "description": "user user",
314                 "domainid": "sdn",
315                 "email": "",
316                 "enabled": true,
317                 "name": "user",
318                 "password": "**********",
319                 "salt": "**********",
320                 "userid": "user@sdn"
321             },
322             {
323                 "description": "admin user",
324                 "domainid": "sdn",
325                 "email": "",
326                 "enabled": true,
327                 "name": "admin",
328                 "password": "**********",
329                 "salt": "**********",
330                 "userid": "admin@sdn"
331             }
332         ]
333     }
334
335 Change a user’s password
336 ''''''''''''''''''''''''
337
338 ::
339
340     $ python etc/idmtool admin change-password admin@sdn
341     Password:
342     Enter new password:
343     Re-enter password:
344     change_password(admin)
345
346     command succeeded!
347
348     json:
349     {
350         "description": "admin user",
351         "domainid": "sdn",
352         "email": "",
353         "enabled": true,
354         "name": "admin",
355         "password": "**********",
356         "salt": "**********",
357         "userid": "admin@sdn"
358     }
359
360 Add a role
361 ''''''''''
362
363 ::
364
365     $ python etc/idmtool admin add-role network-admin
366     Password:
367     add_role(network-admin)
368
369     command succeeded!
370
371     json:
372     {
373         "description": "",
374         "domainid": "sdn",
375         "name": "network-admin",
376         "roleid": "network-admin@sdn"
377     }
378
379 Delete a role
380 '''''''''''''
381
382 ::
383
384     $ python etc/idmtool admin delete-role network-admin@sdn
385     Password:
386     delete_role(network-admin@sdn)
387
388     command succeeded!
389
390 List all roles
391 ''''''''''''''
392
393 ::
394
395     $ python etc/idmtool admin list-roles
396     Password:
397     list_roles
398
399     command succeeded!
400
401     json:
402     {
403         "roles": [
404             {
405                 "description": "a role for admins",
406                 "domainid": "sdn",
407                 "name": "admin",
408                 "roleid": "admin@sdn"
409             },
410             {
411                 "description": "a role for users",
412                 "domainid": "sdn",
413                 "name": "user",
414                 "roleid": "user@sdn"
415             }
416         ]
417     }
418
419 List all domains
420 ''''''''''''''''
421
422 ::
423
424     $ python etc/idmtool admin list-domains
425     Password:
426     list_domains
427
428     command succeeded!
429
430     json:
431     {
432         "domains": [
433             {
434                 "description": "default odl sdn domain",
435                 "domainid": "sdn",
436                 "enabled": true,
437                 "name": "sdn"
438             }
439         ]
440     }
441
442 Add a grant
443 '''''''''''
444
445 ::
446
447     $ python etc/idmtool admin add-grant user@sdn admin@sdn
448     Password:
449     add_grant(userid=user@sdn,roleid=admin@sdn)
450
451     command succeeded!
452
453     json:
454     {
455         "domainid": "sdn",
456         "grantid": "user@sdn@admin@sdn@sdn",
457         "roleid": "admin@sdn",
458         "userid": "user@sdn"
459     }
460
461 Delete a grant
462 ''''''''''''''
463
464 ::
465
466     $ python etc/idmtool admin delete-grant user@sdn admin@sdn
467     Password:
468     http://localhost:8181/auth/v1/domains/sdn/users/user@sdn/roles/admin@sdn
469     delete_grant(userid=user@sdn,roleid=admin@sdn)
470
471     command succeeded!
472
473 Get grants for a user
474 '''''''''''''''''''''
475
476 ::
477
478     python etc/idmtool admin get-grants admin@sdn
479     Password:
480     get_grants(admin@sdn)
481
482     command succeeded!
483
484     json:
485     {
486         "roles": [
487             {
488                 "description": "a role for users",
489                 "domainid": "sdn",
490                 "name": "user",
491                 "roleid": "user@sdn"
492             },
493             {
494                 "description": "a role for admins",
495                 "domainid": "sdn",
496                 "name": "admin",
497                 "roleid": "admin@sdn"
498             }
499         ]
500     }
501
502 **Configuration using the RESTful Web Service**
503 ###############################################
504
505 The TokenAuthRealm IdM policy is fully configurable through a RESTful
506 web service. Full documentation for manipulating AAA IdM data is located
507 online (https://wiki.opendaylight.org/images/0/00/AAA_Test_Plan.docx),
508 and a few examples are included in this guide:
509
510 Get All Users
511 '''''''''''''
512
513 ::
514
515     curl -u admin:admin http://localhost:8181/auth/v1/users
516     OUTPUT:
517     {
518         "users": [
519             {
520                 "description": "user user",
521                 "domainid": "sdn",
522                 "email": "",
523                 "enabled": true,
524                 "name": "user",
525                 "password": "**********",
526                 "salt": "**********",
527                 "userid": "user@sdn"
528             },
529             {
530                 "description": "admin user",
531                 "domainid": "sdn",
532                 "email": "",
533                 "enabled": true,
534                 "name": "admin",
535                 "password": "**********",
536                 "salt": "**********",
537                 "userid": "admin@sdn"
538             }
539         ]
540     }
541
542 Create a User
543 '''''''''''''
544
545 ::
546
547     curl -u admin:admin -X POST -H "Content-Type: application/json" --data-binary @./user.json http://localhost:8181/auth/v1/users
548     PAYLOAD:
549     {
550         "name": "ryan",
551         "password": "ryan",
552         "domainid": "sdn",
553         "description": "Ryan's User Account",
554         "email": "ryandgoulding@gmail.com"
555     }
556
557     OUTPUT:
558     {
559         "userid":"ryan@sdn",
560         "name":"ryan",
561         "description":"Ryan's User Account",
562         "enabled":true,
563         "email":"ryandgoulding@gmail.com",
564         "password":"**********",
565         "salt":"**********",
566         "domainid":"sdn"
567     }
568
569 Create an OAuth2 Token For Admin Scoped to SDN
570 ''''''''''''''''''''''''''''''''''''''''''''''
571
572 ::
573
574     curl -d 'grant_type=password&username=admin&password=a&scope=sdn' http://localhost:8181/oauth2/token
575
576     OUTPUT:
577     {
578         "expires_in":3600,
579         "token_type":"Bearer",
580         "access_token":"5a615fbc-bcad-3759-95f4-ad97e831c730"
581     }
582
583 Use an OAuth2 Token
584 '''''''''''''''''''
585
586 ::
587
588     curl -H "Authorization: Bearer 5a615fbc-bcad-3759-95f4-ad97e831c730" http://localhost:8181/auth/v1/domains
589     {
590         "domains":
591         [
592             {
593                 "domainid":"sdn",
594                 "name":"sdn”,
595                 "description":"default odl sdn domain",
596                 "enabled":true
597             }
598         ]
599     }
600
601 **Token Store Configuration Parameters**
602 ########################################
603
604 Edit the file “etc/opendaylight/karaf/08-authn-config.xml” and edit the
605 following: .\ **timeToLive**: Configure the maximum time, in milliseconds,
606 that tokens are to be cached. Default is 360000. Save the file.
607
608 ODLJndiLdapRealm
609 ^^^^^^^^^^^^^^^^
610
611 How it works
612 ~~~~~~~~~~~~
613
614 LDAP integration is provided in order to externalize identity
615 management. This configuration allows federation with an external LDAP server.
616 The user’s OpenDaylight role parameters are mapped to corresponding LDAP
617 attributes as specified by the groupRolesMap. Thus, an LDAP operator can
618 provision attributes for LDAP users that support different OpenDaylight role
619 structures.
620
621 Configuring ODLJndiLdapRealm
622 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
623
624 To configure LDAP parameters, modify "etc/shiro.ini"
625 parameters to include the ODLJndiLdapRealm:
626
627 ::
628
629     # OpenDaylight provides a few LDAP implementations, which are disabled out of the box.
630     # ODLJndiLdapRealm includes authorization functionality based on LDAP elements
631     # extracted through and LDAP search.  This requires a bit of knowledge about
632     # how your LDAP system is setup.  An example is provided below:
633     ldapRealm = org.opendaylight.aaa.shiro.realm.ODLJndiLdapRealm
634     ldapRealm.userDnTemplate = uid={0},ou=People,dc=DOMAIN,dc=TLD
635     ldapRealm.contextFactory.url = ldap://<URL>:389
636     ldapRealm.searchBase = dc=DOMAIN,dc=TLD
637     ldapRealm.ldapAttributeForComparison = objectClass
638     ldapRealm.groupRolesMap = "Person":"admin"
639     # ...
640     # further down in the file...
641     # Stacked realm configuration;  realms are round-robbined until authentication succeeds or realm sources are exhausted.
642     securityManager.realms = $tokenAuthRealm, $ldapRealm
643
644 ODLJndiLdapRealmAuthNOnly
645 ^^^^^^^^^^^^^^^^^^^^^^^^^
646
647 How it works
648 ~~~~~~~~~~~~
649
650 This is useful for setups where all LDAP users are allowed equal access.
651
652 Configuring ODLJndiLdapRealmAuthNOnly
653 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
654
655 Edit the "etc/shiro.ini" file and modify the following:
656
657 ::
658
659     ldapRealm = org.opendaylight.aaa.shiro.realm.ODLJndiLdapRealm
660     ldapRealm.userDnTemplate = uid={0},ou=People,dc=DOMAIN,dc=TLD
661     ldapRealm.contextFactory.url = ldap://<URL>:389
662     # ...
663     # further down in the file...
664     # Stacked realm configuration;  realms are round-robbined until authentication succeeds or realm sources are exhausted.
665     securityManager.realms = $tokenAuthRealm, $ldapRealm
666
667 KeystoneAuthRealm
668 ^^^^^^^^^^^^^^^^^
669
670 How it works
671 ~~~~~~~~~~~~
672
673 This realm authenticates OpenDaylight users against the OpenStack's Keystone
674 server. This realm uses the
675 `Keystone's Identity API v3 <https://developer.openstack.org/api-ref/identity/v3/>`_
676 or later.
677
678 .. figure:: ./images/aaa/keystonerealm-authentication.png
679    :alt: KeystoneAuthRealm authentication mechanism
680
681    KeystoneAuthRealm authentication/authorization mechanism
682
683 As can shown on the above diagram, once configured, all the RESTCONF APIs calls
684 will require sending **user**, **password** and optionally **domain** (1). Those
685 credentials are used to authenticate the call against the Keystone server (2) and,
686 if the authentication succeeds, the call will proceed to the MDSAL (3). The
687 credentials must be provisioned in advance within the Keystone Server. The user
688 and password are mandatory, while the domain is optional, in case it is not
689 provided within the REST call, the realm will default to (**Default**),
690 which is hard-coded. The default domain can be also configured through the
691 *shiro.ini* file (see the :doc:`AAA User Guide <user-guide>`).
692
693 The protocol between the Controller and the Keystone Server (2) can be either
694 HTTPS or HTTP. In order to use HTTPS the Keystone Server's certificate
695 must be exported and imported on the Controller (see the :ref:`Certificate Management <certificate-management>` section).
696
697 Configuring KeystoneAuthRealm
698 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
699
700 Edit the "etc/shiro.ini" file and modify the following:
701
702 ::
703
704     # The KeystoneAuthRealm allows for authentication/authorization against an
705     # OpenStack's Keystone server. It uses the Identity's API v3 or later.
706     keystoneAuthRealm = org.opendaylight.aaa.shiro.realm.KeystoneAuthRealm
707     # The URL where the Keystone server exposes the Identity's API v3 the URL
708     # can be either HTTP or HTTPS and it is mandatory for this realm.
709     keystoneAuthRealm.url = https://<host>:<port>
710     # Optional parameter to make the realm verify the certificates in case of HTTPS
711     #keystoneAuthRealm.sslVerification = true
712     # Optional parameter to set up a default domain for requests using credentials
713     # without domain, uncomment in case you want a different value from the hard-coded
714     # one "Default"
715     #keystoneAuthRealm.defaultDomain = Default
716
717 Once configured the realm, the mandatory fields are the fully quallified name of
718 the class implementing the realm *keystoneAuthRealm* and the endpoint where the
719 Keystone Server is listening *keystoneAuthRealm.url*.
720
721 The optional parameter *keystoneAuthRealm.sslVerification* specifies whether the
722 realm has to verify the SSL certificate or not. The optional parameter
723 *keystoneAuthRealm.defaultDomain* allows to use a different default domain from
724 the hard-coded one *"Default"*.
725
726 Authorization Configuration
727 ---------------------------
728
729 OpenDaylight supports two authorization engines at present, both of which are
730 roughly similar in behavior:
731
732 - Shiro-Based Authorization
733
734 - MDSAL-Based Dynamic Authorization
735
736 .. note::
737
738     The preferred mechanism for configuring AAA Authentication is the
739     MDSAL-Based Dynamic Authorization. Read the following section.
740
741 Shiro-Based Static Authorization
742 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
743
744 OpenDaylight AAA has support for Role Based Access Control (RBAC) based
745 on the Apache Shiro permissions system. Configuration of the authorization
746 system is done off-line; authorization currently cannot be configured
747 after the controller is started. The Authorization provided by this mechanism
748 is aimed towards supporting coarse-grained security policies, the MDSAL-Based
749 mechanism allows for a more robust configuration capabilities. `Shiro-based
750 Authorization <http://shiro.apache.org/web.html#Web-%7B%7B%5Curls%5C%7D%7D>`_
751 describes how to configure the Authentication feature in detail.
752
753 .. note::
754
755     The Shiro-Based Authorization that uses the *shiro.ini* URLs section to
756     define roles requirements is **deprecated** and **discouraged** since the
757     changes made to the file are only honored on a controller restart.
758
759     Shiro-Based Authorization is not **cluster-aware**, so the changes made on
760     the *shiro.ini* file have to be replicated on every controller instance
761     belonging to the cluster.
762
763     The URL patterns are matched relative to the Servlet context leaving room
764     for ambiguity, since many endpoints may match (i.e., "/restconf/modules" and
765     "/auth/modules" would both match a "/modules/\**" rule).
766
767 Enable “admin” Role Based Access to the IdMLight RESTful web service
768 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
769
770 Edit the “etc/shiro.ini” configuration file and add “/auth/v1/\**=
771 authcBasic, roles[admin]” above the line “/\** = authcBasic” within the
772 “urls” section.
773
774 ::
775
776     /auth/v1/** = authcBasic, roles[admin]
777     /** = authcBasic
778
779 This will restrict the idmlight rest endpoints so that a grant for admin
780 role must be present for the requesting user.
781
782 .. note::
783
784     The ordering of the authorization rules above is important!
785
786 MDSAL-Based Dynamic Authorization
787 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
788 The MDSAL-Based Dynamic authorization uses the MDSALDynamicAuthorizationFilter
789 engine to restrict access to particular URL endpoint patterns. Users may define
790 a list of policies that are insertion-ordered. Order matters for that list of
791 policies, since the first matching policy is applied. This choice was made to
792 emulate behavior of the Shiro-Based Authorization mechanism.
793
794 A **policy** is a key/value pair, where the key is a **resource**
795 (i.e., a "URL pattern") and the value is a list of **permissions** for the
796 resource. The following describes the various elements of a policy:
797
798 - **Resource**: the resource is a string URL pattern as outlined by
799   Apache Shiro. For more information, see http://shiro.apache.org/web.html.
800
801 - **Description**: an optional description of the URL endpoint and why it is
802   being secured.
803
804 - **Permissions list**: a list of permissions for a particular policy. If more
805   than one permission exists in the permissions list they are evaluated using
806   logical "OR". A permission describes the prerequisites to perform HTTP
807   operations on a particular endpoint. The following describes the various
808   elements of a permission:
809
810   + **Role**: the role required to access the target URL endpoint.
811   + **Actions list**: a leaf-list of HTTP permissions that are allowed for a
812     Subject possessing the required role.
813
814 This an example on how to limit access to the modules endpoint:
815
816 ::
817
818     HTTP Operation:
819     put URL: /restconf/config/aaa:http-authorization/policies
820
821     or
822
823     put RFC8040 URL: /rests/data/aaa:http-authorization/policies
824
825     headers: Content-Type: application/json Accept: application/json
826
827     body:
828       { "aaa:policies":
829         { "aaa:policies":
830           [ { "aaa:resource": "/restconf/modules/**",
831             "aaa:permissions": [ { "aaa:role": "admin",
832                                    "aaa:actions": [ "get",
833                                                     "post",
834                                                     "put",
835                                                     "patch",
836                                                     "delete"
837                                                   ]
838                                  }
839                                ]
840             }
841           ]
842         }
843       }
844
845 The above example locks down access to the modules endpoint (and any URLS
846 available past modules) to the "admin" role. Thus, an attempt from the OOB
847 *admin* user will succeed with 2XX HTTP status code, while an attempt from the
848 OOB *user* user will fail with HTTP status code 401, as the user *user* is not
849 granted the "admin" role.
850
851 Accounting Configuration
852 ------------------------
853
854 Accounting is handled through the standard slf4j logging mechanisms used by the
855 rest of OpenDaylight. Thus, one can control logging verbosity through
856 manipulating the log levels for individual packages and classes directly through
857 the Karaf console, JMX, or etc/org.ops4j.pax.logging.cfg. In normal operations,
858 the default levels exposed do not provide much information about AAA services;
859 this is due to the fact that logging can severely degrade performance.
860
861 All AAA logging is output to the standard karaf.log file. For debugging purposes
862 (i.e., to enable maximum verbosity), issue the following command:
863
864 ::
865
866     log:set TRACE org.opendaylight.aaa
867
868 Enable Successful/Unsuccessful Authentication Attempts Logging
869 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
870
871 By default, successful/unsuccessful authentication attempts are NOT logged. This
872 is due to the fact that logging can severely decrease REST performance.
873 To enable logging of successful/unsuccessful REST attempts, issue the following
874 command in Karaf's console:
875
876 ::
877
878     log:set DEBUG org.opendaylight.aaa.shiro.filters.AuthenticationListener
879
880 It is possible to add custom AuthenticationListener(s) to the Shiro-based
881 configuration, allowing different ways to listen for successful/unsuccessful
882 authentication attempts. Custom AuthenticationListener(s) must implement
883 the org.apache.shiro.authc.AuthenticationListener interface.
884
885 .. _certificate-management:
886
887 Certificate Management
888 ----------------------
889
890 The **Certificate Management Service** is used to manage the keystores and
891 certificates at the OpenDaylight distribution to easily provides the TLS
892 communication.
893
894 The Certificate Management Service managing two keystores:
895
896 1. **OpenDaylight Keystore** which holds the OpenDaylight distribution
897    certificate self sign certificate or signed certificate from a root CA based
898    on generated certificate request.
899
900 2. **Trust Keystore** which holds all the network nodes certificates that shall
901    to communicate with the OpenDaylight distribution through TLS communication.
902
903 The Certificate Management Service stores the keystores (OpenDaylight & Trust)
904 as *.jks* files under configuration/ssl/ directory. Also the keystores
905 could be stored at the MD-SAL datastore in case OpenDaylight distribution
906 running at cluster environment. When the keystores are stored at MD-SAL,
907 the Certificate Management Service rely on the **Encryption-Service** to encrypt
908 the keystore data before storing it to MD-SAL and decrypted at runtime.
909
910 How to use the Certificate Management Service to manage the TLS communication
911 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
912
913 The following are the steps to configure the TLS communication:
914
915 1. After starting the distribution, the *odl-aaa-cert* feature has to get
916 installed. Use the following command at Karaf CLI to check.
917
918 .. code-block:: bash
919
920   opendaylight-user@root>feature:list -i | grep aaa-cert
921   odl-aaa-cert | 0.5.0-SNAPSHOT | x | odl-aaa-0.5.0-SNAPSHOT | OpenDaylight :: AAA :: aaa certificate Service
922
923 2. The initial configuration of the Certificate Manager Service exists under
924 the distribution directory etc/opendaylight/datastore/initial/config/aaa-cert-config.xml.
925
926 .. code-block:: xml
927
928   <aaa-cert-service-config xmlns="urn:opendaylight:yang:aaa:cert">
929     <use-config>false</use-config>
930     <use-mdsal>false</use-mdsal>
931     <bundle-name>opendaylight</bundle-name>
932     <ctlKeystore>
933       <name>ctl.jks</name>
934       <alias>controller</alias>
935       <store-password/>
936       <dname>CN=ODL, OU=Dev, O=LinuxFoundation, L=QC Montreal, C=CA</dname>
937       <validity>365</validity>
938       <key-alg>RSA</key-alg>
939       <sign-alg>SHA1WithRSAEncryption</sign-alg>
940        <keysize>1024</keysize>
941        <cipher-suites>
942          <suite-name />
943        </cipher-suites>
944     </ctlKeystore>
945     <trustKeystore>
946       <name>truststore.jks</name>
947       <store-password/>
948     </trustKeystore>
949   </aaa-cert-service-config>
950
951
952 Now as it is explained above, the Certificate Manager Service support two mode
953 of operations; cluster mode and single mode. To use the single mode change the
954 use-config to true and it is recommended as long as there is no need for
955 cluster environment. To use the cluster mode change the use-config and
956 use-mdsal configurations to true and the keystores will be stored and shard
957 across the cluster nodes within the MD-SAL datastore.
958
959 The initial password become randomly generated when the *aaa-cert* feature is
960 installed.
961
962 The cipher suites can be restricted by changing the **<cipher-suites>**
963 configuration, however, the JDK has to be upgraded by installing the `Java
964 Cryptography Extension
965 <http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html>`_
966 policy.
967
968 .. code-block:: xml
969
970   <cipher-suites>
971     <suite-name>TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384</suite-name>
972   </cipher-suites>
973     <cipher-suites>
974   <suite-name>TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384</suite-name>
975     </cipher-suites>
976   <cipher-suites>
977     <suite-name>TLS_DHE_RSA_WITH_AES_256_GCM_SHA384</suite-name>
978   </cipher-suites>
979
980 3. The new configurations will take affect after restarting the distribution.
981
982 4. Now to add or get certificate to the OpenDaylight and Trust keystores, the
983 Certificate Manager Service provides the following RPCs.
984
985 ::
986
987   a) Set the node certificate that will communicate with OpeDaylight through TLS
988   connection.
989   POST /operations/aaa-cert-rpc:setNodeCertifcate
990   {
991     "input": {
992       "node-cert": "string",
993       "node-alias": "string"
994     }
995   }
996
997 ::
998
999   b) Get the node certificate based on node alias.
1000   POST /operations/aaa-cert-rpc:getNodeCertifcate
1001   {
1002     "input": {
1003       "node-alias": "string"
1004     }
1005   }
1006
1007 ::
1008
1009   c) Get the OpeDaylight keystore certificate.
1010   POST /operations/aaa-cert-rpc:getODLCertificate
1011   {
1012     output {
1013       odl-cert "string"
1014     }
1015   }
1016
1017 ::
1018
1019   d) Generate a certificate request from the OpeDaylight keystore to be signed
1020   by a CA.
1021   POST /operations/aaa-cert-rpc:getODLCertificateReq
1022   {
1023     output {
1024       odl-cert-req "string"
1025     }
1026   }
1027
1028 ::
1029
1030   e) Set the OpeDaylight certificate, the certificate should be generated
1031   based on a certificate request generated from the ODL keystore otherwise the
1032   certificated will not be added.
1033   POST /operations/aaa-cert-rpc:setODLCertificate
1034   {
1035     "input": {
1036       "odl-cert-alias": "string",
1037       "odl-cert": "string"
1038     }
1039   }
1040
1041 .. note::
1042
1043   The Certificate Manager Service RPCs are allowed only to the Role Admin Users
1044   and it could be completely disabled through the shiro.ini config file. Check
1045   the URL section at the shiro.ini.
1046
1047 Encryption Service
1048 ------------------
1049
1050 The **AAA Encryption Service** is used to encrypt the OpenDaylight's users'
1051 passwords and TLS communication certificates. This section shows how to use the
1052 AAA Encryption Service with an OpenDaylight distribution project to encrypt data.
1053
1054 The following are the steps to configure the Encryption Service:
1055
1056 1. After starting the distribution, the *aaa-encryption-service* feature has to
1057    get installed. Use the following command at Karaf CLI to check.
1058
1059    .. code-block:: bash
1060
1061       opendaylight-user@root>feature:list -i | grep aaa-encryption-service
1062       odl-aaa-encryption-service | 0.5.0-SNAPSHOT | x | odl-aaa-0.5.0-SNAPSHOT | OpenDaylight :: AAA :: Encryption Service
1063
1064 2. The initial configuration of the Encryption Service exists under the
1065    distribution directory etc/opendaylight/datastore/initial/config/aaa-encrypt-service-config.xml
1066
1067    .. code-block:: xml
1068
1069       <aaa-encrypt-service-config xmlns="config:aaa:authn:encrypt:service:config">
1070         <encrypt-key/>
1071         <encrypt-salt/>
1072         <encrypt-method>PBKDF2WithHmacSHA1</encrypt-method>
1073         <encrypt-type>AES</encrypt-type>
1074         <encrypt-iteration-count>32768</encrypt-iteration-count>
1075         <encrypt-key-length>128</encrypt-key-length>
1076         <cipher-transforms>AES/CBC/PKCS5Padding</cipher-transforms>
1077       </aaa-encrypt-service-config>
1078
1079    .. note::
1080
1081       Both the initial encryption key and encryption salt become randomly generated
1082       when the *aaa-encryption-service* feature is installed.
1083
1084 3. Finally the new configurations will take affect after restarting the
1085    distribution.
1086
1087 Using the AAA Command Line Interface (CLI)
1088 ------------------------------------------
1089 The AAA offers a CLI through the Karaf's console. This CLI allows the user to
1090 configure and use some of the functionalities provided by AAA.
1091
1092 The AAA CLI exists under the **odl-aaa-cli** feature. This feature can be
1093 installed by executing the following command.
1094
1095 ::
1096
1097   feature:install odl-aaa-cli
1098
1099 To check that the installation of the feature succeeded type "aaa" and press
1100 *tab* to see the list of available commands under the *aaa* scope.
1101
1102 ::
1103
1104   opendaylight-user@root>aaa:
1105   aaa:add-domain           aaa:add-grant            aaa:add-role             aaa:add-user
1106   aaa:change-user-pwd      aaa:export-keystores     aaa:gen-cert-req         aaa:get-cipher-suites
1107   aaa:get-domains          aaa:get-node-cert        aaa:get-odl-cert         aaa:get-roles
1108   aaa:get-tls-protocols    aaa:get-users            aaa:import-keystores     aaa:remove-domain
1109   aaa:remove-grant         aaa:remove-role          aaa:remove-user
1110
1111 Add a User
1112 ^^^^^^^^^^
1113
1114 The *add-user* command allows for adding an OpenDaylight user. The following
1115 user parameters can be specified.
1116
1117 ::
1118
1119   aaa:add-user --userName <user name>
1120                --roleName <role>
1121                --userDescription <user description>
1122                --userEmail <user email>
1123                --domainName <domain name>
1124
1125 List available Users
1126 ^^^^^^^^^^^^^^^^^^^^
1127
1128 The *get-users* command list all the available users within the Controller.
1129
1130 ::
1131
1132   aaa:get-users
1133
1134     user
1135     admin
1136
1137 Remove a User
1138 ^^^^^^^^^^^^^
1139
1140 The *remove-user* command allows for removing an OpenDaylight user. The command
1141 needs the user name as parameter.
1142
1143 ::
1144
1145   aaa:remove-user --name <user name>
1146
1147 Change the OpenDaylight user password
1148 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1149
1150 The *change-user-pwd* command allows for changing the OpenDaylight user's
1151 password. It takes the user name as argument then will ask for the given user
1152 current password.
1153
1154 ::
1155
1156   aaa:change-user-pwd --userName admin
1157     Enter current password:
1158     Enter new password:
1159     admin's password has been changed
1160
1161 Add a Role
1162 ^^^^^^^^^^
1163
1164 The *add-role* command allows for adding a role to the Controller.
1165
1166 ::
1167
1168   aaa:add-role --roleName <role name>
1169                --roleDescription <role description>
1170                --domainName <domain name>
1171
1172 List available Roles
1173 ^^^^^^^^^^^^^^^^^^^^
1174
1175 The *get-roles* command list all the available roles within the controller.
1176
1177 ::
1178
1179   aaa:get-roles
1180
1181     user
1182     admin
1183
1184 Remove a Role
1185 ^^^^^^^^^^^^^
1186
1187 The *remove-role* command allows for removing an OpenDaylight role. The command
1188 needs the role name as parameter.  The role will be removed from those users who
1189 have it.
1190
1191 ::
1192
1193   aaa:remove-role --roleName <role name>
1194
1195 Add a Domain
1196 ^^^^^^^^^^^^
1197
1198 The *add-domain* command allows for adding a domain to the Controller.
1199
1200 ::
1201
1202   aaa:add-domain --domainName <domain name>
1203                  --domainDescription <domain description>
1204
1205 List available Domains
1206 ^^^^^^^^^^^^^^^^^^^^^^
1207
1208 The *get-domains* command list all the available domains within the controller.
1209 The system asks for the administrator credentials to execute this command.
1210
1211 ::
1212
1213   aaa:get-domains
1214
1215     sdn
1216
1217 Remove a Domain
1218 ^^^^^^^^^^^^^^^
1219
1220 The *remove-domain* command allows for removing an OpenDaylight role. The command
1221 needs the domain name as parameter.
1222
1223 ::
1224
1225   aaa:remove-domain --domainName <domain name>
1226
1227 Add a Grant
1228 ^^^^^^^^^^^
1229
1230 The *add-grant* command allows for creating a grant for an existing user. The
1231 command returns a grant id for that user.
1232
1233 ::
1234
1235   aaa:add-grant --userName <user name>
1236                 --domainName <domain name>
1237                 --roleName <role name>
1238
1239 Remove a Grant
1240 ^^^^^^^^^^^^^^
1241
1242 The *remove-grant* command allows for removing an OpenDaylight grant. This command
1243 needs the user name, domain and and role as parameters.
1244
1245 ::
1246
1247   aaa:remove-grant --userName <user name>
1248                    --domainName <domain name>
1249                    --roleName <role name>
1250
1251 Generate Certificate Request
1252 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1253
1254 Generate certificate request command will generate a certificate request based
1255 on the generated OpenDaylight keystore and print it on the Karaf CLI. The system
1256 asks for the keystore password.
1257
1258 ::
1259
1260   aaa:gen-cert-req
1261
1262   -----BEGIN CERTIFICATE REQUEST-----
1263   MIIBlzCCAQACAQAwWTELMAkGA1UEBhMCQ0ExFDASBgNVBAcMC1FDIE1vbnRyZWFsMRgwFgYDVQQKDA
1264   9MaW51eEZvdW5kYXRpb24xDDAKBgNVBAsMA0RldjEMMAoGA1UEAwwDT0RMMIGfMA0GCSqGSIb3DQEB
1265   AQUAA4GNADCBiQKBgQCCmLW6j+JLYJM5yAMwscw/CHqPnp5elPa1YtQsHKEAvp1I+mLVtHKZeXeteA
1266   kyp6ORxw6KQ515fcDyQVrRJiSM15jUd27UaFq5ku0+qJeG+Qh2btx+cvNSE7/+cgUWWosKz4Aff5F5
1267   FqR62jLUTNzqCvoaTbZaOnLYVq+O2dYyZwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADhDr4Jm7gVm/o
1268   p861/FShyw1ZZscxOEl2TprJZiTO6sn3sLptQZv8v52Z+Jm5dAgr7L46c97Xfa+0j6Y4LXNb0f88lL
1269   RG8PxGbk6Tqbjqc0WS+U1Ibc/rcPK4HEN/bcYCn+Na1gLBaFXUPg08ozG6MwqFNeS5Z0jz1W0D9/oiao
1270   -----END CERTIFICATE REQUEST-----
1271
1272 Get OpenDaylight Certificate
1273 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1274
1275 The *get-odl-certificate* command will print the OpenDaylight certificate at the
1276 Karaf CLI. The system asks for the keystore password.
1277
1278 ::
1279
1280   aaa:get-odl-cert -storepass <store_password>
1281
1282   -----BEGIN CERTIFICATE-----
1283   MIICKTCCAZKgAwIBAgIEI75RWDANBgkqhkiG9w0BAQUFADBZMQwwCgYDVQQDDANPREwxDDAKBgNVBA
1284   sMA0RldjEYMBYGA1UECgwPTGludXhGb3VuZGF0aW9uMRQwEgYDVQQHDAtRQyBNb250cmVhbDELMAkG
1285   A1UEBhMCQ0EwHhcNMTYxMTMwMTYyNDE3WhcNMTcxMTMwMTYyNDE3WjBZMQwwCgYDVQQDDANPREwxDD
1286   AKBgNVBAsMA0RldjEYMBYGA1UECgwPTGludXhGb3VuZGF0aW9uMRQwEgYDVQQHDAtRQyBNb250cmVh
1287   bDELMAkGA1UEBhMCQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIKYtbqP4ktgkznIAzCxzD
1288   8Ieo+enl6U9rVi1CwcoQC+nUj6YtW0cpl5d614CTKno5HHDopDnXl9wPJBWtEmJIzXmNR3btRoWrmS
1289   7T6ol4b5CHZu3H5y81ITv/5yBRZaiwrPgB9/kXkWpHraMtRM3OoK+hpNtlo6cthWr47Z1jJnAgMBAA
1290   EwDQYJKoZIhvcNAQEFBQADgYEAL9DK/P/yEBre3Mg3bICAUAvSvZic+ydDmigWLsY4J3UzKdV2f1jI
1291   s+rQTEgtlHShBf/ed546D49cp3XEzYrcxgILhGXDziCrUK0K1TiYqPTp6FLijjdydGlPpwuMyyV5Y0
1292   iDiRclWuPz2fHbs8WQOWNs6VQ+WaREXtEsEC4qgSo=
1293   -----END CERTIFICATE-----
1294
1295 Get Cipher Suites
1296 ^^^^^^^^^^^^^^^^^
1297
1298 The *get-cipher-suites* command shows the cipher suites supported by the
1299 JVM used by the OpenDaylight controller in TLS communication. For example, here
1300 are the `Default Ciphers Suites in JDK 8 <http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#ciphersuites>`_.
1301
1302 ::
1303
1304   aaa:get-cipher-suites
1305
1306     TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
1307     TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
1308     TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
1309
1310 Get TLS Protocols
1311 ^^^^^^^^^^^^^^^^^
1312
1313 The *get-tls-protocols* command shows the TLS protocols supported by the
1314 JVM used by the OpenDaylight controller. For example, the JDK 8 supports the
1315 following TLS protocols: TLSv1.2 (default), TLSv1.1, TLSv1 and SSLv3.
1316
1317 ::
1318
1319   aaa:get-tls-protocols
1320
1321     TLS_KRB5_WITH_RC4_128_SHA
1322     TLS_KRB5_WITH_RC4_128_MD5
1323     TLS_KRB5_WITH_3DES_EDE_CBC_SHA
1324     TLS_KRB5_WITH_3DES_EDE_CBC_MD5
1325     TLS_KRB5_WITH_DES_CBC_SHA
1326
1327 Get Node Certificate
1328 ^^^^^^^^^^^^^^^^^^^^
1329
1330 The *get-node-cert* command prints a certificate for a given network node alias.
1331 This command is useful to check if the network node certificate has been added
1332 properly to the truest keystore. It takes the certificate alias as arguments.
1333
1334 ::
1335
1336   aaa:get-node-cert -alias ovs1
1337   -----BEGIN CERTIFICATE-----
1338   MIICKTCCAZKgAwIBAgIEI75RWDANBgkqhkiG9w0BAQUFADBZMQwwCgYDVQQDDANPREwxDDAKBgNVBA
1339   sMA0RldjEYMBYGA1UECgwPTGludXhGb3VuZGF0aW9uMRQwEgYDVQQHDAtRQyBNb250cmVhbDELMAkG
1340   A1UEBhMCQ0EwHhcNMTYxMTMwMTYyNDE3WhcNMTcxMTMwMTYyNDE3WjBZMQwwCgYDVQQDDANPREwxDD
1341   AKBgNVBAsMA0RldjEYMBYGA1UECgwPTGludXhGb3VuZGF0aW9uMRQwEgYDVQQHDAtRQyBNb250cmVh
1342   bDELMAkGA1UEBhMCQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIKYtbqP4ktgkznIAzCxzD
1343   8Ieo+enl6U9rVi1CwcoQC+nUj6YtW0cpl5d614CTKno5HHDopDnXl9wPJBWtEmJIzXmNR3btRoWrmS
1344   7T6ol4b5CHZu3H5y81ITv/5yBRZaiwrPgB9/kXkWpHraMtRM3OoK+hpNtlo6cthWr47Z1jJnAgMBAA
1345   EwDQYJKoZIhvcNAQEFBQADgYEAL9DK/P/yEBre3Mg3bICAUAvSvZic+ydDmigWLsY4J3UzKdV2f1jI
1346   s+rQTEgtlHShBf/ed546D49cp3XEzYrcxgILhGXDziCrUK0K1TiYqPTp6FLijjdydGlPpwuMyyV5Y0
1347   iDiRclWuPz2fHbs8WQOWNs6VQ+WaREXtEsEC4qgSo=
1348   -----END CERTIFICATE-----
1349
1350 Export Keystores
1351 ^^^^^^^^^^^^^^^^
1352
1353 The *export-keystores* command exports the default MD-SAL Keystores to .jks
1354 files in the default directory for keystores (configuration/ssl/).
1355
1356 ::
1357
1358   aaa:export-keystores
1359
1360     Default directory for keystores is configuration/ssl/
1361
1362 Import Keystores
1363 ^^^^^^^^^^^^^^^^
1364
1365 The *import-keystores* command imports the default MD-SAL Keystores. The
1366 keystores (odl and trust) should exist under default SSL directory
1367 (configuration/ssl/).
1368
1369 .. code-block:: bash
1370
1371   aaa:import-keystores --trustKeystoreName <name of the trust keystore>
1372                        --trustKeystorePwd <password for the trust keystore>
1373                        --odlKeystoreName <name of the ODL keystore>
1374                        --odlKeystorePwd <password for the ODL keystore>
1375                        --odlKeystoreAlias <alias of the ODL keystore>
1376                        --tlsProtocols <list of TLS protocols separated by ','>
1377                        --cipherSuites <list of Cipher suites separated by ','>
1378
1379 .. warning::
1380
1381   It is strongly recommended to run the history clear command after you execute
1382   all the AAA CLI commands so Karaf logs stay clean from any adversary.
1383
1384   ::
1385
1386     history -c