From 8d217e0778d20639a0beeeeea7d682a916d34d44 Mon Sep 17 00:00:00 2001 From: Mike Smith <89040888+smiggiddy@users.noreply.github.com> Date: Thu, 19 Jun 2025 07:55:22 -0400 Subject: [PATCH] fix: updated --- k0sctl.yaml | 34 ++++- selinux-script.sh | 335 ++++++++++++++++++++++++---------------------- 2 files changed, 205 insertions(+), 164 deletions(-) diff --git a/k0sctl.yaml b/k0sctl.yaml index bc5e10d..d61848d 100644 --- a/k0sctl.yaml +++ b/k0sctl.yaml @@ -20,7 +20,7 @@ spec: perm: 0644 - name: selinux-stuff src: selinux.conf - dstDir: /etc/containerd.d/selinux-containers.conf + dstDir: /etc/containerd.d perm: 0644 - ssh: address: k2.lab.smig.tech @@ -31,16 +31,23 @@ spec: files: - name: selinux-script src: ./selinux-script.sh - dstDir: /home/smig/selinux-script.sh + dstDir: /home/smig/ perm: 0700 user: smig group: smig + - name: selinux-stuff + src: selinux.conf + dstDir: /etc/containerd.d + perm: 0644 hooks: apply: after: - date > k0s-selinux.log - echo "Starting SELinux Script" >> k0s-selinux.log - bash /home/smig/selinux-script.sh &>> k0s-selinux.log + reset: + after: + - rm /home/smig/k0s-selinux.log /home/smig/selinux-script.sh /home/smig/.k0s-selinuxsetup-complete - ssh: address: k3.lab.smig.tech user: smig @@ -50,16 +57,23 @@ spec: files: - name: selinux-script src: ./selinux-script.sh - dstDir: /home/smig/selinux-script.sh + dstDir: /home/smig/ perm: 0700 user: smig group: smig + - name: selinux-stuff + src: selinux.conf + dstDir: /etc/containerd.d + perm: 0644 hooks: apply: after: - date > k0s-selinux.log - echo "Starting SELinux Script" >> k0s-selinux.log - bash /home/smig/selinux-script.sh &>> k0s-selinux.log + reset: + after: + - rm /home/smig/k0s-selinux.log /home/smig/selinux-script.sh /home/smig/.k0s-selinuxsetup-complete - ssh: address: k4.lab.smig.tech user: smig @@ -69,16 +83,23 @@ spec: files: - name: selinux-script src: ./selinux-script.sh - dstDir: /home/smig/selinux-script.sh + dstDir: /home/smig/ perm: 0700 user: smig group: smig + - name: selinux-stuff + src: selinux.conf + dstDir: /etc/containerd.d + perm: 0644 hooks: apply: after: - date > k0s-selinux.log - echo "Starting SELinux Script" >> k0s-selinux.log - bash /home/smig/selinux-script.sh &>> k0s-selinux.log + reset: + after: + - rm /home/smig/k0s-selinux.log /home/smig/selinux-script.sh /home/smig/.k0s-selinuxsetup-complete k0s: config: apiVersion: k0s.k0sproject.io/v1beta1 @@ -134,7 +155,7 @@ spec: charts: - name: seaweedfs-operator chartname: seaweedfs-operator/seaweedfs-operator - version: "0.1.1" + version: "0.0.2" order: 2 namespace: seaweefs-operator-system values: | @@ -142,7 +163,8 @@ spec: registry: git.thecodedom.com repository: smig/seaweedfs-operator tag: 0.1.0 - + webhook: + enabled: false - name: openebs chartname: openebs-internal/openebs diff --git a/selinux-script.sh b/selinux-script.sh index 81557e3..5c9375c 100644 --- a/selinux-script.sh +++ b/selinux-script.sh @@ -3,13 +3,13 @@ set -euo pipefail # Configuration -DATA_DIR="/var/lib/k0s" -SCRIPT_NAME="$(basename "$0")" -COMPLETION_FLAG="$HOME/.k0s-selinuxsetup-complete" +readonly DATA_DIR="/var/lib/k0s" +readonly SCRIPT_NAME="$(basename "$0")" +readonly COMPLETION_FLAG="$HOME/.k0s-selinuxsetup-complete" # Logging function log() { - echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >&2 + printf "[%s] %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2 } # Error handling function @@ -18,44 +18,6 @@ error_exit() { exit 1 } -# Check if running as root or with sudo -check_privileges() { - if [[ $EUID -ne 0 ]] && ! sudo -n true 2>/dev/null; then - error_exit "This script requires root privileges or passwordless sudo access" - fi -} - -# Check if SELinux is enabled -check_selinux() { - if ! command -v getenforce >/dev/null 2>&1; then - error_exit "SELinux tools not found. Is SELinux installed?" - fi - - local selinux_status - selinux_status=$(getenforce 2>/dev/null || echo "Disabled") - - if [[ "$selinux_status" == "Disabled" ]]; then - error_exit "SELinux is disabled. This script requires SELinux to be enabled." - fi - - log "SELinux status: $selinux_status" -} - -# Check if required tools are available -check_tools() { - local missing_tools=() - - for tool in semanage restorecon; do - if ! command -v "$tool" >/dev/null 2>&1; then - missing_tools+=("$tool") - fi - done - - if [[ ${#missing_tools[@]} -gt 0 ]]; then - error_exit "Missing required tools: ${missing_tools[*]}. Please install policycoreutils-python-utils or equivalent package." - fi -} - # Check if script has already been run successfully check_completion_flag() { if [[ -f "$COMPLETION_FLAG" ]]; then @@ -67,160 +29,217 @@ check_completion_flag() { fi } +# Check if running with sufficient privileges +check_privileges() { + if ! sudo -n true 2>/dev/null; then + error_exit "This script requires passwordless sudo access" + fi +} + +# Check if SELinux is available and enabled +check_selinux() { + if ! command -v getenforce >/dev/null 2>&1; then + error_exit "getenforce command not found - SELinux may not be installed" + fi + + local selinux_status + if ! selinux_status=$(getenforce 2>/dev/null); then + error_exit "Failed to get SELinux status" + fi + + case "$selinux_status" in + "Enforcing"|"Permissive") + log "SELinux status: $selinux_status" + ;; + *) + error_exit "SELinux is not enabled (status: $selinux_status)" + ;; + esac +} + +# Check if required SELinux management tools are available +check_selinux_tools() { + local missing_tools=() + + for tool in semanage restorecon; do + if ! command -v "$tool" >/dev/null 2>&1; then + missing_tools+=("$tool") + fi + done + + if [[ ${#missing_tools[@]} -gt 0 ]]; then + error_exit "Missing required SELinux tools: ${missing_tools[*]}" + fi +} + +# Check if target directory exists +check_target_directory() { + if [[ ! -d "$DATA_DIR" ]]; then + error_exit "Target directory $DATA_DIR does not exist" + fi + log "Target directory $DATA_DIR exists" +} + +# Check if fcontext rule already exists (safer grep with fixed strings) +fcontext_exists() { + local pattern="$1" + local context_type="$2" + + # Use semanage to list and grep for exact matches + if sudo semanage fcontext -l 2>/dev/null | grep -F "$pattern" | grep -q "$context_type"; then + return 0 + else + return 1 + fi +} + +# Add SELinux file context rule (idempotent) +add_fcontext_rule() { + local pattern="$1" + local context_type="$2" + local description="$3" + + if fcontext_exists "$pattern" "$context_type"; then + log "SKIP: $description - fcontext rule already exists" + return 0 + fi + + log "ADDING: $description ($pattern -> $context_type)" + + if sudo semanage fcontext -a -t "$context_type" "$pattern" 2>/dev/null; then + log "SUCCESS: Added fcontext rule for $pattern" + return 0 + else + log "WARNING: Failed to add fcontext rule for $pattern" + return 1 + fi +} + +# Restore SELinux contexts (non-fatal) +restore_contexts() { + local target_path="$1" + local description="$2" + + if [[ ! -e "$target_path" ]]; then + log "SKIP: $description - path $target_path does not exist" + return 0 + fi + + log "RESTORING: $description" + + # Run restorecon and capture output, but don't fail the script + if sudo restorecon -R -v "$target_path" 2>&1 | while IFS= read -r line; do + [[ -n "$line" ]] && log " restorecon: $line" + done; then + log "SUCCESS: Context restoration completed for $target_path" + return 0 + else + log "WARNING: restorecon reported issues for $target_path (continuing anyway)" + return 1 + fi +} + +# Show what contexts are actually present (informational only) +show_contexts() { + local target_path="$1" + local description="$2" + + if [[ ! -e "$target_path" ]]; then + log "SKIP INFO: $description - path $target_path does not exist" + return 0 + fi + + log "CONTEXTS: $description" + + # Show context summary without making assumptions about what's "correct" + local context_info + if context_info=$(find "$target_path" -exec ls -Z {} \; 2>/dev/null | awk '{print $1}' | sort | uniq -c 2>/dev/null); then + if [[ -n "$context_info" ]]; then + echo "$context_info" | while IFS= read -r line; do + log " $line" + done + else + log " (no context information available)" + fi + else + log " (unable to retrieve context information)" + fi +} + # Create completion flag file create_completion_flag() { - cat > "$COMPLETION_FLAG" << 'EOF' + # Use a here-document with proper quoting + if cat > "$COMPLETION_FLAG" << EOF # k0s SELinux Setup Completion Flag # # This file indicates that the k0s SELinux configuration script has been # run successfully. It prevents the script from running multiple times. # # The script configures SELinux file contexts for: -# - /var/lib/k0s/bin/containerd.* (container_runtime_exec_t) -# - /var/lib/k0s/bin/runc (container_runtime_exec_t) -# - /var/lib/k0s/containerd directory tree (container_var_lib_t) -# - /var/lib/k0s/containerd snapshots (container_ro_file_t) +# - ${DATA_DIR}/bin/containerd.* (container_runtime_exec_t) +# - ${DATA_DIR}/bin/runc (container_runtime_exec_t) +# - ${DATA_DIR}/containerd directory tree (container_var_lib_t) +# - ${DATA_DIR}/containerd snapshots (container_ro_file_t) # # If you remove this file, the SELinux script will run again on the next # k0sapply execution. # # Created: $(date) -# Script: $(readlink -f "$0" 2>/dev/null || echo "$0") +# Script: $0 EOF - - if [[ $? -eq 0 ]]; then + then log "SUCCESS: Created completion flag at $COMPLETION_FLAG" else log "WARNING: Failed to create completion flag at $COMPLETION_FLAG" - fi -} -check_data_dir() { - if [[ ! -d "$DATA_DIR" ]]; then - error_exit "Data directory $DATA_DIR does not exist" - fi - log "Data directory $DATA_DIR exists" -} - -# Check if fcontext rule already exists -fcontext_exists() { - local pattern="$1" - local context="$2" - - sudo semanage fcontext -l | grep -q "^${pattern}.*${context}" 2>/dev/null -} - -# Add SELinux file context rule (idempotent) -add_fcontext() { - local pattern="$1" - local context="$2" - local description="$3" - - if fcontext_exists "$pattern" "$context"; then - log "SKIP: $description - fcontext rule already exists" - return 0 - fi - - log "ADDING: $description" - if sudo semanage fcontext -a -t "$context" "$pattern"; then - log "SUCCESS: Added fcontext rule for $pattern" - return 0 - else - error_exit "Failed to add fcontext rule for $pattern" - fi -} - -# Restore SELinux contexts -restore_contexts() { - local path="$1" - local description="$2" - - if [[ ! -e "$path" ]]; then - log "SKIP: $description - path $path does not exist" - return 0 - fi - - log "RESTORING: $description" - if sudo restorecon -R -v "$path" 2>&1 | while read -r line; do - [[ -n "$line" ]] && log " $line" - done; then - log "SUCCESS: Restored contexts for $path" - return 0 - else - error_exit "Failed to restore contexts for $path" - fi -} - -# Verify that contexts were applied correctly -verify_contexts() { - local path="$1" - local expected_pattern="$2" - local description="$3" - - if [[ ! -e "$path" ]]; then - log "SKIP VERIFY: $description - path $path does not exist" - return 0 - fi - - log "VERIFYING: $description" - - # Get the actual context - local actual_contexts - actual_contexts=$(find "$path" -exec ls -Z {} \; 2>/dev/null | awk '{print $1}' | sort -u) - - if echo "$actual_contexts" | grep -q "$expected_pattern"; then - log "SUCCESS: Verified contexts for $path contain $expected_pattern" - return 0 - else - log "WARNING: Expected pattern $expected_pattern not found in contexts for $path" - log "Actual contexts found: $actual_contexts" return 1 fi } -# Main execution +# Main execution function main() { log "Starting $SCRIPT_NAME" - # Check if already completed + # Early exit if already completed check_completion_flag - # Pre-flight checks + # System checks check_privileges check_selinux - check_tools - check_data_dir + check_selinux_tools + check_target_directory - # Add file context rules (idempotent) - add_fcontext "${DATA_DIR}/bin/containerd.*" "container_runtime_exec_t" "containerd executables" - add_fcontext "${DATA_DIR}/bin/runc" "container_runtime_exec_t" "runc executable" - add_fcontext "${DATA_DIR}/containerd(/.*)?", "container_var_lib_t" "containerd directory" - add_fcontext "${DATA_DIR}/containerd/io.containerd.snapshotter.*/snapshots(/.*)?" "container_ro_file_t" "containerd snapshots" + # Track any failures + local rule_failures=0 + local restore_failures=0 - # Restore contexts - restore_contexts "${DATA_DIR}/bin" "k0s binaries" - restore_contexts "${DATA_DIR}/containerd" "containerd directory" + # Add SELinux file context rules + add_fcontext_rule "${DATA_DIR}/bin/containerd.*" "container_runtime_exec_t" "containerd executables" || ((rule_failures++)) + add_fcontext_rule "${DATA_DIR}/bin/runc" "container_runtime_exec_t" "runc executable" || ((rule_failures++)) + add_fcontext_rule "${DATA_DIR}/containerd(/.*)?" "container_var_lib_t" "containerd directory" || ((rule_failures++)) + add_fcontext_rule "${DATA_DIR}/containerd/io.containerd.snapshotter.*/snapshots(/.*)?" "container_ro_file_t" "containerd snapshots" || ((rule_failures++)) - # Verify contexts were applied (optional verification) - local verification_failed=0 + # Apply contexts to existing files + restore_contexts "${DATA_DIR}/bin" "k0s binaries" || ((restore_failures++)) + restore_contexts "${DATA_DIR}/containerd" "containerd directory" || ((restore_failures++)) - if [[ -d "${DATA_DIR}/bin" ]]; then - verify_contexts "${DATA_DIR}/bin" "container_runtime_exec_t" "k0s binaries" || verification_failed=1 + # Show what contexts are actually present (informational) + show_contexts "${DATA_DIR}/bin" "k0s binaries" + show_contexts "${DATA_DIR}/containerd" "containerd directory" + + # Report any issues but don't fail + if [[ $rule_failures -gt 0 ]]; then + log "WARNING: $rule_failures fcontext rule(s) failed to add" fi - if [[ -d "${DATA_DIR}/containerd" ]]; then - verify_contexts "${DATA_DIR}/containerd" "container_" "containerd directory" || verification_failed=1 + if [[ $restore_failures -gt 0 ]]; then + log "WARNING: $restore_failures context restoration(s) had issues" fi - if [[ $verification_failed -eq 1 ]]; then - log "WARNING: Some context verifications failed. Check the logs above." - log "You may want to run 'sudo restorecon -R -v $DATA_DIR' manually." - fi - - # Create completion flag to prevent future runs + # Create completion flag regardless of warnings create_completion_flag - log "Completed $SCRIPT_NAME successfully" + log "Completed $SCRIPT_NAME" } -# Run main function +# Execute main function main "$@"