mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-29 17:58:15 +08:00
349 lines
15 KiB
Go
349 lines
15 KiB
Go
/*
|
|
Copyright 2021 Gravitational, Inc.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
// Package keypaths defines several keypaths used by multiple Teleport services.
|
|
package keypaths
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
// keypath constants aren't exported in order to force
|
|
// helper function usage and maintain consistency.
|
|
const (
|
|
// sessionKeyDir is a sub-directory where session keys are stored
|
|
sessionKeyDir = "keys"
|
|
// sshDirSuffix is the suffix of a sub-directory where SSH certificates are stored.
|
|
sshDirSuffix = "-ssh"
|
|
// fileNameKnownHosts is a file where known hosts are stored.
|
|
fileNameKnownHosts = "known_hosts"
|
|
// fileExtTLSCert is the suffix/extension of a file where a TLS cert is stored.
|
|
fileExtTLSCert = "-x509.pem"
|
|
// fileNameTLSCerts is a file where TLS Cert Authorities are stored.
|
|
fileNameTLSCerts = "certs.pem"
|
|
// fileExtCert is the suffix/extension of a file where an SSH Cert is stored.
|
|
fileExtSSHCert = "-cert.pub"
|
|
// fileExtPPK is the suffix/extension of a file where an SSH keypair is stored in PuTTY PPK format.
|
|
fileExtPPK = ".ppk"
|
|
// fileExtPub is the extension of a file where a public key is stored.
|
|
fileExtPub = ".pub"
|
|
// fileExtLocalCA is the extension of a file where a self-signed localhost CA cert is stored.
|
|
fileExtLocalCA = "-localca.pem"
|
|
// appDirSuffix is the suffix of a sub-directory where app TLS certs are stored.
|
|
appDirSuffix = "-app"
|
|
// db DirSuffix is the suffix of a sub-directory where db TLS certs are stored.
|
|
dbDirSuffix = "-db"
|
|
// kubeDirSuffix is the suffix of a sub-directory where kube TLS certs are stored.
|
|
kubeDirSuffix = "-kube"
|
|
// kubeConfigSuffix is the suffix of a kubeconfig file stored under the keys directory.
|
|
kubeConfigSuffix = "-kubeconfig"
|
|
// casDir is the directory name for where clusters certs are stored.
|
|
casDir = "cas"
|
|
// fileExtPem is the extension of a file where a public certificate is stored.
|
|
fileExtPem = ".pem"
|
|
// currentProfileFileName is a file containing the name of the current profile
|
|
currentProfileFilename = "current-profile"
|
|
// profileFileExt is the suffix of a profile file.
|
|
profileFileExt = ".yaml"
|
|
// fileLocalCA is the filename where a self-signed localhost CA cert is stored.
|
|
fileLocalCA = "localca.pem"
|
|
// oracleWalletDirSuffix is the suffix of the oracle wallet database directory.
|
|
oracleWalletDirSuffix = "-wallet"
|
|
)
|
|
|
|
// Here's the file layout of all these keypaths.
|
|
// ~/.tsh/ --> default base directory
|
|
// ├── current-profile --> file containing the name of the currently active profile
|
|
// ├── one.example.com.yaml --> file containing profile details for proxy "one.example.com"
|
|
// ├── two.example.com.yaml --> file containing profile details for proxy "two.example.com"
|
|
// ├── known_hosts --> trusted certificate authorities (their keys) in a format similar to known_hosts
|
|
// └── keys --> session keys directory
|
|
// ├── one.example.com --> Proxy hostname
|
|
// │ ├── certs.pem --> TLS CA certs for the Teleport CA
|
|
// │ ├── foo --> Private Key for user "foo"
|
|
// │ ├── foo.pub --> Public Key
|
|
// │ ├── foo.ppk --> PuTTY PPK-formatted keypair for user "foo"
|
|
// │ ├── foo-x509.pem --> TLS client certificate for Auth Server
|
|
// │ ├── foo-ssh --> SSH certs for user "foo"
|
|
// │ │ ├── root-cert.pub --> SSH cert for Teleport cluster "root"
|
|
// │ │ └── leaf-cert.pub --> SSH cert for Teleport cluster "leaf"
|
|
// │ ├── foo-app --> App access certs for user "foo"
|
|
// │ │ ├── root --> App access certs for cluster "root"
|
|
// │ │ │ ├── appA-x509.pem --> TLS cert for app service "appA"
|
|
// │ │ │ └── appB-x509.pem --> TLS cert for app service "appB"
|
|
// │ │ │ └── appB-localca.pem --> Self-signed localhost CA cert for app service "appB"
|
|
// │ │ └── leaf --> App access certs for cluster "leaf"
|
|
// │ │ └── appC-x509.pem --> TLS cert for app service "appC"
|
|
// │ ├── foo-db --> Database access certs for user "foo"
|
|
// │ │ ├── root --> Database access certs for cluster "root"
|
|
// │ │ │ ├── dbA-x509.pem --> TLS cert for database service "dbA"
|
|
// │ │ │ ├── dbB-x509.pem --> TLS cert for database service "dbB"
|
|
// │ │ │ └── dbC-wallet --> Oracle Client wallet Configuration directory.
|
|
// │ │ ├── leaf --> Database access certs for cluster "leaf"
|
|
// │ │ │ └── dbC-x509.pem --> TLS cert for database service "dbC"
|
|
// │ │ └── proxy-localca.pem --> Self-signed TLS Routing local proxy CA
|
|
// │ ├── foo-kube --> Kubernetes certs for user "foo"
|
|
// │ | ├── root --> Kubernetes certs for Teleport cluster "root"
|
|
// │ | │ ├── kubeA-kubeconfig --> standalone kubeconfig for Kubernetes cluster "kubeA"
|
|
// │ | │ ├── kubeA-x509.pem --> TLS cert for Kubernetes cluster "kubeA"
|
|
// │ | │ ├── kubeB-kubeconfig --> standalone kubeconfig for Kubernetes cluster "kubeB"
|
|
// │ | │ ├── kubeB-x509.pem --> TLS cert for Kubernetes cluster "kubeB"
|
|
// │ | │ └── localca.pem --> Self-signed localhost CA cert for Teleport cluster "root"
|
|
// │ | └── leaf --> Kubernetes certs for Teleport cluster "leaf"
|
|
// │ | ├── kubeC-kubeconfig --> standalone kubeconfig for Kubernetes cluster "kubeC"
|
|
// │ | └── kubeC-x509.pem --> TLS cert for Kubernetes cluster "kubeC"
|
|
// | └── cas --> Trusted clusters certificates
|
|
// | ├── root.pem --> TLS CA for teleport cluster "root"
|
|
// | ├── leaf1.pem --> TLS CA for teleport cluster "leaf1"
|
|
// | └── leaf2.pem --> TLS CA for teleport cluster "leaf2"
|
|
// └── two.example.com --> Additional proxy host entries follow the same format
|
|
// ...
|
|
|
|
// KeyDir returns the path to the keys directory.
|
|
//
|
|
// <baseDir>/keys
|
|
func KeyDir(baseDir string) string {
|
|
return filepath.Join(baseDir, sessionKeyDir)
|
|
}
|
|
|
|
// CurrentProfile returns the path to the current profile file.
|
|
//
|
|
// <baseDir>/current-profile
|
|
func CurrentProfileFilePath(baseDir string) string {
|
|
return filepath.Join(baseDir, currentProfileFilename)
|
|
}
|
|
|
|
// ProfileFilePath returns the path to the profile file for the given profile.
|
|
//
|
|
// <baseDir>/<profileName>.yaml
|
|
func ProfileFilePath(baseDir, profileName string) string {
|
|
return filepath.Join(baseDir, profileName+profileFileExt)
|
|
}
|
|
|
|
// KnownHostsPath returns the path to the known hosts file.
|
|
//
|
|
// <baseDir>/known_hosts
|
|
func KnownHostsPath(baseDir string) string {
|
|
return filepath.Join(baseDir, fileNameKnownHosts)
|
|
}
|
|
|
|
// ProxyKeyDir returns the path to the proxy's keys directory.
|
|
//
|
|
// <baseDir>/keys/<proxy>
|
|
func ProxyKeyDir(baseDir, proxy string) string {
|
|
return filepath.Join(KeyDir(baseDir), proxy)
|
|
}
|
|
|
|
// UserKeyPath returns the path to the users's private key
|
|
// for the given proxy.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>.
|
|
func UserKeyPath(baseDir, proxy, username string) string {
|
|
return filepath.Join(ProxyKeyDir(baseDir, proxy), username)
|
|
}
|
|
|
|
// TLSCertPath returns the path to the users's TLS certificate
|
|
// for the given proxy.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>-x509.pem
|
|
func TLSCertPath(baseDir, proxy, username string) string {
|
|
return filepath.Join(ProxyKeyDir(baseDir, proxy), username+fileExtTLSCert)
|
|
}
|
|
|
|
// PublicKeyPath returns the path to the users's public key
|
|
// for the given proxy.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>.pub
|
|
func PublicKeyPath(baseDir, proxy, username string) string {
|
|
return filepath.Join(ProxyKeyDir(baseDir, proxy), username+fileExtPub)
|
|
}
|
|
|
|
// CAsDir returns path to trusted clusters certificates directory.
|
|
//
|
|
// <baseDir>/keys/<proxy>/cas
|
|
func CAsDir(baseDir, proxy string) string {
|
|
return filepath.Join(ProxyKeyDir(baseDir, proxy), casDir)
|
|
}
|
|
|
|
// TLSCAsPath returns the path to the users's TLS CA's certificates
|
|
// for the given proxy.
|
|
// <baseDir>/keys/<proxy>/certs.pem
|
|
// DELETE IN 10.0. Deprecated
|
|
func TLSCAsPath(baseDir, proxy string) string {
|
|
return filepath.Join(ProxyKeyDir(baseDir, proxy), fileNameTLSCerts)
|
|
}
|
|
|
|
// TLSCAsPathCluster returns the path to the specified cluster's CA directory.
|
|
//
|
|
// <baseDir>/keys/<proxy>/cas/<cluster>.pem
|
|
func TLSCAsPathCluster(baseDir, proxy, cluster string) string {
|
|
return filepath.Join(ProxyKeyDir(baseDir, proxy), casDir, cluster+fileExtPem)
|
|
}
|
|
|
|
// SSHDir returns the path to the user's SSH directory for the given proxy.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>-ssh
|
|
func SSHDir(baseDir, proxy, username string) string {
|
|
return filepath.Join(ProxyKeyDir(baseDir, proxy), username+sshDirSuffix)
|
|
}
|
|
|
|
// PPKFilePath returns the path to the user's PuTTY PPK-formatted keypair
|
|
// for the given proxy and cluster.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>.ppk
|
|
func PPKFilePath(baseDir, proxy, username string) string {
|
|
return filepath.Join(ProxyKeyDir(baseDir, proxy), username+fileExtPPK)
|
|
}
|
|
|
|
// SSHCertPath returns the path to the users's SSH certificate
|
|
// for the given proxy and cluster.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>-ssh/<cluster>-cert.pub
|
|
func SSHCertPath(baseDir, proxy, username, cluster string) string {
|
|
return filepath.Join(SSHDir(baseDir, proxy, username), cluster+fileExtSSHCert)
|
|
}
|
|
|
|
// AppDir returns the path to the user's app directory
|
|
// for the given proxy.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>-app
|
|
func AppDir(baseDir, proxy, username string) string {
|
|
return filepath.Join(ProxyKeyDir(baseDir, proxy), username+appDirSuffix)
|
|
}
|
|
|
|
// AppCertDir returns the path to the user's app cert directory
|
|
// for the given proxy and cluster.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>-app/<cluster>
|
|
func AppCertDir(baseDir, proxy, username, cluster string) string {
|
|
return filepath.Join(AppDir(baseDir, proxy, username), cluster)
|
|
}
|
|
|
|
// AppCertPath returns the path to the user's TLS certificate
|
|
// for the given proxy, cluster, and app.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>-app/<cluster>/<appname>-x509.pem
|
|
func AppCertPath(baseDir, proxy, username, cluster, appname string) string {
|
|
return filepath.Join(AppCertDir(baseDir, proxy, username, cluster), appname+fileExtTLSCert)
|
|
}
|
|
|
|
// AppLocalCAPath returns the path to a self-signed localhost CA for the given
|
|
// proxy, cluster, and app.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>-app/<cluster>/<appname>-localca.pem
|
|
func AppLocalCAPath(baseDir, proxy, username, cluster, appname string) string {
|
|
return filepath.Join(AppCertDir(baseDir, proxy, username, cluster), appname+fileExtLocalCA)
|
|
}
|
|
|
|
// KubeLocalCAPath returns the path to a self-signed localhost CA for the given
|
|
// proxy, cluster, and app.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>-kube/<cluster>/localca.pem
|
|
func KubeLocalCAPath(baseDir, proxy, username, cluster string) string {
|
|
return filepath.Join(KubeCertDir(baseDir, proxy, username, cluster), fileLocalCA)
|
|
}
|
|
|
|
// DatabaseDir returns the path to the user's database directory
|
|
// for the given proxy.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>-db
|
|
func DatabaseDir(baseDir, proxy, username string) string {
|
|
return filepath.Join(ProxyKeyDir(baseDir, proxy), username+dbDirSuffix)
|
|
}
|
|
|
|
// DatabaseCertDir returns the path to the user's database cert directory
|
|
// for the given proxy and cluster.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>-db/<cluster>
|
|
func DatabaseCertDir(baseDir, proxy, username, cluster string) string {
|
|
return filepath.Join(DatabaseDir(baseDir, proxy, username), cluster)
|
|
}
|
|
|
|
// DatabaseCertPath returns the path to the user's TLS certificate
|
|
// for the given proxy, cluster, and database.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>-db/<cluster>/<dbname>-x509.pem
|
|
func DatabaseCertPath(baseDir, proxy, username, cluster, dbname string) string {
|
|
return filepath.Join(DatabaseCertDir(baseDir, proxy, username, cluster), dbname+fileExtTLSCert)
|
|
}
|
|
|
|
// DatabaseOracleWalletDirectory returns the path to the user's Oracle Wallet configuration directory.
|
|
// for the given proxy, cluster and database.
|
|
// <baseDir>/keys/<proxy>/<username>-db/<cluster>/dbname-wallet/
|
|
func DatabaseOracleWalletDirectory(baseDir, proxy, username, cluster, dbname string) string {
|
|
return filepath.Join(DatabaseCertDir(baseDir, proxy, username, cluster), dbname+oracleWalletDirSuffix)
|
|
}
|
|
|
|
// KubeDir returns the path to the user's kube directory
|
|
// for the given proxy.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>-kube
|
|
func KubeDir(baseDir, proxy, username string) string {
|
|
return filepath.Join(ProxyKeyDir(baseDir, proxy), username+kubeDirSuffix)
|
|
}
|
|
|
|
// KubeCertDir returns the path to the user's kube cert directory
|
|
// for the given proxy and cluster.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>-kube/<cluster>
|
|
func KubeCertDir(baseDir, proxy, username, cluster string) string {
|
|
return filepath.Join(KubeDir(baseDir, proxy, username), cluster)
|
|
}
|
|
|
|
// KubeCertPath returns the path to the user's TLS certificate
|
|
// for the given proxy, cluster, and kube cluster.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>-kube/<cluster>/<kubename>-x509.pem
|
|
func KubeCertPath(baseDir, proxy, username, cluster, kubename string) string {
|
|
return filepath.Join(KubeCertDir(baseDir, proxy, username, cluster), kubename+fileExtTLSCert)
|
|
}
|
|
|
|
// KubeConfigPath returns the path to the user's standalone kubeconfig
|
|
// for the given proxy, cluster, and kube cluster.
|
|
//
|
|
// <baseDir>/keys/<proxy>/<username>-kube/<cluster>/<kubename>-kubeconfig
|
|
func KubeConfigPath(baseDir, proxy, username, cluster, kubename string) string {
|
|
return filepath.Join(KubeCertDir(baseDir, proxy, username, cluster), kubename+kubeConfigSuffix)
|
|
}
|
|
|
|
// IsProfileKubeConfigPath makes a best effort attempt to check if the given
|
|
// path is a profile specific kubeconfig path generated by this package.
|
|
func IsProfileKubeConfigPath(path string) (bool, error) {
|
|
if path == "" {
|
|
return false, nil
|
|
}
|
|
// Split path on sessionKeyDir since we can't do filepath.Match with baseDir
|
|
splitPath := strings.Split(path, "/"+sessionKeyDir+"/")
|
|
match := fmt.Sprintf("*/*%v/*/*%v", kubeDirSuffix, kubeConfigSuffix)
|
|
return filepath.Match(match, splitPath[len(splitPath)-1])
|
|
}
|
|
|
|
// IdentitySSHCertPath returns the path to the identity file's SSH certificate.
|
|
//
|
|
// <identity-file-dir>/<path>-cert.pub
|
|
func IdentitySSHCertPath(path string) string {
|
|
return path + fileExtSSHCert
|
|
}
|
|
|
|
// TrimCertPathSuffix returns the given path with any cert suffix/extension trimmed off.
|
|
func TrimCertPathSuffix(path string) string {
|
|
trimmedPath := strings.TrimSuffix(path, fileExtTLSCert)
|
|
trimmedPath = strings.TrimSuffix(trimmedPath, fileExtSSHCert)
|
|
return trimmedPath
|
|
}
|