Installation of a branded new CI ******************************** Configuration of the Credential Infrastructure ============================================== Since its version 3.0, **CVault** has migrated to the concept of “extended configuration”, which allows to present unified data structure to all parts of the CI. The overall CI is configured with a common configuration file *“cv.xconf”*. The cache manager and the admin daemon may get their specialized configuration from a dedicated file, respectively *“cvad.xconf”* and *“cvcm.xconf”*. All configuration directives have the form:: item = value part1; value part2; ... The configuration files are hierarchical: this avoid to store common directives (to both daemons for example) in a common files accessible by anyone. The overriding path is the following: default => cv.xconf => cvcm.xconf => cvad.xconf. Common configuration: **cv.xconf** ---------------------------------- This files store the configuration directives used by anyone of the CI, summarized in the table below: ============= ========================================================= ======================== ============ name item default value min-max ============= ========================================================= ======================== ============ *udpport* UDP port **cvcm** listens to. 7777 1024-65535 *sockpath* UX socket linked to **cvcm**. **CVROOT**/var/cvcm.sock - *tcpport* TCP port **cvad** listens to. 8888 1024-65535 *verbosity* Messages verbosity in logs. - 0-255 ============= ========================================================= ======================== ============ For the verbosity configuration item, some synonyms have been defined: * *extern, intern, cascade*: origin of the transaction which activity is being logged, * *daemon, rpc, automat, cache, backend, plugin*: sublevel (going to the deepest) to log. * *debug*: log everything. The file *cv.xconf* should be set readable by the primary group of the "cvault" user, and writeable only to "cvault" user. Cache Manager configuration: **cvcm.xconf** ------------------------------------------- This file stores the configuration directives used by the cache manager only. The table below gives the directives used by the cache manager only: ============= ========================================================= ======================== ============ name item default value min-max ============= ========================================================= ======================== ============ *clogfile* Full path of the file where **cvcm** logs its messages. **CVROOT**/var/cvcm.log - *cachelife* maximum time (sec) data remains in cache. 5 (minutes) 0 - INTmax *cachesize* number max of credentials lines, (ACLs = 10x). 1000 0 - INTmax *threshold* number of cache lines triggering BTree search. 100 0 - cachesize *serverlife* inactivity timeout for being removed from DB by peers. 60 (1 hour) 0 - INTmax *threads* Nb threads max for processing atomic transactions. 0 0 - INTmax *dbpoolsize* Nb of simultaneous connections to the DB. 5 0 - INTmax *dbfallback* Whether DB search fall back on local file. 0 (no) 0 - 1 *dbsnapshots* Interval between backups (whole DB) into local file. 5 0 - INTmax *masterkey* Master Key Store. **CVROOT**/var/cvcm.mk - *keyfile* File with binary keys of allowed clients. **CVROOT**/var/cvcm.clk - *cliuuid* Client ID used for internally triggered secure queries. None but Mandatory. - *admhosts* List of hosts allowed to perform privileged transactions. None but List Mandatory. - ============= ========================================================= ======================== ============ All items relative to timing are given in minutes. The last item *admhosts* is particular: the CI manager must set a list of trusted hosts. At least *localhost* should have been given, otherwise no management tasks will be possible. The table below gives the directives used by the cache manager, but also shared with the admin manager: ============= ========================================================= ======================== ============ name item default value min-max ============= ========================================================= ======================== ============ *dbengine* MySQL, Postgres, LDAP or file (decides plugin to load). DBFile - *dbhost* FQDN of DB server host (localhost for DBfile). - - *dbport* TCP port of the DB server (none for DBFile). According to the engine. 0 - 65535 *dbuser* DB username for LDAP, MySQL or PostgreSQL. None but mandatory. - *dbpasswd* DB user credential (encrypted with MK). - - *dbfile* DB filename, also for import & export. **CVROOT**/var/cvci.fdb - *basedn* Root DIT (LDAP only, mandatory in that case). - - *dbtimeout* Timeout before failing DB connection. 1 0 - INTmax *syslog* Whether logs messages are syslog'ed as well. 0 (No) 0 - 1 *secmemsz* Amount of secure memory (kB) 1024 0 - INTmax *useracct* Account name of the user the CI belongs to (cvault). None but Mandatory. - *plugpath* Path where to find the DB plugins. **CVROOT**/lib - *mkprivilege* Binaries which have rights to perform MK remote ops. None but List Mandatory. - ============= ========================================================= ======================== ============ The file *cvcm.xconf* should be set read-writeable only for the "cvault" user. The cache manager is "hot-reconfigurable". In this case, one must note that the *dbfile* and *dbsnap* values are not reconfigurable. This means that these values are read once and fixed for the whole life of **cvcm**. These choices have been dictated by performance reasons to avoid locking storms on the configuration structure. Admin Daemon configuration: **cvad.xconf** ------------------------------------------ This file stores the configuration directives used by the administration server only. It is read by no one else and no directive are shared. On the other hand, since we are at the highest level of the hierarchy, **cvad** may override any configuration item. Discrepancies with previous directives (backend DB definitions, etc) may lead to severe consequences. ============= ========================================================= ======================== ============ name item default value min-max ============= ========================================================= ======================== ============ *admfile* Filename for admin users (overridden by DB entries). **CVROOT**/etc/cvad.adm - *admuser* Default admin username. cvmgr - *alogfile* Full path of the file where **cvcm** logs its messages. **CVROOT**/var/cvad.log - ============= ========================================================= ======================== ============ The file *cvad.xconf* should be set read-writeable only for the "cvault" user. Setting a new Credentials Infrastructure from scratch ===================================================== To begin with a branded new CI, the tasks to perform are the following: initialization of the back-end DB, getting encrypted credentials for the CI, and loading the credentials that will be managed. Once the back-end database and its related accessing user are created, everything can be performed with the CI itself. Overall setting considerations for the CI ----------------------------------------- Before starting any deployment, there are some initial credentials to define. * Master Key: The root encryption key for all protected data. * Backend credentials: User used to connect to the DB Backend. * **cvcm** password: Password from which the cache manager derives its binary key used to encrypt its confidential data. * Admin credentials : The administrator of the overall CI. For the purpose of this document, we will use the following credentials: ============== ============================== Name Value ============== ============================== CI user "cvault", group "cvault" Master Key "MasterKey" Backend "cvback"/"bkpwd" cvcm key default, embedded (i.e ENTER) Admin "cvmgr"/"mgrpwd" ============== ============================== We will need to record the Master Key in its file, then generate the encrypted password of the database user 'cvback' and at last generate the keys for each trusted binary which has to exchange confidential data with the cache manager. System Settings --------------- From now on, we consider that the installation has occurred in *"/opt/cv"* and belongs to the system user *"cvault"* of the primary group *"cvault"* (all default build values). The first setting to ensure is that all users allowed to use the CI are added to the group "cvault". CV needs some privileges on the system, particularly the ability to reserve memory anchored in the core and not swappable. The settings have to allow somewhat 2 to 4 MB to the user "cvault" and 256k to the group "cvault". For example, on Linux, this will go through the edition of the system file *"/etc/security/limits.conf"* adding the following lines:: cvault hard memlock 4096 @cvault hard memlock 256 On Solaris, this goes first through the modifications of the privileges allowing the users to perform this reservation:: root$ usermod -k defaultpriv=basic,proc_loc_memory cvault root$ groupmod -k defaultpriv=basic,proc_loc_memory cvault The last setting is to include *"/opt/cv/bin"* in the PATH of all users belonging to the group "cvault". Eventually, it may happen that **cvcm** refuses to start with a message like:: *** ABORT @ main.347: Unknown host (-1) This probably means that the hostname running **cvcm** is not resolved by the *resolver* and complementary settings may be necessary either in the DNS or in the local file ``/etc/hosts``. CI Initial Settings ------------------- To produce the Master key, the backend encrypted credentials and to register the keys of the trusted binaries, we need a working CI. To achieve this, we want to define a minimalistic configuration: madatory parameters, all other parameters set to default values and DB on file (the file has to exist, but must not necessary contain data). The configuration files reduced to their minimum may look like the following: **cv.xconf**: :: verbosity = debug **cvcm.xconf**: :: useracct = cvault cliuuid = 00000000 admhosts = localhost mkprivilege = dummy; Then create an empty DB file with:: cvault$ touch /opt/cv/var/cvci.fdb This is enough to be able to launch the cache manager for our purposes. Now it is time to create the Master Key and this is achieved by running the command: :: cvault$ cvcm -m password: Master Key cvault$ It is wise to verify that only the user cvault can read the newly created Master key file *"/opt/var/cvcc.mk"*. It is recommended to execute this operation on every host, instead of propagating the Master Key file over the whole CI: since the same key will appear in a different manner, this would help vanish the information "which host belongs to which CI". Then we let the cache manager register the signatures of the trusted binaries. These trusted binaries are the ones allowed to exchange confidential data with the cache manager through an encrypted channel. There are also the clients which have the right to connect to the administration server. Their registration occurs as follow: :: cvault$ cvcm -s cvquery,cvad,cvctl password: *** Successfully stored 'cvquery' signature. *** Successfully stored 'cvad' signature. *** Successfully stored 'cvctl' signature. cvault$ Again, we want to verify that only the user *cvault* can read the newly created keystore file *"/opt/var/cvcm.clk"* and we are done for the very first settings. It may be useful to cross-check the cryptography settings between each client and the cache manager. For the utility *cvquery* for example, it would look like the following: First perform the test from the cache manager side: :: cvault$ cvcm -X cvquery foobar HMACSHA1(cvquery,foobar) = gK5P2RYEoHNlddqRhbDBjLPP4aJ= Then perform the test from the client side: :: cvault$ cvquery -X foobar HMACSHA1(cvquery,foobar) = gK5P2RYEoHNlddqRhbDBjLPP4aJ= cvault$ The answers are identical, so both entities can communicate via secured channel. Repeat this cross check for the other 2 clients... Back-end Settings ----------------- Setting the MySQL/MariaDB back-end ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The minimum version to use if 5.05. As we want to access the DB from any host of the organization network, the binding directive must be deactivated in the configuration file *“my.cnf”*. A commented line such as below is also a solution: :: # bind-address = [xxx.xxx.xxx.xxx] Then, we want to login as root (MySQL's root: after a branded new installation, issuing *"mysqladmin password "* may be necessary), remove the generic user for obvious security reasons, create the user *“cvback”* and grant to it any right on the CV database. If the user is supposed to also connect directly from the DB server, then a user *“cvback@localhost”* must be created as well.:: cvault$ mysql -u root -p mysql> use mysql; mysql> delete from user where user = ''; mysql> create user cvback identified by 'bkpwd'; mysql> grant all on CV.* to cvback; mysql> create user cvback@localhost identified by 'bkpwd'; mysql> grant all on CV.* to cvback@localhost; mysql> flush privileges; mysql> exit; cvault$ After this, login as user 'cvback' and create the database using the following statement:: cvault$ mysql -u cvback -pbkpwd mysql> CREATE DATABASE IF NOT EXISTS CV DEFAULT CHARACTER SET latin1 COLLATE latin1_bin; mysql> USE CV; mysql> SET storage_engine = InnoDB; mysql> exit; cvault$ We use the InnoDB storage engine because we want to ensure that MySQL will not ignore the integrity constraints in the schema. The MySQL back-end is ready for initialization. Setting the PostgreSQL back-end ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ On PostgresSQL installations, the default settings usually allow only users with Unix account to connect to the database as administrator, and only local connections are allowed. Therefore, login as *“postgres”* Unix user and then edit the file *"postgresql.conf"* to make sure to have the following entries allowing remote connections on standard port: :: listen_addresses = '*' port = 5432 Then edit the file *"pg_hba.conf"* to allow remote connections from the company's network (we assume here a class C network 192.168.2.0 with MD5 password authentication) and local connections as well:: host all all 192.168.2.0/24 md5 host all all 127.0.0.1/32 md5 A restart is mandatory. Then, we want to login with the “admin” user (often from the unix user *'postgres'* after an initial installation), create the user “cvback” and its database “CV” by running the following:: postgres$ psql -U postgres postgres=# create user cvback with encrypted password 'bkpwd'; postgres=# CREATE DATABASE "CV" WITH OWNER = cvback TEMPLATE = template0 ENCODING = 'LATIN1' -- (or 'UTF-8' or 'WIN1252' ...) TABLESPACE = pg_default; postgres=# \q postgres$ The PostgreSQL back-end is ready for initialization. Setting the LDAP back-end ~~~~~~~~~~~~~~~~~~~~~~~~~ The schema of CV *cv.schema* must be included on an up & running LDAP server (beside *core*, *cosine* and *inetorgperson* schema's). From a fresh installation of LDAP, the dc object for the Root DSE must have been created first. With the LDAP manager credentials, create the main container of CV and its accessing user from the shell:: cvault$ ldapadd -h -D -w < objectClass: top objectClass: cvContainer cn: cv dn: cn=cvback,cn=cv, objectClass: top objectClass: person sn: cvback cn: cvback CONTAINER cvault$ Then set the LDAP password for the user “cvback” from the shell:: cvault$ ldappasswd -h -D -w -s bkpwd cn=cvback,cn=cv, Test if access is Ok (may be enforced and constrained with ACLs at the LDAP server level):: cvault$ ldapsearch -h -D cn=cvback,cn=cv, -w bkpwd -b cn=cv, The LDAP back-end is ready for initialization. CI Daemons Setting ------------------ The CI will be set-up with its own tools. To get an overall help, each tool will present a quick usage guide with the switch ``--help``. Cache manager configuration and back-end DB initialization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We will need to generate the encrypted password of the database user “cvback” and then initialize an empty database. We will take the LDAP back-end as example, but the operations are exactly the same for MySQL and PostgreSQL back-ends. It obviously doesn't apply to the DBFile back-end, since this one is read-only for the cache manager. Taking back our previous starting configuration file *"/opt/cv/etc/cvcm.xconf"*, we now define the utilities which are allowed to perform Master Key related operations via the cache manager, we will need them soon: :: mkprivilege = cvad; cvctl Next step is to generate the encrypted backend password to put it in the configuration file:: cvault$ cvcm -P bkpwd M3+NX6OVG+WZYLONkvzxGL2Nc8pxFD== cvault$ Password are randomized, so nobody will get the answer from this example. One can verify the randomization by issuing a second time the same command:: cvault$ cvcm -P bkpwd eHJBpvyIFNHLqoJeP3k643BXWp7tbB== cvault$ We can now update the configuration file of the cache manager with the directives set according to the features we really want to use (here: cache activated, log also in syslog, and fallback on flat files in case of failure of the back-end with snapshot every hour). A starting configuration may look like below: **cvcm.xconf**:: useracct = cvault cliuuid = 00000000 admhosts = localhost mkprivilege = cvad; cvctl # DB backend settings dbhost = dbengine = LDAP basedn = cn=cv, # The base DN is not necessary for the dbuser dbuser = cn=cvback dbpasswd = eHJBpvyIFNHLqoJeP3k643BXWp7tbB== # Cache (linear only) cachelife = 10 cachesize = 1000 threshold = 0 # DB availability dbfallback = Yes dbsnap = 60 # Misc threads = 16 verbosity = debug From here, we can (re-)initialize an empty DB:: cvault$ cvcm -r Using a nice GUI to look directly inside the data of the LDAP (*LDAPBrowser* is such a lightweight tool), one can notice the overall DIT, which has just been created. In cases of MySQL and PostgreSQL, this command triggers the creation of the tables (and *Squirrel* is a nice lightweight tool for those DB engines). Admin server configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~ The administration server *“cvad”* manages the DB and the cache manager. It retrieves its main configuration from the cache manager one, hence a very reduced configuration file: **cvad.xconf**:: admfile = "/opt/cv/etc/cvad.adm" With an empty DB, the administrators must be defined in a special configuration file. The credentials stored in this file are the HMAC-SHA1 in B64 encoding of the passwords (authentication on *cvad* occurs with only encrypted passwords). First, we want to generate the HMAC of "cvmgr's" password. With a running *cvcm*, this is performed by the following:: cvault$ cvad -s cvmgr cvmgr password: cvault$ After the DB has been set up, the administrators can be stored into it, with two different password policies: * The HMAC of the password is stored with the admin user in the corresponding entry: in that case, each call to "*cvctl"* will lead to a manual login (password must be typed on the keyboard). * The password is not stored with the entry, but like any other credential as standard record of the CI. In that case, it will be retrieved (provided the corresponding ACL allows this) and no interactive login will occur when calling "*cvctl"*. The last step is to load at least one user key into the DB. First generate a keyfile to load: :: cvault$ cat </opt/cv/var/cvcache.pkey privkeys = $(cvcm -P CvUsrKey) PRIVKEY Then upload the file into the DB and remove it:: cvault$ cvctl -u /opt/cv/var/cvcache.pkey cvault$ rm /opt/cv/var/cvcache.pkey The DB is ready for use. Now, an initial load may occur if a DB file is already available. Otherwise, the DB can be fulfilled with the Java GUI administration tool *"CvAdmin"* from any java capable host. DB File Format and creating entries manually -------------------------------------------- With the data semantic in mind, the DB file has to respect the following constraints: * a credential must have a single id, * an ACL must have a single id and refer to an existing credential id * an Access Control must refer to an existing acl id The overall format is the following::: adusers = ; MKHMAC(admin password) privkeys = ; credentials = ; ; ; [container]; ; [comment] accesslist = ; ; ; ; ; accessctrl = ; Let's consider we want to create the password entry for the administrator user "cvmgr", and that our CI is running on a host named "cvhost". Since it is a *"system"* credential, it will be stored "Hmac'ed" with the Maser Key in the DB file: :: cvault$ cvcm -H mgrpwd password: VqxDbBE6rjG5l/uwoe/eK/d47wL= cvault$ We now create the corresponding line: :: adusers = cvmgr; VqxDbBE6rjG5l/uwoe/eK/d47wL= Now, consider we want to create an entry for the resource "UX", a user "UX_usr", password "UXpwd", operating in "PROD" environment. The credential should be accessible for the user "dom" from the host "cvhost". First, We want to create the user key, which will encrypt this password: :: cvault$ cvcm -P CvUsrKey HWdYPHwZ02wvilkhd3yEtpnXeNLfahG5AC== cvault$ The corresponding entry in the file will have the following format: :: privkeys = 0; HWdYPHwZ02wvilkhd3yEtpnXeNLfahG5AC== Next, we create the credential line. For this, we must encrypt the password "UXpwd" with the user key we just have registered (**cvcm** must be set up to work on this DB file and running): :: cvault$ cvquery -p UXpwd -k 0 bl7L3LUbPDm7fnMnHrOtqUdqBqzqeB== cvault$ We now can create our first credential: :: credentials = 0; UXusr; UX; PROD; bl7L3LUbPDm7fnMnHrOtqUdqBqzqeB==; "My first cred !" The ACL line tells for who and when this credential is available and the ACL Control tells from which host: :: accesslist = 0; 0; dom; Y; 1970-01-01; 2037-12-31 accessctrl = 0; cvhost The data becomes available for the user dom:: dom@cvhost$ cvquery -f UXusr UX PROD UXpwd dom@cvhost$ We now can switch back the CI into LDAP and perform an import of this file into the DB. Both *cvcm* and *cvad* must be up and running. The import will be done with *cvctl*, which must have been registered by the cache manager. The command would look like: :: cvault$ cvctl -i /opt/cv/var/cvci.fdb cvmgr: cvault$ The last lines of *cvad*'s log file should show the following: :: IMPORT_DB | #keys:1 - #adusrs:1 - #adclis:0 - #creds:1 - #acls:1 - #ctrls:1 - #svrs:0 CHK_DATA | Data integrity check completed. RPC_MAIN | IMPORT_DB: cvmgr@cvhost - completed. RPC_MAIN | ADMLOGOUT: cvmgr@cvhost From the cache manager point of view, the log should show the following: :: BROADCAST-DB_HANGUP | Not to myself DB_HANGUP | Ok. BROADCAST-DB_RELEASE | Not to myself DB_RELEASE | Ok. BROADCAST-TRASH_CACHE | Not to myself TRASH_CACHE: OK This gives a small insight at what is running behind the scene when a DB import occurs: #. All cache managers are required not to touch the DB any more. This cache manager received the ``DB_HANGUP`` query with the request of forwarding it to everyone else. All cache manager operations can be conducted from the cache, and if one has no cache, it would shutdown automatically. #. The admin server tells its local manager to reuse the DB (and forward this to everyone). #. Then the admin server asks all cache managers to trash their cache, which may contain dirty data after the DB import. This will be discussed more in details in the admin guide... From now on, the CI is up and running!