github.com/gravitational/teleport/api@v0.0.0-20240507183017-3110591cbafc/utils/keypaths/keypaths.go (about) 1 /* 2 Copyright 2021 Gravitational, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // Package keypaths defines several keypaths used by multiple Teleport services. 18 package keypaths 19 20 import ( 21 "fmt" 22 "path/filepath" 23 "strings" 24 ) 25 26 // keypath constants aren't exported in order to force 27 // helper function usage and maintain consistency. 28 const ( 29 // sessionKeyDir is a sub-directory where session keys are stored 30 sessionKeyDir = "keys" 31 // sshDirSuffix is the suffix of a sub-directory where SSH certificates are stored. 32 sshDirSuffix = "-ssh" 33 // fileNameKnownHosts is a file where known hosts are stored. 34 fileNameKnownHosts = "known_hosts" 35 // fileExtTLSCert is the suffix/extension of a file where a TLS cert is stored. 36 fileExtTLSCert = "-x509.pem" 37 // fileNameTLSCerts is a file where TLS Cert Authorities are stored. 38 fileNameTLSCerts = "certs.pem" 39 // fileExtCert is the suffix/extension of a file where an SSH Cert is stored. 40 fileExtSSHCert = "-cert.pub" 41 // fileExtPPK is the suffix/extension of a file where an SSH keypair is stored in PuTTY PPK format. 42 fileExtPPK = ".ppk" 43 // fileExtPub is the extension of a file where a public key is stored. 44 fileExtPub = ".pub" 45 // fileExtLocalCA is the extension of a file where a self-signed localhost CA cert is stored. 46 fileExtLocalCA = "-localca.pem" 47 // appDirSuffix is the suffix of a sub-directory where app TLS certs are stored. 48 appDirSuffix = "-app" 49 // db DirSuffix is the suffix of a sub-directory where db TLS certs are stored. 50 dbDirSuffix = "-db" 51 // kubeDirSuffix is the suffix of a sub-directory where kube TLS certs are stored. 52 kubeDirSuffix = "-kube" 53 // kubeConfigSuffix is the suffix of a kubeconfig file stored under the keys directory. 54 kubeConfigSuffix = "-kubeconfig" 55 // fileNameKubeCredLock is file name of lockfile used to prevent excessive login attempts. 56 fileNameKubeCredLock = "kube_credentials.lock" 57 // casDir is the directory name for where clusters certs are stored. 58 casDir = "cas" 59 // fileExtPem is the extension of a file where a public certificate is stored. 60 fileExtPem = ".pem" 61 // currentProfileFileName is a file containing the name of the current profile 62 currentProfileFilename = "current-profile" 63 // profileFileExt is the suffix of a profile file. 64 profileFileExt = ".yaml" 65 // oracleWalletDirSuffix is the suffix of the oracle wallet database directory. 66 oracleWalletDirSuffix = "-wallet" 67 ) 68 69 // Here's the file layout of all these keypaths. 70 // ~/.tsh/ --> default base directory 71 // ├── current-profile --> file containing the name of the currently active profile 72 // ├── one.example.com.yaml --> file containing profile details for proxy "one.example.com" 73 // ├── two.example.com.yaml --> file containing profile details for proxy "two.example.com" 74 // ├── known_hosts --> trusted certificate authorities (their keys) in a format similar to known_hosts 75 // └── keys --> session keys directory 76 // ├── one.example.com --> Proxy hostname 77 // │ ├── certs.pem --> TLS CA certs for the Teleport CA 78 // │ ├── foo --> Private Key for user "foo" 79 // │ ├── foo.pub --> Public Key 80 // │ ├── foo.ppk --> PuTTY PPK-formatted keypair for user "foo" 81 // │ ├── kube_credentials.lock --> Kube credential lockfile, used to prevent excessive relogin attempts 82 // │ ├── foo-x509.pem --> TLS client certificate for Auth Server 83 // │ ├── foo-ssh --> SSH certs for user "foo" 84 // │ │ ├── root-cert.pub --> SSH cert for Teleport cluster "root" 85 // │ │ └── leaf-cert.pub --> SSH cert for Teleport cluster "leaf" 86 // │ ├── foo-app --> App access certs for user "foo" 87 // │ │ ├── root --> App access certs for cluster "root" 88 // │ │ │ ├── appA-x509.pem --> TLS cert for app service "appA" 89 // │ │ │ └── appB-x509.pem --> TLS cert for app service "appB" 90 // │ │ │ └── appB-localca.pem --> Self-signed localhost CA cert for app service "appB" 91 // │ │ └── leaf --> App access certs for cluster "leaf" 92 // │ │ └── appC-x509.pem --> TLS cert for app service "appC" 93 // │ ├── foo-db --> Database access certs for user "foo" 94 // │ │ ├── root --> Database access certs for cluster "root" 95 // │ │ │ ├── dbA-x509.pem --> TLS cert for database service "dbA" 96 // │ │ │ ├── dbB-x509.pem --> TLS cert for database service "dbB" 97 // │ │ │ └── dbC-wallet --> Oracle Client wallet Configuration directory. 98 // │ │ ├── leaf --> Database access certs for cluster "leaf" 99 // │ │ │ └── dbC-x509.pem --> TLS cert for database service "dbC" 100 // │ │ └── proxy-localca.pem --> Self-signed TLS Routing local proxy CA 101 // │ ├── foo-kube --> Kubernetes certs for user "foo" 102 // │ | ├── root --> Kubernetes certs for Teleport cluster "root" 103 // │ | │ ├── kubeA-kubeconfig --> standalone kubeconfig for Kubernetes cluster "kubeA" 104 // │ | │ ├── kubeA-x509.pem --> TLS cert for Kubernetes cluster "kubeA" 105 // │ | │ ├── kubeB-kubeconfig --> standalone kubeconfig for Kubernetes cluster "kubeB" 106 // │ | │ ├── kubeB-x509.pem --> TLS cert for Kubernetes cluster "kubeB" 107 // │ | │ └── localca.pem --> Self-signed localhost CA cert for Teleport cluster "root" 108 // │ | └── leaf --> Kubernetes certs for Teleport cluster "leaf" 109 // │ | ├── kubeC-kubeconfig --> standalone kubeconfig for Kubernetes cluster "kubeC" 110 // │ | └── kubeC-x509.pem --> TLS cert for Kubernetes cluster "kubeC" 111 // | └── cas --> Trusted clusters certificates 112 // | ├── root.pem --> TLS CA for teleport cluster "root" 113 // | ├── leaf1.pem --> TLS CA for teleport cluster "leaf1" 114 // | └── leaf2.pem --> TLS CA for teleport cluster "leaf2" 115 // └── two.example.com --> Additional proxy host entries follow the same format 116 // ... 117 118 // KeyDir returns the path to the keys directory. 119 // 120 // <baseDir>/keys 121 func KeyDir(baseDir string) string { 122 return filepath.Join(baseDir, sessionKeyDir) 123 } 124 125 // CurrentProfile returns the path to the current profile file. 126 // 127 // <baseDir>/current-profile 128 func CurrentProfileFilePath(baseDir string) string { 129 return filepath.Join(baseDir, currentProfileFilename) 130 } 131 132 // ProfileFilePath returns the path to the profile file for the given profile. 133 // 134 // <baseDir>/<profileName>.yaml 135 func ProfileFilePath(baseDir, profileName string) string { 136 return filepath.Join(baseDir, profileName+profileFileExt) 137 } 138 139 // KnownHostsPath returns the path to the known hosts file. 140 // 141 // <baseDir>/known_hosts 142 func KnownHostsPath(baseDir string) string { 143 return filepath.Join(baseDir, fileNameKnownHosts) 144 } 145 146 // ProxyKeyDir returns the path to the proxy's keys directory. 147 // 148 // <baseDir>/keys/<proxy> 149 func ProxyKeyDir(baseDir, proxy string) string { 150 return filepath.Join(KeyDir(baseDir), proxy) 151 } 152 153 // UserKeyPath returns the path to the users's private key 154 // for the given proxy. 155 // 156 // <baseDir>/keys/<proxy>/<username>. 157 func UserKeyPath(baseDir, proxy, username string) string { 158 return filepath.Join(ProxyKeyDir(baseDir, proxy), username) 159 } 160 161 // TLSCertPath returns the path to the users's TLS certificate 162 // for the given proxy. 163 // 164 // <baseDir>/keys/<proxy>/<username>-x509.pem 165 func TLSCertPath(baseDir, proxy, username string) string { 166 return filepath.Join(ProxyKeyDir(baseDir, proxy), username+fileExtTLSCert) 167 } 168 169 // PublicKeyPath returns the path to the users's public key 170 // for the given proxy. 171 // 172 // <baseDir>/keys/<proxy>/<username>.pub 173 func PublicKeyPath(baseDir, proxy, username string) string { 174 return filepath.Join(ProxyKeyDir(baseDir, proxy), username+fileExtPub) 175 } 176 177 // CAsDir returns path to trusted clusters certificates directory. 178 // 179 // <baseDir>/keys/<proxy>/cas 180 func CAsDir(baseDir, proxy string) string { 181 return filepath.Join(ProxyKeyDir(baseDir, proxy), casDir) 182 } 183 184 // TLSCAsPath returns the path to the users's TLS CA's certificates 185 // for the given proxy. 186 // <baseDir>/keys/<proxy>/certs.pem 187 // DELETE IN 10.0. Deprecated 188 func TLSCAsPath(baseDir, proxy string) string { 189 return filepath.Join(ProxyKeyDir(baseDir, proxy), fileNameTLSCerts) 190 } 191 192 // TLSCAsPathCluster returns the path to the specified cluster's CA directory. 193 // 194 // <baseDir>/keys/<proxy>/cas/<cluster>.pem 195 func TLSCAsPathCluster(baseDir, proxy, cluster string) string { 196 return filepath.Join(ProxyKeyDir(baseDir, proxy), casDir, cluster+fileExtPem) 197 } 198 199 // SSHDir returns the path to the user's SSH directory for the given proxy. 200 // 201 // <baseDir>/keys/<proxy>/<username>-ssh 202 func SSHDir(baseDir, proxy, username string) string { 203 return filepath.Join(ProxyKeyDir(baseDir, proxy), username+sshDirSuffix) 204 } 205 206 // PPKFilePath returns the path to the user's PuTTY PPK-formatted keypair 207 // for the given proxy and cluster. 208 // 209 // <baseDir>/keys/<proxy>/<username>.ppk 210 func PPKFilePath(baseDir, proxy, username string) string { 211 return filepath.Join(ProxyKeyDir(baseDir, proxy), username+fileExtPPK) 212 } 213 214 // SSHCertPath returns the path to the users's SSH certificate 215 // for the given proxy and cluster. 216 // 217 // <baseDir>/keys/<proxy>/<username>-ssh/<cluster>-cert.pub 218 func SSHCertPath(baseDir, proxy, username, cluster string) string { 219 return filepath.Join(SSHDir(baseDir, proxy, username), cluster+fileExtSSHCert) 220 } 221 222 // AppDir returns the path to the user's app directory 223 // for the given proxy. 224 // 225 // <baseDir>/keys/<proxy>/<username>-app 226 func AppDir(baseDir, proxy, username string) string { 227 return filepath.Join(ProxyKeyDir(baseDir, proxy), username+appDirSuffix) 228 } 229 230 // AppCertDir returns the path to the user's app cert directory 231 // for the given proxy and cluster. 232 // 233 // <baseDir>/keys/<proxy>/<username>-app/<cluster> 234 func AppCertDir(baseDir, proxy, username, cluster string) string { 235 return filepath.Join(AppDir(baseDir, proxy, username), cluster) 236 } 237 238 // AppCertPath returns the path to the user's TLS certificate 239 // for the given proxy, cluster, and app. 240 // 241 // <baseDir>/keys/<proxy>/<username>-app/<cluster>/<appname>-x509.pem 242 func AppCertPath(baseDir, proxy, username, cluster, appname string) string { 243 return filepath.Join(AppCertDir(baseDir, proxy, username, cluster), appname+fileExtTLSCert) 244 } 245 246 // AppLocalCAPath returns the path to a self-signed localhost CA for the given 247 // proxy, cluster, and app. 248 // 249 // <baseDir>/keys/<proxy>/<username>-app/<cluster>/<appname>-localca.pem 250 func AppLocalCAPath(baseDir, proxy, username, cluster, appname string) string { 251 return filepath.Join(AppCertDir(baseDir, proxy, username, cluster), appname+fileExtLocalCA) 252 } 253 254 // DatabaseDir returns the path to the user's database directory 255 // for the given proxy. 256 // 257 // <baseDir>/keys/<proxy>/<username>-db 258 func DatabaseDir(baseDir, proxy, username string) string { 259 return filepath.Join(ProxyKeyDir(baseDir, proxy), username+dbDirSuffix) 260 } 261 262 // DatabaseCertDir returns the path to the user's database cert directory 263 // for the given proxy and cluster. 264 // 265 // <baseDir>/keys/<proxy>/<username>-db/<cluster> 266 func DatabaseCertDir(baseDir, proxy, username, cluster string) string { 267 return filepath.Join(DatabaseDir(baseDir, proxy, username), cluster) 268 } 269 270 // DatabaseCertPath returns the path to the user's TLS certificate 271 // for the given proxy, cluster, and database. 272 // 273 // <baseDir>/keys/<proxy>/<username>-db/<cluster>/<dbname>-x509.pem 274 func DatabaseCertPath(baseDir, proxy, username, cluster, dbname string) string { 275 return filepath.Join(DatabaseCertDir(baseDir, proxy, username, cluster), dbname+fileExtTLSCert) 276 } 277 278 // DatabaseOracleWalletDirectory returns the path to the user's Oracle Wallet configuration directory. 279 // for the given proxy, cluster and database. 280 // <baseDir>/keys/<proxy>/<username>-db/<cluster>/dbname-wallet/ 281 func DatabaseOracleWalletDirectory(baseDir, proxy, username, cluster, dbname string) string { 282 return filepath.Join(DatabaseCertDir(baseDir, proxy, username, cluster), dbname+oracleWalletDirSuffix) 283 } 284 285 // KubeDir returns the path to the user's kube directory 286 // for the given proxy. 287 // 288 // <baseDir>/keys/<proxy>/<username>-kube 289 func KubeDir(baseDir, proxy, username string) string { 290 return filepath.Join(ProxyKeyDir(baseDir, proxy), username+kubeDirSuffix) 291 } 292 293 // KubeCertDir returns the path to the user's kube cert directory 294 // for the given proxy and cluster. 295 // 296 // <baseDir>/keys/<proxy>/<username>-kube/<cluster> 297 func KubeCertDir(baseDir, proxy, username, cluster string) string { 298 return filepath.Join(KubeDir(baseDir, proxy, username), cluster) 299 } 300 301 // KubeCertPath returns the path to the user's TLS certificate 302 // for the given proxy, cluster, and kube cluster. 303 // 304 // <baseDir>/keys/<proxy>/<username>-kube/<cluster>/<kubename>-x509.pem 305 func KubeCertPath(baseDir, proxy, username, cluster, kubename string) string { 306 return filepath.Join(KubeCertDir(baseDir, proxy, username, cluster), kubename+fileExtTLSCert) 307 } 308 309 // KubeConfigPath returns the path to the user's standalone kubeconfig 310 // for the given proxy, cluster, and kube cluster. 311 // 312 // <baseDir>/keys/<proxy>/<username>-kube/<cluster>/<kubename>-kubeconfig 313 func KubeConfigPath(baseDir, proxy, username, cluster, kubename string) string { 314 return filepath.Join(KubeCertDir(baseDir, proxy, username, cluster), kubename+kubeConfigSuffix) 315 } 316 317 // KubeCredLockfilePath returns the kube credentials lock file for given proxy 318 // 319 // <baseDir>/keys/<proxy>/kube_credentials.lock 320 func KubeCredLockfilePath(baseDir, proxy string) string { 321 return filepath.Join(ProxyKeyDir(baseDir, proxy), fileNameKubeCredLock) 322 } 323 324 // IsProfileKubeConfigPath makes a best effort attempt to check if the given 325 // path is a profile specific kubeconfig path generated by this package. 326 func IsProfileKubeConfigPath(path string) (bool, error) { 327 if path == "" { 328 return false, nil 329 } 330 // Split path on sessionKeyDir since we can't do filepath.Match with baseDir 331 splitPath := strings.Split(path, "/"+sessionKeyDir+"/") 332 match := fmt.Sprintf("*/*%v/*/*%v", kubeDirSuffix, kubeConfigSuffix) 333 return filepath.Match(match, splitPath[len(splitPath)-1]) 334 } 335 336 // IdentitySSHCertPath returns the path to the identity file's SSH certificate. 337 // 338 // <identity-file-dir>/<path>-cert.pub 339 func IdentitySSHCertPath(path string) string { 340 return path + fileExtSSHCert 341 } 342 343 // TrimCertPathSuffix returns the given path with any cert suffix/extension trimmed off. 344 func TrimCertPathSuffix(path string) string { 345 trimmedPath := strings.TrimSuffix(path, fileExtTLSCert) 346 trimmedPath = strings.TrimSuffix(trimmedPath, fileExtSSHCert) 347 return trimmedPath 348 }