#!/bin/bash

# This script configures all we need to configure k3s / rke2 hardened cluster
# Instructions from https://docs.k3s.io/security/hardening-guide and https://docs.rke2.io/security/hardening_guide

set -e -x

# Variables
K3S_SERVER_DIR="/var/lib/rancher/k3s/server"
K3S_CONFIG_DIR="/etc/rancher/k3s"
K3S_CONFIG_FILE="${K3S_CONFIG_DIR}/config.yaml"
RKE2_SERVER_DIR="/etc/rancher/rke2"
RKE2_CONFIG_FILE="${RKE2_SERVER_DIR}/config.yaml"
RKE2_BINARY="/usr/local/bin/rke2"
MANIFESTS_DIR="${K3S_SERVER_DIR}/manifests/"
SYSCTL_DIR="/etc/sysctl.d"
HARDENED_DIR="../assets/hardened_cluster"
SYSCTL_CONF="${HARDENED_DIR}/90-kubelet.conf"
PSA_YAML="${HARDENED_DIR}/psa.yaml"
NETWORK_POLICY_YAML="${HARDENED_DIR}/networkpolicy.yaml"
AUDIT_YAML="${HARDENED_DIR}/audit.yaml"

# Apply mandatory sysctl config
cp ${SYSCTL_CONF} ${SYSCTL_DIR}
sysctl -p ${SYSCTL_DIR}/90-kubelet.conf

# Check if we are running RKE2 or K3S
if [[ -f ${RKE2_BINARY} ]]; then
  # Create RKE2 directory and config file
  mkdir -p ${RKE2_SERVER_DIR}
  # Enable hardened profile
  cp ${PSA_YAML} ${RKE2_SERVER_DIR}
  cat << EOF > ${RKE2_CONFIG_FILE}
profile: cis-1.23
pod-security-admission-config-file: ${RKE2_SERVER_DIR}/psa.yaml
EOF
  # Create etcd user
  useradd -r -c "etcd user" -s /sbin/nologin -M etcd -U
else
  # Create K3S directories to preload manifests
  mkdir -p -m 700 ${MANIFESTS_DIR}
  mkdir ${K3S_SERVER_DIR}/logs

  # Copy policies to manifests directory
  cp ${NETWORK_POLICY_YAML} ${MANIFESTS_DIR}

  # Enable auditing
  cp ${PSA_YAML} ${AUDIT_YAML} ${K3S_SERVER_DIR}

  # Create K3S config file
  mkdir -p ${K3S_CONFIG_DIR}
  cat << EOF > ${K3S_CONFIG_FILE}
protect-kernel-defaults: true
kube-apiserver-arg:
  - "admission-control-config-file=/var/lib/rancher/k3s/server/psa.yaml"
  - "audit-log-path=/var/lib/rancher/k3s/server/logs/audit.log"
  - "audit-policy-file=/var/lib/rancher/k3s/server/audit.yaml"
  - "audit-log-maxage=30"
  - "audit-log-maxbackup=10"
  - "audit-log-maxsize=100"
  - "request-timeout=300s"
  - "service-account-lookup=true"
  - "anonymous-auth=false"
kubelet-arg:
  - "make-iptables-util-chains=true" 
EOF
fi
