1package vault 2 3import ( 4 "context" 5 "crypto/ecdsa" 6 "crypto/subtle" 7 "crypto/x509" 8 "encoding/base64" 9 "errors" 10 "fmt" 11 "net" 12 "net/http" 13 "net/url" 14 "path/filepath" 15 "sync" 16 "sync/atomic" 17 "time" 18 19 "github.com/hashicorp/vault/api" 20 "github.com/hashicorp/vault/helper/metricsutil" 21 "github.com/hashicorp/vault/physical/raft" 22 23 metrics "github.com/armon/go-metrics" 24 log "github.com/hashicorp/go-hclog" 25 multierror "github.com/hashicorp/go-multierror" 26 uuid "github.com/hashicorp/go-uuid" 27 cache "github.com/patrickmn/go-cache" 28 29 "google.golang.org/grpc" 30 31 "github.com/hashicorp/errwrap" 32 "github.com/hashicorp/vault/audit" 33 "github.com/hashicorp/vault/helper/namespace" 34 "github.com/hashicorp/vault/helper/reload" 35 "github.com/hashicorp/vault/sdk/helper/certutil" 36 "github.com/hashicorp/vault/sdk/helper/consts" 37 "github.com/hashicorp/vault/sdk/helper/jsonutil" 38 "github.com/hashicorp/vault/sdk/helper/logging" 39 "github.com/hashicorp/vault/sdk/helper/mlock" 40 "github.com/hashicorp/vault/sdk/helper/strutil" 41 "github.com/hashicorp/vault/sdk/helper/tlsutil" 42 "github.com/hashicorp/vault/sdk/logical" 43 "github.com/hashicorp/vault/sdk/physical" 44 "github.com/hashicorp/vault/shamir" 45 "github.com/hashicorp/vault/vault/cluster" 46 "github.com/hashicorp/vault/vault/seal" 47 shamirseal "github.com/hashicorp/vault/vault/seal/shamir" 48) 49 50const ( 51 // CoreLockPath is the path used to acquire a coordinating lock 52 // for a highly-available deploy. 53 CoreLockPath = "core/lock" 54 55 // The poison pill is used as a check during certain scenarios to indicate 56 // to standby nodes that they should seal 57 poisonPillPath = "core/poison-pill" 58 59 // coreLeaderPrefix is the prefix used for the UUID that contains 60 // the currently elected leader. 61 coreLeaderPrefix = "core/leader/" 62 63 // knownPrimaryAddrsPrefix is used to store last-known cluster address 64 // information for primaries 65 knownPrimaryAddrsPrefix = "core/primary-addrs/" 66 67 // coreKeyringCanaryPath is used as a canary to indicate to replicated 68 // clusters that they need to perform a rekey operation synchronously; this 69 // isn't keyring-canary to avoid ignoring it when ignoring core/keyring 70 coreKeyringCanaryPath = "core/canary-keyring" 71) 72 73var ( 74 // ErrAlreadyInit is returned if the core is already 75 // initialized. This prevents a re-initialization. 76 ErrAlreadyInit = errors.New("Vault is already initialized") 77 78 // ErrNotInit is returned if a non-initialized barrier 79 // is attempted to be unsealed. 80 ErrNotInit = errors.New("Vault is not initialized") 81 82 // ErrInternalError is returned when we don't want to leak 83 // any information about an internal error 84 ErrInternalError = errors.New("internal error") 85 86 // ErrHANotEnabled is returned if the operation only makes sense 87 // in an HA setting 88 ErrHANotEnabled = errors.New("Vault is not configured for highly-available mode") 89 90 // manualStepDownSleepPeriod is how long to sleep after a user-initiated 91 // step down of the active node, to prevent instantly regrabbing the lock. 92 // It's var not const so that tests can manipulate it. 93 manualStepDownSleepPeriod = 10 * time.Second 94 95 // Functions only in the Enterprise version 96 enterprisePostUnseal = enterprisePostUnsealImpl 97 enterprisePreSeal = enterprisePreSealImpl 98 startReplication = startReplicationImpl 99 stopReplication = stopReplicationImpl 100 LastWAL = lastWALImpl 101 LastPerformanceWAL = lastPerformanceWALImpl 102 PerformanceMerkleRoot = merkleRootImpl 103 DRMerkleRoot = merkleRootImpl 104 LastRemoteWAL = lastRemoteWALImpl 105 WaitUntilWALShipped = waitUntilWALShippedImpl 106) 107 108// NonFatalError is an error that can be returned during NewCore that should be 109// displayed but not cause a program exit 110type NonFatalError struct { 111 Err error 112} 113 114func (e *NonFatalError) WrappedErrors() []error { 115 return []error{e.Err} 116} 117 118func (e *NonFatalError) Error() string { 119 return e.Err.Error() 120} 121 122// NewNonFatalError returns a new non-fatal error. 123func NewNonFatalError(err error) *NonFatalError { 124 return &NonFatalError{Err: err} 125} 126 127// IsFatalError returns true if the given error is a fatal error. 128func IsFatalError(err error) bool { 129 return !errwrap.ContainsType(err, new(NonFatalError)) 130} 131 132// ErrInvalidKey is returned if there is a user-based error with a provided 133// unseal key. This will be shown to the user, so should not contain 134// information that is sensitive. 135type ErrInvalidKey struct { 136 Reason string 137} 138 139func (e *ErrInvalidKey) Error() string { 140 return fmt.Sprintf("invalid key: %v", e.Reason) 141} 142 143type RegisterAuthFunc func(context.Context, time.Duration, string, *logical.Auth) error 144 145type activeAdvertisement struct { 146 RedirectAddr string `json:"redirect_addr"` 147 ClusterAddr string `json:"cluster_addr,omitempty"` 148 ClusterCert []byte `json:"cluster_cert,omitempty"` 149 ClusterKeyParams *certutil.ClusterKeyParams `json:"cluster_key_params,omitempty"` 150} 151 152type unlockInformation struct { 153 Parts [][]byte 154 Nonce string 155} 156 157// Core is used as the central manager of Vault activity. It is the primary point of 158// interface for API handlers and is responsible for managing the logical and physical 159// backends, router, security barrier, and audit trails. 160type Core struct { 161 entCore 162 163 // The registry of builtin plugins is passed in here as an interface because 164 // if it's used directly, it results in import cycles. 165 builtinRegistry BuiltinRegistry 166 167 // N.B.: This is used to populate a dev token down replication, as 168 // otherwise, after replication is started, a dev would have to go through 169 // the generate-root process simply to talk to the new follower cluster. 170 devToken string 171 172 // HABackend may be available depending on the physical backend 173 ha physical.HABackend 174 175 // redirectAddr is the address we advertise as leader if held 176 redirectAddr string 177 178 // clusterAddr is the address we use for clustering 179 clusterAddr *atomic.Value 180 181 // physical backend is the un-trusted backend with durable data 182 physical physical.Backend 183 184 // underlyingPhysical will always point to the underlying backend 185 // implementation. This is an un-trusted backend with durable data 186 underlyingPhysical physical.Backend 187 188 // seal is our seal, for seal configuration information 189 seal Seal 190 191 raftUnseal bool 192 193 raftChallenge *physical.EncryptedBlobInfo 194 195 raftLeaderClient *api.Client 196 197 raftLeaderBarrierConfig *SealConfig 198 199 // migrationSeal is the seal to use during a migration operation. It is the 200 // seal we're migrating *from*. 201 migrationSeal Seal 202 203 // unwrapSeal is the seal to use on Enterprise to unwrap values wrapped 204 // with the previous seal. 205 unwrapSeal Seal 206 207 // barrier is the security barrier wrapping the physical backend 208 barrier SecurityBarrier 209 210 // router is responsible for managing the mount points for logical backends. 211 router *Router 212 213 // logicalBackends is the mapping of backends to use for this core 214 logicalBackends map[string]logical.Factory 215 216 // credentialBackends is the mapping of backends to use for this core 217 credentialBackends map[string]logical.Factory 218 219 // auditBackends is the mapping of backends to use for this core 220 auditBackends map[string]audit.Factory 221 222 // stateLock protects mutable state 223 stateLock sync.RWMutex 224 sealed *uint32 225 226 standby bool 227 perfStandby bool 228 standbyDoneCh chan struct{} 229 standbyStopCh chan struct{} 230 manualStepDownCh chan struct{} 231 keepHALockOnStepDown *uint32 232 heldHALock physical.Lock 233 234 // unlockInfo has the keys provided to Unseal until the threshold number of parts is available, as well as the operation nonce 235 unlockInfo *unlockInformation 236 237 // generateRootProgress holds the shares until we reach enough 238 // to verify the master key 239 generateRootConfig *GenerateRootConfig 240 generateRootProgress [][]byte 241 generateRootLock sync.Mutex 242 243 // These variables holds the config and shares we have until we reach 244 // enough to verify the appropriate master key. Note that the same lock is 245 // used; this isn't time-critical so this shouldn't be a problem. 246 barrierRekeyConfig *SealConfig 247 recoveryRekeyConfig *SealConfig 248 rekeyLock sync.RWMutex 249 250 // mounts is loaded after unseal since it is a protected 251 // configuration 252 mounts *MountTable 253 254 // mountsLock is used to ensure that the mounts table does not 255 // change underneath a calling function 256 mountsLock sync.RWMutex 257 258 // auth is loaded after unseal since it is a protected 259 // configuration 260 auth *MountTable 261 262 // authLock is used to ensure that the auth table does not 263 // change underneath a calling function 264 authLock sync.RWMutex 265 266 // audit is loaded after unseal since it is a protected 267 // configuration 268 audit *MountTable 269 270 // auditLock is used to ensure that the audit table does not 271 // change underneath a calling function 272 auditLock sync.RWMutex 273 274 // auditBroker is used to ingest the audit events and fan 275 // out into the configured audit backends 276 auditBroker *AuditBroker 277 278 // auditedHeaders is used to configure which http headers 279 // can be output in the audit logs 280 auditedHeaders *AuditedHeadersConfig 281 282 // systemBackend is the backend which is used to manage internal operations 283 systemBackend *SystemBackend 284 285 // cubbyholeBackend is the backend which manages the per-token storage 286 cubbyholeBackend *CubbyholeBackend 287 288 // systemBarrierView is the barrier view for the system backend 289 systemBarrierView *BarrierView 290 291 // expiration manager is used for managing LeaseIDs, 292 // renewal, expiration and revocation 293 expiration *ExpirationManager 294 295 // rollback manager is used to run rollbacks periodically 296 rollback *RollbackManager 297 298 // policy store is used to manage named ACL policies 299 policyStore *PolicyStore 300 301 // token store is used to manage authentication tokens 302 tokenStore *TokenStore 303 304 // identityStore is used to manage client entities 305 identityStore *IdentityStore 306 307 // metricsCh is used to stop the metrics streaming 308 metricsCh chan struct{} 309 310 // metricsMutex is used to prevent a race condition between 311 // metrics emission and sealing leading to a nil pointer 312 metricsMutex sync.Mutex 313 314 defaultLeaseTTL time.Duration 315 maxLeaseTTL time.Duration 316 317 // baseLogger is used to avoid ResetNamed as it strips useful prefixes in 318 // e.g. testing 319 baseLogger log.Logger 320 logger log.Logger 321 322 // cachingDisabled indicates whether caches are disabled 323 cachingDisabled bool 324 // Cache stores the actual cache; we always have this but may bypass it if 325 // disabled 326 physicalCache physical.ToggleablePurgemonster 327 328 // reloadFuncs is a map containing reload functions 329 reloadFuncs map[string][]reload.ReloadFunc 330 331 // reloadFuncsLock controls access to the funcs 332 reloadFuncsLock sync.RWMutex 333 334 // wrappingJWTKey is the key used for generating JWTs containing response 335 // wrapping information 336 wrappingJWTKey *ecdsa.PrivateKey 337 338 // 339 // Cluster information 340 // 341 // Name 342 clusterName string 343 // Specific cipher suites to use for clustering, if any 344 clusterCipherSuites []uint16 345 // Used to modify cluster parameters 346 clusterParamsLock sync.RWMutex 347 // The private key stored in the barrier used for establishing 348 // mutually-authenticated connections between Vault cluster members 349 localClusterPrivateKey *atomic.Value 350 // The local cluster cert 351 localClusterCert *atomic.Value 352 // The parsed form of the local cluster cert 353 localClusterParsedCert *atomic.Value 354 // The TCP addresses we should use for clustering 355 clusterListenerAddrs []*net.TCPAddr 356 // The handler to use for request forwarding 357 clusterHandler http.Handler 358 // Write lock used to ensure that we don't have multiple connections adjust 359 // this value at the same time 360 requestForwardingConnectionLock sync.RWMutex 361 // Lock for the leader values, ensuring we don't run the parts of Leader() 362 // that change things concurrently 363 leaderParamsLock sync.RWMutex 364 // Current cluster leader values 365 clusterLeaderParams *atomic.Value 366 // Info on cluster members 367 clusterPeerClusterAddrsCache *cache.Cache 368 // The context for the client 369 rpcClientConnContext context.Context 370 // The function for canceling the client connection 371 rpcClientConnCancelFunc context.CancelFunc 372 // The grpc ClientConn for RPC calls 373 rpcClientConn *grpc.ClientConn 374 // The grpc forwarding client 375 rpcForwardingClient *forwardingClient 376 // The UUID used to hold the leader lock. Only set on active node 377 leaderUUID string 378 379 // CORS Information 380 corsConfig *CORSConfig 381 382 // The active set of upstream cluster addresses; stored via the Echo 383 // mechanism, loaded by the balancer 384 atomicPrimaryClusterAddrs *atomic.Value 385 386 atomicPrimaryFailoverAddrs *atomic.Value 387 388 // replicationState keeps the current replication state cached for quick 389 // lookup; activeNodeReplicationState stores the active value on standbys 390 replicationState *uint32 391 activeNodeReplicationState *uint32 392 393 // uiConfig contains UI configuration 394 uiConfig *UIConfig 395 396 // rawEnabled indicates whether the Raw endpoint is enabled 397 rawEnabled bool 398 399 // pluginDirectory is the location vault will look for plugin binaries 400 pluginDirectory string 401 402 // pluginCatalog is used to manage plugin configurations 403 pluginCatalog *PluginCatalog 404 405 enableMlock bool 406 407 // This can be used to trigger operations to stop running when Vault is 408 // going to be shut down, stepped down, or sealed 409 activeContext context.Context 410 activeContextCancelFunc *atomic.Value 411 412 // Stores the sealunwrapper for downgrade needs 413 sealUnwrapper physical.Backend 414 415 // unsealwithStoredKeysLock is a mutex that prevents multiple processes from 416 // unsealing with stored keys are the same time. 417 unsealWithStoredKeysLock sync.Mutex 418 419 // Stores any funcs that should be run on successful postUnseal 420 postUnsealFuncs []func() 421 422 // replicationFailure is used to mark when replication has entered an 423 // unrecoverable failure. 424 replicationFailure *uint32 425 426 // disablePerfStanby is used to tell a standby not to attempt to become a 427 // perf standby 428 disablePerfStandby bool 429 430 licensingStopCh chan struct{} 431 432 // Stores loggers so we can reset the level 433 allLoggers []log.Logger 434 allLoggersLock sync.RWMutex 435 436 // Can be toggled atomically to cause the core to never try to become 437 // active, or give up active as soon as it gets it 438 neverBecomeActive *uint32 439 440 // loadCaseSensitiveIdentityStore enforces the loading of identity store 441 // artifacts in a case sensitive manner. To be used only in testing. 442 loadCaseSensitiveIdentityStore bool 443 444 // clusterListener starts up and manages connections on the cluster ports 445 clusterListener *cluster.Listener 446 447 // Telemetry objects 448 metricsHelper *metricsutil.MetricsHelper 449 450 // Stores request counters 451 counters counters 452 453 // Stores the raft applied index for standby nodes 454 raftFollowerStates *raftFollowerStates 455 // Stop channel for raft TLS rotations 456 raftTLSRotationStopCh chan struct{} 457 // Stores the pending peers we are waiting to give answers 458 pendingRaftPeers map[string][]byte 459 460 coreNumber int 461} 462 463// CoreConfig is used to parameterize a core 464type CoreConfig struct { 465 DevToken string `json:"dev_token" structs:"dev_token" mapstructure:"dev_token"` 466 467 BuiltinRegistry BuiltinRegistry `json:"builtin_registry" structs:"builtin_registry" mapstructure:"builtin_registry"` 468 469 LogicalBackends map[string]logical.Factory `json:"logical_backends" structs:"logical_backends" mapstructure:"logical_backends"` 470 471 CredentialBackends map[string]logical.Factory `json:"credential_backends" structs:"credential_backends" mapstructure:"credential_backends"` 472 473 AuditBackends map[string]audit.Factory `json:"audit_backends" structs:"audit_backends" mapstructure:"audit_backends"` 474 475 Physical physical.Backend `json:"physical" structs:"physical" mapstructure:"physical"` 476 477 // May be nil, which disables HA operations 478 HAPhysical physical.HABackend `json:"ha_physical" structs:"ha_physical" mapstructure:"ha_physical"` 479 480 Seal Seal `json:"seal" structs:"seal" mapstructure:"seal"` 481 482 Logger log.Logger `json:"logger" structs:"logger" mapstructure:"logger"` 483 484 // Disables the LRU cache on the physical backend 485 DisableCache bool `json:"disable_cache" structs:"disable_cache" mapstructure:"disable_cache"` 486 487 // Disables mlock syscall 488 DisableMlock bool `json:"disable_mlock" structs:"disable_mlock" mapstructure:"disable_mlock"` 489 490 // Custom cache size for the LRU cache on the physical backend, or zero for default 491 CacheSize int `json:"cache_size" structs:"cache_size" mapstructure:"cache_size"` 492 493 // Set as the leader address for HA 494 RedirectAddr string `json:"redirect_addr" structs:"redirect_addr" mapstructure:"redirect_addr"` 495 496 // Set as the cluster address for HA 497 ClusterAddr string `json:"cluster_addr" structs:"cluster_addr" mapstructure:"cluster_addr"` 498 499 DefaultLeaseTTL time.Duration `json:"default_lease_ttl" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"` 500 501 MaxLeaseTTL time.Duration `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"` 502 503 ClusterName string `json:"cluster_name" structs:"cluster_name" mapstructure:"cluster_name"` 504 505 ClusterCipherSuites string `json:"cluster_cipher_suites" structs:"cluster_cipher_suites" mapstructure:"cluster_cipher_suites"` 506 507 EnableUI bool `json:"ui" structs:"ui" mapstructure:"ui"` 508 509 // Enable the raw endpoint 510 EnableRaw bool `json:"enable_raw" structs:"enable_raw" mapstructure:"enable_raw"` 511 512 PluginDirectory string `json:"plugin_directory" structs:"plugin_directory" mapstructure:"plugin_directory"` 513 514 DisableSealWrap bool `json:"disable_sealwrap" structs:"disable_sealwrap" mapstructure:"disable_sealwrap"` 515 516 ReloadFuncs *map[string][]reload.ReloadFunc 517 ReloadFuncsLock *sync.RWMutex 518 519 // Licensing 520 LicensingConfig *LicensingConfig 521 // Don't set this unless in dev mode, ideally only when using inmem 522 DevLicenseDuration time.Duration 523 524 DisablePerformanceStandby bool 525 DisableIndexing bool 526 DisableKeyEncodingChecks bool 527 528 AllLoggers []log.Logger 529 530 // Telemetry objects 531 MetricsHelper *metricsutil.MetricsHelper 532 533 CounterSyncInterval time.Duration 534} 535 536func (c *CoreConfig) Clone() *CoreConfig { 537 return &CoreConfig{ 538 DevToken: c.DevToken, 539 LogicalBackends: c.LogicalBackends, 540 CredentialBackends: c.CredentialBackends, 541 AuditBackends: c.AuditBackends, 542 Physical: c.Physical, 543 HAPhysical: c.HAPhysical, 544 Seal: c.Seal, 545 Logger: c.Logger, 546 DisableCache: c.DisableCache, 547 DisableMlock: c.DisableMlock, 548 CacheSize: c.CacheSize, 549 RedirectAddr: c.RedirectAddr, 550 ClusterAddr: c.ClusterAddr, 551 DefaultLeaseTTL: c.DefaultLeaseTTL, 552 MaxLeaseTTL: c.MaxLeaseTTL, 553 ClusterName: c.ClusterName, 554 ClusterCipherSuites: c.ClusterCipherSuites, 555 EnableUI: c.EnableUI, 556 EnableRaw: c.EnableRaw, 557 PluginDirectory: c.PluginDirectory, 558 DisableSealWrap: c.DisableSealWrap, 559 ReloadFuncs: c.ReloadFuncs, 560 ReloadFuncsLock: c.ReloadFuncsLock, 561 LicensingConfig: c.LicensingConfig, 562 DevLicenseDuration: c.DevLicenseDuration, 563 DisablePerformanceStandby: c.DisablePerformanceStandby, 564 DisableIndexing: c.DisableIndexing, 565 AllLoggers: c.AllLoggers, 566 CounterSyncInterval: c.CounterSyncInterval, 567 } 568} 569 570// NewCore is used to construct a new core 571func NewCore(conf *CoreConfig) (*Core, error) { 572 if conf.HAPhysical != nil && conf.HAPhysical.HAEnabled() { 573 if conf.RedirectAddr == "" { 574 return nil, fmt.Errorf("missing API address, please set in configuration or via environment") 575 } 576 } 577 578 if conf.DefaultLeaseTTL == 0 { 579 conf.DefaultLeaseTTL = defaultLeaseTTL 580 } 581 if conf.MaxLeaseTTL == 0 { 582 conf.MaxLeaseTTL = maxLeaseTTL 583 } 584 if conf.DefaultLeaseTTL > conf.MaxLeaseTTL { 585 return nil, fmt.Errorf("cannot have DefaultLeaseTTL larger than MaxLeaseTTL") 586 } 587 588 // Validate the advertise addr if its given to us 589 if conf.RedirectAddr != "" { 590 u, err := url.Parse(conf.RedirectAddr) 591 if err != nil { 592 return nil, errwrap.Wrapf("redirect address is not valid url: {{err}}", err) 593 } 594 595 if u.Scheme == "" { 596 return nil, fmt.Errorf("redirect address must include scheme (ex. 'http')") 597 } 598 } 599 600 // Make a default logger if not provided 601 if conf.Logger == nil { 602 conf.Logger = logging.NewVaultLogger(log.Trace) 603 } 604 605 syncInterval := conf.CounterSyncInterval 606 if syncInterval.Nanoseconds() == 0 { 607 syncInterval = 30 * time.Second 608 } 609 610 // Setup the core 611 c := &Core{ 612 entCore: entCore{}, 613 devToken: conf.DevToken, 614 physical: conf.Physical, 615 underlyingPhysical: conf.Physical, 616 redirectAddr: conf.RedirectAddr, 617 clusterAddr: new(atomic.Value), 618 seal: conf.Seal, 619 router: NewRouter(), 620 sealed: new(uint32), 621 standby: true, 622 baseLogger: conf.Logger, 623 logger: conf.Logger.Named("core"), 624 defaultLeaseTTL: conf.DefaultLeaseTTL, 625 maxLeaseTTL: conf.MaxLeaseTTL, 626 cachingDisabled: conf.DisableCache, 627 clusterName: conf.ClusterName, 628 clusterPeerClusterAddrsCache: cache.New(3*cluster.HeartbeatInterval, time.Second), 629 enableMlock: !conf.DisableMlock, 630 rawEnabled: conf.EnableRaw, 631 replicationState: new(uint32), 632 atomicPrimaryClusterAddrs: new(atomic.Value), 633 atomicPrimaryFailoverAddrs: new(atomic.Value), 634 localClusterPrivateKey: new(atomic.Value), 635 localClusterCert: new(atomic.Value), 636 localClusterParsedCert: new(atomic.Value), 637 activeNodeReplicationState: new(uint32), 638 keepHALockOnStepDown: new(uint32), 639 replicationFailure: new(uint32), 640 disablePerfStandby: true, 641 activeContextCancelFunc: new(atomic.Value), 642 allLoggers: conf.AllLoggers, 643 builtinRegistry: conf.BuiltinRegistry, 644 neverBecomeActive: new(uint32), 645 clusterLeaderParams: new(atomic.Value), 646 metricsHelper: conf.MetricsHelper, 647 counters: counters{ 648 requests: new(uint64), 649 syncInterval: syncInterval, 650 }, 651 } 652 653 atomic.StoreUint32(c.sealed, 1) 654 c.allLoggers = append(c.allLoggers, c.logger) 655 656 c.router.logger = c.logger.Named("router") 657 c.allLoggers = append(c.allLoggers, c.router.logger) 658 659 atomic.StoreUint32(c.replicationState, uint32(consts.ReplicationDRDisabled|consts.ReplicationPerformanceDisabled)) 660 c.localClusterCert.Store(([]byte)(nil)) 661 c.localClusterParsedCert.Store((*x509.Certificate)(nil)) 662 c.localClusterPrivateKey.Store((*ecdsa.PrivateKey)(nil)) 663 664 c.clusterLeaderParams.Store((*ClusterLeaderParams)(nil)) 665 c.clusterAddr.Store(conf.ClusterAddr) 666 c.activeContextCancelFunc.Store((context.CancelFunc)(nil)) 667 668 if conf.ClusterCipherSuites != "" { 669 suites, err := tlsutil.ParseCiphers(conf.ClusterCipherSuites) 670 if err != nil { 671 return nil, errwrap.Wrapf("error parsing cluster cipher suites: {{err}}", err) 672 } 673 c.clusterCipherSuites = suites 674 } 675 676 // Load CORS config and provide a value for the core field. 677 c.corsConfig = &CORSConfig{ 678 core: c, 679 Enabled: new(uint32), 680 } 681 682 if c.seal == nil { 683 c.seal = NewDefaultSeal(shamirseal.NewSeal(c.logger.Named("shamir"))) 684 } 685 c.seal.SetCore(c) 686 687 if err := coreInit(c, conf); err != nil { 688 return nil, err 689 } 690 691 if !conf.DisableMlock { 692 // Ensure our memory usage is locked into physical RAM 693 if err := mlock.LockMemory(); err != nil { 694 return nil, fmt.Errorf( 695 "Failed to lock memory: %v\n\n"+ 696 "This usually means that the mlock syscall is not available.\n"+ 697 "Vault uses mlock to prevent memory from being swapped to\n"+ 698 "disk. This requires root privileges as well as a machine\n"+ 699 "that supports mlock. Please enable mlock on your system or\n"+ 700 "disable Vault from using it. To disable Vault from using it,\n"+ 701 "set the `disable_mlock` configuration option in your configuration\n"+ 702 "file.", 703 err) 704 } 705 } 706 707 var err error 708 709 if conf.PluginDirectory != "" { 710 c.pluginDirectory, err = filepath.Abs(conf.PluginDirectory) 711 if err != nil { 712 return nil, errwrap.Wrapf("core setup failed, could not verify plugin directory: {{err}}", err) 713 } 714 } 715 716 // Construct a new AES-GCM barrier 717 c.barrier, err = NewAESGCMBarrier(c.physical) 718 if err != nil { 719 return nil, errwrap.Wrapf("barrier setup failed: {{err}}", err) 720 } 721 722 createSecondaries(c, conf) 723 724 if conf.HAPhysical != nil && conf.HAPhysical.HAEnabled() { 725 c.ha = conf.HAPhysical 726 } 727 728 // We create the funcs here, then populate the given config with it so that 729 // the caller can share state 730 conf.ReloadFuncsLock = &c.reloadFuncsLock 731 c.reloadFuncsLock.Lock() 732 c.reloadFuncs = make(map[string][]reload.ReloadFunc) 733 c.reloadFuncsLock.Unlock() 734 conf.ReloadFuncs = &c.reloadFuncs 735 736 logicalBackends := make(map[string]logical.Factory) 737 for k, f := range conf.LogicalBackends { 738 logicalBackends[k] = f 739 } 740 _, ok := logicalBackends["kv"] 741 if !ok { 742 logicalBackends["kv"] = PassthroughBackendFactory 743 } 744 745 logicalBackends["cubbyhole"] = CubbyholeBackendFactory 746 logicalBackends[systemMountType] = func(ctx context.Context, config *logical.BackendConfig) (logical.Backend, error) { 747 sysBackendLogger := conf.Logger.Named("system") 748 c.AddLogger(sysBackendLogger) 749 b := NewSystemBackend(c, sysBackendLogger) 750 if err := b.Setup(ctx, config); err != nil { 751 return nil, err 752 } 753 return b, nil 754 } 755 logicalBackends["identity"] = func(ctx context.Context, config *logical.BackendConfig) (logical.Backend, error) { 756 identityLogger := conf.Logger.Named("identity") 757 c.AddLogger(identityLogger) 758 return NewIdentityStore(ctx, c, config, identityLogger) 759 } 760 addExtraLogicalBackends(c, logicalBackends) 761 c.logicalBackends = logicalBackends 762 763 credentialBackends := make(map[string]logical.Factory) 764 for k, f := range conf.CredentialBackends { 765 credentialBackends[k] = f 766 } 767 credentialBackends["token"] = func(ctx context.Context, config *logical.BackendConfig) (logical.Backend, error) { 768 tsLogger := conf.Logger.Named("token") 769 c.AddLogger(tsLogger) 770 return NewTokenStore(ctx, tsLogger, c, config) 771 } 772 addExtraCredentialBackends(c, credentialBackends) 773 c.credentialBackends = credentialBackends 774 775 auditBackends := make(map[string]audit.Factory) 776 for k, f := range conf.AuditBackends { 777 auditBackends[k] = f 778 } 779 c.auditBackends = auditBackends 780 781 uiStoragePrefix := systemBarrierPrefix + "ui" 782 c.uiConfig = NewUIConfig(conf.EnableUI, physical.NewView(c.physical, uiStoragePrefix), NewBarrierView(c.barrier, uiStoragePrefix)) 783 784 return c, nil 785} 786 787// Shutdown is invoked when the Vault instance is about to be terminated. It 788// should not be accessible as part of an API call as it will cause an availability 789// problem. It is only used to gracefully quit in the case of HA so that failover 790// happens as quickly as possible. 791func (c *Core) Shutdown() error { 792 c.logger.Debug("shutdown called") 793 return c.sealInternal() 794} 795 796// CORSConfig returns the current CORS configuration 797func (c *Core) CORSConfig() *CORSConfig { 798 return c.corsConfig 799} 800 801func (c *Core) GetContext() (context.Context, context.CancelFunc) { 802 c.stateLock.RLock() 803 defer c.stateLock.RUnlock() 804 805 return context.WithCancel(namespace.RootContext(c.activeContext)) 806} 807 808// Sealed checks if the Vault is current sealed 809func (c *Core) Sealed() bool { 810 return atomic.LoadUint32(c.sealed) == 1 811} 812 813// SecretProgress returns the number of keys provided so far 814func (c *Core) SecretProgress() (int, string) { 815 c.stateLock.RLock() 816 defer c.stateLock.RUnlock() 817 switch c.unlockInfo { 818 case nil: 819 return 0, "" 820 default: 821 return len(c.unlockInfo.Parts), c.unlockInfo.Nonce 822 } 823} 824 825// ResetUnsealProcess removes the current unlock parts from memory, to reset 826// the unsealing process 827func (c *Core) ResetUnsealProcess() { 828 c.stateLock.Lock() 829 defer c.stateLock.Unlock() 830 c.unlockInfo = nil 831} 832 833// Unseal is used to provide one of the key parts to unseal the Vault. 834// 835// They key given as a parameter will automatically be zerod after 836// this method is done with it. If you want to keep the key around, a copy 837// should be made. 838func (c *Core) Unseal(key []byte) (bool, error) { 839 return c.unseal(key, false) 840} 841 842func (c *Core) UnsealWithRecoveryKeys(key []byte) (bool, error) { 843 return c.unseal(key, true) 844} 845 846func (c *Core) unseal(key []byte, useRecoveryKeys bool) (bool, error) { 847 defer metrics.MeasureSince([]string{"core", "unseal"}, time.Now()) 848 849 c.stateLock.Lock() 850 defer c.stateLock.Unlock() 851 852 c.logger.Debug("unseal key supplied") 853 854 ctx := context.Background() 855 856 // Explicitly check for init status. This also checks if the seal 857 // configuration is valid (i.e. non-nil). 858 init, err := c.Initialized(ctx) 859 if err != nil { 860 return false, err 861 } 862 if !init && !c.isRaftUnseal() { 863 return false, ErrNotInit 864 } 865 866 // Verify the key length 867 min, max := c.barrier.KeyLength() 868 max += shamir.ShareOverhead 869 if len(key) < min { 870 return false, &ErrInvalidKey{fmt.Sprintf("key is shorter than minimum %d bytes", min)} 871 } 872 if len(key) > max { 873 return false, &ErrInvalidKey{fmt.Sprintf("key is longer than maximum %d bytes", max)} 874 } 875 876 // Check if already unsealed 877 if !c.Sealed() { 878 return true, nil 879 } 880 881 sealToUse := c.seal 882 if c.migrationSeal != nil { 883 sealToUse = c.migrationSeal 884 } 885 886 masterKey, err := c.unsealPart(ctx, sealToUse, key, useRecoveryKeys) 887 if err != nil { 888 return false, err 889 } 890 891 if masterKey != nil { 892 if c.seal.BarrierType() == seal.Shamir { 893 _, err := c.seal.GetAccess().(*shamirseal.ShamirSeal).SetConfig(map[string]string{ 894 "key": base64.StdEncoding.EncodeToString(masterKey), 895 }) 896 if err != nil { 897 return false, err 898 } 899 } 900 901 if !c.isRaftUnseal() { 902 return c.unsealInternal(ctx, masterKey) 903 } 904 905 // If we are in the middle of a raft join send the answer and wait for 906 // data to start streaming in. 907 if err := c.joinRaftSendAnswer(ctx, c.raftLeaderClient, c.raftChallenge, c.seal.GetAccess()); err != nil { 908 return false, err 909 } 910 // Reset the state 911 c.raftUnseal = false 912 c.raftChallenge = nil 913 c.raftLeaderBarrierConfig = nil 914 c.raftLeaderClient = nil 915 916 go func() { 917 keyringFound := false 918 defer func() { 919 if keyringFound { 920 _, err := c.unsealInternal(ctx, masterKey) 921 if err != nil { 922 c.logger.Error("failed to unseal", "error", err) 923 } 924 } 925 }() 926 927 // Wait until we at least have the keyring before we attempt to 928 // unseal the node. 929 for { 930 keys, err := c.underlyingPhysical.List(ctx, keyringPrefix) 931 if err != nil { 932 c.logger.Error("failed to list physical keys", "error", err) 933 return 934 } 935 if strutil.StrListContains(keys, "keyring") { 936 keyringFound = true 937 return 938 } 939 select { 940 case <-time.After(1 * time.Second): 941 } 942 } 943 }() 944 945 // Return Vault as sealed since unsealing happens in background 946 // which gets delayed until the data from the leader is streamed to 947 // the follower. 948 return true, nil 949 } 950 951 return false, nil 952} 953 954// unsealPart takes in a key share, and returns the master key if the threshold 955// is met. If recovery keys are supported, recovery key shares may be provided. 956func (c *Core) unsealPart(ctx context.Context, seal Seal, key []byte, useRecoveryKeys bool) ([]byte, error) { 957 // Check if we already have this piece 958 if c.unlockInfo != nil { 959 for _, existing := range c.unlockInfo.Parts { 960 if subtle.ConstantTimeCompare(existing, key) == 1 { 961 return nil, nil 962 } 963 } 964 } else { 965 uuid, err := uuid.GenerateUUID() 966 if err != nil { 967 return nil, err 968 } 969 c.unlockInfo = &unlockInformation{ 970 Nonce: uuid, 971 } 972 } 973 974 // Store this key 975 c.unlockInfo.Parts = append(c.unlockInfo.Parts, key) 976 977 var config *SealConfig 978 var err error 979 980 switch { 981 case seal.RecoveryKeySupported() && (useRecoveryKeys || c.migrationSeal != nil): 982 config, err = seal.RecoveryConfig(ctx) 983 case c.isRaftUnseal(): 984 // Ignore follower's seal config and refer to leader's barrier 985 // configuration. 986 config = c.raftLeaderBarrierConfig 987 default: 988 config, err = seal.BarrierConfig(ctx) 989 } 990 if err != nil { 991 return nil, err 992 } 993 994 // Check if we don't have enough keys to unlock, proceed through the rest of 995 // the call only if we have met the threshold 996 if len(c.unlockInfo.Parts) < config.SecretThreshold { 997 if c.logger.IsDebug() { 998 c.logger.Debug("cannot unseal, not enough keys", "keys", len(c.unlockInfo.Parts), "threshold", config.SecretThreshold, "nonce", c.unlockInfo.Nonce) 999 } 1000 return nil, nil 1001 } 1002 1003 // Best-effort memzero of unlock parts once we're done with them 1004 defer func() { 1005 for i := range c.unlockInfo.Parts { 1006 memzero(c.unlockInfo.Parts[i]) 1007 } 1008 c.unlockInfo = nil 1009 }() 1010 1011 // Recover the split key. recoveredKey is the shamir combined 1012 // key, or the single provided key if the threshold is 1. 1013 var recoveredKey []byte 1014 var masterKey []byte 1015 var recoveryKey []byte 1016 if config.SecretThreshold == 1 { 1017 recoveredKey = make([]byte, len(c.unlockInfo.Parts[0])) 1018 copy(recoveredKey, c.unlockInfo.Parts[0]) 1019 } else { 1020 recoveredKey, err = shamir.Combine(c.unlockInfo.Parts) 1021 if err != nil { 1022 return nil, errwrap.Wrapf("failed to compute master key: {{err}}", err) 1023 } 1024 } 1025 1026 if seal.RecoveryKeySupported() && (useRecoveryKeys || c.migrationSeal != nil) { 1027 // Verify recovery key 1028 if err := seal.VerifyRecoveryKey(ctx, recoveredKey); err != nil { 1029 return nil, err 1030 } 1031 recoveryKey = recoveredKey 1032 1033 // Get stored keys and shamir combine into single master key. Unsealing with 1034 // recovery keys currently does not support: 1) mixed stored and non-stored 1035 // keys setup, nor 2) seals that support recovery keys but not stored keys. 1036 // If insufficient shares are provided, shamir.Combine will error, and if 1037 // no stored keys are found it will return masterKey as nil. 1038 if seal.StoredKeysSupported() { 1039 masterKeyShares, err := seal.GetStoredKeys(ctx) 1040 if err != nil { 1041 return nil, errwrap.Wrapf("unable to retrieve stored keys: {{err}}", err) 1042 } 1043 1044 switch len(masterKeyShares) { 1045 case 0: 1046 return nil, errors.New("seal returned no master key shares") 1047 case 1: 1048 masterKey = masterKeyShares[0] 1049 default: 1050 masterKey, err = shamir.Combine(masterKeyShares) 1051 if err != nil { 1052 return nil, errwrap.Wrapf("failed to compute master key: {{err}}", err) 1053 } 1054 } 1055 } 1056 } else { 1057 masterKey = recoveredKey 1058 } 1059 1060 // If we have a migration seal, now's the time! 1061 if c.migrationSeal != nil { 1062 // Unseal the barrier so we can rekey 1063 if err := c.barrier.Unseal(ctx, masterKey); err != nil { 1064 return nil, errwrap.Wrapf("error unsealing barrier with constructed master key: {{err}}", err) 1065 } 1066 defer c.barrier.Seal() 1067 1068 switch { 1069 case c.migrationSeal.RecoveryKeySupported() && c.seal.RecoveryKeySupported(): 1070 // Set the recovery and barrier keys to be the same. 1071 recoveryKey, err := c.migrationSeal.RecoveryKey(ctx) 1072 if err != nil { 1073 return nil, errwrap.Wrapf("error getting recovery key to set on new seal: {{err}}", err) 1074 } 1075 1076 if err := c.seal.SetRecoveryKey(ctx, recoveryKey); err != nil { 1077 return nil, errwrap.Wrapf("error setting new recovery key information during migrate: {{err}}", err) 1078 } 1079 1080 barrierKeys, err := c.migrationSeal.GetStoredKeys(ctx) 1081 if err != nil { 1082 return nil, errwrap.Wrapf("error getting stored keys to set on new seal: {{err}}", err) 1083 } 1084 1085 if err := c.seal.SetStoredKeys(ctx, barrierKeys); err != nil { 1086 return nil, errwrap.Wrapf("error setting new barrier key information during migrate: {{err}}", err) 1087 } 1088 1089 case c.migrationSeal.RecoveryKeySupported(): 1090 // Auto to Shamir, since recovery key isn't supported on new seal 1091 1092 // In this case we have to ensure that the recovery information was 1093 // set properly. 1094 if recoveryKey == nil { 1095 return nil, errors.New("did not get expected recovery information to set new seal during migration") 1096 } 1097 1098 // We have recovery keys; we're going to use them as the new 1099 // barrier key. 1100 if err := c.barrier.Rekey(ctx, recoveryKey); err != nil { 1101 return nil, errwrap.Wrapf("error rekeying barrier during migration: {{err}}", err) 1102 } 1103 1104 if err := c.barrier.Delete(ctx, StoredBarrierKeysPath); err != nil { 1105 // Don't actually exit here as successful deletion isn't critical 1106 c.logger.Error("error deleting stored barrier keys after migration; continuing anyways", "error", err) 1107 } 1108 1109 masterKey = recoveryKey 1110 1111 case c.seal.RecoveryKeySupported(): 1112 // The new seal will have recovery keys; we set it to the existing 1113 // master key, so barrier key shares -> recovery key shares 1114 if err := c.seal.SetRecoveryKey(ctx, masterKey); err != nil { 1115 return nil, errwrap.Wrapf("error setting new recovery key information: {{err}}", err) 1116 } 1117 1118 // Generate a new master key 1119 newMasterKey, err := c.barrier.GenerateKey() 1120 if err != nil { 1121 return nil, errwrap.Wrapf("error generating new master key: {{err}}", err) 1122 } 1123 1124 // Rekey the barrier 1125 if err := c.barrier.Rekey(ctx, newMasterKey); err != nil { 1126 return nil, errwrap.Wrapf("error rekeying barrier during migration: {{err}}", err) 1127 } 1128 1129 // Store the new master key 1130 if err := c.seal.SetStoredKeys(ctx, [][]byte{newMasterKey}); err != nil { 1131 return nil, errwrap.Wrapf("error storing new master key: {[err}}", err) 1132 } 1133 1134 // Return the new key so it can be used to unlock the barrier 1135 masterKey = newMasterKey 1136 1137 default: 1138 return nil, errors.New("unhandled migration case (shamir to shamir)") 1139 } 1140 1141 // At this point we've swapped things around and need to ensure we 1142 // don't migrate again 1143 c.migrationSeal = nil 1144 1145 // Ensure we populate the new values 1146 bc, err := c.seal.BarrierConfig(ctx) 1147 if err != nil { 1148 return nil, errwrap.Wrapf("error fetching barrier config after migration: {{err}}", err) 1149 } 1150 if err := c.seal.SetBarrierConfig(ctx, bc); err != nil { 1151 return nil, errwrap.Wrapf("error storing barrier config after migration: {{err}}", err) 1152 } 1153 1154 if c.seal.RecoveryKeySupported() { 1155 rc, err := c.seal.RecoveryConfig(ctx) 1156 if err != nil { 1157 return nil, errwrap.Wrapf("error fetching recovery config after migration: {{err}}", err) 1158 } 1159 if err := c.seal.SetRecoveryConfig(ctx, rc); err != nil { 1160 return nil, errwrap.Wrapf("error storing recovery config after migration: {{err}}", err) 1161 } 1162 } 1163 } 1164 1165 return masterKey, nil 1166} 1167 1168// unsealInternal takes in the master key and attempts to unseal the barrier. 1169// N.B.: This must be called with the state write lock held. 1170func (c *Core) unsealInternal(ctx context.Context, masterKey []byte) (bool, error) { 1171 defer memzero(masterKey) 1172 1173 // Attempt to unlock 1174 if err := c.barrier.Unseal(ctx, masterKey); err != nil { 1175 return false, err 1176 } 1177 1178 if err := preUnsealInternal(ctx, c); err != nil { 1179 return false, err 1180 } 1181 1182 if err := c.startClusterListener(ctx); err != nil { 1183 return false, err 1184 } 1185 1186 if err := c.startRaftStorage(ctx); err != nil { 1187 return false, err 1188 } 1189 1190 // Do post-unseal setup if HA is not enabled 1191 if c.ha == nil { 1192 // We still need to set up cluster info even if it's not part of a 1193 // cluster right now. This also populates the cached cluster object. 1194 if err := c.setupCluster(ctx); err != nil { 1195 c.logger.Error("cluster setup failed", "error", err) 1196 c.barrier.Seal() 1197 c.logger.Warn("vault is sealed") 1198 return false, err 1199 } 1200 1201 ctx, ctxCancel := context.WithCancel(namespace.RootContext(nil)) 1202 if err := c.postUnseal(ctx, ctxCancel, standardUnsealStrategy{}); err != nil { 1203 c.logger.Error("post-unseal setup failed", "error", err) 1204 c.barrier.Seal() 1205 c.logger.Warn("vault is sealed") 1206 return false, err 1207 } 1208 1209 c.standby = false 1210 } else { 1211 // Go to standby mode, wait until we are active to unseal 1212 c.standbyDoneCh = make(chan struct{}) 1213 c.manualStepDownCh = make(chan struct{}) 1214 c.standbyStopCh = make(chan struct{}) 1215 go c.runStandby(c.standbyDoneCh, c.manualStepDownCh, c.standbyStopCh) 1216 } 1217 1218 // Force a cache bust here, which will also run migration code 1219 if c.seal.RecoveryKeySupported() { 1220 c.seal.SetRecoveryConfig(ctx, nil) 1221 } 1222 1223 // Success! 1224 atomic.StoreUint32(c.sealed, 0) 1225 1226 if c.logger.IsInfo() { 1227 c.logger.Info("vault is unsealed") 1228 } 1229 1230 if c.ha != nil { 1231 sd, ok := c.ha.(physical.ServiceDiscovery) 1232 if ok { 1233 if err := sd.NotifySealedStateChange(); err != nil { 1234 if c.logger.IsWarn() { 1235 c.logger.Warn("failed to notify unsealed status", "error", err) 1236 } 1237 } 1238 } 1239 } 1240 return true, nil 1241} 1242 1243// SealWithRequest takes in a logical.Request, acquires the lock, and passes 1244// through to sealInternal 1245func (c *Core) SealWithRequest(httpCtx context.Context, req *logical.Request) error { 1246 defer metrics.MeasureSince([]string{"core", "seal-with-request"}, time.Now()) 1247 1248 if c.Sealed() { 1249 return nil 1250 } 1251 1252 c.stateLock.RLock() 1253 1254 // This will unlock the read lock 1255 // We use background context since we may not be active 1256 ctx, cancel := context.WithCancel(namespace.RootContext(nil)) 1257 defer cancel() 1258 1259 go func() { 1260 select { 1261 case <-ctx.Done(): 1262 case <-httpCtx.Done(): 1263 cancel() 1264 } 1265 }() 1266 1267 // This will unlock the read lock 1268 return c.sealInitCommon(ctx, req) 1269} 1270 1271// Seal takes in a token and creates a logical.Request, acquires the lock, and 1272// passes through to sealInternal 1273func (c *Core) Seal(token string) error { 1274 defer metrics.MeasureSince([]string{"core", "seal"}, time.Now()) 1275 1276 if c.Sealed() { 1277 return nil 1278 } 1279 1280 c.stateLock.RLock() 1281 1282 req := &logical.Request{ 1283 Operation: logical.UpdateOperation, 1284 Path: "sys/seal", 1285 ClientToken: token, 1286 } 1287 1288 // This will unlock the read lock 1289 // We use background context since we may not be active 1290 return c.sealInitCommon(namespace.RootContext(nil), req) 1291} 1292 1293// sealInitCommon is common logic for Seal and SealWithRequest and is used to 1294// re-seal the Vault. This requires the Vault to be unsealed again to perform 1295// any further operations. Note: this function will read-unlock the state lock. 1296func (c *Core) sealInitCommon(ctx context.Context, req *logical.Request) (retErr error) { 1297 defer metrics.MeasureSince([]string{"core", "seal-internal"}, time.Now()) 1298 1299 var unlocked bool 1300 defer func() { 1301 if !unlocked { 1302 c.stateLock.RUnlock() 1303 } 1304 }() 1305 1306 if req == nil { 1307 retErr = multierror.Append(retErr, errors.New("nil request to seal")) 1308 return retErr 1309 } 1310 1311 // Since there is no token store in standby nodes, sealing cannot be done. 1312 // Ideally, the request has to be forwarded to leader node for validation 1313 // and the operation should be performed. But for now, just returning with 1314 // an error and recommending a vault restart, which essentially does the 1315 // same thing. 1316 if c.standby { 1317 c.logger.Error("vault cannot seal when in standby mode; please restart instead") 1318 retErr = multierror.Append(retErr, errors.New("vault cannot seal when in standby mode; please restart instead")) 1319 return retErr 1320 } 1321 1322 acl, te, entity, identityPolicies, err := c.fetchACLTokenEntryAndEntity(ctx, req) 1323 if err != nil { 1324 retErr = multierror.Append(retErr, err) 1325 return retErr 1326 } 1327 1328 // Audit-log the request before going any further 1329 auth := &logical.Auth{ 1330 ClientToken: req.ClientToken, 1331 Accessor: req.ClientTokenAccessor, 1332 } 1333 if te != nil { 1334 auth.IdentityPolicies = identityPolicies[te.NamespaceID] 1335 delete(identityPolicies, te.NamespaceID) 1336 auth.ExternalNamespacePolicies = identityPolicies 1337 auth.TokenPolicies = te.Policies 1338 auth.Policies = append(te.Policies, identityPolicies[te.NamespaceID]...) 1339 auth.Metadata = te.Meta 1340 auth.DisplayName = te.DisplayName 1341 auth.EntityID = te.EntityID 1342 auth.TokenType = te.Type 1343 } 1344 1345 logInput := &logical.LogInput{ 1346 Auth: auth, 1347 Request: req, 1348 } 1349 if err := c.auditBroker.LogRequest(ctx, logInput, c.auditedHeaders); err != nil { 1350 c.logger.Error("failed to audit request", "request_path", req.Path, "error", err) 1351 retErr = multierror.Append(retErr, errors.New("failed to audit request, cannot continue")) 1352 return retErr 1353 } 1354 1355 if entity != nil && entity.Disabled { 1356 c.logger.Warn("permission denied as the entity on the token is disabled") 1357 retErr = multierror.Append(retErr, logical.ErrPermissionDenied) 1358 return retErr 1359 } 1360 if te != nil && te.EntityID != "" && entity == nil { 1361 c.logger.Warn("permission denied as the entity on the token is invalid") 1362 retErr = multierror.Append(retErr, logical.ErrPermissionDenied) 1363 return retErr 1364 } 1365 1366 // Attempt to use the token (decrement num_uses) 1367 // On error bail out; if the token has been revoked, bail out too 1368 if te != nil { 1369 te, err = c.tokenStore.UseToken(ctx, te) 1370 if err != nil { 1371 c.logger.Error("failed to use token", "error", err) 1372 retErr = multierror.Append(retErr, ErrInternalError) 1373 return retErr 1374 } 1375 if te == nil { 1376 // Token is no longer valid 1377 retErr = multierror.Append(retErr, logical.ErrPermissionDenied) 1378 return retErr 1379 } 1380 } 1381 1382 // Verify that this operation is allowed 1383 authResults := c.performPolicyChecks(ctx, acl, te, req, entity, &PolicyCheckOpts{ 1384 RootPrivsRequired: true, 1385 }) 1386 if !authResults.Allowed { 1387 retErr = multierror.Append(retErr, authResults.Error) 1388 if authResults.Error.ErrorOrNil() == nil || authResults.DeniedError { 1389 retErr = multierror.Append(retErr, logical.ErrPermissionDenied) 1390 } 1391 return retErr 1392 } 1393 1394 if te != nil && te.NumUses == tokenRevocationPending { 1395 // Token needs to be revoked. We do this immediately here because 1396 // we won't have a token store after sealing. 1397 leaseID, err := c.expiration.CreateOrFetchRevocationLeaseByToken(c.activeContext, te) 1398 if err == nil { 1399 err = c.expiration.Revoke(c.activeContext, leaseID) 1400 } 1401 if err != nil { 1402 c.logger.Error("token needed revocation before seal but failed to revoke", "error", err) 1403 retErr = multierror.Append(retErr, ErrInternalError) 1404 } 1405 } 1406 1407 // Unlock; sealing will grab the lock when needed 1408 unlocked = true 1409 c.stateLock.RUnlock() 1410 1411 sealErr := c.sealInternal() 1412 1413 if sealErr != nil { 1414 retErr = multierror.Append(retErr, sealErr) 1415 } 1416 1417 return 1418} 1419 1420// UIEnabled returns if the UI is enabled 1421func (c *Core) UIEnabled() bool { 1422 return c.uiConfig.Enabled() 1423} 1424 1425// UIHeaders returns configured UI headers 1426func (c *Core) UIHeaders() (http.Header, error) { 1427 return c.uiConfig.Headers(context.Background()) 1428} 1429 1430// sealInternal is an internal method used to seal the vault. It does not do 1431// any authorization checking. 1432func (c *Core) sealInternal() error { 1433 return c.sealInternalWithOptions(true, false, true) 1434} 1435 1436func (c *Core) sealInternalWithOptions(grabStateLock, keepHALock, shutdownRaft bool) error { 1437 // Mark sealed, and if already marked return 1438 if swapped := atomic.CompareAndSwapUint32(c.sealed, 0, 1); !swapped { 1439 return nil 1440 } 1441 1442 c.logger.Info("marked as sealed") 1443 1444 // Clear forwarding clients 1445 c.requestForwardingConnectionLock.Lock() 1446 c.clearForwardingClients() 1447 c.requestForwardingConnectionLock.Unlock() 1448 1449 activeCtxCancel := c.activeContextCancelFunc.Load().(context.CancelFunc) 1450 cancelCtxAndLock := func() { 1451 doneCh := make(chan struct{}) 1452 go func() { 1453 select { 1454 case <-doneCh: 1455 // Attempt to drain any inflight requests 1456 case <-time.After(DefaultMaxRequestDuration): 1457 if activeCtxCancel != nil { 1458 activeCtxCancel() 1459 } 1460 } 1461 }() 1462 1463 c.stateLock.Lock() 1464 close(doneCh) 1465 // Stop requests from processing 1466 if activeCtxCancel != nil { 1467 activeCtxCancel() 1468 } 1469 } 1470 1471 // Do pre-seal teardown if HA is not enabled 1472 if c.ha == nil { 1473 if grabStateLock { 1474 cancelCtxAndLock() 1475 defer c.stateLock.Unlock() 1476 } 1477 // Even in a non-HA context we key off of this for some things 1478 c.standby = true 1479 1480 // Stop requests from processing 1481 if activeCtxCancel != nil { 1482 activeCtxCancel() 1483 } 1484 1485 if err := c.preSeal(); err != nil { 1486 c.logger.Error("pre-seal teardown failed", "error", err) 1487 return fmt.Errorf("internal error") 1488 } 1489 } else { 1490 // If we are keeping the lock we already have the state write lock 1491 // held. Otherwise grab it here so that when stopCh is triggered we are 1492 // locked. 1493 if keepHALock { 1494 atomic.StoreUint32(c.keepHALockOnStepDown, 1) 1495 } 1496 if grabStateLock { 1497 cancelCtxAndLock() 1498 defer c.stateLock.Unlock() 1499 } 1500 1501 // If we are trying to acquire the lock, force it to return with nil so 1502 // runStandby will exit 1503 // If we are active, signal the standby goroutine to shut down and wait 1504 // for completion. We have the state lock here so nothing else should 1505 // be toggling standby status. 1506 close(c.standbyStopCh) 1507 c.logger.Debug("finished triggering standbyStopCh for runStandby") 1508 1509 // Wait for runStandby to stop 1510 <-c.standbyDoneCh 1511 atomic.StoreUint32(c.keepHALockOnStepDown, 0) 1512 c.logger.Debug("runStandby done") 1513 } 1514 1515 // If the storage backend needs to be sealed 1516 if shutdownRaft { 1517 if raftStorage, ok := c.underlyingPhysical.(*raft.RaftBackend); ok { 1518 if err := raftStorage.TeardownCluster(c.clusterListener); err != nil { 1519 c.logger.Error("error stopping storage cluster", "error", err) 1520 return err 1521 } 1522 } 1523 1524 // Stop the cluster listener 1525 c.stopClusterListener() 1526 } 1527 1528 c.logger.Debug("sealing barrier") 1529 if err := c.barrier.Seal(); err != nil { 1530 c.logger.Error("error sealing barrier", "error", err) 1531 return err 1532 } 1533 1534 if c.ha != nil { 1535 sd, ok := c.ha.(physical.ServiceDiscovery) 1536 if ok { 1537 if err := sd.NotifySealedStateChange(); err != nil { 1538 if c.logger.IsWarn() { 1539 c.logger.Warn("failed to notify sealed status", "error", err) 1540 } 1541 } 1542 } 1543 } 1544 1545 postSealInternal(c) 1546 1547 c.logger.Info("vault is sealed") 1548 1549 return nil 1550} 1551 1552type UnsealStrategy interface { 1553 unseal(context.Context, log.Logger, *Core) error 1554} 1555 1556type standardUnsealStrategy struct{} 1557 1558func (s standardUnsealStrategy) unseal(ctx context.Context, logger log.Logger, c *Core) error { 1559 // Clear forwarding clients; we're active 1560 c.requestForwardingConnectionLock.Lock() 1561 c.clearForwardingClients() 1562 c.requestForwardingConnectionLock.Unlock() 1563 1564 if err := postUnsealPhysical(c); err != nil { 1565 return err 1566 } 1567 1568 if err := enterprisePostUnseal(c); err != nil { 1569 return err 1570 } 1571 1572 if !c.IsDRSecondary() { 1573 if err := c.ensureWrappingKey(ctx); err != nil { 1574 return err 1575 } 1576 } 1577 if err := c.setupPluginCatalog(ctx); err != nil { 1578 return err 1579 } 1580 if err := c.loadMounts(ctx); err != nil { 1581 return err 1582 } 1583 if err := c.setupMounts(ctx); err != nil { 1584 return err 1585 } 1586 if err := c.setupPolicyStore(ctx); err != nil { 1587 return err 1588 } 1589 if err := c.loadCORSConfig(ctx); err != nil { 1590 return err 1591 } 1592 if err := c.loadCurrentRequestCounters(ctx, time.Now()); err != nil { 1593 return err 1594 } 1595 if err := c.loadCredentials(ctx); err != nil { 1596 return err 1597 } 1598 if err := c.setupCredentials(ctx); err != nil { 1599 return err 1600 } 1601 if !c.IsDRSecondary() { 1602 if err := c.startRollback(); err != nil { 1603 return err 1604 } 1605 if err := c.setupExpiration(expireLeaseStrategyRevoke); err != nil { 1606 return err 1607 } 1608 if err := c.loadAudits(ctx); err != nil { 1609 return err 1610 } 1611 if err := c.setupAudits(ctx); err != nil { 1612 return err 1613 } 1614 if err := c.loadIdentityStoreArtifacts(ctx); err != nil { 1615 return err 1616 } 1617 if err := loadMFAConfigs(ctx, c); err != nil { 1618 return err 1619 } 1620 if err := c.setupAuditedHeadersConfig(ctx); err != nil { 1621 return err 1622 } 1623 } else { 1624 c.auditBroker = NewAuditBroker(c.logger) 1625 } 1626 1627 if c.clusterListener != nil && (c.ha != nil || shouldStartClusterListener(c)) { 1628 if err := c.setupRaftActiveNode(ctx); err != nil { 1629 return err 1630 } 1631 1632 if err := c.startForwarding(ctx); err != nil { 1633 return err 1634 } 1635 1636 } 1637 1638 c.clusterParamsLock.Lock() 1639 defer c.clusterParamsLock.Unlock() 1640 if err := startReplication(c); err != nil { 1641 return err 1642 } 1643 1644 return nil 1645} 1646 1647// postUnseal is invoked after the barrier is unsealed, but before 1648// allowing any user operations. This allows us to setup any state that 1649// requires the Vault to be unsealed such as mount tables, logical backends, 1650// credential stores, etc. 1651func (c *Core) postUnseal(ctx context.Context, ctxCancelFunc context.CancelFunc, unsealer UnsealStrategy) (retErr error) { 1652 defer metrics.MeasureSince([]string{"core", "post_unseal"}, time.Now()) 1653 1654 // Clear any out 1655 c.postUnsealFuncs = nil 1656 1657 // Create a new request context 1658 c.activeContext = ctx 1659 c.activeContextCancelFunc.Store(ctxCancelFunc) 1660 1661 defer func() { 1662 if retErr != nil { 1663 ctxCancelFunc() 1664 c.preSeal() 1665 } 1666 }() 1667 c.logger.Info("post-unseal setup starting") 1668 1669 // Enable the cache 1670 c.physicalCache.Purge(ctx) 1671 if !c.cachingDisabled { 1672 c.physicalCache.SetEnabled(true) 1673 } 1674 1675 // Purge these for safety in case of a rekey 1676 c.seal.SetBarrierConfig(ctx, nil) 1677 if c.seal.RecoveryKeySupported() { 1678 c.seal.SetRecoveryConfig(ctx, nil) 1679 } 1680 1681 if err := unsealer.unseal(ctx, c.logger, c); err != nil { 1682 return err 1683 } 1684 1685 c.metricsCh = make(chan struct{}) 1686 go c.emitMetrics(c.metricsCh) 1687 1688 // This is intentionally the last block in this function. We want to allow 1689 // writes just before allowing client requests, to ensure everything has 1690 // been set up properly before any writes can have happened. 1691 for _, v := range c.postUnsealFuncs { 1692 v() 1693 } 1694 1695 c.logger.Info("post-unseal setup complete") 1696 return nil 1697} 1698 1699// preSeal is invoked before the barrier is sealed, allowing 1700// for any state teardown required. 1701func (c *Core) preSeal() error { 1702 defer metrics.MeasureSince([]string{"core", "pre_seal"}, time.Now()) 1703 c.logger.Info("pre-seal teardown starting") 1704 1705 // Clear any pending funcs 1706 c.postUnsealFuncs = nil 1707 1708 // Clear any rekey progress 1709 c.barrierRekeyConfig = nil 1710 c.recoveryRekeyConfig = nil 1711 1712 if c.metricsCh != nil { 1713 close(c.metricsCh) 1714 c.metricsCh = nil 1715 } 1716 var result error 1717 1718 c.stopForwarding() 1719 1720 c.stopRaftActiveNode() 1721 1722 c.clusterParamsLock.Lock() 1723 if err := stopReplication(c); err != nil { 1724 result = multierror.Append(result, errwrap.Wrapf("error stopping replication: {{err}}", err)) 1725 } 1726 c.clusterParamsLock.Unlock() 1727 1728 if err := c.teardownAudits(); err != nil { 1729 result = multierror.Append(result, errwrap.Wrapf("error tearing down audits: {{err}}", err)) 1730 } 1731 if err := c.stopExpiration(); err != nil { 1732 result = multierror.Append(result, errwrap.Wrapf("error stopping expiration: {{err}}", err)) 1733 } 1734 if err := c.teardownCredentials(context.Background()); err != nil { 1735 result = multierror.Append(result, errwrap.Wrapf("error tearing down credentials: {{err}}", err)) 1736 } 1737 if err := c.teardownPolicyStore(); err != nil { 1738 result = multierror.Append(result, errwrap.Wrapf("error tearing down policy store: {{err}}", err)) 1739 } 1740 if err := c.stopRollback(); err != nil { 1741 result = multierror.Append(result, errwrap.Wrapf("error stopping rollback: {{err}}", err)) 1742 } 1743 if err := c.unloadMounts(context.Background()); err != nil { 1744 result = multierror.Append(result, errwrap.Wrapf("error unloading mounts: {{err}}", err)) 1745 } 1746 if err := enterprisePreSeal(c); err != nil { 1747 result = multierror.Append(result, err) 1748 } 1749 1750 preSealPhysical(c) 1751 1752 c.logger.Info("pre-seal teardown complete") 1753 return result 1754} 1755 1756func enterprisePostUnsealImpl(c *Core) error { 1757 return nil 1758} 1759 1760func enterprisePreSealImpl(c *Core) error { 1761 return nil 1762} 1763 1764func startReplicationImpl(c *Core) error { 1765 return nil 1766} 1767 1768func stopReplicationImpl(c *Core) error { 1769 return nil 1770} 1771 1772// emitMetrics is used to periodically expose metrics while running 1773func (c *Core) emitMetrics(stopCh chan struct{}) { 1774 emitTimer := time.Tick(time.Second) 1775 writeTimer := time.Tick(c.counters.syncInterval) 1776 1777 for { 1778 select { 1779 case <-emitTimer: 1780 c.metricsMutex.Lock() 1781 if c.expiration != nil { 1782 c.expiration.emitMetrics() 1783 } 1784 c.metricsMutex.Unlock() 1785 1786 case <-writeTimer: 1787 if stopped := grabLockOrStop(c.stateLock.RLock, c.stateLock.RUnlock, stopCh); stopped { 1788 // Go through the loop again, this time the stop channel case 1789 // should trigger 1790 continue 1791 } 1792 if c.perfStandby { 1793 syncCounter(c) 1794 } else { 1795 err := c.saveCurrentRequestCounters(context.Background(), time.Now()) 1796 if err != nil { 1797 c.logger.Error("writing request counters to barrier", "err", err) 1798 } 1799 } 1800 c.stateLock.RUnlock() 1801 1802 case <-stopCh: 1803 return 1804 } 1805 } 1806} 1807 1808func (c *Core) ReplicationState() consts.ReplicationState { 1809 return consts.ReplicationState(atomic.LoadUint32(c.replicationState)) 1810} 1811 1812func (c *Core) ActiveNodeReplicationState() consts.ReplicationState { 1813 return consts.ReplicationState(atomic.LoadUint32(c.activeNodeReplicationState)) 1814} 1815 1816func (c *Core) SealAccess() *SealAccess { 1817 return NewSealAccess(c.seal) 1818} 1819 1820func (c *Core) Logger() log.Logger { 1821 return c.logger 1822} 1823 1824func (c *Core) BarrierKeyLength() (min, max int) { 1825 min, max = c.barrier.KeyLength() 1826 max += shamir.ShareOverhead 1827 return 1828} 1829 1830func (c *Core) AuditedHeadersConfig() *AuditedHeadersConfig { 1831 return c.auditedHeaders 1832} 1833 1834func waitUntilWALShippedImpl(ctx context.Context, c *Core, index uint64) bool { 1835 return true 1836} 1837 1838func merkleRootImpl(c *Core) string { 1839 return "" 1840} 1841 1842func lastWALImpl(c *Core) uint64 { 1843 return 0 1844} 1845 1846func lastPerformanceWALImpl(c *Core) uint64 { 1847 return 0 1848} 1849 1850func lastRemoteWALImpl(c *Core) uint64 { 1851 return 0 1852} 1853 1854func (c *Core) PhysicalSealConfigs(ctx context.Context) (*SealConfig, *SealConfig, error) { 1855 pe, err := c.physical.Get(ctx, barrierSealConfigPath) 1856 if err != nil { 1857 return nil, nil, errwrap.Wrapf("failed to fetch barrier seal configuration at migration check time: {{err}}", err) 1858 } 1859 if pe == nil { 1860 return nil, nil, nil 1861 } 1862 1863 barrierConf := new(SealConfig) 1864 1865 if err := jsonutil.DecodeJSON(pe.Value, barrierConf); err != nil { 1866 return nil, nil, errwrap.Wrapf("failed to decode barrier seal configuration at migration check time: {{err}}", err) 1867 } 1868 err = barrierConf.Validate() 1869 if err != nil { 1870 return nil, nil, errwrap.Wrapf("failed to validate barrier seal configuration at migration check time: {{err}}", err) 1871 } 1872 // In older versions of vault the default seal would not store a type. This 1873 // is here to offer backwards compatibility for older seal configs. 1874 if barrierConf.Type == "" { 1875 barrierConf.Type = seal.Shamir 1876 } 1877 1878 var recoveryConf *SealConfig 1879 pe, err = c.physical.Get(ctx, recoverySealConfigPlaintextPath) 1880 if err != nil { 1881 return nil, nil, errwrap.Wrapf("failed to fetch seal configuration at migration check time: {{err}}", err) 1882 } 1883 if pe != nil { 1884 recoveryConf = &SealConfig{} 1885 if err := jsonutil.DecodeJSON(pe.Value, recoveryConf); err != nil { 1886 return nil, nil, errwrap.Wrapf("failed to decode seal configuration at migration check time: {{err}}", err) 1887 } 1888 err = recoveryConf.Validate() 1889 if err != nil { 1890 return nil, nil, errwrap.Wrapf("failed to validate seal configuration at migration check time: {{err}}", err) 1891 } 1892 // In older versions of vault the default seal would not store a type. This 1893 // is here to offer backwards compatibility for older seal configs. 1894 if recoveryConf.Type == "" { 1895 recoveryConf.Type = seal.Shamir 1896 } 1897 } 1898 1899 return barrierConf, recoveryConf, nil 1900} 1901 1902func (c *Core) SetSealsForMigration(migrationSeal, newSeal, unwrapSeal Seal) { 1903 c.stateLock.Lock() 1904 defer c.stateLock.Unlock() 1905 c.unwrapSeal = unwrapSeal 1906 if c.unwrapSeal != nil { 1907 c.unwrapSeal.SetCore(c) 1908 } 1909 if newSeal != nil && migrationSeal != nil { 1910 c.migrationSeal = migrationSeal 1911 c.migrationSeal.SetCore(c) 1912 c.seal = newSeal 1913 c.seal.SetCore(c) 1914 c.logger.Warn("entering seal migration mode; Vault will not automatically unseal even if using an autoseal", "from_barrier_type", c.migrationSeal.BarrierType(), "to_barrier_type", c.seal.BarrierType()) 1915 } 1916} 1917 1918func (c *Core) IsInSealMigration() bool { 1919 c.stateLock.RLock() 1920 defer c.stateLock.RUnlock() 1921 return c.migrationSeal != nil 1922} 1923 1924func (c *Core) BarrierEncryptorAccess() *BarrierEncryptorAccess { 1925 return NewBarrierEncryptorAccess(c.barrier) 1926} 1927 1928func (c *Core) PhysicalAccess() *physical.PhysicalAccess { 1929 return physical.NewPhysicalAccess(c.physical) 1930} 1931 1932func (c *Core) RouterAccess() *RouterAccess { 1933 return NewRouterAccess(c) 1934} 1935 1936// IsDRSecondary returns if the current cluster state is a DR secondary. 1937func (c *Core) IsDRSecondary() bool { 1938 return c.ReplicationState().HasState(consts.ReplicationDRSecondary) 1939} 1940 1941func (c *Core) AddLogger(logger log.Logger) { 1942 c.allLoggersLock.Lock() 1943 defer c.allLoggersLock.Unlock() 1944 c.allLoggers = append(c.allLoggers, logger) 1945} 1946 1947func (c *Core) SetLogLevel(level log.Level) { 1948 c.allLoggersLock.RLock() 1949 defer c.allLoggersLock.RUnlock() 1950 for _, logger := range c.allLoggers { 1951 logger.SetLevel(level) 1952 } 1953} 1954 1955// BuiltinRegistry is an interface that allows the "vault" package to use 1956// the registry of builtin plugins without getting an import cycle. It 1957// also allows for mocking the registry easily. 1958type BuiltinRegistry interface { 1959 Contains(name string, pluginType consts.PluginType) bool 1960 Get(name string, pluginType consts.PluginType) (func() (interface{}, error), bool) 1961 Keys(pluginType consts.PluginType) []string 1962} 1963