This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
# shellcheck shell=bash
|
||||
|
||||
require_supported_ubuntu() {
|
||||
if [[ ! -r /etc/os-release ]] || ! command -v dpkg >/dev/null 2>&1; then
|
||||
printf 'CRITICAL: Ubuntu release detection requires /etc/os-release and dpkg\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
source /etc/os-release
|
||||
if [[ "${ID:-}" != "ubuntu" ]]; then
|
||||
printf 'CRITICAL: this toolkit supports Ubuntu only; detected %s\n' "${ID:-unknown}" >&2
|
||||
exit 2
|
||||
fi
|
||||
if ! dpkg --compare-versions "${VERSION_ID:-0}" ge "24.04"; then
|
||||
printf 'CRITICAL: Ubuntu 24.04 or newer is required; detected %s\n' \
|
||||
"${VERSION_ID:-unknown}" >&2
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
Executable
+124
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
section() {
|
||||
printf '\n== %s ==\n' "$1"
|
||||
}
|
||||
|
||||
run_optional() {
|
||||
local description="$1"
|
||||
shift
|
||||
|
||||
if "$@"; then
|
||||
return 0
|
||||
fi
|
||||
printf 'WARNING: %s failed\n' "$description"
|
||||
return 0
|
||||
}
|
||||
|
||||
section "Operating system"
|
||||
if [[ -r /etc/os-release ]]; then
|
||||
run_optional "OS release report" cat /etc/os-release
|
||||
else
|
||||
printf 'WARNING: /etc/os-release is unavailable\n'
|
||||
fi
|
||||
run_optional "kernel report" uname -a
|
||||
|
||||
section "Host"
|
||||
run_optional "hostname report" hostname
|
||||
run_optional "uptime report" uptime
|
||||
|
||||
section "CPU and virtualization"
|
||||
if command -v lscpu >/dev/null 2>&1; then
|
||||
run_optional "CPU report" lscpu
|
||||
printf '\nVirtualization flags:\n'
|
||||
lscpu | grep -E 'Virtualization|Hypervisor vendor' || \
|
||||
printf 'INFO: no virtualization summary reported by lscpu\n'
|
||||
else
|
||||
printf 'WARNING: lscpu is unavailable\n'
|
||||
fi
|
||||
if grep -Eqm1 '(^|[[:space:]])(vmx|svm)([[:space:]]|$)' /proc/cpuinfo; then
|
||||
printf 'OK: CPU virtualization flags detected\n'
|
||||
else
|
||||
printf 'WARNING: CPU virtualization flags were not detected\n'
|
||||
fi
|
||||
|
||||
section "Memory"
|
||||
if command -v free >/dev/null 2>&1; then
|
||||
run_optional "memory report" free -h
|
||||
else
|
||||
run_optional "memory report" cat /proc/meminfo
|
||||
fi
|
||||
|
||||
section "Disks"
|
||||
if command -v lsblk >/dev/null 2>&1; then
|
||||
run_optional "block device report" lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINTS,MODEL
|
||||
else
|
||||
printf 'WARNING: lsblk is unavailable\n'
|
||||
fi
|
||||
run_optional "filesystem report" df -hT
|
||||
|
||||
section "Network"
|
||||
if command -v ip >/dev/null 2>&1; then
|
||||
run_optional "network interface report" ip -brief address
|
||||
run_optional "route report" ip route
|
||||
else
|
||||
printf 'WARNING: ip is unavailable\n'
|
||||
fi
|
||||
|
||||
section "Firmware and Secure Boot"
|
||||
if [[ -d /sys/firmware/efi ]]; then
|
||||
printf 'OK: boot mode is UEFI\n'
|
||||
else
|
||||
printf 'INFO: boot mode appears to be legacy BIOS\n'
|
||||
fi
|
||||
if command -v mokutil >/dev/null 2>&1; then
|
||||
run_optional "Secure Boot report" mokutil --sb-state
|
||||
else
|
||||
printf 'INFO: mokutil is unavailable; Secure Boot state not queried\n'
|
||||
fi
|
||||
|
||||
section "IOMMU"
|
||||
if [[ -r /proc/cmdline ]]; then
|
||||
printf 'Kernel command line:\n'
|
||||
cat /proc/cmdline
|
||||
if grep -Eq '(^|[[:space:]])(intel_iommu=on|amd_iommu=on|iommu=)' /proc/cmdline; then
|
||||
printf 'OK: IOMMU-related kernel arguments detected\n'
|
||||
else
|
||||
printf 'INFO: no explicit IOMMU kernel argument detected\n'
|
||||
fi
|
||||
fi
|
||||
if command -v dmesg >/dev/null 2>&1; then
|
||||
dmesg 2>/dev/null | grep -Ei 'DMAR|IOMMU|AMD-Vi' | tail -n 30 || \
|
||||
printf 'INFO: no readable IOMMU hints found in dmesg\n'
|
||||
fi
|
||||
|
||||
section "NVIDIA hardware"
|
||||
if command -v lspci >/dev/null 2>&1; then
|
||||
lspci -nn | grep -i nvidia || printf 'INFO: no NVIDIA PCI devices detected\n'
|
||||
else
|
||||
printf 'INFO: lspci is unavailable\n'
|
||||
fi
|
||||
|
||||
section "Existing platform components"
|
||||
for command_name in docker virsh cockpit-bridge; do
|
||||
if command -v "$command_name" >/dev/null 2>&1; then
|
||||
printf 'OK: %s is installed at %s\n' "$command_name" "$(command -v "$command_name")"
|
||||
else
|
||||
printf 'INFO: %s is not installed\n' "$command_name"
|
||||
fi
|
||||
done
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
for unit in docker.service libvirtd.service cockpit.socket; do
|
||||
if systemctl cat "$unit" >/dev/null 2>&1; then
|
||||
state="$(systemctl is-active "$unit" 2>/dev/null || true)"
|
||||
printf 'INFO: %-20s state=%s\n' "$unit" "${state:-unknown}"
|
||||
else
|
||||
printf 'INFO: %s is not installed\n' "$unit"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
printf '\nOK: preflight completed without modifying the host\n'
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=00-platform-guard.inc
|
||||
source "$SCRIPT_DIR/00-platform-guard.inc"
|
||||
|
||||
packages=(
|
||||
curl wget git vim nano tmux byobu htop btop glances
|
||||
jq unzip zip rsync tree ncdu duf
|
||||
lsof strace tcpdump nmap dnsutils net-tools iperf3 ethtool
|
||||
smartmontools nvme-cli lm-sensors pciutils usbutils hwinfo
|
||||
sysstat iotop iftop nload
|
||||
ca-certificates gnupg software-properties-common apt-transport-https
|
||||
needrestart unattended-upgrades logrotate
|
||||
)
|
||||
|
||||
if ((EUID != 0)); then
|
||||
printf 'CRITICAL: base package setup must run as root\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
require_supported_ubuntu
|
||||
if ! command -v apt-get >/dev/null 2>&1; then
|
||||
printf 'CRITICAL: apt-get is required\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
printf 'INFO: refreshing APT metadata\n'
|
||||
apt-get update
|
||||
printf 'INFO: installing baseline operational packages\n'
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}"
|
||||
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
systemctl enable --now sysstat
|
||||
else
|
||||
printf 'WARNING: systemctl is unavailable; sysstat was not enabled\n'
|
||||
fi
|
||||
|
||||
printf 'OK: baseline operational packages are installed\n'
|
||||
Executable
+60
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=00-platform-guard.inc
|
||||
source "$SCRIPT_DIR/00-platform-guard.inc"
|
||||
SOURCE_FILE="$SCRIPT_DIR/../files/bashrc.d/ailab.sh"
|
||||
PROFILE_DIR="/root/.bashrc.d"
|
||||
PROFILE_FILE="$PROFILE_DIR/ailab.sh"
|
||||
BASHRC="/root/.bashrc"
|
||||
SOURCE_LINE='[[ -f /root/.bashrc.d/ailab.sh ]] && source /root/.bashrc.d/ailab.sh'
|
||||
|
||||
backup_file() {
|
||||
local path="$1"
|
||||
local backup
|
||||
|
||||
backup="${path}.$(date '+%Y%m%d-%H%M%S').bak"
|
||||
install -m 0644 "$path" "$backup"
|
||||
printf 'INFO: backed up %s to %s\n' "$path" "$backup"
|
||||
}
|
||||
|
||||
if ((EUID != 0)); then
|
||||
printf 'CRITICAL: shell profile setup must run as root\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
require_supported_ubuntu
|
||||
if [[ ! -r "$SOURCE_FILE" ]]; then
|
||||
printf 'CRITICAL: shell profile source is missing: %s\n' "$SOURCE_FILE" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
install -d -m 0755 "$PROFILE_DIR"
|
||||
if [[ ! -f "$PROFILE_FILE" ]] || ! cmp -s "$SOURCE_FILE" "$PROFILE_FILE"; then
|
||||
if [[ -f "$PROFILE_FILE" ]]; then
|
||||
backup_file "$PROFILE_FILE"
|
||||
fi
|
||||
install -m 0644 "$SOURCE_FILE" "$PROFILE_FILE"
|
||||
printf 'OK: installed %s\n' "$PROFILE_FILE"
|
||||
else
|
||||
printf 'OK: shell profile is already current\n'
|
||||
fi
|
||||
|
||||
if [[ ! -f "$BASHRC" ]]; then
|
||||
install -m 0644 /dev/null "$BASHRC"
|
||||
fi
|
||||
|
||||
source_count="$(grep -Fxc "$SOURCE_LINE" "$BASHRC" || true)"
|
||||
if [[ "$source_count" != "1" ]]; then
|
||||
tmp_bashrc="$(mktemp)"
|
||||
trap 'rm -f "$tmp_bashrc"' EXIT
|
||||
grep -Fvx "$SOURCE_LINE" "$BASHRC" >"$tmp_bashrc" || true
|
||||
printf '\n%s\n' "$SOURCE_LINE" >>"$tmp_bashrc"
|
||||
backup_file "$BASHRC"
|
||||
install -m 0644 "$tmp_bashrc" "$BASHRC"
|
||||
printf 'OK: configured %s to source the AI lab profile exactly once\n' "$BASHRC"
|
||||
else
|
||||
printf 'OK: %s already sources the AI lab profile exactly once\n' "$BASHRC"
|
||||
fi
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=00-platform-guard.inc
|
||||
source "$SCRIPT_DIR/00-platform-guard.inc"
|
||||
|
||||
required_packages=(
|
||||
cockpit cockpit-system cockpit-storaged cockpit-networkmanager
|
||||
cockpit-packagekit cockpit-machines cockpit-sosreport cockpit-pcp
|
||||
)
|
||||
|
||||
if ((EUID != 0)); then
|
||||
printf 'CRITICAL: Cockpit setup must run as root\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
require_supported_ubuntu
|
||||
if ! command -v apt-get >/dev/null 2>&1; then
|
||||
printf 'CRITICAL: apt-get is required\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y "${required_packages[@]}"
|
||||
|
||||
if apt-cache show cockpit-files >/dev/null 2>&1; then
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y cockpit-files
|
||||
printf 'OK: installed optional cockpit-files package\n'
|
||||
else
|
||||
printf 'WARNING: cockpit-files is unavailable; continuing without it\n'
|
||||
fi
|
||||
|
||||
systemctl enable --now cockpit.socket
|
||||
printf 'OK: Cockpit is enabled at https://%s:9090\n' "$(hostname)"
|
||||
Executable
+136
@@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=00-platform-guard.inc
|
||||
source "$SCRIPT_DIR/00-platform-guard.inc"
|
||||
SOURCE_CONFIG="$SCRIPT_DIR/../files/docker/daemon.json"
|
||||
DOCKER_CONFIG="/etc/docker/daemon.json"
|
||||
temporary_files=()
|
||||
|
||||
cleanup() {
|
||||
local path
|
||||
|
||||
for path in "${temporary_files[@]}"; do
|
||||
rm -f "$path"
|
||||
done
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
backup_file() {
|
||||
local path="$1"
|
||||
local backup
|
||||
|
||||
backup="${path}.$(date '+%Y%m%d-%H%M%S').bak"
|
||||
install -m 0644 "$path" "$backup"
|
||||
printf 'INFO: backed up %s to %s\n' "$path" "$backup"
|
||||
}
|
||||
|
||||
if ((EUID != 0)); then
|
||||
printf 'CRITICAL: Docker setup must run as root\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
require_supported_ubuntu
|
||||
for command_name in apt-get apt-cache; do
|
||||
if ! command -v "$command_name" >/dev/null 2>&1; then
|
||||
printf 'CRITICAL: required command is missing: %s\n' "$command_name" >&2
|
||||
exit 2
|
||||
fi
|
||||
done
|
||||
|
||||
apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates curl gnupg jq
|
||||
|
||||
if apt-cache show docker.io >/dev/null 2>&1; then
|
||||
packages=(docker.io)
|
||||
if apt-cache show docker-compose-v2 >/dev/null 2>&1; then
|
||||
packages+=(docker-compose-v2)
|
||||
else
|
||||
printf 'WARNING: docker-compose-v2 is unavailable from Ubuntu repositories\n'
|
||||
fi
|
||||
else
|
||||
printf 'WARNING: docker.io is unavailable; configuring Docker official repository\n'
|
||||
install -d -m 0755 /etc/apt/keyrings
|
||||
tmp_key="$(mktemp)"
|
||||
temporary_files+=("$tmp_key")
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
|
||||
| gpg --dearmor --yes -o "$tmp_key"
|
||||
if [[ ! -f /etc/apt/keyrings/docker.gpg ]] || \
|
||||
! cmp -s "$tmp_key" /etc/apt/keyrings/docker.gpg; then
|
||||
if [[ -f /etc/apt/keyrings/docker.gpg ]]; then
|
||||
backup_file /etc/apt/keyrings/docker.gpg
|
||||
fi
|
||||
install -m 0644 "$tmp_key" /etc/apt/keyrings/docker.gpg
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
source /etc/os-release
|
||||
architecture="$(dpkg --print-architecture)"
|
||||
tmp_repository="$(mktemp)"
|
||||
temporary_files+=("$tmp_repository")
|
||||
printf 'deb [arch=%s signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu %s stable\n' \
|
||||
"$architecture" "${VERSION_CODENAME:?}" \
|
||||
>"$tmp_repository"
|
||||
if [[ ! -f /etc/apt/sources.list.d/docker.list ]] || \
|
||||
! cmp -s "$tmp_repository" /etc/apt/sources.list.d/docker.list; then
|
||||
if [[ -f /etc/apt/sources.list.d/docker.list ]]; then
|
||||
backup_file /etc/apt/sources.list.d/docker.list
|
||||
fi
|
||||
install -m 0644 "$tmp_repository" /etc/apt/sources.list.d/docker.list
|
||||
fi
|
||||
apt-get update
|
||||
packages=(docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin)
|
||||
fi
|
||||
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}"
|
||||
install -d -m 0755 /etc/docker
|
||||
|
||||
if [[ ! -r "$SOURCE_CONFIG" ]]; then
|
||||
printf 'CRITICAL: Docker configuration template is missing: %s\n' "$SOURCE_CONFIG" >&2
|
||||
exit 2
|
||||
fi
|
||||
jq empty "$SOURCE_CONFIG"
|
||||
|
||||
tmp_config="$(mktemp)"
|
||||
temporary_files+=("$tmp_config")
|
||||
if [[ -f "$DOCKER_CONFIG" ]]; then
|
||||
if ! jq empty "$DOCKER_CONFIG" >/dev/null 2>&1; then
|
||||
printf 'CRITICAL: %s is invalid JSON; refusing to overwrite it\n' "$DOCKER_CONFIG" >&2
|
||||
exit 1
|
||||
fi
|
||||
jq '. + {
|
||||
"log-driver": "json-file",
|
||||
"log-opts": ((."log-opts" // {}) + {"max-size": "50m", "max-file": "5"})
|
||||
}' "$DOCKER_CONFIG" >"$tmp_config"
|
||||
else
|
||||
install -m 0644 "$SOURCE_CONFIG" "$tmp_config"
|
||||
fi
|
||||
jq empty "$tmp_config"
|
||||
|
||||
config_changed=0
|
||||
if [[ ! -f "$DOCKER_CONFIG" ]] || ! cmp -s "$tmp_config" "$DOCKER_CONFIG"; then
|
||||
if [[ -f "$DOCKER_CONFIG" ]]; then
|
||||
backup_file "$DOCKER_CONFIG"
|
||||
fi
|
||||
install -m 0644 "$tmp_config" "$DOCKER_CONFIG"
|
||||
config_changed=1
|
||||
printf 'OK: installed Docker daemon log limits\n'
|
||||
else
|
||||
printf 'OK: Docker daemon configuration is already current\n'
|
||||
fi
|
||||
|
||||
systemctl enable --now docker
|
||||
if ((config_changed == 1)); then
|
||||
systemctl restart docker
|
||||
fi
|
||||
|
||||
docker version
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
docker compose version
|
||||
else
|
||||
printf 'WARNING: Docker Compose v2 is unavailable\n'
|
||||
fi
|
||||
printf 'OK: Docker setup completed\n'
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=00-platform-guard.inc
|
||||
source "$SCRIPT_DIR/00-platform-guard.inc"
|
||||
|
||||
packages=(
|
||||
qemu-system-x86 qemu-utils libvirt-daemon-system libvirt-clients
|
||||
virtinst virt-manager bridge-utils ovmf swtpm swtpm-tools dnsmasq-base
|
||||
)
|
||||
|
||||
if ((EUID != 0)); then
|
||||
printf 'CRITICAL: libvirt setup must run as root\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
require_supported_ubuntu
|
||||
if ! command -v apt-get >/dev/null 2>&1; then
|
||||
printf 'CRITICAL: apt-get is required\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}"
|
||||
systemctl enable --now libvirtd
|
||||
|
||||
printf '\n== Virtual machines ==\n'
|
||||
virsh list --all || printf 'WARNING: unable to list virtual machines\n'
|
||||
printf '\n== Virtual networks ==\n'
|
||||
virsh net-list --all || printf 'WARNING: unable to list virtual networks\n'
|
||||
printf 'OK: libvirt/KVM setup completed\n'
|
||||
Executable
+88
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=00-platform-guard.inc
|
||||
source "$SCRIPT_DIR/00-platform-guard.inc"
|
||||
|
||||
driver_version=""
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: sudo ./06-nvidia-tools.sh [--install-driver VERSION]
|
||||
|
||||
Without --install-driver, only non-driver diagnostic tools are installed.
|
||||
EOF
|
||||
}
|
||||
|
||||
while (($# > 0)); do
|
||||
case "$1" in
|
||||
--install-driver)
|
||||
if (($# < 2)); then
|
||||
printf 'CRITICAL: --install-driver requires a VERSION\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
driver_version="$2"
|
||||
if [[ ! "$driver_version" =~ ^[0-9]+$ ]]; then
|
||||
printf 'CRITICAL: NVIDIA driver VERSION must contain digits only\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
printf 'CRITICAL: unknown option: %s\n' "$1" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if ((EUID != 0)); then
|
||||
printf 'CRITICAL: NVIDIA tooling setup must run as root\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
require_supported_ubuntu
|
||||
if ! command -v apt-get >/dev/null 2>&1; then
|
||||
printf 'CRITICAL: apt-get is required\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y nvtop clinfo pciutils
|
||||
|
||||
printf '\n== NVIDIA PCI devices ==\n'
|
||||
lspci -nn | grep -i nvidia || printf 'INFO: no NVIDIA PCI devices detected\n'
|
||||
|
||||
printf '\n== NVIDIA runtime ==\n'
|
||||
if command -v nvidia-smi >/dev/null 2>&1; then
|
||||
nvidia-smi || printf 'WARNING: nvidia-smi returned an error\n'
|
||||
else
|
||||
printf 'INFO: nvidia-smi is not installed\n'
|
||||
fi
|
||||
|
||||
printf '\n== DKMS ==\n'
|
||||
if command -v dkms >/dev/null 2>&1; then
|
||||
dkms status || printf 'WARNING: dkms status returned an error\n'
|
||||
else
|
||||
printf 'INFO: dkms is not installed\n'
|
||||
fi
|
||||
|
||||
if [[ -n "$driver_version" ]]; then
|
||||
driver_package="nvidia-driver-$driver_version"
|
||||
if ! apt-cache show "$driver_package" >/dev/null 2>&1; then
|
||||
printf 'CRITICAL: requested NVIDIA driver package is unavailable: %s\n' \
|
||||
"$driver_package" >&2
|
||||
exit 1
|
||||
fi
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y "$driver_package"
|
||||
printf 'WARNING: NVIDIA driver %s was installed; reboot before validation\n' \
|
||||
"$driver_version"
|
||||
else
|
||||
printf 'OK: NVIDIA diagnostic tools installed; no driver was installed\n'
|
||||
fi
|
||||
Executable
+67
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=00-platform-guard.inc
|
||||
source "$SCRIPT_DIR/00-platform-guard.inc"
|
||||
JOURNAL_SOURCE="$SCRIPT_DIR/../files/systemd/journald-ailab-limits.conf"
|
||||
JOURNAL_DEST="/etc/systemd/journald.conf.d/ailab-limits.conf"
|
||||
SYSCTL_SOURCE="$SCRIPT_DIR/../files/sysctl/99-ailab.conf"
|
||||
SYSCTL_DEST="/etc/sysctl.d/99-ailab.conf"
|
||||
|
||||
install_config() {
|
||||
local source_path="$1"
|
||||
local destination_path="$2"
|
||||
local mode="$3"
|
||||
local backup
|
||||
|
||||
install -d -m 0755 "$(dirname "$destination_path")"
|
||||
if [[ -f "$destination_path" ]] && cmp -s "$source_path" "$destination_path"; then
|
||||
printf 'OK: %s is already current\n' "$destination_path"
|
||||
return 0
|
||||
fi
|
||||
if [[ -f "$destination_path" ]]; then
|
||||
backup="${destination_path}.$(date '+%Y%m%d-%H%M%S').bak"
|
||||
install -m "$mode" "$destination_path" "$backup"
|
||||
printf 'INFO: backed up %s to %s\n' "$destination_path" "$backup"
|
||||
fi
|
||||
install -m "$mode" "$source_path" "$destination_path"
|
||||
printf 'OK: installed %s\n' "$destination_path"
|
||||
}
|
||||
|
||||
if ((EUID != 0)); then
|
||||
printf 'CRITICAL: tuning setup must run as root\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
require_supported_ubuntu
|
||||
for source_path in "$JOURNAL_SOURCE" "$SYSCTL_SOURCE"; do
|
||||
if [[ ! -r "$source_path" ]]; then
|
||||
printf 'CRITICAL: required configuration is missing: %s\n' "$source_path" >&2
|
||||
exit 2
|
||||
fi
|
||||
done
|
||||
|
||||
if ! command -v sysctl >/dev/null 2>&1 || ! command -v systemctl >/dev/null 2>&1; then
|
||||
printf 'CRITICAL: sysctl and systemctl are required\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if ! command -v sensors-detect >/dev/null 2>&1 || \
|
||||
! systemctl cat sysstat.service >/dev/null 2>&1; then
|
||||
apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y lm-sensors sysstat
|
||||
fi
|
||||
|
||||
install_config "$JOURNAL_SOURCE" "$JOURNAL_DEST" 0644
|
||||
install_config "$SYSCTL_SOURCE" "$SYSCTL_DEST" 0644
|
||||
|
||||
sysctl --system
|
||||
systemctl restart systemd-journald
|
||||
systemctl enable --now sysstat
|
||||
|
||||
if command -v sensors-detect >/dev/null 2>&1; then
|
||||
sensors-detect --auto || printf 'WARNING: sensors-detect did not complete successfully\n'
|
||||
fi
|
||||
printf 'OK: host tuning completed\n'
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=00-platform-guard.inc
|
||||
source "$SCRIPT_DIR/00-platform-guard.inc"
|
||||
|
||||
enable_ufw=0
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: sudo ./08-security-baseline.sh [--enable-ufw]
|
||||
|
||||
Installs fail2ban and UFW. UFW is enabled only with the explicit flag.
|
||||
EOF
|
||||
}
|
||||
|
||||
while (($# > 0)); do
|
||||
case "$1" in
|
||||
--enable-ufw)
|
||||
enable_ufw=1
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
printf 'CRITICAL: unknown option: %s\n' "$1" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if ((EUID != 0)); then
|
||||
printf 'CRITICAL: security baseline setup must run as root\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
require_supported_ubuntu
|
||||
if ! command -v apt-get >/dev/null 2>&1; then
|
||||
printf 'CRITICAL: apt-get is required\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y fail2ban ufw
|
||||
systemctl enable --now fail2ban
|
||||
|
||||
if ((enable_ufw == 1)); then
|
||||
printf 'WARNING: UFW was explicitly requested; SSH and Cockpit rules will be added before enablement\n'
|
||||
ufw allow OpenSSH
|
||||
ufw allow 9090/tcp comment 'Cockpit'
|
||||
ufw --force enable
|
||||
else
|
||||
printf 'WARNING: UFW is installed but was not enabled; use --enable-ufw after reviewing access requirements\n'
|
||||
fi
|
||||
|
||||
ufw status verbose || printf 'WARNING: unable to read UFW status\n'
|
||||
printf 'OK: security baseline completed\n'
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
section() {
|
||||
printf '\n== %s ==\n' "$1"
|
||||
}
|
||||
|
||||
run_optional() {
|
||||
local description="$1"
|
||||
shift
|
||||
|
||||
if "$@"; then
|
||||
return 0
|
||||
fi
|
||||
printf 'WARNING: %s failed\n' "$description"
|
||||
return 0
|
||||
}
|
||||
|
||||
section "Failed systemd units"
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
run_optional "failed systemd unit report" systemctl --failed --no-pager
|
||||
|
||||
section "Selected service status"
|
||||
for unit in cockpit.socket docker.service libvirtd.service fail2ban.service; do
|
||||
if systemctl cat "$unit" >/dev/null 2>&1; then
|
||||
run_optional "$unit status" systemctl status "$unit" --no-pager
|
||||
else
|
||||
printf 'INFO: %s is not installed\n' "$unit"
|
||||
fi
|
||||
done
|
||||
else
|
||||
printf 'WARNING: systemctl is unavailable\n'
|
||||
fi
|
||||
|
||||
section "Docker"
|
||||
if command -v docker >/dev/null 2>&1; then
|
||||
run_optional "Docker container list" docker ps
|
||||
else
|
||||
printf 'INFO: Docker is not installed\n'
|
||||
fi
|
||||
|
||||
section "Libvirt"
|
||||
if command -v virsh >/dev/null 2>&1; then
|
||||
run_optional "libvirt guest list" virsh list --all
|
||||
else
|
||||
printf 'INFO: virsh is not installed\n'
|
||||
fi
|
||||
|
||||
section "NVIDIA"
|
||||
if command -v nvidia-smi >/dev/null 2>&1; then
|
||||
run_optional "NVIDIA status" nvidia-smi
|
||||
else
|
||||
printf 'INFO: nvidia-smi is not installed\n'
|
||||
fi
|
||||
|
||||
section "Filesystems"
|
||||
run_optional "filesystem report" df -hT
|
||||
|
||||
section "Listening ports"
|
||||
if command -v ss >/dev/null 2>&1; then
|
||||
run_optional "listening port report" ss -tulpn
|
||||
else
|
||||
printf 'WARNING: ss is unavailable\n'
|
||||
fi
|
||||
|
||||
printf '\nOK: postcheck completed; review warnings above\n'
|
||||
exit 0
|
||||
Reference in New Issue
Block a user