diff --git a/install.sh b/install.sh index 98e20b29..2d612551 100755 --- a/install.sh +++ b/install.sh @@ -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 @@ -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}" @@ -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 } @@ -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 diff --git a/main.go b/main.go index 48a080b7..7bea145b 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,7 @@ package main import ( "fmt" "os" + "strings" "github.com/mattn/go-colorable" "github.com/rancher/system-agent/pkg/applyinator" @@ -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() { @@ -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 { diff --git a/pkg/k8splan/watcher.go b/pkg/k8splan/watcher.go index 1f22b74f..cd86ee54 100644 --- a/pkg/k8splan/watcher.go +++ b/pkg/k8splan/watcher.go @@ -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 { @@ -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 {