Skip to content

Commit

Permalink
chore: rotate-certs creates its own known_hosts copy
Browse files Browse the repository at this point in the history
  • Loading branch information
jadarsie committed Oct 17, 2023
1 parent dcc7db8 commit e053c72
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 50 deletions.
4 changes: 4 additions & 0 deletions docs/topics/rotate-certs.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ This helps protect against man-in-the-middle attacks, where an attacker may atte
Starting with AKS Engine v0.77.0, `StrictHostKeyChecking` will be enforced during the execution of the `aks-engine-azurestack rotate-certs` command.
Hence, new entries will be appended to the local `known_hosts` file if no SSH sessions to the remove host were established in the past.

Starting with AKS Engine v0.79.0, file `~/.ssh/known_hosts` is kept unchanged.
Instead, AKS Engine creates a copy in `~/.aks-engine-azurestack/known_hosts` and new entries are added to this file.
Every AKS Engine command execution refreshes the content of `~/.aks-engine-azurestack/known_hosts`.

### Generating certificates

`aks-engine-azurestack rotate-certs` is able to generate the new set of certificates that will be deployed to the cluster based on the information found in the API model.
Expand Down
38 changes: 1 addition & 37 deletions docs/tutorials/cli-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,42 +119,6 @@ We generally recommend that you manage node pool scaling dynamically using the `
Detailed documentation on `aks-engine-azurestack scale` can be found [here](../topics/scale.md).
### `aks-engine-azurestack update`
The `aks-engine-azurestack update` command will update the VMSS model of a node pool according to a modified configuration of the aks-engine-generated `apimodel.json`. The updated node configuration will not take affect on any existing nodes, but will be applied to all future, new nodes created by VMSS scale out operations. Use this command to update the node configuration (such as the OS configuration, VM SKU, or Kubernetes kubelet configuration) of an existing VMSS node pool.
Note: `aks-engine-azurestack update` **can not** be used to update the control plane! To update control plane VM configuration, see [`aks-engine-azurestack upgrade --control-plane-only` documentation here](../topics/upgrade.md#when-should-i-use-aks-engine-upgrade---control-plane-only).
```sh
$ aks-engine-azurestack update --help
Update an existing AKS Engine-created VMSS node pool in a Kubernetes cluster by updating its VMSS model
Usage:
aks-engine-azurestack update [flags]
Flags:
-m, --api-model string path to the generated apimodel.json file
--auth-method client_secret auth method (default:client_secret, `cli`, `client_certificate`, `device`) (default "cli")
--azure-env string the target Azure cloud (default "AzurePublicCloud")
--certificate-path string path to client certificate (used with --auth-method=client_certificate)
--client-id string client id (used with --auth-method=[client_secret|client_certificate])
--client-secret string client secret (used with --auth-method=client_secret)
-h, --help help for update
--identity-system azure_ad identity system (default:azure_ad, `adfs`) (default "azure_ad")
--language string language to return error messages in (default "en-us")
-l, --location string location the cluster is deployed in
--node-pool string node pool to scale
--private-key-path string path to private key (used with --auth-method=client_certificate)
-g, --resource-group string the resource group where the cluster is deployed
-s, --subscription-id string azure subscription id (required)
Global Flags:
--debug enable verbose debug logs
```
Detailed documentation on `aks-engine-azurestack update` can be found [here](../topics/update.md).
### `aks-engine-azurestack addpool`
The `aks-engine-azurestack addpool` command will add a new node pool to an existing AKS Engine-created cluster. Using a JSON file to define a the new node pool's configuration, and referencing the aks-engine-generated `apimodel.json`, you can add new nodes to your cluster. Use this command to add a specific number of new nodes using a discrete configuration compared to existing nodes participating in your cluster.
Expand Down Expand Up @@ -262,7 +226,7 @@ Detailed documentation on `aks-engine-azurestack generate` can be found [here](.
### `aks-engine-azurestack rotate-certs`
The `aks-engine-azurestack rotate-certs` command is currently experimental and not recommended for use on production clusters.
Detailed documentation on `aks-engine-azurestack rotate-certs` can be found [here](../topics/rotate-certs.md).
### `aks-engine-azurestack get-logs`
Expand Down
46 changes: 44 additions & 2 deletions pkg/helpers/ssh/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,49 @@

package ssh

import (
"io"
"os"
"path"

log "github.com/sirupsen/logrus"
)

var (
khpath string
lineBreak string
khsource string
khpath string
)

const (
knownHostFileName = "known_hosts"
)

// copyKnownHosts copies the SSH's known_hosts file to aks-engine's working directory.
// Errors are logged but not returned as we can still continue regardless.
func copyKnownHosts() {
src, err := os.Open(khsource)
if err != nil {
log.Warnf("failed to open file %s", khsource)
return
}
defer src.Close()

dir := path.Dir(khpath)
if err = os.MkdirAll(dir, 0700); err != nil {
log.Warnf("failed to create %s directory", dir)
return
}

dst, err := os.Create(khpath)
if err != nil {
log.Warnf("failed to open file %s", khpath)
return
}
defer dst.Close()

_, err = io.Copy(dst, src)
if err != nil {
log.Warnf("failed to copy %s to %s", khsource, khpath)
return
}
}
5 changes: 3 additions & 2 deletions pkg/helpers/ssh/init_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
)

func init() {
khpath = filepath.Join(os.Getenv("HOME"), ".ssh", "known_hosts")
lineBreak = "\n"
khsource = filepath.Join(os.Getenv("HOME"), ".ssh", knownHostFileName)
khpath = filepath.Join(os.Getenv("HOME"), ".aks-engine-azurestack", knownHostFileName)
copyKnownHosts()
}
5 changes: 3 additions & 2 deletions pkg/helpers/ssh/init_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
)

func init() {
khpath = filepath.Join(os.Getenv("HOME"), ".ssh", "known_hosts")
lineBreak = "\n"
khsource = filepath.Join(os.Getenv("HOME"), ".ssh", knownHostFileName)
khpath = filepath.Join(os.Getenv("HOME"), ".aks-engine-azurestack", knownHostFileName)
copyKnownHosts()
}
5 changes: 3 additions & 2 deletions pkg/helpers/ssh/init_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
)

func init() {
khpath = filepath.Join(os.Getenv("UserProfile"), ".ssh", "known_hosts")
lineBreak = "\r\n"
khsource = filepath.Join(os.Getenv("UserProfile"), ".ssh", knownHostFileName)
khpath = filepath.Join(os.Getenv("UserProfile"), ".aks-engine-azurestack", knownHostFileName)
copyKnownHosts()
}
10 changes: 5 additions & 5 deletions pkg/helpers/ssh/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ func clientConfigAuth(authConfig *AuthConfig) ([]ssh.AuthMethod, error) {
return []ssh.AuthMethod{ssh.Password(authConfig.Password)}, nil
}

// knownHostsHostKeyCallback returns a host key callback that uses file
// ${HOME}/.ssh/known_hosts to store known host keys
// knownHostsHostKeyCallback returns a host key callback that uses
// a known_hosts file to store known host keys
func knownHostsHostKeyCallback() (ssh.HostKeyCallback, error) {
err := ensuresKnownHosts()
if err != nil {
Expand All @@ -178,7 +178,7 @@ func knownHostsHostKeyCallback() (ssh.HostKeyCallback, error) {
return khCallback, nil
}

// ensuresKnownHosts creates file ${HOME}/.ssh/known_hosts if it does not exist
// ensuresKnownHosts creates the known_hosts file if it does not exist
func ensuresKnownHosts() error {
if err := os.MkdirAll(path.Dir(khpath), 0700); err != nil {
return errors.Wrap(err, "creating .ssh directory")
Expand All @@ -196,15 +196,15 @@ func hostKeyString(k ssh.PublicKey) string {
return fmt.Sprintf("%s %s", k.Type(), base64.StdEncoding.EncodeToString(k.Marshal()))
}

// addHostKey adds an entry to ${HOME}/.ssh/known_hosts
// addHostKey adds an entry to the known_hosts file
func addHostKey(hostname string, pubKey ssh.PublicKey) error {
f, err := os.OpenFile(khpath, os.O_APPEND|os.O_WRONLY, 0600)
if err != nil {
return errors.Wrap(err, "opening known_hosts file")
}
defer f.Close()
// append blank line
if _, err = f.WriteString(lineBreak); err != nil {
if _, err = f.WriteString(fmt.Sprintln()); err != nil {
return errors.Wrap(err, "appending blank line to known_hosts file")
}
// append host key line
Expand Down

0 comments on commit e053c72

Please sign in to comment.