Skip to content

Commit

Permalink
Add support for CATTLE_AGENT_STRICT_VERIFY|STRICT_VERIFY environment …
Browse files Browse the repository at this point in the history
…variables to ensure kubeconfig CA data is valid (#171)

Signed-off-by: Chris Kim <[email protected]>
  • Loading branch information
Oats87 authored Jun 27, 2024
1 parent 41c07d0 commit 3bf716f
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 9 deletions.
15 changes: 14 additions & 1 deletion install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ fi
# - CATTLE_AGENT_BINARY_LOCAL_LOCATION (default: )
# - CATTLE_AGENT_UNINSTALL_LOCAL (default: false)
# - CATTLE_AGENT_UNINSTALL_LOCAL_LOCATION (default: )
# - CATTLE_AGENT_STRICT_VERIFY | STRICT_VERIFY (default: false)

FALLBACK=v0.2.9
CACERTS_PATH=cacerts
Expand Down Expand Up @@ -390,6 +391,14 @@ setup_env() {
fi
fi

if [ -z "${CATTLE_AGENT_STRICT_VERIFY}" ]; then
CATTLE_AGENT_STRICT_VERIFY=false
if [ -n "${STRICT_VERIFY}" ]; then
CATTLE_AGENT_STRICT_VERIFY=${STRICT_VERIFY}
fi
info "CA strict verification is set to ${CATTLE_AGENT_STRICT_VERIFY}"
fi

if [ -z "${CATTLE_AGENT_CONFIG_DIR}" ]; then
CATTLE_AGENT_CONFIG_DIR=/etc/rancher/agent
info "Using default agent configuration directory ${CATTLE_AGENT_CONFIG_DIR}"
Expand Down Expand Up @@ -563,6 +572,7 @@ Restart=always
RestartSec=5s
Environment=CATTLE_LOGLEVEL=${CATTLE_AGENT_LOGLEVEL}
Environment=CATTLE_AGENT_CONFIG=${CATTLE_AGENT_CONFIG_DIR}/config.yaml
Environment=CATTLE_AGENT_STRICT_VERIFY=${CATTLE_AGENT_STRICT_VERIFY}
ExecStart=${CATTLE_AGENT_BIN_PREFIX}/bin/rancher-system-agent sentinel
EOF
}
Expand Down Expand Up @@ -874,7 +884,10 @@ do_install() {
touch ${CATTLE_AGENT_VAR_DIR}/interlock/restart-pending
ensure_applyinator_not_active

if [ -n "${CATTLE_CA_CHECKSUM}" ]; then
if [ -z "${CATTLE_CA_CHECKSUM}" ] && [ $(echo "${CATTLE_AGENT_STRICT_VERIFY}" | tr '[:upper:]' '[:lower:]') = "true" ]; then
fatal "Aborting system-agent installation due to requested strict CA verification with no CA checksum provided"
fi
if [ -n "${CATTLE_CA_CHECKSUM}" && [ $(echo "${CATTLE_AGENT_STRICT_VERIFY}" | tr '[:upper:]' '[:lower:]') != "true" ]; then
validate_ca_required
fi
validate_ca_checksum
Expand Down
15 changes: 11 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"fmt"
"os"
"strings"

"github.com/mattn/go-colorable"
"github.com/rancher/system-agent/pkg/applyinator"
Expand All @@ -17,9 +18,10 @@ import (
)

const (
cattleLogLevelEnv = "CATTLE_LOGLEVEL"
cattleAgentConfigEnv = "CATTLE_AGENT_CONFIG"
defaultConfigFile = "/etc/rancher/agent/config.yaml"
cattleLogLevelEnv = "CATTLE_LOGLEVEL"
cattleAgentConfigEnv = "CATTLE_AGENT_CONFIG"
cattleAgentStrictVerifyEnv = "CATTLE_AGENT_STRICT_VERIFY"
defaultConfigFile = "/etc/rancher/agent/config.yaml"
)

func main() {
Expand Down Expand Up @@ -92,7 +94,12 @@ func run(c *cli.Context) error {
return fmt.Errorf("unable to parse connection info file: %w", err)
}

k8splan.Watch(topContext, *applyinator, connInfo)
var strictVerify bool // When strictVerify is set to true, the kubeconfig validator will not discard CA data if it is invalid
if strings.ToLower(os.Getenv(cattleAgentStrictVerifyEnv)) == "true" {
strictVerify = true
}

k8splan.Watch(topContext, *applyinator, connInfo, strictVerify)
}

if cf.LocalEnabled {
Expand Down
12 changes: 8 additions & 4 deletions pkg/k8splan/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ const (
cooldownTimerDuration = "30s"
)

func Watch(ctx context.Context, applyinator applyinator.Applyinator, connInfo config.ConnectionInfo) {
func Watch(ctx context.Context, applyinator applyinator.Applyinator, connInfo config.ConnectionInfo, strictVerify bool) {
w := &watcher{
connInfo: connInfo,
applyinator: applyinator,
}

go w.start(ctx)
go w.start(ctx, strictVerify)
}

type watcher struct {
Expand All @@ -86,14 +86,18 @@ func incrementCount(count []byte) []byte {
return []byte("1")
}

func (w *watcher) start(ctx context.Context) {
func (w *watcher) start(ctx context.Context, strictVerify bool) {
kc, err := clientcmd.RESTConfigFromKubeConfig([]byte(w.connInfo.KubeConfig))
if err != nil {
panic(err)
}

if strictVerify && len(kc.CAData) == 0 {
logrus.Fatal("CA Data in provided kubeconfig was empty while strict verify was enabled. Aborting startup.")
}

if err := validateKC(ctx, kc); err != nil {
if strings.Contains(err.Error(), "x509: certificate signed by unknown authority") && len(kc.CAData) != 0 {
if strings.Contains(err.Error(), "x509: certificate signed by unknown authority") && len(kc.CAData) != 0 && !strictVerify {
logrus.Infof("Initial connection to Kubernetes cluster failed with error %v, removing CA data and trying again", err)
kc.CAData = nil // nullify the provided CA data
if err := validateKC(ctx, kc); err != nil {
Expand Down

0 comments on commit 3bf716f

Please sign in to comment.