diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index 6c6e637b9..a27d8ce09 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -1544,7 +1544,7 @@ func (a adminAPIHandlers) ServerInfoHandler(w http.ResponseWriter, r *http.Reque return } - vault := fetchVaultStatus() + kmsStat := fetchKMSStatus() ldap := madmin.LDAP{} if globalLDAPConfig.Enabled { @@ -1613,7 +1613,7 @@ func (a adminAPIHandlers) ServerInfoHandler(w http.ResponseWriter, r *http.Reque domain := globalDomainNames services := madmin.Services{ - Vault: vault, + KMS: kmsStat, LDAP: ldap, Logger: log, Audit: audit, @@ -1689,47 +1689,46 @@ func fetchLambdaInfo() []map[string][]madmin.TargetIDStatus { return notify } -// fetchVaultStatus fetches Vault Info -func fetchVaultStatus() madmin.Vault { - vault := madmin.Vault{} +// fetchKMSStatus fetches KMS-related status information. +func fetchKMSStatus() madmin.KMS { + kmsStat := madmin.KMS{} if GlobalKMS == nil { - vault.Status = "disabled" - return vault + kmsStat.Status = "disabled" + return kmsStat } keyID := GlobalKMS.DefaultKeyID() kmsInfo := GlobalKMS.Info() - if len(kmsInfo.Endpoints) == 0 { - vault.Status = "KMS configured using master key" - return vault + kmsStat.Status = "KMS configured using master key" + return kmsStat } if err := checkConnection(kmsInfo.Endpoints[0], 15*time.Second); err != nil { - vault.Status = "offline" + kmsStat.Status = "offline" } else { - vault.Status = "online" + kmsStat.Status = "online" kmsContext := crypto.Context{"MinIO admin API": "ServerInfoHandler"} // Context for a test key operation // 1. Generate a new key using the KMS. key, sealedKey, err := GlobalKMS.GenerateKey(keyID, kmsContext) if err != nil { - vault.Encrypt = fmt.Sprintf("Encryption failed: %v", err) + kmsStat.Encrypt = fmt.Sprintf("Encryption failed: %v", err) } else { - vault.Encrypt = "Ok" + kmsStat.Encrypt = "Ok" } // 2. Verify that we can indeed decrypt the (encrypted) key decryptedKey, err := GlobalKMS.UnsealKey(keyID, sealedKey, kmsContext) switch { case err != nil: - vault.Decrypt = fmt.Sprintf("Decryption failed: %v", err) + kmsStat.Decrypt = fmt.Sprintf("Decryption failed: %v", err) case subtle.ConstantTimeCompare(key[:], decryptedKey[:]) != 1: - vault.Decrypt = "Decryption failed: decrypted key does not match generated key" + kmsStat.Decrypt = "Decryption failed: decrypted key does not match generated key" default: - vault.Decrypt = "Ok" + kmsStat.Decrypt = "Ok" } } - return vault + return kmsStat } // fetchLoggerDetails return log info diff --git a/cmd/config-current.go b/cmd/config-current.go index 8a0ee04f9..71b41253a 100644 --- a/cmd/config-current.go +++ b/cmd/config-current.go @@ -480,11 +480,13 @@ func lookupConfigs(s config.Config, setDriveCounts []int) { if err != nil { logger.LogIf(ctx, fmt.Errorf("Unable to setup KMS with current KMS config: %w", err)) } + globalAutoEncryption = kmsCfg.AutoEncryption // Enable auto-encryption if enabled - // Enable auto-encryption if enabled - globalAutoEncryption = kmsCfg.AutoEncryption - if globalAutoEncryption && !globalIsGateway { - logger.LogIf(ctx, fmt.Errorf("%s env is deprecated please migrate to using `mc encrypt` at bucket level", crypto.EnvKMSAutoEncryption)) + if kmsCfg.Vault.Enabled { + const deprecationWarning = `Native Hashicorp Vault support is deprecated and will be removed on 2021-10-01. Please migrate to KES + Hashicorp Vault: https://github.com/minio/kes/wiki/Hashicorp-Vault-Keystore +Note that native Hashicorp Vault and KES + Hashicorp Vault are not compatible. +If you need help to migrate smoothly visit: https://min.io/pricing` + logger.LogIf(ctx, fmt.Errorf(deprecationWarning)) } globalOpenIDConfig, err = openid.LookupConfig(s[config.IdentityOpenIDSubSys][config.Default], diff --git a/docs/kms/vault-config.json b/docs/kms/vault-config.json deleted file mode 100644 index 3020c8792..000000000 --- a/docs/kms/vault-config.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "api_addr": "https://127.0.0.1:8200", - "backend": { - "file": { - "path": "vault/file" - } - }, - "default_lease_ttl": "168h", - "max_lease_ttl": "720h", - "listener": { - "tcp": { - "address": "0.0.0.0:8200", - "tls_cert_file": "vault-tls.crt", - "tls_key_file": "vault-tls.key", - "tls_min_version": "tls12" - } - } -} diff --git a/docs/kms/vault-legacy.md b/docs/kms/vault-legacy.md deleted file mode 100644 index eb12aa7a3..000000000 --- a/docs/kms/vault-legacy.md +++ /dev/null @@ -1,269 +0,0 @@ -# KMS Quickstart Guide [![Slack](https://slack.min.io/slack?type=svg)](https://slack.min.io) - -MinIO uses a key-management-system (KMS) to support SSE-S3. If a client requests SSE-S3, or auto-encryption -is enabled, the MinIO server encrypts each object with an unique object key which is protected by a master key -managed by the KMS. Usually all object keys are protected by a single master key. - -MinIO supports two different KMS concepts: - - External KMS: - MinIO can be configured to use an external KMS i.e. [Hashicorp Vault](https://www.vaultproject.io/). - An external KMS decouples MinIO as storage system from key-management. An external KMS can - be managed by a dedicated security team and allows you to grant/deny access to (certain) objects - by enabling or disabling the corresponding master keys on demand. - -- Direct KMS master keys: - MinIO can also be configured to directly use a master key specified by the environment variable `MINIO_KMS_MASTER_KEY` or with a docker secret key. - Direct master keys are useful if the storage backend is not on the same machine as the MinIO server, e.g., - if network drives or MinIO gateway is used and an external KMS would cause too much management overhead. - - Note: KMS master keys are mainly for testing purposes. It's not recommended to use them for production deployments. - Further if the MinIO server machine is ever compromised, then the master key must also be treated as compromised. - -**Important:** -If multiple MinIO servers are configured as [gateways](https://github.com/minio/minio/blob/master/docs/gateway/README.md) pointing to the *same* backend - for example the same NAS storage - then the KMS configuration **must** be the same for all gateways. Otherwise one gateway may not be able to decrypt objects created by another gateway. It is the operator responsibility to ensure consistency. - -## Get started - -### 1. Prerequisites -Install MinIO - [MinIO Quickstart Guide](https://docs.min.io/docs/minio-quickstart-guide). - -### 2. Setup a KMS - -Either use Hashicorp Vault as external KMS or specify a master key directly depending on your use case. - -#### 2.1 Setup Hashicorp Vault - -Here is a sample quick start for configuring vault with a transit backend and Approle with correct policy - -MinIO requires the following Vault setup: -- The [transit backend](https://www.vaultproject.io/api/secret/transit/index.html) configured with a named encryption key-ring -- [AppRole](https://www.vaultproject.io/docs/auth/approle.html) based authentication with read/update policy for transit backend. In particular, read and update policy are required for the [Generate Data Key](https://www.vaultproject.io/api/secret/transit/index.html#generate-data-key) endpoint and [Decrypt Data](https://www.vaultproject.io/api/secret/transit/index.html#decrypt-data) endpoint. - -**2.1.1 Start Vault server** - -Vault requires access to `mlock` syscall by default. Use `setcap` to give the Vault executable the ability to use the `mlock` syscall without running the process as root. To do so run: -``` -sudo setcap cap_ipc_lock=+ep $(readlink -f $(which vault)) -``` - -Create `vault-config.json` to use file backend and start the server. -``` -cat > vault-config.json < NOTE: In this example we use `"tls_disable": true` for demonstration purposes only, -> in production setup you should generate proper TLS certificates by specifying -> - [`tls_cert_file`](https://www.vaultproject.io/docs/configuration/listener/tcp.html#tls_cert_file) -> - [`tls_key_file`](https://www.vaultproject.io/docs/configuration/listener/tcp.html#tls_key_file) - - -**2.1.2 Initialize vault and unseal it** - -``` -export VAULT_ADDR='http://127.0.0.1:8200' -vault operator init -Unseal Key 1: eyW/+8ZtsgT81Cb0e8OVxzJAQP5lY7Dcamnze+JnWEDT -Unseal Key 2: 0tZn+7QQCxphpHwTm6/dC3LpP5JGIbYl6PK8Sy79R+P2 -Unseal Key 3: cmhs+AUMXUuB6Lzsvgcbp3bRT6VDGQjgCBwB2xm0ANeF -Unseal Key 4: /fTPpec5fWpGqWHK+uhnnTNMQyAbl5alUi4iq2yNgyqj -Unseal Key 5: UPdDVPto+H6ko+20NKmagK40MOskqOBw4y/S51WpgVy/ - -Initial Root Token: s.zaU4Gbcu0Wh46uj2V3VuUde0 - -Vault is initialized with 5 key shares and a key threshold of 3. Please securely -distribute the key shares printed above. When the Vault is re-sealed, -restarted, or stopped, you must supply at least 3 of these keys to unseal it -before it can start servicing requests. - -Vault does not store the generated master key. Without at least 3 key to -reconstruct the master key, Vault will remain permanently sealed! - -It is possible to generate new unseal keys, provided you have a quorum of -existing unseal keys shares. See "vault operator rekey" for more information. -``` - -Use any of the previously generated keys to unseal the vault -``` -vault operator unseal eyW/+8ZtsgT81Cb0e8OVxzJAQP5lY7Dcamnze+JnWEDT -vault operator unseal 0tZn+7QQCxphpHwTm6/dC3LpP5JGIbYl6PK8Sy79R+P2 -vault operator unseal cmhs+AUMXUuB6Lzsvgcbp3bRT6VDGQjgCBwB2xm0ANeF -Key Value ---- ----- -Seal Type shamir -Initialized true -Sealed false ---> NOTE: vault is unsealed -Total Shares 5 -Threshold 3 -Version 1.1.3 -Cluster Name vault-cluster-3f084948 -Cluster ID 8c92e999-7062-4da6-4434-0fc05f34824d -HA Enabled false -``` - -Obtain root token from the `vault operator init` output above. It is displayed as `Initial Root Token: s.zaU4Gbcu0Wh46uj2V3VuUde0` - -**2.1.3 Set up vault transit backend and create an app role** -``` -export VAULT_TOKEN=s.zaU4Gbcu0Wh46uj2V3VuUde0 - -vault auth enable approle # enable approle style auth -vault secrets enable transit # enable transit secrets engine -# define an encryption key-ring for the transit path -vault write -f transit/keys/my-minio-key - -cat > vaultpolicy.hcl <