mirror of
https://github.com/nearai/ironclaw.git
synced 2026-09-02 23:56:24 +08:00
322 lines
6.7 KiB
Plaintext
322 lines
6.7 KiB
Plaintext
---
|
|
title: Linux
|
|
sidebarTitle: Linux
|
|
description: Running IronClaw on Linux with systemd, GNOME Keyring, and UFW
|
|
---
|
|
|
|
IronClaw runs natively on Linux with full support for systemd service management, GNOME Keyring for secure key storage, and UFW/fail2ban for host hardening.
|
|
|
|
## Installation
|
|
|
|
### Shell Script (Recommended)
|
|
|
|
```bash
|
|
curl -fsSL https://install.ironclaw.ai | bash
|
|
```
|
|
|
|
Installs to `~/.local/bin/ironclaw`. Add to PATH if not already present:
|
|
|
|
```bash
|
|
export PATH="$HOME/.local/bin:$PATH"
|
|
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
|
|
source ~/.bashrc
|
|
```
|
|
|
|
### Package Manager (Ubuntu / Debian)
|
|
|
|
```bash
|
|
curl -fsSL https://repo.ironclaw.ai/gpg | sudo gpg --dearmor -o /usr/share/keyrings/ironclaw.gpg
|
|
echo "deb [signed-by=/usr/share/keyrings/ironclaw.gpg] https://repo.ironclaw.ai stable main" \
|
|
| sudo tee /etc/apt/sources.list.d/ironclaw.list
|
|
|
|
sudo apt update && sudo apt install ironclaw
|
|
```
|
|
|
|
### Cargo (Build from Source)
|
|
|
|
```bash
|
|
cargo install ironclaw
|
|
```
|
|
|
|
Requires Rust 1.78+. Install Rust via [rustup.rs](https://rustup.rs).
|
|
|
|
---
|
|
|
|
## systemd Service
|
|
|
|
Run IronClaw as a managed background service that restarts on failure and launches on boot.
|
|
|
|
### Unit File
|
|
|
|
Create `/etc/systemd/system/ironclaw.service`:
|
|
|
|
```ini
|
|
[Unit]
|
|
Description=IronClaw AI Assistant
|
|
Documentation=https://docs.ironclaw.ai
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=ironclaw
|
|
Group=ironclaw
|
|
EnvironmentFile=/etc/ironclaw/ironclaw.env
|
|
ExecStart=/usr/local/bin/ironclaw run
|
|
ExecReload=/bin/kill -HUP $MAINPID
|
|
Restart=on-failure
|
|
RestartSec=5s
|
|
TimeoutStopSec=30s
|
|
|
|
# Security hardening
|
|
NoNewPrivileges=true
|
|
PrivateTmp=true
|
|
ProtectSystem=strict
|
|
ProtectHome=read-only
|
|
ReadWritePaths=/var/lib/ironclaw /home/ironclaw/.ironclaw
|
|
|
|
# Logging
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
SyslogIdentifier=ironclaw
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
```
|
|
|
|
### Environment File
|
|
|
|
Create `/etc/ironclaw/ironclaw.env` (mode 640, owned by root:ironclaw):
|
|
|
|
```bash
|
|
sudo mkdir -p /etc/ironclaw
|
|
sudo touch /etc/ironclaw/ironclaw.env
|
|
sudo chmod 640 /etc/ironclaw/ironclaw.env
|
|
sudo chown root:ironclaw /etc/ironclaw/ironclaw.env
|
|
```
|
|
|
|
Example contents:
|
|
|
|
```bash
|
|
DATABASE_BACKEND=libsql
|
|
LLM_BACKEND=nearai
|
|
NEARAI_SESSION_TOKEN=sess_xxx
|
|
GATEWAY_ENABLED=true
|
|
GATEWAY_HOST=127.0.0.1
|
|
GATEWAY_PORT=3000
|
|
GATEWAY_AUTH_TOKEN=change_this_to_a_random_secret
|
|
RUST_LOG=ironclaw=info
|
|
```
|
|
|
|
### Enable and Start
|
|
|
|
```bash
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable --now ironclaw
|
|
|
|
# Verify
|
|
sudo systemctl status ironclaw
|
|
```
|
|
|
|
---
|
|
|
|
## GNOME Keyring Integration
|
|
|
|
IronClaw uses the system keyring to store the encryption master key for secrets. On GNOME-based desktops, this is GNOME Keyring.
|
|
|
|
### Install libsecret
|
|
|
|
```bash
|
|
# Ubuntu / Debian
|
|
sudo apt install gnome-keyring libsecret-tools
|
|
|
|
# Fedora
|
|
sudo dnf install gnome-keyring libsecret
|
|
|
|
# Arch
|
|
sudo pacman -S gnome-keyring libsecret
|
|
```
|
|
|
|
### Store the Master Key Manually (optional)
|
|
|
|
IronClaw handles this automatically on first run, but you can pre-seed the key:
|
|
|
|
```bash
|
|
secret-tool store \
|
|
--label="IronClaw Master Key" \
|
|
application ironclaw \
|
|
key master
|
|
```
|
|
|
|
Retrieve it later:
|
|
|
|
```bash
|
|
secret-tool lookup application ironclaw key master
|
|
```
|
|
|
|
### Headless / Server Environments
|
|
|
|
GNOME Keyring requires a D-Bus session. On headless servers, use the environment variable fallback instead:
|
|
|
|
```bash
|
|
IRONCLAW_MASTER_KEY=<base64-encoded-32-byte-key>
|
|
```
|
|
|
|
Generate a secure key:
|
|
|
|
```bash
|
|
openssl rand -base64 32
|
|
```
|
|
|
|
<Warning>
|
|
The environment variable approach exposes the key in process listings. Use the keyring on desktop systems. On servers, prefer a secrets manager (Vault, AWS Secrets Manager) and inject at startup.
|
|
</Warning>
|
|
|
|
---
|
|
|
|
## UFW Firewall Rules
|
|
|
|
Restrict access to the Web Gateway so only local processes can reach it.
|
|
|
|
```bash
|
|
# Allow SSH (do this first to avoid locking yourself out)
|
|
sudo ufw allow 22/tcp
|
|
|
|
# Block port 3000 from external access
|
|
sudo ufw deny in on eth0 to any port 3000
|
|
|
|
# If you need access from a specific trusted IP only
|
|
# sudo ufw allow from 192.168.1.100 to any port 3000
|
|
|
|
# Enable UFW
|
|
sudo ufw enable
|
|
sudo ufw status verbose
|
|
```
|
|
|
|
<Note>
|
|
If you expose IronClaw via a reverse proxy (Caddy, nginx), the proxy listens on 443 and forwards to 127.0.0.1:3000 internally. Port 3000 never needs to be public-facing. See [VPS Hardening](/platforms/vps) for the full reverse proxy setup.
|
|
</Note>
|
|
|
|
---
|
|
|
|
## fail2ban Configuration
|
|
|
|
Protect against repeated authentication failures against the Web Gateway.
|
|
|
|
Create `/etc/fail2ban/filter.d/ironclaw.conf`:
|
|
|
|
```ini
|
|
[Definition]
|
|
failregex = ^.*401 Unauthorized.*from <HOST>.*$
|
|
^.*auth.*failed.*<HOST>.*$
|
|
ignoreregex =
|
|
```
|
|
|
|
Create `/etc/fail2ban/jail.d/ironclaw.conf`:
|
|
|
|
```ini
|
|
[ironclaw]
|
|
enabled = true
|
|
port = 3000
|
|
filter = ironclaw
|
|
logpath = /var/log/ironclaw/access.log
|
|
maxretry = 5
|
|
bantime = 3600
|
|
findtime = 600
|
|
action = ufw
|
|
```
|
|
|
|
Reload fail2ban:
|
|
|
|
```bash
|
|
sudo systemctl reload fail2ban
|
|
sudo fail2ban-client status ironclaw
|
|
```
|
|
|
|
---
|
|
|
|
## Viewing Logs
|
|
|
|
```bash
|
|
# Follow live logs
|
|
journalctl -u ironclaw -f
|
|
|
|
# Last 100 lines
|
|
journalctl -u ironclaw -n 100
|
|
|
|
# Logs from the past hour
|
|
journalctl -u ironclaw --since "1 hour ago"
|
|
|
|
# With debug output (set RUST_LOG=ironclaw=debug in env file first)
|
|
journalctl -u ironclaw -f --output=short-precise
|
|
|
|
# Export to file
|
|
journalctl -u ironclaw --since today > ironclaw-today.log
|
|
```
|
|
|
|
---
|
|
|
|
## AppArmor Profile (Optional)
|
|
|
|
An AppArmor profile can constrain IronClaw's filesystem and network access at the kernel level.
|
|
|
|
Create `/etc/apparmor.d/usr.local.bin.ironclaw`:
|
|
|
|
```
|
|
#include <tunables/global>
|
|
|
|
/usr/local/bin/ironclaw {
|
|
#include <abstractions/base>
|
|
#include <abstractions/nameservice>
|
|
|
|
# Binary
|
|
/usr/local/bin/ironclaw mr,
|
|
|
|
# Config and data
|
|
/home/ironclaw/.ironclaw/** rw,
|
|
/var/lib/ironclaw/** rw,
|
|
/etc/ironclaw/ironclaw.env r,
|
|
|
|
# Keyring
|
|
/run/user/*/keyring/** rw,
|
|
|
|
# Docker socket (for sandbox)
|
|
/var/run/docker.sock rw,
|
|
|
|
# Network
|
|
network tcp,
|
|
network udp,
|
|
|
|
# Deny everything else
|
|
deny /etc/shadow r,
|
|
deny /root/** rw,
|
|
}
|
|
```
|
|
|
|
Load the profile:
|
|
|
|
```bash
|
|
sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.ironclaw
|
|
sudo aa-status | grep ironclaw
|
|
```
|
|
|
|
<Note>
|
|
The AppArmor profile is optional. IronClaw's own sandbox (Docker containers with dropped capabilities) provides defense-in-depth regardless of whether AppArmor is configured.
|
|
</Note>
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
<CardGroup cols={3}>
|
|
<Card title="VPS Hardening" icon="shield" href="/platforms/vps">
|
|
UFW, Caddy, fail2ban, and SSH hardening for public-facing deployments
|
|
</Card>
|
|
<Card title="Docker Compose" icon="layers" href="/platforms/docker-compose">
|
|
Production deployment with PostgreSQL and named volumes
|
|
</Card>
|
|
<Card title="Logging" icon="file-text" href="/ops/logging">
|
|
RUST_LOG levels, journalctl, and cost tracking
|
|
</Card>
|
|
</CardGroup>
|