This commit is contained in:
first 2025-07-08 21:18:32 +00:00
parent 697b84b9b5
commit 33e7efe3bb

237
README.md
View file

@ -1,48 +1,221 @@
# First-Boot Server Utilities
This repository contains a collection of small, independent utilities designed to run on a server's first boot to perform a specific, helpful task.
This top-level README serves as a directory to the tools contained within.
## The Tools
### 1. Ripcord
**To prevent a disk-full event and recover your system, delete this file.**
On first boot Ripcord creates a large "ballast" file of random data. If your server's disk fills up and locks you out, you can delete this single file to instantly free up space, giving you breathing room to log in and fix the underlying issue.
➡️ **For full details, see the [Ripcord README](./ripcord/README.md)**
### 2. SYNterloper
**A first-boot, truncated, rolling PCAP logger.**
SYNterloper sets up a persistent, low-overhead network capture service (by default for SSH on port 22). It's designed for automated deployment (e.g., AWS User Data) to log connection attempts for security or troubleshooting, with automatic log rotation and pruning.
➡️ **For full details, see the [SYNterloper README](./synterloper/README.md)**
# Unified First-Boot Server Setup Script
A complete, self-contained provisioning script for automated server deployment that combines both **Ripcord** and **SYNterloper** with system hardening tasks (user creation, SSH setup, sudoers) in one idempotent user-data script.
---
## Important: Project Management and Status
## 🔧 Purpose
This script automates the following tasks on first boot:
- Creates a non-root user with SSH access and sudo privileges
- Installs Ansible-ready Python packages
- Deploys **Ripcord** (emergency disk space reserve)
- Deploys **SYNterloper** (rolling SSH connection logger)
- Validates each step with `.flag` files
- Leaves all components ready for manual management
The tools in this repository, **Ripcord** and **SYNterloper**, are currently maintained as two separate and distinct projects.
➡️ **For tool-specific details, see individual READMEs**:
- [Ripcord README](./ripcord/README.md)
- [SYNterloper README](./synterloper/README.md)
- **No Unified Installer:** There is no single script to install or manage both tools. They were developed for different purposes and have their own installation and management logic.
- **Separate Documentation:** Each tool has its own `README.md` file with specific installation, configuration, and usage instructions.
- **Independent Operation:** The scripts do not interact with or depend on each other. You can install one, the other, or both without conflict.
### How to Use This Repository
To use a tool, please navigate to its respective directory and follow the instructions in its README file.
---
## 📦 Repository Structure
```
.
├── user-data.sh # This script
├── ripcord/
│ ├── ripcord.sh
│ └── README.md
├── synterloper/
│ ├── synterloper.sh
│ └── README.md
└── README.md (You are here)
└── README.md # You are here
```
While a unified toolkit may be considered in the future, the current approach ensures each utility remains simple, self-contained, and easy to understand.
---
## 🚀 Installation
Paste this script into your cloud provider's **User Data** field during instance creation:
```bash
#!/bin/bash
set -e # Exit on any error
# Define user and flag locations
USRNAME=fastsoul
FLAG_DIR=/var/lib/cloud/scripts/user
mkdir -p "$FLAG_DIR"
# --- Step 1: Create user ---
if [ ! -f "$FLAG_DIR/.user_created.flag" ]; then
echo "Creating user: $USRNAME"
if ! id "$USRNAME" &>/dev/null; then
useradd "$USRNAME" -s /bin/bash -d /home/"$USRNAME" -m || { echo "User creation failed"; exit 1; }
chown -R "$USRNAME":"$USRNAME" /home/"$USRNAME"
else
echo "User $USRNAME already exists. Skipping creation."
fi
touch "$FLAG_DIR/.user_created.flag"
fi
# --- Step 2: Create SSH directory and authorized_keys file ---
if [ ! -f "$FLAG_DIR/.ssh_setup.flag" ]; then
echo "Setting up SSH for $USRNAME"
mkdir -p "/home/$USRNAME/.ssh"
touch "/home/$USRNAME/.ssh/authorized_keys"
chown -R "$USRNAME":"$USRNAME" "/home/$USRNAME/.ssh"
chmod 700 "/home/$USRNAME/.ssh"
chmod 600 "/home/$USRNAME/.ssh/authorized_keys"
touch "$FLAG_DIR/.ssh_setup.flag"
fi
# --- Step 3: Add SSH keys to authorized_keys ---
if [ ! -f "$FLAG_DIR/.ssh_keys_added.flag" ]; then
echo "Adding SSH keys to authorized_keys"
cat << EOF >> /home/$USRNAME/.ssh/authorized_keys
cert-authority ssh-rsa AAAAB3NzaXXXX== user@example.com
ssh-rsa AAAAB3NzaYYYYYYYYYYYYYYYYYYYYYYYYYYYYQ==
ssh-rsa AAAAB3NzaXXXXXXXXXXXXXXXXXXXXXXXXXXXXQ==
EOF
if [ $? -eq 0 ]; then
chown -R "$USRNAME":"$USRNAME" "/home/$USRNAME/.ssh/authorized_keys"
touch "$FLAG_DIR/.ssh_keys_added.flag"
else
echo "Failed to write SSH keys to authorized_keys"
exit 1
fi
fi
# --- Step 4: Set NOPASSWD sudoers ---
if [ ! -f "$FLAG_DIR/.sudoers_set.flag" ]; then
echo "Setting up NOPASSWD sudo for $USRNAME"
echo "$USRNAME ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/"$USRNAME" || { echo "Failed to write sudoers file"; exit 1; }
touch "$FLAG_DIR/.sudoers_set.flag"
fi
# --- Step 5: Install python3-apt for Ansible support ---
if [ ! -f "$FLAG_DIR/.python_installed.flag" ]; then
echo "Updating APT and installing python3-apt"
apt update -y || { echo "APT update failed"; exit 1; }
apt install -y python3-apt || { echo "Failed to install python3-apt"; exit 1; }
touch "$FLAG_DIR/.python_installed.flag"
fi
# --- Step 6: Download Ripcord and SYNterloper from Git ---
if [ ! -f "$FLAG_DIR/.scripts_downloaded.flag" ]; then
echo "Downloading Ripcord and SYNterloper scripts"
curl -fsSL -o /usr/local/sbin/ripcord.sh https://git.r21.io/primemover/user-data/raw/branch/master/ripcord/ripcord.sh || { echo "Ripcord download failed"; exit 1; }
curl -fsSL -o /usr/local/sbin/synterloper.sh https://git.r21.io/primemover/user-data/raw/branch/master/synterloper/synterloper.sh || { echo "SYNterloper download failed"; exit 1; }
chmod +x /usr/local/sbin/ripcord.sh /usr/local/sbin/synterloper.sh || { echo "chmod failed"; exit 1; }
touch "$FLAG_DIR/.scripts_downloaded.flag"
fi
# --- Step 7: Setup Ripcord systemd service ---
if [ ! -f "$FLAG_DIR/.ripcord_setup.flag" ]; then
echo "Setting up Ripcord systemd service"
cat << EOF | sudo tee /etc/systemd/system/ripcord.service
[Unit]
Description=Ripcord Emergency Disk Space Reserve
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/ripcord.sh
ExecStartPost=/bin/sh -c "systemctl disable ripcord.service"
[Install]
WantedBy=multi-user.target
EOF
systemctl enable ripcord.service || { echo "Failed to enable Ripcord service"; exit 1; }
touch "$FLAG_DIR/.ripcord_setup.flag"
fi
# --- Step 8: Install SYNterloper ---
if [ ! -f "$FLAG_DIR/.synterloper_installed.flag" ]; then
echo "Installing SYNterloper"
/usr/local/sbin/synterloper.sh install || { echo "SYNterloper install failed"; exit 1; }
touch "$FLAG_DIR/.synterloper_installed.flag"
fi
# --- Final Step: Mark completion ---
if [ ! -f "$FLAG_DIR/.user_data_complete.flag" ]; then
echo "Marking user-data completion"
touch /root/user_data_completed.txt
touch "$FLAG_DIR/.user_data_complete.flag"
fi
echo "All steps completed successfully."
exit 0
```
### ✅ What Gets Installed
| Component | Purpose | Validation Flag |
|-------------------|----------------------------------|-------------------------------------|
| User: `fastsoul` | Primary admin account | `/var/lib/cloud/scripts/user/.user_created.flag` |
| SSH Keys | Cert-authority and/or deployment keys | `/var/lib/cloud/scripts/user/.ssh_keys_added.flag` |
| Sudoers | NOPASSWD:ALL access | `/var/lib/cloud/scripts/user/.sudoers_set.flag` |
| Python 3-apt | Ansible dependency | `/var/lib/cloud/scripts/user/.python_installed.flag` |
| Ripcord.sh | Emergency disk ballast | `/var/lib/cloud/scripts/user/.ripcord_setup.flag` |
| Synterloper.sh | Rolling SSH connection logger | `/var/lib/cloud/scripts/user/.synterloper_installed.flag` |
---
## ⚙️ Configuration
Edit these variables at the top of the script to customize:
```bash
# Change these to match your needs
USRNAME=fastsoul
SSH_KEYS="
cert-authority ssh-rsa AAAAB3NzaXXXXXXXXXXXXXXXXXX...user@example.com
ssh-rsa AAAAB3NzaYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYQ==
ssh-rsa AAAAB3NzaXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXQ==
```
---
## 🔍 Validation
All steps are validated with `.flag` files in `/var/lib/cloud/scripts/user/`:
```bash
ls -la /var/lib/cloud/scripts/user/
```
Expected output:
```
.user_created.flag
.ssh_keys_added.flag
.sudoers_set.flag
.python_installed.flag
.scripts_downloaded.flag
.ripcord_setup.flag
.synterloper_installed.flag
.user_data_complete.flag
```
---
## 🧹 Re-running
To re-run the script (e.g., for testing):
1. Delete specific `.flag` files:
```bash
rm /var/lib/cloud/scripts/user/.sudoers_set.flag
```
2. Re-run the script:
```bash
sudo /var/lib/cloud/scripts/user/user-data.sh
```
---
## ⚠️ Known Limitations
- **Debian/Ubuntu only** (FreeBSD support would require separate logic)
- **Root access required** (must be run via cloud-init)
- **Hardcoded SSH keys** (rotate credentials for production use)
---
## 📚 For More Details
- [Ripcord README](./ripcord/README.md)
- [SYNterloper README](./synterloper/README.md)
---
## 📄 License
This script is released under the **MIT License**. See `LICENSE` for details.