- Shell 96.6%
- PowerShell 3.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .scripts | ||
| installer | ||
| tests | ||
| .editorconfig | ||
| .gitattributes | ||
| .gitignore | ||
| AGENTS.md | ||
| CHANGELOG.md | ||
| checksums.sha256 | ||
| cspell.json | ||
| kInit.sh | ||
| kInit.vars | ||
| LICENSE | ||
| README.md | ||
| uninstall.sh | ||
kInit - Automated System Setup & Configuration
kInit is a modular, opinionated, and extensible Bash-based installer for quickly setting up and configuring Debian/Ubuntu servers. It automates system hardening, package installation, monitoring, and maintenance tasks, with a focus on best practices and maintainability.
Warning: Read Before Executing
Never execute random scripts from the internet without reading them first. This installer downloads and executes code on your system. Always review the scripts and understand what they do before running. Visit the repository to inspect the code before using this installer.
Security Notice
This installer enables key-based root SSH login (
PermitRootLogin prohibit-password— password root login stays disabled) and, when it installs a key, disables password authentication entirely (PasswordAuthentication no, override withSSH_PASSWORD_AUTH="yes"). It modifies authentication settings; ensure you understand the security implications before use, especially on public-facing servers. The root-login policy is configurable viaSSH_PERMIT_ROOT_LOGIN(e.g.nofor the CIS-recommended posture).
Table of Contents
- Quick Start
- Requirements
- Security
- Architecture
- What Gets Installed
- What Settings Are Changed
- Customization
- Development
- Breaking Changes
- Uninstallation
- Disclaimer
- License
- Feedback
Quick Start
Recommended: Two-Step Download (Safer)
Download and review before executing:
# Step 1: Download the installer
wget https://kleb.sh/kInit.sh
# Step 2: Review the script
less kInit.sh
# Step 3: Run as root
bash kInit.sh
One-Liner (Use with Caution)
For quick deployments, you can use piped execution (less safe - script not reviewed):
bash <(wget -qO- https://kleb.sh/kInit.sh)
or
bash <(curl -fsSL https://kleb.sh/kInit.sh)
The one-liner trusts the downloaded kInit.sh completely. Embedded checksums only protect the files that kInit.sh downloads after it starts; they cannot prove the first script was authentic. For production, prefer the two-step download, review, and run flow above, or pin the installer hash through your deployment tooling.
Remote Setup Profile Bootstrap
If you are consuming a setup profile published from kUtils, point kInit at the generated bootstrap URL:
bash kInit.sh --setup-profile-url https://example.com/setup/alice/base/bootstrap.sh
You can also provide the decrypt passphrase up front:
KINIT_SETUP_PASSPHRASE='correct horse battery staple' \
bash kInit.sh --setup-profile-url https://example.com/setup/alice/base
Requirements
- Supported OS: Debian 11/12, Ubuntu 20.04/22.04/24.04 (
x86_64,amd64) - Privileges: Must be run as
root - Network: Internet access required for package downloads
Security
What We Do to Keep You Safe
Bootstrap Validation
- kInit validates
utils.shusing an embedded SHA256 checksum before executing - This protects the second-stage helper download after a trusted
kInit.shhas started - Validation is performed automatically — no action is needed from you
Checksum Verification
- Files downloaded through the standard module flow are verified against the pinned SHA256 manifest
- Corrupted or tampered files are rejected with clear error messages
- Checksums are regenerated during development using
.scripts/unix/checksum.sh - Exception: a
--setup-profile-urlbootstrap is not in the manifest. It must usehttps://and must be pinned viaKINIT_SETUP_BOOTSTRAP_SHA256; without a pin it refuses to run unless you explicitly setKINIT_SETUP_BOOTSTRAP_ALLOW_UNVERIFIED=1
Signature Verification (optional)
- Hash pinning proves a file matches
kInit.sh, but not thatkInit.shand its embedded hashes are authentic. A detached minisign signature overchecksums.sha256, made with a key held off-repo, closes that gap. - To enable: generate a keypair (
minisign -G -p kinit.pub -s kinit.key), paste the public key intoKINIT_MINISIGN_PUBKEYinkInit.sh, and sign each release with.scripts/unix/checksum.sh --sign(publishingchecksums.sha256.minisigalongside the manifest). - When
KINIT_MINISIGN_PUBKEYis empty (the default) signature verification is skipped; when set, kInit fails closed if the signature is missing or invalid.
Input Validation
- All user inputs (hostnames, ports, SSH keys, timezones) are validated
- Dangerous characters and injection attempts are rejected
- SSH keys are validated for format and strength
- Cron jobs are validated to prevent command injection
Secure Temporary Files
- Temporary files are created with restrictive permissions (chmod 700)
- Cron operations use secure temporary directories
- Debug logs are created with permission mode 600 (readable only by owner)
Command Injection Prevention
- Internal command wrappers execute commands as argv arrays instead of parsing command strings through a shell
- User inputs that reach configuration files, cron entries, or service commands are validated before use
What You Should Do
Before Running
- Download the script first:
wget https://kleb.sh/kInit.sh - Review the code carefully before execution
- Run on a test system or fresh VM first
- Never use the one-liner pipe method on production systems
Protecting Credentials
- SSH keys and other credentials should be protected with restrictive file permissions
- Use local configuration files (
.vars.local) for sensitive settings - these are git-ignored - Never commit passwords, API keys, or private keys to the repository
- Debug logs may contain sensitive data — use
shred -uto securely delete them
Checksum Bypass (Development Only)
- Use
KINIT_SKIP_CHECKSUMS=1to skip validation during development - Requires interactive confirmation by typing "I UNDERSTAND THE RISKS"
- Never use in production - checksums are critical for security
Reporting Security Issues
If you discover a security vulnerability, please report it responsibly:
- Do NOT open a public GitHub issue
- Contact the maintainers directly
- Allow time for a fix before public disclosure
Architecture
Entry Point & Execution Flow
-
kInit.sh - Main entry point that orchestrates the installation
- Downloads
utils.sh(shared utilities) andkInit.vars(module toggle config) - Executes enabled modules in order: System → Utilities → Software → Miscellaneous
- Each module is downloaded, checksum-validated, and executed as a child script
- Can optionally execute a remote
kUtilssetup profile bootstrap instead of the default module flow
- Downloads
-
installer/utils.sh - Shared utility library sourced by all modules
- Progress/logging functions (
logInfo,logError,updateProgress,runWithSpinner) - Download with retry and checksum validation
- Package installation utilities
- File operations and service management
- Cron and shell configuration helpers
- Progress/logging functions (
Module Structure
Each module follows a consistent pattern:
- installer/<module>/<module>.sh - Main script with lifecycle functions
- installer/<module>/<module>.vars - Configuration variables
- installer/<module>/files/ - Additional files (scripts, configs) deployed by the module
Available Modules:
- system - Locale, timezone, SSH keys, virtualization detection, MOTD, Fish shell setup
- utilities - Maintenance scripts (update.sh, clean.sh) and cron jobs
- software - Zabbix Agent installation and monitoring addons
- miscellaneous - Post-install tasks (runs update/clean scripts, reboot check)
What Gets Installed (Default Configuration)
The current configuration will install and configure the following components:
1. System Essentials
- Packages installed:
bc,curl,ethtool,fish,gnupg,btop,inotify-tools,lsb-release,moreutils,net-tools,nfs-common,sudo,unzip,wget,zip,cron,wtmpdb,bat,jq - Locale: Set to
en_US.UTF-8 - Timezone: Set to
Europe/Berlin - SSH Keys: Installs datacenter-specific public SSH keys for root login, selected based on IP range detection
- SSH Configuration: Enables MOTD and disables PrintLastLog in SSH
- MOTD: Installs custom Message of the Day script, refreshed every 15 minutes via cron
- Virtualization: Detects and installs guest agents for KVM/Proxmox, VMware, and LXC as needed
- Shell: Installs and configures Fish shell with optional theme and custom aliases
2. Utilities
Two maintenance scripts are installed to $HOME and scheduled to run daily:
update.sh - System package updates
Refreshes the package lists, then upgrades all installed packages (pulling in new dependencies such as a new kernel) with appropriate dpkg options to avoid configuration conflicts. It does not remove packages — it is a plain upgrade, not a full-upgrade/dist-upgrade:
apt-get updateapt-get upgrade --with-new-pkgs
clean.sh - System cleanup
Performs regular maintenance:
- Rotates and vacuums systemd journal
- Runs
apt autoremoveandapt clean - Prunes Docker images (if Docker is installed)
- Cron: Both scripts are scheduled to run
@dailywithMAILTOconfigured (empty by default) - Cleanup controls:
CLEAN_VACUUM_JOURNAL,CLEAN_JOURNAL_VACUUM_TIME, andCLEAN_DOCKER_PRUNEare written to/etc/default/kinit-cleanso cleanup behavior can be adjusted without editing the installed script.
3. Monitoring
- Zabbix Agent 2 (default): Installed for system monitoring. Zabbix Agent 1 can be enabled via
software.varsif required. The bundled per-distrozabbix.debfiles are the small Zabbix repository-configuration package (zabbix-release, currently 7.4), not the agent itself; the agent binary is then installed from the official Zabbix apt repo (with apt's normal key verification). Refresh the bundled packages with.scripts/unix/download/zabbix.sh. - APT Monitoring: Includes Zabbix APT addon, scheduled to run every 5 minutes
- LXC Monitoring (Agent 1 only, optional): The Zabbix LXC addon can be enabled and is installed when running in an LXC container.
- Auto-detection: Zabbix server/proxy and hostname are automatically detected based on IP range, with configurable prefixes and suffixes
4. Miscellaneous
- Runs update and clean scripts once after installation
- Checks if system reboot is required and logs a notification
What Settings Are Changed
System Configuration
| Setting | Configuration |
|---|---|
| Locale | en_US.UTF-8 in /etc/locale.gen and via update-locale |
| Timezone | Europe/Berlin in /etc/localtime and /etc/timezone |
SSH Configuration
- Enables datacenter-specific public keys for root (IP range-based selection); a host whose IP matches no
SSH_IP_RANGESentry installs no key unlessSSH_KEY_DEFAULT_DCis set - Sets
PermitRootLogintoprohibit-password(root login by SSH key only; password root login stays disabled), configurable viaSSH_PERMIT_ROOT_LOGIN(setnofor the CIS-recommended posture, using a separate sudo user instead) - When a key is installed, disables password authentication (
PasswordAuthentication no+KbdInteractiveAuthentication no) so the installed key is the access path and no brute-force surface is left open; override withSSH_PASSWORD_AUTH="yes". This is only applied on hosts where a key was installed, so a host matching noSSH_IP_RANGESentry is never locked out - Sets
LoginGraceTimeto60(override viaSSH_LOGIN_GRACE_TIME) to shrink the pre-auth window - Configures
AuthorizedKeysFile(.ssh/authorized_keys) for key-based authentication - Applies these via
/etc/ssh/sshd_config.d/00-kinit.confwhen the host supports drop-ins (remove that file to revert), else edits/etc/ssh/sshd_configin place after backing it up, and validates withsshd -tbefore reloading - Enables
PrintMotd, disablesPrintLastLog - Comments out
pam_mail.soin/etc/pam.d/sshd - Restarts SSH service with changes
Services and Cron
- MOTD: Replaces
/etc/update-motd.d/*with custom script and cron refresh job - Crontab: Adds jobs for update, clean, and MOTD refresh with
MAILTOconfiguration - Zabbix: Installs and configures Zabbix Agent 2, APT monitoring, and LXC monitoring as per environment
- Idempotency: Cron jobs, Fish aliases, and file-based settings are only added if missing, so rerunning the installer does not duplicate entries.
Shell Configuration
Fish shell is configured with the following features (if enabled in system.vars):
- Set as default shell for root
- Fisher package manager installed
- Catppuccin Mocha theme applied
- Custom aliases:
bat→batcat(requires batcat package)pc→netstat -tupln(displays listening ports)
- Aliases stored in
~/.config/fish/conf.d/aliases.fish
Customization
Editing Settings
Each module has a .vars configuration file:
system.vars- System module configurationutilities.vars- Utilities module configurationsoftware.vars- Software/monitoring configurationmiscellaneous.vars- Miscellaneous module configurationchecksums.sha256- File integrity checksums
To customize the installer:
-
Download the relevant
.varsfile:wget https://kleb.sh/installer/system/system.vars -
Edit the variables to your needs
-
Run the installer with your custom configuration:
bash <(wget -qO- https://kleb.sh/kInit.sh) --base-url https://yourdomain
Available URL options:
--system-url- Custom system configuration--utilities-url- Custom utilities configuration--local-files- Resolve bundled module assets fromBASE_URLinstead ofhttps://kleb.sh--software-url- Custom software configuration--miscellaneous-url- Custom miscellaneous configuration--checksum-url- Custom checksum file URL used for download verification--checksum-sha256- Expected SHA256 for a custom integrity manifest URL
Additional CLI flags:
--continue-on-error- Continue execution even if a module download or script fails--analyze- Print configuration and module results before cleanup (CI/CD mode)--setup-profile-url- Execute a remote setup profile bootstrap URL instead of the default module flow (must behttps://)--setup-passphrase- Provide the passphrase for a remote setup profile (prefer theKINIT_SETUP_PASSPHRASEenv var; a value passed here is visible in process listings)--log-view <auto|tty|off>- Live log view mode (default: auto)--log-tty <number>- Virtual terminal for the live log view (default: 2)--help- Show the built-in usage/help text
Recommendation: For advanced customizations, fork this repository and maintain your own installer scripts and variable files for easier long-term management. Sanitized starting points are provided as
installer/system/system.vars.exampleandinstaller/software/software.vars.example— copy them to the corresponding.varsand replace the placeholders with your own keys, IP ranges, and Zabbix server. Never commit real SSH keys or internal addresses to a public fork.
Cleanup Configuration
The Utilities module installs /root/clean.sh and writes /etc/default/kinit-clean from utilities.vars:
CLEAN_VACUUM_JOURNAL="TRUE"- rotate and vacuum systemd journal logs during cleanupCLEAN_JOURNAL_VACUUM_TIME="7d"- journal retention passed tojournalctl --vacuum-time(set lower only if you deliberately want shorter retention;1serases almost the entire journal)CLEAN_DOCKER_PRUNE="TRUE"- prune Docker images older than 24 hours when Docker is installed (dangling/untagged layers only by default)CLEAN_DOCKER_PRUNE_ALL="FALSE"- set toTRUEto also remove all unused tagged images older than 24h (docker image prune -a); leaveFALSEto preserve the image cache
Remote Setup Profiles
kInit can execute a remote setup profile bootstrap generated by kUtils.
--setup-profile-url/-sppoints to the published bootstrap URL or its parent setup profile URL--setup-passphrase/-spppre-seeds the decryption passphrase for non-interactive useKINIT_SETUP_PROFILE_URLprovides the same URL through the environmentKINIT_SETUP_PASSPHRASEandKUTILS_SETUP_PASSPHRASEare both honored for generated bootstraps
When a setup profile URL is provided, kInit downloads the remote bootstrap into a secure temporary directory, executes it, and skips the default kInit.vars module-download flow for that run.
Disabling/Enabling Modules
Edit kInit.vars to enable or disable specific installation modules:
SYSTEM_EXECUTE="TRUE"or"FALSE"- System configurationUTILITIES_EXECUTE="TRUE"or"FALSE"- Maintenance utilitiesSOFTWARE_EXECUTE="TRUE"or"FALSE"- Zabbix monitoringMISCELLANEOUS_EXECUTE="TRUE"or"FALSE"- Post-install tasks
Fish Shell Configuration
Customize Fish shell behavior by editing system.vars:
FISH_DEFAULT_SHELL="TRUE"- Set Fish as default shellFISH_INSTALL_FISHER="TRUE"- Install Fisher package managerFISHER_SHA256="<sha256>"- Required when Fisher installation is enabledFISH_INSTALL_CATPPUCCIN="TRUE"- Apply Catppuccin Mocha themeFISH_ALIAS_BAT="TRUE"- Enablebat→batcataliasFISH_ALIAS_PC="TRUE"- Enablepc→netstat -tuplnalias
Breaking Changes
Version 3.3+
Removed Features
--skip-checksumsCLI flag has been removed for security reasons- Use environment variable instead:
KINIT_SKIP_CHECKSUMS=1
Changed Behavior
- Checksum bypass now requires interactive confirmation
- Users must type "I UNDERSTAND THE RISKS" to skip validation
- Bootstrap validation is enabled by default (validates utils.sh before sourcing)
- All inputs are now validated (hostnames, ports, SSH keys, etc.)
Migration Guide
If you're using the old --skip-checksums flag:
# OLD (no longer works)
bash kInit.sh --skip-checksums
# NEW (requires confirmation)
KINIT_SKIP_CHECKSUMS=1 bash kInit.sh
# Then type: I UNDERSTAND THE RISKS
New environment variables:
KINIT_SKIP_CHECKSUMS=1- Skip checksum validation (requires confirmation)KINIT_SKIP_BOOTSTRAP_VALIDATION=1- Skip utils.sh validation (development only)KINIT_SETUP_PROFILE_URL=<url>- Remote setup profile bootstrap or setup URLKINIT_SETUP_PASSPHRASE=<value>- Remote setup-profile passphraseKUTILS_SETUP_PASSPHRASE=<value>- Alternate passphrase variable for generatedkUtilssetup bootstrapsAUTO_DELETE_DEBUG_LOG=TRUE- Auto-delete debug logs after execution
Development
Line Ending Conversion
Before committing changes, ensure Unix line endings for all shell scripts:
bash .scripts/unix/unix-format.sh
Generating Checksums
After modifying any files under installer/, regenerate the integrity manifest:
cd .scripts/unix
bash checksum.sh
Running Tests
Unit tests for the validation helpers (SSH keys, cron lines, hostnames, ports,
timezones, secret redaction) live in tests/ and run with
bats-core:
bats tests/
Run these together with ShellCheck and sha256sum -c checksums.sha256 before
committing changes.
Local Testing
Test the installer locally by serving the repository and pointing both module scripts and bundled assets at that local server:
python3 -m http.server 8000
bash kInit.sh --base-url "http://localhost:8000" --local-files --checksum-sha256 "<sha256_of_local_checksums.sha256>"
Uninstallation / Restoration
This installer makes system-level changes. A best-effort uninstall.sh is provided:
sudo bash uninstall.sh
It restores the config backups kInit creates (*.kinit-bak-*), removes the
/etc/ssh/sshd_config.d/00-kinit.conf drop-in, deletes kInit-installed files and
cron jobs, and reloads SSH only if the config still validates. It deliberately
does not remove installed packages or SSH authorized keys.
To finish reverting manually:
- Review/remove keys in
~/.ssh/authorized_keysif desired - Remove installed packages using
apt removeorapt purge(e.g.zabbix-agent2,fish) - Delete the leftover
*.kinit-bak-*backups once satisfied
Recommendation: Take a snapshot or create a backup before running the installer on production systems.
Disclaimer
This project is provided "as is" without any warranties or guarantees, express or implied.
Risk Acknowledgment:
- Use this software at your own risk
- The authors and contributors are not responsible for damage, data loss, or issues arising from use
- Review all code and configuration before use, especially in production
- No support or maintenance is guaranteed
- Features may change or be removed without notice
- By using this project, you accept full responsibility for consequences
Always back up your data and thoroughly test in a safe environment before deploying to production.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Feedback
Questions, suggestions, or issues?
- Open an issue in the repository
- Email: feedback@kleb.dev