Agent-Box · Song Linh Plus
Từ cài Ubuntu → đến agent AI dùng từ xa + bot Telegram riêng. Viết cho người mới, có AI hỗ trợ. Mỗi mục nói rõ là gì, vì sao cần, và bỏ qua được không.
Agent-Box = 1 máy Ubuntu (laptop/mini-PC) cho mỗi khách: bảo mật, truy cập từ xa, chạy 4 AI agent (Claude Code, Codex, Antigravity, Grok) qua SSH+tmux, kèm bot Telegram riêng. Khách dùng agent từ bất kỳ đâu.
Sau khi đã có Ubuntu + SSH (mục 3–4), phần lớn việc còn lại tự động bằng 1 script. Copy thư mục
agent-box/ lên máy rồi chạy:
cd agent-box
bash bootstrap-agent-box.sh # mặc định: có Caddy
# tuỳ chọn: --no-caddy | --with-tunnel (web ra internet) | --with-modules (Samba/Syncthing/Cockpit)
Script tự cài: công cụ cơ bản, UFW/Fail2ban/SSH hardening, Tailscale, Docker, Node + 4 AI CLI, Caddy,
bot Telegram (sl-bot) + skills sl-*, banner thương hiệu. Idempotent — chạy lại an toàn.
Bên dưới là bản thủ công để hiểu rõ / xử lý khi script lỗi.
| Phần cứng | Tài khoản tạo trước |
|---|---|
| Mini-PC/laptop: RAM ≥ 4GB, ổ ≥ 64GB · USB ≥ 4GB · màn hình+bàn phím (lúc cài) · dây mạng LAN | Cloudflare (nếu cần web public) · Tailscale · GitHub · tài khoản AI của KHÁCH (Anthropic/OpenAI/Google/xAI) |
Tải: Ubuntu Server 24.04 LTS (ubuntu.com/download/server) · Rufus (Windows) hoặc Balena Etcher (macOS) để tạo USB boot.
① Tạo USB boot (Rufus/Etcher → chọn file .iso). ② Cắm USB, vào Boot Menu (F12/F2/Del) → Try or Install Ubuntu Server.
③ Ngôn ngữ English · Keyboard US · bản Ubuntu Server (không GUI).
④ Mạng — để DHCP (tự xin IP): giữ mặc định (Automatic). KHÔNG đặt IP tĩnh cứng — khi bàn giao sang mạng khác của khách dễ bị sai subnet/trùng IP → mất kết nối. Ta sẽ truy cập bằng TÊN máy (mục 6), không cần nhớ IP.
⑤ Proxy: trống · Storage: Use entire disk (+LVM). ⑥ Profile: hostname đặt theo khách
(vd agentbox-khachA — dùng cho tên truy cập), username, mật khẩu mạnh (≥12).
⑦ Ubuntu Pro: Skip. ⑧ ✅ Tick "Install OpenSSH server". ⑨ Snaps: không chọn → cài → Reboot, rút USB.
Sau reboot, đăng nhập rồi lấy IP: ip addr show (dòng inet 192.168.x.x).
🔌 SSH — điều khiển máy từ xa qua dòng lệnh
# từ máy cá nhân (PowerShell/Terminal)
ssh username@192.168.1.100
# tạo SSH key để khỏi nhập mật khẩu mỗi lần
ssh-keygen -t ed25519 -C "email@example.com" # Enter 3 lần
ssh-copy-id username@192.168.1.100 # (macOS/Linux) → nhập mật khẩu lần cuối
type $env:USERPROFILE\.ssh\id_ed25519.pub, rồi paste vào
~/.ssh/authorized_keys trên server (chmod 700 ~/.ssh; chmod 600 ~/.ssh/authorized_keys).🛡️ Bảo mật cơ bản — UFW · Fail2ban · SSH hardening · tự vá lỗi
sudo apt update && sudo apt upgrade -y
sudo apt install -y ufw fail2ban
sudo ufw allow OpenSSH && sudo ufw --force enable
# Fail2ban: bật bảo vệ SSH (script tạo /etc/fail2ban/jail.local: maxretry 3, bantime 24h)
sudo systemctl enable --now fail2ban
# SSH: cấm root, giới hạn thử
sudo sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sudo systemctl restart ssh
🔐 Tailscale — mạng riêng, vào máy từ xa mà không mở cổng
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --hostname=agentbox-khachA # đăng nhập 1 lần; đặt tên máy theo khách
sudo systemctl enable tailscaled
sudo ufw allow in on tailscale0
sudo apt install -y avahi-daemon # để có "ten-may.local" trong LAN
| Truy cập | Lệnh | Hoạt động khi… |
|---|---|---|
| Từ xa (mọi nơi) | ssh user@agentbox-khachA | Bật MagicDNS (1 lần ở login.tailscale.com/admin/dns) — chạy trên MẠNG NÀO CŨNG ĐƯỢC, khách đổi router/IP vẫn vào. |
| Trong nhà khách (LAN) | ssh user@agentbox-khachA.local | avahi/mDNS — Windows/Mac/Linux đều thấy, khỏi biết IP. |
| Dự phòng | ssh user@100.x.x.x | tailscale ip -4 |
~/.ssh/config rồi chỉ cần ssh khachA:
Host khachA
HostName agentbox-khachA # Tailscale MagicDNS (hoặc agentbox-khachA.local trong LAN)
User username
(Script bootstrap-agent-box.sh --name agentbox-khachA tự đặt hostname + in sẵn đoạn này.)📦 Docker — "đóng hộp" ứng dụng chạy cô lập
# Docker (script làm tự động). tmux để agent chạy nền khi đóng máy:
sudo apt install -y tmux
tmux new -s ai # tạo phiên ; Ctrl+b rồi d = thoát (vẫn chạy) ; tmux attach -t ai = quay lại
🤖 4 AI CLI — Claude Code · Codex · Antigravity · Grok
| Agent | Lệnh cài | Chạy |
|---|---|---|
| Claude Code (Anthropic) | npm i -g @anthropic-ai/claude-code | claude |
| Codex (OpenAI) | npm i -g @openai/codex | codex |
| Antigravity (Google) | curl -fsSL https://antigravity.google/cli/install.sh | bash | agy |
| Grok Build (xAI) | curl -fsSL https://x.ai/cli/install.sh | bash | grok |
# lần đầu mỗi CLI: chạy nó để đăng nhập (qua SSH nó in URL+code, dán vào trình duyệt)
tmux new -s ai
claude # đăng nhập tài khoản Anthropic của khách
# tương tự: codex / agy / grok
# Ctrl+b d để thoát — agent vẫn chạy; đóng laptop vẫn ok
~/projects/<ten-du-an>. Skill sl-box (đã cài) nhắc sẵn các lệnh máy.📩 Bot Telegram — thông báo & điều khiển qua Telegram
/status. Dùng cơ chế long-polling (bot tự hỏi Telegram) nên không cần mở port hay Cloudflare.① Mở @BotFather trên Telegram → /newbot → đặt tên → nhận BOT_TOKEN.
② Lấy chat-id: nhắn @userinfobot → copy số id của bạn.
③ Điền vào ~/.config/agent-box/secrets.env (mode 600 — script tạo sẵn template):
BOT_TOKEN=123456:ABC...
ADMIN_CHAT_IDS=123456789
④ Bật + test:
sudo systemctl restart agent-box-bot
/opt/agent-box/sl-bot/notify.sh "Xin chào từ Agent-Box" # → nhận tin trên Telegram
# trong Telegram nhắn /status để xem tình trạng máy
🌐 Caddy — web server tự động cấp HTTPS
--no-caddy để bỏ.sudo nano /etc/caddy/Caddyfile
vidu.com {
reverse_proxy localhost:3000 # app Node/Python chạy cổng 3000
}
tinh.vidu.com {
root * /var/www/tinh
file_server # web tĩnh
}
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
--with-tunnel (Cloudflare Tunnel) — đưa app ra ngoài
không cần mở port/IP tĩnh public. Trỏ tunnel thẳng vào localhost:port, hoặc qua Caddy nếu nhiều site.Chuyển sang tab Checklist bàn giao (ở đầu trang) để điền thông tin + chạy smoke test + lưu lại thành file JSON/Markdown trước khi giao. Lệnh hay dùng:
| Việc | Lệnh |
|---|---|
| IP truy cập xa | tailscale ip -4 |
| Tình trạng dịch vụ | systemctl status agent-box-bot docker caddy tailscaled |
| Gửi thông báo | /opt/agent-box/sl-bot/notify.sh "..." |
| Reload web | sudo systemctl reload caddy |
| Dọn ổ đĩa | docker system prune -a · sudo apt autoremove |
👥 Nhiều người dùng — mỗi người 1 session/folder riêng
agent-team + thư mục chung /srv/shared để chia sẻ khi cần.Admin tạo người dùng bằng 1 lệnh:
sudo /opt/agent-box/sl-adduser.sh nhanvienA --shared # cho thấy /srv/shared
sudo /opt/agent-box/sl-adduser.sh sep --sudo --shared # admin phụ
Người dùng đăng nhập (ssh nhanvienA@ten-may hoặc Cockpit web → Terminal) → tmux new -s ai
→ chạy claude/codex bằng tài khoản AI của họ. Giới hạn 1 folder cụ thể:
setfacl -R -m u:nhanvienA:rwx /srv/duan-x.
🔒 2 nhân sự · 2 session riêng · 1 dự án chung
/run/user/<uid>/… quyền 700 → tmux ls của người này không thấy session người kia. Thêm /srv/shared chỉ chia sẻ file dữ liệu, KHÔNG đụng cấu hình (~/.claude, đăng nhập Claude, secrets.env vẫn riêng).setfacl. B (nhóm): cả nhóm agent-team + /srv/shared — dưới đây.Cách B — admin dựng 1 lần (ví dụ 2 nhân sự alice, bob; KHÔNG cấp --sudo để họ không xem session của nhau):
# tạo user + vào nhóm chung, siết home riêng tư
sudo /opt/agent-box/sl-adduser.sh alice --shared
sudo /opt/agent-box/sl-adduser.sh bob --shared
sudo chmod 750 /home/alice /home/bob
# thư mục dự án chung (setgid: file mới tự thuộc nhóm) + git chống đè nhau
sudo install -d -m 2770 -g agent-team /srv/shared/du-an-x
echo 'umask 002' | sudo tee -a /home/alice/.bashrc /home/bob/.bashrc # nhóm ghi được file mới
cd /srv/shared/du-an-x && sudo git init -b main
Hoặc 1 lệnh (tạo folder + set nhóm/umask cho tất cả thành viên):
sudo /opt/agent-box/sl-adduser.sh alice --project du-an-x --members alice,bob
Mỗi người làm việc bằng tài khoản của mình: ssh alice@ten-may → tmux new -s work →
cd /srv/shared/du-an-x → claude (đăng nhập tài khoản Claude của họ). Cùng sửa 1 bộ file, session tách biệt.
sudo -u bob tmux ls không thấy session của alice · sudo -u bob ls /home/alice/projects báo Permission denied = đúng. Chi tiết + xử lý lỗi: docs/huong-dan-multi-user-cach-b-agent-team.md.| Module | Là gì / dùng khi nào | Bật + dùng |
|---|---|---|
| Samba ổ mạng | Biến /srv/shared thành ổ đĩa mạng cho Windows/Mac — kéo-thả file như ổ thường. | Bật: --with-samba · Windows \\ten-may\shared · Mac smb://ten-may.local · mật khẩu: sudo smbpasswd -a <user> |
| Syncthing đồng bộ | Đồng bộ thư mục 2 chiều giữa box ↔ máy/điện thoại, không qua cloud. | Bật: --with-syncthing · UI :8384 (qua SSH/Tailscale) |
| Cockpit quản trị web | Trang web quản trị máy: tạo user, mở Terminal, theo dõi tài nguyên — cho người ngại dòng lệnh. | Bật: --with-cockpit · https://ten-may.local:9090 |
Bật cả ba: bash bootstrap-agent-box.sh --name agentbox-khachA --with-modules.
| Triệu chứng | Kiểm tra |
|---|---|
| SSH không vào được | ping 192.168.1.100 · sai IP/firewall · ssh -v ... |
| Bot không trả lời | sudo systemctl status agent-box-bot · token/chat-id trong secrets.env · bạn có trong ADMIN_CHAT_IDS? |
| Web không lên | sudo journalctl -u caddy -n 50 · app chạy chưa? curl localhost:3000 |
| Agent CLI không thấy | mở SSH mới (PATH nvm/~/.local/bin) · đăng nhập lại CLI |
| Docker cần sudo | đăng xuất/đăng nhập lại sau khi thêm group docker |
secrets.env bí mật (mode 600).Agent-Box · Dùng hằng ngày
Dành cho người dùng box mỗi ngày: kết nối vào máy, chạy AI chạy nền, làm dự án chung, dùng bot Telegram. Không cần biết cài đặt — phần đó đã xong ở tab Hướng dẫn cài đặt.
tmux attach -t ai (quay lại phiên đang chạy) → ③ gõ việc cho AI. Xong thì Ctrl-b rồi d để thoát — AI vẫn chạy tiếp.| Cách | Làm gì | Khi nào |
|---|---|---|
| SSH qua Tailscale chính | ssh <ten-cua-ban>@<ten-may> — bật Tailscale trên máy/điện thoại trước, rồi mở Terminal. | Mọi nơi, mọi lúc (không cần cùng mạng nhà). |
| Cockpit web ngại lệnh | Mở https://<ten-may>.local:9090 → đăng nhập → Terminal. | Trong LAN, thích giao diện web (nếu đã bật --with-cockpit). |
tmux giữ phiên làm việc sống ngay cả khi bạn tắt Terminal / rớt mạng / đóng laptop. Chỉ cần nhớ vài lệnh:
| Việc | Lệnh |
|---|---|
Mở phiên mới tên ai | tmux new -s ai |
| Thoát ra (AI chạy tiếp) | bấm Ctrl-b rồi thả, bấm d |
| Quay lại phiên cũ | tmux attach -t ai |
| Xem các phiên đang có | tmux ls chỉ thấy phiên của bạn |
| Cuộn xem lại (thoát: q) | bấm Ctrl-b rồi [ , dùng mũi tên/PageUp |
Trong phiên tmux, gõ tên agent để bắt đầu:
claude # hoặc: codex
# Lần đầu sẽ hỏi đăng nhập → dùng TÀI KHOẢN AI CỦA BẠN (mở link, dán mã).
# Gõ yêu cầu bằng tiếng Việt. Thoát agent: gõ /exit (hoặc Ctrl-c 2 lần).
tmux attach -t ai là thấy AI vẫn đang làm.Nếu admin đã tạo dự án chung, vào thư mục dự án rồi chạy AI ở đó. Cả nhóm sửa chung 1 bộ file, nhưng phiên ai nấy chạy:
cd /srv/shared/<ten-du-an>
git pull # lấy thay đổi mới nhất của người khác (nếu dùng git)
claude # làm việc
git add -A && git commit -m "viec cua toi" && git push # lưu + chia sẻ
docs/huong-dan-multi-user-cach-b-agent-team.md.| Lệnh / việc | Kết quả |
|---|---|
Nhắn /status cho bot | Bot báo tình trạng máy (CPU, ổ đĩa, dịch vụ). |
Nhắn /help | Danh sách lệnh bot hiểu. |
| Nhận thông báo tự động | Bot tự nhắn khi có sự kiện (backup, cảnh báo…). Không cần làm gì. |
# chạy app của bạn ở 1 cổng, ví dụ localhost:3000, rồi trỏ tên miền qua Caddy
sudo nano /etc/caddy/Caddyfile # thêm: ten-mien.com { reverse_proxy localhost:3000 }
sudo systemctl reload caddy # áp dụng — Caddy tự lo HTTPS
Bỏ qua mục này nếu chỉ dùng AI qua SSH.
| Tình huống | Làm gì |
|---|---|
| Gặp lỗi bất kỳ | Chụp / copy đúng dòng lỗi → dán hỏi AI (claude) hoặc gửi admin. Đừng đoán mò. |
| Quên mình đang ở đâu | pwd (thư mục hiện tại) · tmux ls (các phiên) · whoami (tài khoản). |
| AI/Terminal bị treo | Ctrl-c để dừng lệnh · thoát tmux (Ctrl-b d) rồi attach lại. |
| Bảo mật | Không đưa mật khẩu/token cho người ngoài · chỉ vào máy qua Tailscale · không tự ý mở cổng ra internet. |
Agent-Box · Bàn giao khách
Điền thông tin, tích các mục đã xong, rồi bấm Lưu JSON hoặc Lưu Markdown để tải file lưu trữ. Dữ liệu tự lưu trên trình duyệt này (không gửi đi đâu).
| Tên khách | Ngày cài | ||
| Hostname | Username | ||
| IP nội bộ | Tailscale IP | ||
| Domain (nếu có) | Telegram chat-id | ||
| Telegram BOT_TOKEN | |||
| Tài khoản AI của khách | email: | ||