# Lightweight Ubuntu Server Setup **English** | [Русский](docs/readme/README.ru.md) | [Español](docs/readme/README.es.md) | [Deutsch](docs/readme/README.de.md) | [Français](docs/readme/README.fr.md) | [Português](docs/readme/README.pt.md) | [中文](docs/readme/README.zh-CN.md) | [日本語](docs/readme/README.ja.md) | [العربية](docs/readme/README.ar.md) | [हिन्दी](docs/readme/README.hi.md) A modular set of Bash installers for the initial setup, security hardening, administration, VPN, web panel, WARP, and backups on Ubuntu Server. Run the unified wizard for a guided installation or execute only the modules you need. > **Manage multiple servers:** use the companion [Server Monitor Manager](https://github.com/ochenstarik-ui/server-monitor-manager) project to add servers, collect reports, and manage several hosts from one application. It is currently in early development and should not yet be treated as production-ready. ## Quick installation Obtain an approved full commit SHA and the archive SHA-256 through a trusted release/review channel. The digest is specific to the selected source: Forgejo and GitHub archives can differ. Do not use a branch name or obtain the expected digest from the downloaded archive itself. Until a reviewed release publishes these values, this procedure requires the operator to supply them. The complete block verifies the archive before starting the wizard. Forgejo is the default; GitHub is optional: ```bash set -e cd "$HOME" sudo apt-get update sudo apt-get install -y curl ca-certificates tar read -rp 'Reviewed full commit SHA (40 hex): ' revision read -rp 'Trusted archive SHA-256 (64 hex): ' expected [[ "$revision" =~ ^[0-9a-f]{40}$ && "$expected" =~ ^[0-9a-f]{64}$ ]] read -rp 'Source: forgejo or github [forgejo]: ' source case "${source:-forgejo}" in forgejo) url="https://git.ochenstarik.ru/ochenstarik/lightweight-server/archive/${revision}.tar.gz" ;; github) url="https://codeload.github.com/ochenstarik-ui/lightweight-server/tar.gz/${revision}" ;; *) exit 1 ;; esac archive="$(mktemp)" trap 'rm -f "$archive"' EXIT curl -fLsS --proto '=https' --proto-redir '=https' --tlsv1.2 \ --retry 3 --connect-timeout 30 --max-time 300 "$url" -o "$archive" printf '%s %s\n' "$expected" "$archive" | sha256sum -c - # Refuse to mix a reviewed archive with files from an earlier installation. [[ ! -e lightweight-server ]] mkdir -m 700 lightweight-server tar -xzf "$archive" -C lightweight-server --strip-components=1 cd lightweight-server chmod 700 ./*.sh sudo ./ochenstarik-server-install.sh ``` The first wizard prompt selects the dialog language. English is the default; Russian, Spanish, German, French, Portuguese, Simplified Chinese, Japanese, Arabic, and Hindi are also available. The wizard then opens the main menu with steps 1–8. Select any step, run it, and the wizard returns to the main menu. Keep the current SSH session open while changing the SSH port. Test the new login in a second terminal before disconnecting. The wizard intentionally requires all module scripts to be present locally. Use the full archive or `git clone`; a single downloaded wizard file will not fetch missing modules from the mutable `main` branch. ## Modules | Script | Purpose | Standalone use | | --- | --- | --- | | `ochenstarik-server-install.sh` | Unified wizard with language selection and a main menu for all modules | Recommended | | `ochenstarik-server-1.sh` | Timezone, terminal locale, program groups, and a 2 GiB swap file | Yes | | `ochenstarik-server-2.sh` | Base packages, SSH port, IPv4/IPv6 mode, UFW, and port management | Yes | | `ochenstarik-server-user-3.sh` | Administrative user, SSH key permissions, SSH migration, sudo, and fail2ban | Run after step 2 | | `ochenstarik-server-tg-4.sh` | Telegram notifications for successful SSH logins | Optional | | `ochenstarik-server-vpn-5.sh` | System VPN through Xray; repeated runs can connect, disconnect, reconfigure, or show status | Optional | | `ochenstarik-server-panel-warp-6.sh` | 3x-ui panel and optional local Cloudflare WARP proxy | Optional | | `ochenstarik-server-backup-7.sh` | Protected initial snapshot and selected daily, weekly, or monthly schedules | Optional | | `ochenstarik-server-ai-agents-8.sh` | Installs selected AI agents: Hermes, OpenClaw, OpenHands, OpenCode, Aider, AutoGPT, or Pi Coding Agent | Optional | | `ochenstarik-server-uninstall.sh` | Removes project-managed settings so installation can start again | Use carefully | Every module can be run independently from the full archive or cloned repository: ```bash chmod 700 SCRIPT_NAME.sh bash -n SCRIPT_NAME.sh sudo ./SCRIPT_NAME.sh ``` Replace `SCRIPT_NAME.sh` with the required filename from the table. ## Installation flow 1. Select the wizard dialog language. 2. Configure the timezone, terminal locale, recommended tools, and swap. 3. Select IPv4, IPv6, or dual-stack operation; install base services and select the future SSH port. 4. Create or update the administrative user, install the public SSH key, repair ownership and permissions, and move SSH to the port selected in step 2. 5. Optionally configure Telegram SSH-login notifications. 6. Optionally configure the system VPN and subscription port. 7. Optionally deploy 3x-ui with separate panel/subscription access choices; WARP is a separate opt-in. 8. Optionally create the permanent initial backup and configure rotating schedules. 9. Optionally install one or more AI agents for the administrative user. ## VPN connection control After the first successful setup, running `ochenstarik-server-vpn-5.sh` again opens an action menu: connect using saved settings, disconnect while keeping the configuration, replace the subscription, or show status. The same actions are available directly: ```bash sudo ./ochenstarik-server-vpn-5.sh --enable sudo ./ochenstarik-server-vpn-5.sh --disable sudo ./ochenstarik-server-vpn-5.sh --reconfigure sudo ./ochenstarik-server-vpn-5.sh --status ``` Disconnecting removes the system routing rules but keeps Xray and its configuration so the VPN can be reconnected without entering the subscription again. ## Pinned VPN and panel installers Steps 5 and 6 require the bundled `ochenstarik-server-supply-chain.sh`. They verify the installers and executable payloads against committed SHA-256 values: 3x-ui `v3.10.2`, Xray installer commit `05aa47266c94e6fb5ca48cad96afdb4becb5891f`, Xray-core `v26.10.21` (amd64/arm64). Select GitHub or an operator-prepared HTTPS Forgejo mirror. The mirror must contain the files listed below; `ochenstarik-server-supply-chain-pins.txt` summarizes the hashes enforced by the helper; no mirror release is assumed to exist. Unknown installer downloads fail closed. Ordinary OS packages still require access to configured APT repositories. The mirror layout is flat: `xui-install.sh`, `x-ui-linux-amd64.tar.gz` or `x-ui-linux-arm64.tar.gz`, `x-ui.sh`, `x-ui.service.debian`, `xray-install.sh`, and `Xray-linux-64.zip` or `Xray-linux-arm64-v8a.zip`. Digests are the committed values; the helper creates digest sidecars locally. Step 5 only needs the two Xray files. ## Optional AI agents Do not install step 8 on VPN servers or Telegram client nodes. Use a separate machine for AI agents. Step 8 offers a multiple selection of seven popular agents: Hermes Agent, OpenClaw, OpenHands, OpenCode, Aider, AutoGPT, and Pi Coding Agent. Installers are downloaded only from each project's official HTTPS endpoint, checked with `bash -n`, and launched as the selected regular user rather than directly as `root`. AutoGPT is a larger Docker-based platform. Its official installer can request `sudo`, install Docker-related dependencies, and start local services. Pi is a lightweight terminal coding agent; after installation, start it with `pi` and use `/login` to connect a supported provider. The script does not request or store model-provider API keys. After installation, log in as the selected user and run the displayed onboarding command. AI agents can execute commands, access files, install plugins, and use network services; review their permissions and sandbox settings before connecting production data or secrets. ## Firewall and SSH notes - Step 2 supports IPv4-only, IPv6-only, and dual-stack UFW rules. IPv4-only mode blocks public inbound IPv6 through UFW without disabling the kernel IPv6 stack. - A repeated step 2 run can change the IP-family mode or add ports without reinstalling everything. - Step 3 reads the SSH port chosen in step 2 and creates an administrator with sudo access. - The home directory, `.ssh`, and `authorized_keys` ownership and permissions are checked on every run. - Defaults expose only the SSH ports needed during migration and TCP 443. Port 80, subscriptions (2096), WARP (40000), and 63636 are not opened automatically. Additional application rules require an explicit selection; existing managed application rules are listed for an explicit keep/remove decision. - After you successfully log in on the new SSH port and confirm this in step 3, it removes temporary TCP 22 access from UFW and managed state. Without confirmation it keeps 22; no cleanup runs when SSH remains on 22 or UFW management is disabled. - The panel defaults to `webListen=127.0.0.1`, checked against real TCP listener addresses. Reach it through an SSH tunnel. Subscriptions independently default to loopback, can be disabled, or can be explicitly published with a random secret path. Existing sufficiently random paths are preserved by default; rotation requires confirmation because it invalidates client URLs. Preserve subscription URLs privately. Only explicitly public services receive UFW rules. WARP defaults to off and remains loopback-only when selected. - Telegram login notifications run only for PAM `open_session`; detached delivery does not wait for Telegram during login or send a second login notification at session close. ## Backups Step 7 can create: - one initial snapshot that is never rotated automatically; - daily backups retained for 7 days; - weekly backups retained for 4 weeks; - monthly backups retained for 12 months. Schedules are selected independently. Backups contain server secrets. Local plaintext `.tar.zst` remains the default; opt into age encryption by providing the recipient public key. Encrypted output is streamed into `.tar.zst.age`, with no temporary plaintext archive. Keep the private recovery key separately and test decryption before relying on a backup. Optional SCP upload sends the completed archive and checksum with batch authentication and strict host-key checking against the operator-supplied known_hosts file. Configure a dedicated destination account and existing SSH key; no passwords or automatic host-key trust. Upload errors are failures. An existing plaintext initial snapshot is preserved: selecting age then stops with an explicit error rather than claiming it is encrypted. Move it to safe storage and resolve the initial-snapshot policy before continuing. Re-running `initial` verifies the existing checksum and retries offsite upload, including after an earlier upload failure. Local retention does not provide remote retention or protect against loss of the host. To restore an encrypted archive, decrypt with `age --decrypt -i RECOVERY_KEY` before passing the stream through `zstd -dc | tar`; never commit recovery keys. ## Multi-server monitoring and management [Server Monitor Manager](https://github.com/ochenstarik-ui/server-monitor-manager) is the companion project for centralized server operations. Its planned architecture includes: - a Flutter client for Android and iOS; - an ASP.NET Core API with accounts, TOTP two-factor authentication, and SignalR; - an outbound Linux agent for metrics and managed operations; - support for adding and monitoring multiple servers from one application. The manager is under active early development. Review its security and development documentation before connecting real production servers. ## Requirements - Ubuntu Server with systemd and APT; - root access through `sudo`; - an active SSH session; - outbound HTTPS access to the selected archive/vendor source and configured APT repositories; - a valid public SSH key for the administrator setup. ## Update Use another reviewed full commit and its source-specific archive checksum with the verified download procedure above, into a fresh directory. Review the changes before running modules again; do not update production installers by pulling a mutable branch. ## Reset project-managed configuration ```bash cd ~/lightweight-server sudo ./ochenstarik-server-uninstall.sh ``` Read every confirmation carefully. The reset script preserves critical Ubuntu packages and avoids removing access until explicitly confirmed.