Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kubelet: Restrict access to TLS private key #2639

Merged
merged 2 commits into from
Jan 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Release.toml
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,6 @@ version = "1.12.0"
"migrate_v1.11.0_public-control-container-v0-6-4.lz4",
]
"(1.11.0, 1.11.1)" = []
"(1.11.1, 1.12.0)" = []
"(1.11.1, 1.12.0)" = [
"migrate_v1.12.0_k8s-private-pki-path.lz4",
]
6 changes: 3 additions & 3 deletions packages/kubernetes-1.21/etc-kubernetes-pki.mount
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[Unit]
Description=Kubernetes PKI directory (/etc/kubernetes/pki)
Description=Kubernetes PKI private directory (/etc/kubernetes/pki/private)
DefaultDependencies=no
Conflicts=umount.target
Before=local-fs.target umount.target
Expand All @@ -8,9 +8,9 @@ Wants=selinux-policy-files.service

[Mount]
What=tmpfs
Where=/etc/kubernetes/pki
Where=/etc/kubernetes/pki/private
Type=tmpfs
Options=nosuid,nodev,noexec,noatime,context=system_u:object_r:secret_t:s0,mode=0700

[Install]
WantedBy=preconfigured.target
WantedBy=preconfigured.target
2 changes: 1 addition & 1 deletion packages/kubernetes-1.21/kubelet-config
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ protectKernelDefaults: true
serializeImagePulls: false
{{#if (and (default "" settings.kubernetes.server-certificate) (default "" settings.kubernetes.server-key))}}
tlsCertFile: "/etc/kubernetes/pki/kubelet-server.crt"
tlsPrivateKeyFile: "/etc/kubernetes/pki/kubelet-server.key"
tlsPrivateKeyFile: "/etc/kubernetes/pki/private/kubelet-server.key"
{{else}}
serverTLSBootstrap: {{settings.kubernetes.server-tls-bootstrap}}
{{/if}}
Expand Down
6 changes: 3 additions & 3 deletions packages/kubernetes-1.22/etc-kubernetes-pki.mount
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[Unit]
Description=Kubernetes PKI directory (/etc/kubernetes/pki)
Description=Kubernetes PKI private directory (/etc/kubernetes/pki/private)
DefaultDependencies=no
Conflicts=umount.target
Before=local-fs.target umount.target
Expand All @@ -8,9 +8,9 @@ Wants=selinux-policy-files.service

[Mount]
What=tmpfs
Where=/etc/kubernetes/pki
Where=/etc/kubernetes/pki/private
Type=tmpfs
Options=nosuid,nodev,noexec,noatime,context=system_u:object_r:secret_t:s0,mode=0700

[Install]
WantedBy=preconfigured.target
WantedBy=preconfigured.target
jpmcb marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion packages/kubernetes-1.22/kubelet-config
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ protectKernelDefaults: true
serializeImagePulls: false
{{#if (and (default "" settings.kubernetes.server-certificate) (default "" settings.kubernetes.server-key))}}
tlsCertFile: "/etc/kubernetes/pki/kubelet-server.crt"
tlsPrivateKeyFile: "/etc/kubernetes/pki/kubelet-server.key"
tlsPrivateKeyFile: "/etc/kubernetes/pki/private/kubelet-server.key"
{{else}}
serverTLSBootstrap: {{settings.kubernetes.server-tls-bootstrap}}
{{/if}}
Expand Down
6 changes: 3 additions & 3 deletions packages/kubernetes-1.23/etc-kubernetes-pki.mount
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[Unit]
Description=Kubernetes PKI directory (/etc/kubernetes/pki)
Description=Kubernetes PKI private directory (/etc/kubernetes/pki/private)
DefaultDependencies=no
Conflicts=umount.target
Before=local-fs.target umount.target
Expand All @@ -8,9 +8,9 @@ Wants=selinux-policy-files.service

[Mount]
What=tmpfs
Where=/etc/kubernetes/pki
Where=/etc/kubernetes/pki/private
Type=tmpfs
Options=nosuid,nodev,noexec,noatime,context=system_u:object_r:secret_t:s0,mode=0700

[Install]
WantedBy=preconfigured.target
WantedBy=preconfigured.target
2 changes: 1 addition & 1 deletion packages/kubernetes-1.23/kubelet-config
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ protectKernelDefaults: true
serializeImagePulls: false
{{#if (and (default "" settings.kubernetes.server-certificate) (default "" settings.kubernetes.server-key))}}
tlsCertFile: "/etc/kubernetes/pki/kubelet-server.crt"
tlsPrivateKeyFile: "/etc/kubernetes/pki/kubelet-server.key"
tlsPrivateKeyFile: "/etc/kubernetes/pki/private/kubelet-server.key"
{{else}}
serverTLSBootstrap: {{settings.kubernetes.server-tls-bootstrap}}
{{/if}}
Expand Down
4 changes: 2 additions & 2 deletions packages/kubernetes-1.24/etc-kubernetes-pki.mount
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[Unit]
Description=Kubernetes PKI directory (/etc/kubernetes/pki)
Description=Kubernetes PKI private directory (/etc/kubernetes/pki/private)
DefaultDependencies=no
Conflicts=umount.target
Before=local-fs.target umount.target
Expand All @@ -8,7 +8,7 @@ Wants=selinux-policy-files.service

[Mount]
What=tmpfs
Where=/etc/kubernetes/pki
Where=/etc/kubernetes/pki/private
Type=tmpfs
Options=nosuid,nodev,noexec,noatime,context=system_u:object_r:secret_t:s0,mode=0700

Expand Down
2 changes: 1 addition & 1 deletion packages/kubernetes-1.24/kubelet-config
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ protectKernelDefaults: true
serializeImagePulls: false
{{#if (and (default "" settings.kubernetes.server-certificate) (default "" settings.kubernetes.server-key))}}
tlsCertFile: "/etc/kubernetes/pki/kubelet-server.crt"
tlsPrivateKeyFile: "/etc/kubernetes/pki/kubelet-server.key"
tlsPrivateKeyFile: "/etc/kubernetes/pki/private/kubelet-server.key"
{{else}}
serverTLSBootstrap: {{settings.kubernetes.server-tls-bootstrap}}
{{/if}}
Expand Down
8 changes: 8 additions & 0 deletions sources/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion sources/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ members = [
"api/prairiedog",

# "api/migration/migrations/vX.Y.Z/..."
# (all migrations currently archived; replace this line with new ones)
# (all previous migrations archived; add new ones after this line)
"api/migration/migrations/v1.12.0/k8s-private-pki-path",

"bottlerocket-release",

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "k8s-private-pki-path"
version = "0.1.0"
authors = ["Sean McGinnis <[email protected]>"]
license = "Apache-2.0 OR MIT"
edition = "2018"
publish = false
# Don't rebuild crate just because of changes to README.
exclude = ["README.md"]

[dependencies]
migration-helpers = { path = "../../../migration-helpers", version = "0.1.0"}
serde_json = "1.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#![deny(rust_2018_idioms)]

use migration_helpers::{migrate, Migration, MigrationData, Result};
use std::process;

const SETTING: &'static str = "configuration-files.kubelet-server-key.path";
const OLD_VALUE: &'static str = "/etc/kubernetes/pki/kubelet-server.key";
const NEW_VALUE: &'static str = "/etc/kubernetes/pki/private/kubelet-server.key";

/// We moved the render output location for the kubelet PKI private key to be in a restricted
/// subdirectory. We need to update this output path in the stored configuration so updated nodes
/// pick up the change.
fn run() -> Result<()> {
migrate(KubeletServerKey {})
}

pub struct KubeletServerKey {}

impl KubeletServerKey {
fn migrate(&mut self, mut input: MigrationData, action: &'static str) -> Result<MigrationData> {
let old_value;
let new_value;
if action == "upgrade" {
old_value = OLD_VALUE;
new_value = NEW_VALUE;
} else {
// Downgrade: everything old is new again
old_value = NEW_VALUE;
new_value = OLD_VALUE;
etungsten marked this conversation as resolved.
Show resolved Hide resolved
}

if let Some(data) = input.data.get_mut(SETTING) {
match data {
serde_json::Value::String(current_value) => {
if current_value == old_value {
*data = new_value.into();
println!(
"Changed '{}' from {:?} to {:?} on {}",
SETTING, old_value, new_value, action
);
} else {
println!(
"'{}' is already set to {:?}, leaving alone",
SETTING, new_value
);
}
}
_ => {
println!(
"'{}' is set to non-string value '{}'; KubeletServerKey only handles strings",
SETTING, data
);
}
}
} else {
println!("Found no setting '{}'", SETTING);
}

Ok(input)
}
}

impl Migration for KubeletServerKey {
fn forward(&mut self, input: MigrationData) -> Result<MigrationData> {
self.migrate(input, "upgrade")
}

fn backward(&mut self, input: MigrationData) -> Result<MigrationData> {
self.migrate(input, "downgrade")
}
}

// Returning a Result from main makes it print a Debug representation of the error, but with Snafu
// we have nice Display representations of the error, so we wrap "main" (run) and print any error.
// https://github.com/shepmaster/snafu/issues/110
fn main() {
if let Err(e) = run() {
eprintln!("{}", e);
process::exit(1);
}
}
2 changes: 1 addition & 1 deletion sources/models/shared-defaults/kubernetes-services.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ path = "/etc/kubernetes/pki/kubelet-server.crt"
template-path = "/usr/share/templates/kubelet-server-crt"

[configuration-files.kubelet-server-key]
path = "/etc/kubernetes/pki/kubelet-server.key"
path = "/etc/kubernetes/pki/private/kubelet-server.key"
stmcginnis marked this conversation as resolved.
Show resolved Hide resolved
template-path = "/usr/share/templates/kubelet-server-key"

[configuration-files.kubelet-exec-start-conf]
Expand Down