github.com/hyperledger/fabric-ca@v2.0.0-alpha.0.20201120210307-7b4f34729db1+incompatible/cmd/fabric-ca-server/config.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package main 8 9 import ( 10 "io/ioutil" 11 "os" 12 "path/filepath" 13 "strings" 14 15 "github.com/cloudflare/cfssl/log" 16 calog "github.com/hyperledger/fabric-ca/internal/pkg/log" 17 "github.com/hyperledger/fabric-ca/internal/pkg/util" 18 "github.com/hyperledger/fabric-ca/lib" 19 "github.com/hyperledger/fabric-ca/lib/metadata" 20 "github.com/pkg/errors" 21 ) 22 23 const ( 24 longName = "Hyperledger Fabric Certificate Authority Server" 25 shortName = "fabric-ca server" 26 cmdName = "fabric-ca-server" 27 envVarPrefix = "FABRIC_CA_SERVER" 28 homeEnvVar = "FABRIC_CA_SERVER_HOME" 29 caNameReqMsg = "ca.name property is required but is missing from the configuration file" 30 ) 31 32 const ( 33 defaultCfgTemplate = `############################################################################# 34 # This is a configuration file for the fabric-ca-server command. 35 # 36 # COMMAND LINE ARGUMENTS AND ENVIRONMENT VARIABLES 37 # ------------------------------------------------ 38 # Each configuration element can be overridden via command line 39 # arguments or environment variables. The precedence for determining 40 # the value of each element is as follows: 41 # 1) command line argument 42 # Examples: 43 # a) --port 443 44 # To set the listening port 45 # b) --ca.keyfile ../mykey.pem 46 # To set the "keyfile" element in the "ca" section below; 47 # note the '.' separator character. 48 # 2) environment variable 49 # Examples: 50 # a) FABRIC_CA_SERVER_PORT=443 51 # To set the listening port 52 # b) FABRIC_CA_SERVER_CA_KEYFILE="../mykey.pem" 53 # To set the "keyfile" element in the "ca" section below; 54 # note the '_' separator character. 55 # 3) configuration file 56 # 4) default value (if there is one) 57 # All default values are shown beside each element below. 58 # 59 # FILE NAME ELEMENTS 60 # ------------------ 61 # The value of all fields whose name ends with "file" or "files" are 62 # name or names of other files. 63 # For example, see "tls.certfile" and "tls.clientauth.certfiles". 64 # The value of each of these fields can be a simple filename, a 65 # relative path, or an absolute path. If the value is not an 66 # absolute path, it is interpretted as being relative to the location 67 # of this configuration file. 68 # 69 ############################################################################# 70 71 # Version of config file 72 version: <<<VERSION>>> 73 74 # Server's listening port (default: 7054) 75 port: 7054 76 77 # Cross-Origin Resource Sharing (CORS) 78 cors: 79 enabled: false 80 origins: 81 - "*" 82 83 # Enables debug logging (default: false) 84 debug: false 85 86 # Size limit of an acceptable CRL in bytes (default: 512000) 87 crlsizelimit: 512000 88 89 ############################################################################# 90 # TLS section for the server's listening port 91 # 92 # The following types are supported for client authentication: NoClientCert, 93 # RequestClientCert, RequireAnyClientCert, VerifyClientCertIfGiven, 94 # and RequireAndVerifyClientCert. 95 # 96 # Certfiles is a list of root certificate authorities that the server uses 97 # when verifying client certificates. 98 ############################################################################# 99 tls: 100 # Enable TLS (default: false) 101 enabled: false 102 # TLS for the server's listening port 103 certfile: 104 keyfile: 105 clientauth: 106 type: noclientcert 107 certfiles: 108 109 ############################################################################# 110 # The CA section contains information related to the Certificate Authority 111 # including the name of the CA, which should be unique for all members 112 # of a blockchain network. It also includes the key and certificate files 113 # used when issuing enrollment certificates (ECerts). 114 # The chainfile (if it exists) contains the certificate chain which 115 # should be trusted for this CA, where the 1st in the chain is always the 116 # root CA certificate. 117 ############################################################################# 118 ca: 119 # Name of this CA 120 name: 121 # Key file (is only used to import a private key into BCCSP) 122 keyfile: 123 # Certificate file (default: ca-cert.pem) 124 certfile: 125 # Chain file 126 chainfile: 127 128 ############################################################################# 129 # The gencrl REST endpoint is used to generate a CRL that contains revoked 130 # certificates. This section contains configuration options that are used 131 # during gencrl request processing. 132 ############################################################################# 133 crl: 134 # Specifies expiration for the generated CRL. The number of hours 135 # specified by this property is added to the UTC time, the resulting time 136 # is used to set the 'Next Update' date of the CRL. 137 expiry: 24h 138 139 ############################################################################# 140 # The registry section controls how the fabric-ca-server does two things: 141 # 1) authenticates enrollment requests which contain a username and password 142 # (also known as an enrollment ID and secret). 143 # 2) once authenticated, retrieves the identity's attribute names and values. 144 # These attributes are useful for making access control decisions in 145 # chaincode. 146 # There are two main configuration options: 147 # 1) The fabric-ca-server is the registry. 148 # This is true if "ldap.enabled" in the ldap section below is false. 149 # 2) An LDAP server is the registry, in which case the fabric-ca-server 150 # calls the LDAP server to perform these tasks. 151 # This is true if "ldap.enabled" in the ldap section below is true, 152 # which means this "registry" section is ignored. 153 ############################################################################# 154 registry: 155 # Maximum number of times a password/secret can be reused for enrollment 156 # (default: -1, which means there is no limit) 157 maxenrollments: -1 158 159 # Contains identity information which is used when LDAP is disabled 160 identities: 161 - name: <<<ADMIN>>> 162 pass: <<<ADMINPW>>> 163 type: client 164 affiliation: "" 165 attrs: 166 hf.Registrar.Roles: "*" 167 hf.Registrar.DelegateRoles: "*" 168 hf.Revoker: true 169 hf.IntermediateCA: true 170 hf.GenCRL: true 171 hf.Registrar.Attributes: "*" 172 hf.AffiliationMgr: true 173 174 ############################################################################# 175 # Database section 176 # Supported types are: "sqlite3", "postgres", and "mysql". 177 # The datasource value depends on the type. 178 # If the type is "sqlite3", the datasource value is a file name to use 179 # as the database store. Since "sqlite3" is an embedded database, it 180 # may not be used if you want to run the fabric-ca-server in a cluster. 181 # To run the fabric-ca-server in a cluster, you must choose "postgres" 182 # or "mysql". 183 ############################################################################# 184 db: 185 type: sqlite3 186 datasource: fabric-ca-server.db 187 tls: 188 enabled: false 189 certfiles: 190 client: 191 certfile: 192 keyfile: 193 194 ############################################################################# 195 # LDAP section 196 # If LDAP is enabled, the fabric-ca-server calls LDAP to: 197 # 1) authenticate enrollment ID and secret (i.e. username and password) 198 # for enrollment requests; 199 # 2) To retrieve identity attributes 200 ############################################################################# 201 ldap: 202 # Enables or disables the LDAP client (default: false) 203 # If this is set to true, the "registry" section is ignored. 204 enabled: false 205 # The URL of the LDAP server 206 url: ldap://<adminDN>:<adminPassword>@<host>:<port>/<base> 207 # TLS configuration for the client connection to the LDAP server 208 tls: 209 certfiles: 210 client: 211 certfile: 212 keyfile: 213 # Attribute related configuration for mapping from LDAP entries to Fabric CA attributes 214 attribute: 215 # 'names' is an array of strings containing the LDAP attribute names which are 216 # requested from the LDAP server for an LDAP identity's entry 217 names: ['uid','member'] 218 # The 'converters' section is used to convert an LDAP entry to the value of 219 # a fabric CA attribute. 220 # For example, the following converts an LDAP 'uid' attribute 221 # whose value begins with 'revoker' to a fabric CA attribute 222 # named "hf.Revoker" with a value of "true" (because the boolean expression 223 # evaluates to true). 224 # converters: 225 # - name: hf.Revoker 226 # value: attr("uid") =~ "revoker*" 227 converters: 228 - name: 229 value: 230 # The 'maps' section contains named maps which may be referenced by the 'map' 231 # function in the 'converters' section to map LDAP responses to arbitrary values. 232 # For example, assume a user has an LDAP attribute named 'member' which has multiple 233 # values which are each a distinguished name (i.e. a DN). For simplicity, assume the 234 # values of the 'member' attribute are 'dn1', 'dn2', and 'dn3'. 235 # Further assume the following configuration. 236 # converters: 237 # - name: hf.Registrar.Roles 238 # value: map(attr("member"),"groups") 239 # maps: 240 # groups: 241 # - name: dn1 242 # value: peer 243 # - name: dn2 244 # value: client 245 # The value of the user's 'hf.Registrar.Roles' attribute is then computed to be 246 # "peer,client,dn3". This is because the value of 'attr("member")' is 247 # "dn1,dn2,dn3", and the call to 'map' with a 2nd argument of 248 # "group" replaces "dn1" with "peer" and "dn2" with "client". 249 maps: 250 groups: 251 - name: 252 value: 253 254 ############################################################################# 255 # Affiliations section. Fabric CA server can be bootstrapped with the 256 # affiliations specified in this section. Affiliations are specified as maps. 257 # For example: 258 # businessunit1: 259 # department1: 260 # - team1 261 # businessunit2: 262 # - department2 263 # - department3 264 # 265 # Affiliations are hierarchical in nature. In the above example, 266 # department1 (used as businessunit1.department1) is the child of businessunit1. 267 # team1 (used as businessunit1.department1.team1) is the child of department1. 268 # department2 (used as businessunit2.department2) and department3 (businessunit2.department3) 269 # are children of businessunit2. 270 # Note: Affiliations are case sensitive except for the non-leaf affiliations 271 # (like businessunit1, department1, businessunit2) that are specified in the configuration file, 272 # which are always stored in lower case. 273 ############################################################################# 274 affiliations: 275 org1: 276 - department1 277 - department2 278 org2: 279 - department1 280 281 ############################################################################# 282 # Signing section 283 # 284 # The "default" subsection is used to sign enrollment certificates; 285 # the default expiration ("expiry" field) is "8760h", which is 1 year in hours. 286 # 287 # The "ca" profile subsection is used to sign intermediate CA certificates; 288 # the default expiration ("expiry" field) is "43800h" which is 5 years in hours. 289 # Note that "isca" is true, meaning that it issues a CA certificate. 290 # A maxpathlen of 0 means that the intermediate CA cannot issue other 291 # intermediate CA certificates, though it can still issue end entity certificates. 292 # (See RFC 5280, section 4.2.1.9) 293 # 294 # The "tls" profile subsection is used to sign TLS certificate requests; 295 # the default expiration ("expiry" field) is "8760h", which is 1 year in hours. 296 ############################################################################# 297 signing: 298 default: 299 usage: 300 - digital signature 301 expiry: 8760h 302 profiles: 303 ca: 304 usage: 305 - cert sign 306 - crl sign 307 expiry: 43800h 308 caconstraint: 309 isca: true 310 maxpathlen: 0 311 tls: 312 usage: 313 - signing 314 - key encipherment 315 - server auth 316 - client auth 317 - key agreement 318 expiry: 8760h 319 320 ########################################################################### 321 # Certificate Signing Request (CSR) section. 322 # This controls the creation of the root CA certificate. 323 # The expiration for the root CA certificate is configured with the 324 # "ca.expiry" field below, whose default value is "131400h" which is 325 # 15 years in hours. 326 # The pathlength field is used to limit CA certificate hierarchy as described 327 # in section 4.2.1.9 of RFC 5280. 328 # Examples: 329 # 1) No pathlength value means no limit is requested. 330 # 2) pathlength == 1 means a limit of 1 is requested which is the default for 331 # a root CA. This means the root CA can issue intermediate CA certificates, 332 # but these intermediate CAs may not in turn issue other CA certificates 333 # though they can still issue end entity certificates. 334 # 3) pathlength == 0 means a limit of 0 is requested; 335 # this is the default for an intermediate CA, which means it can not issue 336 # CA certificates though it can still issue end entity certificates. 337 ########################################################################### 338 csr: 339 cn: <<<COMMONNAME>>> 340 keyrequest: 341 algo: ecdsa 342 size: 256 343 names: 344 - C: US 345 ST: "North Carolina" 346 L: 347 O: Hyperledger 348 OU: Fabric 349 hosts: 350 - <<<MYHOST>>> 351 - localhost 352 ca: 353 expiry: 131400h 354 pathlength: <<<PATHLENGTH>>> 355 356 ########################################################################### 357 # Each CA can issue both X509 enrollment certificate as well as Idemix 358 # Credential. This section specifies configuration for the issuer component 359 # that is responsible for issuing Idemix credentials. 360 ########################################################################### 361 idemix: 362 # Specifies pool size for revocation handles. A revocation handle is an unique identifier of an 363 # Idemix credential. The issuer will create a pool revocation handles of this specified size. When 364 # a credential is requested, issuer will get handle from the pool and assign it to the credential. 365 # Issuer will repopulate the pool with new handles when the last handle in the pool is used. 366 # A revocation handle and credential revocation information (CRI) are used to create non revocation proof 367 # by the prover to prove to the verifier that her credential is not revoked. 368 rhpoolsize: 1000 369 370 # The Idemix credential issuance is a two step process. First step is to get a nonce from the issuer 371 # and second step is send credential request that is constructed using the nonce to the isuser to 372 # request a credential. This configuration property specifies expiration for the nonces. By default is 373 # nonces expire after 15 seconds. The value is expressed in the time.Duration format (see https://golang.org/pkg/time/#ParseDuration). 374 nonceexpiration: 15s 375 376 # Specifies interval at which expired nonces are removed from datastore. Default value is 15 minutes. 377 # The value is expressed in the time.Duration format (see https://golang.org/pkg/time/#ParseDuration) 378 noncesweepinterval: 15m 379 380 ############################################################################# 381 # BCCSP (BlockChain Crypto Service Provider) section is used to select which 382 # crypto library implementation to use 383 ############################################################################# 384 bccsp: 385 default: SW 386 sw: 387 hash: SHA2 388 security: 256 389 filekeystore: 390 # The directory used for the software file-based keystore 391 keystore: msp/keystore 392 393 ############################################################################# 394 # Multi CA section 395 # 396 # Each Fabric CA server contains one CA by default. This section is used 397 # to configure multiple CAs in a single server. 398 # 399 # 1) --cacount <number-of-CAs> 400 # Automatically generate <number-of-CAs> non-default CAs. The names of these 401 # additional CAs are "ca1", "ca2", ... "caN", where "N" is <number-of-CAs> 402 # This is particularly useful in a development environment to quickly set up 403 # multiple CAs. Note that, this config option is not applicable to intermediate CA server 404 # i.e., Fabric CA server that is started with intermediate.parentserver.url config 405 # option (-u command line option) 406 # 407 # 2) --cafiles <CA-config-files> 408 # For each CA config file in the list, generate a separate signing CA. Each CA 409 # config file in this list MAY contain all of the same elements as are found in 410 # the server config file except port, debug, and tls sections. 411 # 412 # Examples: 413 # fabric-ca-server start -b admin:adminpw --cacount 2 414 # 415 # fabric-ca-server start -b admin:adminpw --cafiles ca/ca1/fabric-ca-server-config.yaml 416 # --cafiles ca/ca2/fabric-ca-server-config.yaml 417 # 418 ############################################################################# 419 420 cacount: 421 422 cafiles: 423 424 ############################################################################# 425 # Intermediate CA section 426 # 427 # The relationship between servers and CAs is as follows: 428 # 1) A single server process may contain or function as one or more CAs. 429 # This is configured by the "Multi CA section" above. 430 # 2) Each CA is either a root CA or an intermediate CA. 431 # 3) Each intermediate CA has a parent CA which is either a root CA or another intermediate CA. 432 # 433 # This section pertains to configuration of #2 and #3. 434 # If the "intermediate.parentserver.url" property is set, 435 # then this is an intermediate CA with the specified parent 436 # CA. 437 # 438 # parentserver section 439 # url - The URL of the parent server 440 # caname - Name of the CA to enroll within the server 441 # 442 # enrollment section used to enroll intermediate CA with parent CA 443 # profile - Name of the signing profile to use in issuing the certificate 444 # label - Label to use in HSM operations 445 # 446 # tls section for secure socket connection 447 # certfiles - PEM-encoded list of trusted root certificate files 448 # client: 449 # certfile - PEM-encoded certificate file for when client authentication 450 # is enabled on server 451 # keyfile - PEM-encoded key file for when client authentication 452 # is enabled on server 453 ############################################################################# 454 intermediate: 455 parentserver: 456 url: 457 caname: 458 459 enrollment: 460 hosts: 461 profile: 462 label: 463 464 tls: 465 certfiles: 466 client: 467 certfile: 468 keyfile: 469 470 ############################################################################# 471 # CA configuration section 472 # 473 # Configure the number of incorrect password attempts are allowed for 474 # identities. By default, the value of 'passwordattempts' is 10, which 475 # means that 10 incorrect password attempts can be made before an identity get 476 # locked out. 477 ############################################################################# 478 cfg: 479 identities: 480 passwordattempts: 10 481 482 ############################################################################### 483 # 484 # Operations section 485 # 486 ############################################################################### 487 operations: 488 # host and port for the operations server 489 listenAddress: 127.0.0.1:9443 490 491 # TLS configuration for the operations endpoint 492 tls: 493 # TLS enabled 494 enabled: false 495 496 # path to PEM encoded server certificate for the operations server 497 cert: 498 file: 499 500 # path to PEM encoded server key for the operations server 501 key: 502 file: 503 504 # require client certificate authentication to access all resources 505 clientAuthRequired: false 506 507 # paths to PEM encoded ca certificates to trust for client authentication 508 clientRootCAs: 509 files: [] 510 511 ############################################################################### 512 # 513 # Metrics section 514 # 515 ############################################################################### 516 metrics: 517 # statsd, prometheus, or disabled 518 provider: disabled 519 520 # statsd configuration 521 statsd: 522 # network type: tcp or udp 523 network: udp 524 525 # statsd server address 526 address: 127.0.0.1:8125 527 528 # the interval at which locally cached counters and gauges are pushsed 529 # to statsd; timings are pushed immediately 530 writeInterval: 10s 531 532 # prefix is prepended to all emitted statsd merics 533 prefix: server 534 ` 535 ) 536 537 var ( 538 extraArgsError = "Unrecognized arguments found: %v\n\n%s" 539 ) 540 541 // Initialize config 542 func (s *ServerCmd) configInit() (err error) { 543 if !s.configRequired() { 544 return nil 545 } 546 547 s.cfgFileName, s.homeDirectory, err = util.ValidateAndReturnAbsConf(s.cfgFileName, s.homeDirectory, cmdName) 548 if err != nil { 549 return err 550 } 551 552 s.myViper.AutomaticEnv() // read in environment variables that match 553 logLevel := s.myViper.GetString("loglevel") 554 debug := s.myViper.GetBool("debug") 555 calog.SetLogLevel(logLevel, debug) 556 557 log.Debugf("Home directory: %s", s.homeDirectory) 558 559 // If the config file doesn't exist, create a default one 560 if !util.FileExists(s.cfgFileName) { 561 err = s.createDefaultConfigFile() 562 if err != nil { 563 return errors.WithMessage(err, "Failed to create default configuration file") 564 } 565 log.Infof("Created default configuration file at %s", s.cfgFileName) 566 } else { 567 log.Infof("Configuration file location: %s", s.cfgFileName) 568 } 569 570 // Read the config 571 err = lib.UnmarshalConfig(s.cfg, s.myViper, s.cfgFileName, true) 572 if err != nil { 573 return err 574 } 575 576 // Read operations tls files 577 if s.myViper.GetBool("operations.tls.enabled") { 578 cf := s.myViper.GetString("operations.tls.cert.file") 579 if cf == "" { 580 cf = s.cfg.Operations.TLS.CertFile 581 } 582 if !filepath.IsAbs(cf) { 583 cf = filepath.Join(s.homeDirectory, cf) 584 } 585 if !util.FileExists(cf) { 586 return errors.Errorf("failed to read certificate file: %s", cf) 587 } 588 s.cfg.Operations.TLS.CertFile = cf 589 590 kf := s.myViper.GetString("operations.tls.key.file") 591 if kf == "" { 592 kf = s.cfg.Operations.TLS.KeyFile 593 } 594 if !filepath.IsAbs(kf) { 595 kf = filepath.Join(s.homeDirectory, kf) 596 } 597 if !util.FileExists(kf) { 598 return errors.Errorf("failed to read key file: %s", kf) 599 } 600 s.cfg.Operations.TLS.KeyFile = kf 601 } 602 603 // The pathlength field controls how deep the CA hierarchy when requesting 604 // certificates. If it is explicitly set to 0, set the PathLenZero field to 605 // true as CFSSL expects. 606 pl := "csr.ca.pathlength" 607 if s.myViper.IsSet(pl) && s.myViper.GetInt(pl) == 0 { 608 s.cfg.CAcfg.CSR.CA.PathLenZero = true 609 } 610 // The maxpathlen field controls how deep the CA hierarchy when issuing 611 // a CA certificate. If it is explicitly set to 0, set the PathLenZero 612 // field to true as CFSSL expects. 613 pl = "signing.profiles.ca.caconstraint.maxpathlen" 614 if s.myViper.IsSet(pl) && s.myViper.GetInt(pl) == 0 { 615 s.cfg.CAcfg.Signing.Profiles["ca"].CAConstraint.MaxPathLenZero = true 616 } 617 618 return nil 619 } 620 621 func (s *ServerCmd) createDefaultConfigFile() error { 622 var user, pass string 623 // If LDAP is enabled, authentication of enrollment requests are performed 624 // by using LDAP authentication; therefore, no bootstrap username and password 625 // are required. 626 ldapEnabled := s.myViper.GetBool("ldap.enabled") 627 if !ldapEnabled { 628 // When LDAP is disabled, the fabric-ca-server functions as its own 629 // identity registry; therefore, we require that the default configuration 630 // file have a bootstrap username and password that is used to enroll a 631 // bootstrap administrator. Other identities can be dynamically registered. 632 // Create the default config, but only if they provided this bootstrap 633 // username and password. 634 up := s.myViper.GetString("boot") 635 if up == "" { 636 return errors.New("The '-b user:pass' option is required") 637 } 638 ups := strings.Split(up, ":") 639 if len(ups) < 2 { 640 return errors.Errorf("The value '%s' on the command line is missing a colon separator", up) 641 } 642 if len(ups) > 2 { 643 ups = []string{ups[0], strings.Join(ups[1:], ":")} 644 } 645 user = ups[0] 646 pass = ups[1] 647 if len(user) >= 1024 { 648 return errors.Errorf("The identity name must be less than 1024 characters: '%s'", user) 649 } 650 if len(pass) == 0 { 651 return errors.New("An empty password in the '-b user:pass' option is not permitted") 652 } 653 } 654 655 var myhost string 656 var err error 657 myhost, err = os.Hostname() 658 if err != nil { 659 return err 660 } 661 662 // Do string subtitution to get the default config 663 cfg := strings.Replace(defaultCfgTemplate, "<<<VERSION>>>", metadata.Version, 1) 664 cfg = strings.Replace(cfg, "<<<ADMIN>>>", user, 1) 665 cfg = strings.Replace(cfg, "<<<ADMINPW>>>", pass, 1) 666 cfg = strings.Replace(cfg, "<<<MYHOST>>>", myhost, 1) 667 purl := s.myViper.GetString("intermediate.parentserver.url") 668 log.Debugf("parent server URL: '%s'", util.GetMaskedURL(purl)) 669 if purl == "" { 670 // This is a root CA 671 cfg = strings.Replace(cfg, "<<<COMMONNAME>>>", "fabric-ca-server", 1) 672 cfg = strings.Replace(cfg, "<<<PATHLENGTH>>>", "1", 1) 673 } else { 674 // This is an intermediate CA 675 cfg = strings.Replace(cfg, "<<<COMMONNAME>>>", "", 1) 676 cfg = strings.Replace(cfg, "<<<PATHLENGTH>>>", "0", 1) 677 } 678 679 // Now write the file 680 cfgDir := filepath.Dir(s.cfgFileName) 681 err = os.MkdirAll(cfgDir, 0755) 682 if err != nil { 683 return err 684 } 685 686 // Now write the file 687 return ioutil.WriteFile(s.cfgFileName, []byte(cfg), 0644) 688 }