אירוח עצמי של open-kritt על שרת VPS: מדריך התקנה
למדו כיצד להריץ את open-kritt בבטחה באמצעות Docker Compose. המדריך כולל הגדרת גרסה קבועה, יצירת מנהרת SSH לפורט 5173 וקביעת תקציב ספק ה-API לפני תחילת הסריקה הראשונה.
מדוע לארח את open-kritt על שרת VPS ולא על המחשב האישי
אחסנו את open-kritt על שרת שניתן להשמיד ולהקים מחדש. הכלי מריץ את סוכני הניתוח שלו כ-root בתוך מכולות (containers) חד-פעמיות, מעניק לכל אחד מהם עותק בר-כתיבה של הקוד שלכם וגישה ישירה לאינטרנט, ומבצע mount ל-Docker socket של המארח לתוך שירות ה-engine שלו. זו פשרה סבירה עבור מכונה המוקדשת למשימה זו בלבד. זו פשרה גרועה עבור המכונה שבה שמורים מפתחות ה-SSH שלכם.
ארבע תכונות של הגדרת ברירת המחדל מובילות להמלצה זו, וכולן מופיעות ב-README ובקובץ ה-compose של הפרויקט עצמו.
הסוכנים מתוכננים להיות בעלי עוצמה רבה. ה-README מציין שסוכנים המופעלים על ידי כלים רצים כ-root בתוך מכולות עבודה חד-פעמיות, עם עותקי מאגר (repository) ברי-כתיבה וגישה ישירה לאינטרנט, כדי שיוכלו להתקין כלים, לקמפל יעדים, להריץ בדיקות ולבנות הוכחות היתכנות. סריקה אינה רק linter שקורא קבצים. מדובר בהרצת קוד שרירותי שביקשתם לבצע.
ה-engine מחזיק ב-Docker socket. docker-compose.yml מבצע mount ל-Docker socket של המארח לתוך שירות ה-engine, כיוון שה-engine בונה ומפעיל מכולת סריקה אחת לכל משימה. כל תהליך שיכול לגשת ל-socket הזה יכול להפעיל מכולה שמבצעת mount למערכת הקבצים של המארח. לכן, ה-engine הוא למעשה בעל הרשאות root על כל מארח שמריץ אותו.
אין מסך התחברות. ה-backend מסופק ללא אימות משתמשים (authentication). גישה לפורט משמעותה גישה לממצאים שלכם ולקרדיט של ספק השירות שלכם.
הקוד שאתם סורקים לרוב אינו שלכם. הפניית סוכנים למאגר צד-שלישי משמעותה הרצת תהליך הבנייה של אותו מאגר על המכונה שלכם, כ-root, עם גישה לרשת.
אם קראתם את מדוע סוכני תכנות שייכים למכונה וירטואלית חד-פעמית, מדובר באותו מודל איומים, רק חזק יותר. הקצו ל-open-kritt שרת VPS שאין עליו דבר מלבד זאת, והפעילו את ה-VPS הזה מתוך חשבון משתמש נפרד בעל הרשאות מינימליות במקום כ-root.
מה open-kritt עושה בפועל
open-kritt (המאגר נמצא ב-Kritt-ai/open-kritt, תחת רישיון AGPL-3.0) מפרק מחקר פגיעויות למשימות קטנות, מריץ את המשימות הללו באמצעות סוכני AI במקביל, ולאחר מכן מסיר כפילויות ומדרג את התוצאות שמתקבלות. אתם מגדירים תהליך עבודה כשרשרת של הנחיות (prompts) ממוקדות, וכל שלב מקבל הקשר מובנה מהשלבים שקדמו לו. יעד הסריקה הוא מאגר git מרוחק או מקומי. מנוע הניתוח הוא Codex או Claude Code. לאחר שמופיע מועמד לפגיעות, סקריפטים אופציונליים לאחר הניתוח יכולים לנסות לאמת אותו או לבנות הוכחת היתכנות (PoC).
מה שמתקבל בסוף הוא רשימה מדורגת של מועמדים. התייחסו אליה כאל תור למיון (triage), ולא כאל דוח סופי.
דרישות קדם
- שרת VPS המריץ Ubuntu 24.04, Debian 12 או Rocky Linux 9. מסמכי ההתקנה מציינים הפצות אלו כנבדקות, על ארכיטקטורות x86_64 ו-ARM64.
- Docker Engine עם תוסף Compose.
- Node.js 20 או גרסה חדשה יותר על המארח, כיוון ש-
./krittCLI רץ על המארח ולא בתוך מכולה. - ספק מודלים אחד: פרטי התחברות ל-Codex, או
OPENAI_API_KEY,CODEX_API_KEY,ANTHROPIC_API_KEYאוOPENROUTER_API_KEY. GITHUB_TOKENנדרש רק אם בכוונתכם לסרוק מאגרים פרטיים. ה-.env.exampleהמצורף מבהיר זאת: אסימון (token) של GitHub לבדו אינו מספיק להרצת סריקות.
התקנת Docker ו-Node 20 תחילה
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USERבצעו יציאה (logout) וכניסה מחדש (login) כדי שחברות בקבוצה החדשה תיכנס לתוקף, ולאחר מכן ודאו שתוסף ה-Compose מותקן.
docker compose versionמחרוזת גרסה מעידה על כך ש-Compose מותקן כתוסף. docker: 'compose' is not a docker command מציין שברשותכם הקובץ הבינארי העצמאי הישן docker-compose, בעוד open-kritt קורא ל-docker compose. חברות בקבוצת docker שקולה להרשאות root על המארח, לכן הוסיפו אליה רק את החשבון שמריץ את open-kritt. לגרסה המורחבת של הגדרה זו, ראו הרצת Docker על גבי VPS.
Ubuntu 24.04 מפיצה את Node 18 במאגרים שלה, אך ה-CLI מפסיק את פעולתו בכל גרסה הנמוכה מ-20. השתמשו ב-NodeSource.
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
node -vnode -v חייב להדפיס v20. או גרסה גבוהה יותר. ב-Rocky Linux 9 הפעולה המקבילה היא sudo dnf module enable nodejs:20 -y ולאחריה sudo dnf install -y nodejs.
שכפול open-kritt וקיבוע לגרסה משוחררת (tagged release)
git clone https://github.com/Kritt-ai/open-kritt
cd open-kritt
git fetch --tags
git tag --list
git checkout v1.3.0main משתנה תחת ידיך. תגית (tag) אינה משתנה. נכון לאוגוסט 2026, התגית העדכנית ביותר היא v1.3.0, שפורסמה ב-4 באוגוסט 2026, ו-git tag --list מציג את המצב הקיים ביום השכפול. ביצוע checkout לתגית משאיר את ה-repository במצב detached HEAD, וזהו המצב התקין כאן: אתה מתייחס לשכפול זה כאל פריסה מקובעת (pinned deployment), ולא כאל branch שאתה מבצע אליו commit. כדי לשדרג בעתיד, קרא את הערות השחרור, הרץ את git fetch --tags, בצע checkout לתגית החדשה, והרץ שוב את ./kritt start, שכן start בונה מחדש את ה-images.
אל תריץ את ./kritt עם sudo. התיעוד מפורש בנושא זה. ה-CLI מנהל תיקיות הרשאות מקומיות לפרויקט תחת .data/, לכן הרצה כ-root משאירה את התיקיות הללו בבעלות root, והרצה רגילה לאחר מכן לא תוכל לכתוב אליהן.
הגדרת גישה למודל באמצעות ./kritt setup
./kritt setupהפקודה יוצרת את .env מתוך .env.example אם הוא אינו קיים, מציגה את הסטטוס של כל פרט אימות, ומאפשרת להגדיר או לבטל אותם. היא לעולם אינה מדפיסה את הערכים בחזרה למסוף. גם .env וגם קובץ פרטי האימות של המנוע נכתבים עם הרשאות 0600.
אם אתם מעדיפים לבצע זאת ידנית:
cp .env.example .env
chmod 600 .env
mkdir -p .data/codex
chmod 700 .data/codexלאחר מכן, ערכו את מפתח הספק לתוך .env והשאירו את הקובץ בהרשאות 0600. כך או כך, פרטי אימות תקינים של הספק נמצאים כעת על השרת, וזו סיבה נוספת לכך שהשרת לא אמור להכיל שום דבר אחר. צרו מפתח עבור פרויקט זה בלבד, כך שביטולו בעתיד לא יפגע בשום דבר שחשוב לכם. שמירה על סודות מחוץ להישג ידם של סוכני AI מכסה את ההרגל הרחב יותר.
הגדרת תקרת הוצאות אצל ספק השירות לפני הסריקה הראשונה
open-kritt בנוי לעבודה במקביל (fan-out), וזהו המנגנון שעליו משלמים. ערכי ברירת המחדל ב-.env.example בגרסה v1.3.0 הם שמרניים: ENGINE_WORKER_COUNT=2, שמתואר בקובץ כברירת מחדל שמרנית למכונת 2-vCPU קטנה, ו-ENGINE_MAX_CONCURRENT_SCANS=1. מעליהם נמצאים ENGINE_WORKERS_PER_ACCOUNT=15, מספר הקריאות המקביליות המרבי למודל השורש המותר בחשבון ספק אחד, ו-ENGINE_CODEX_MAX_SUBAGENTS_PER_SESSION=5, כיוון שסשן Codex עשוי להפעיל עד חמישה סוכני משנה. העלאת מספר ה-workers בשרת VPS חזק יותר תגדיל בהתאם את מספר הקריאות למודל שמתבצעות בו-זמנית.
אין במאגר הקוד מנגנון להגבלת ההוצאות. לא קיימת הגדרת תקציב ב-.env.example. תנאי העצירה של המנוע עצמו הם מגבלות ה-workers הללו בתוספת ENGINE_HARNESS_TIMEOUT_SECONDS, שערך ברירת המחדל שלו הוא 7200 שניות לכל הרצה. לכן, תקרת ההוצאות חייבת להיקבע אצל ספק השירות. פתחו את ממשק הניהול של הספק והגדירו מגבלה חודשית קשיחה לפני הסריקה הראשונה, לא אחריה. המדריך שליטה בעלויות של סוכן AI בשרת VPS מפרט את ההגדרות עבור כל ספק.
קיימת גם אפשרות לעצירה מקומית. הגדרת ENGINE_WORKER_COUNT=0 משהה את משיכת המשימות החדשות, וניתן לשנות את אותם ערכי workers במסך ההגדרות לאחר שהמערכת פועלת.
מדריך זה אינו נוקב במחיר לסריקה, כיוון שהעלות תלויה בגודל המאגר, בתהליך העבודה שבניתם ובמודל שמאחוריו. בצעו סריקה אחת על מאגר קטן, ולאחר מכן בדקו את דף השימוש אצל ספק השירות לפני שתפנו את המערכת למאגרים גדולים.
הפעלת ה-stack ובדיקת תקינותו
./kritt startפעולה זו בודקת את .env ואת אחד האישורים לפחות, ולאחר מכן מריצה את docker compose up --build. הבנייה הראשונה איטית, כיוון שהיא בונה את ה-images של ה-frontend, ה-backend, ה-engine, ה-executor view ומסד הנתונים. התהליך רץ בחזית (foreground), לכן סגירת ה-SSH session תעצור את ה-stack. הפעילו אותו בתוך tmux, או העלו אותו במצב מנותק (detached) לאחר שהבנייה הראשונה הושלמה בהצלחה. אף אחת מהשיטות הללו לא שורדת אתחול (reboot) באופן עצמאי, לכן אם ברצונכם שה-stack יעלה מחדש לאחר שהשרת עולה, תבנית ה-systemd unit ב-שמירה על סוכן מאוחסן עצמית פעיל לאחר אתחול ניתנת ליישום ישיר.
docker compose up -d --build
docker compose psהפקודה docker compose ps אמורה להציג את open-kritt-frontend, open-kritt-backend, open-kritt-engine, open-kritt-executor-view ו-open-kritt-db. לאחר מכן, בדקו שה-backend מגיב בתוך השרת עצמו.
curl -s http://127.0.0.1:3002/api/healthתגובת JSON מעידה על כך שה-backend פעיל. Failed to connect to 127.0.0.1 port 3002: Connection refused מעיד על כך שהוא אינו פעיל, ו-docker compose logs backend יפרט את הסיבה לכך. עצרו את כל השירותים באמצעות docker compose down מתוך ספריית ה-repository.
תוספת אופציונלית: docker compose exec backend npm run seed טוען נתוני הדגמה (demo data), דרך פשוטה לבחון את הממשק לפני השקעת משאבים בסריקה אמיתית.
גישה לממשק המשתמש בפורט 5173 באמצעות מנהרת SSH
כל שירות בקובץ ה-compose מאזין כברירת מחדל ל-127.0.0.1: ה-frontend ב-5173, ה-backend ב-3002, ה-executor view ב-8090 ו-Postgres ב-5432. השאירו הגדרות אלו כפי שהן ובצעו העברת פורט (port forwarding) דרך SSH מהמחשב המקומי שלכם.
ssh -N -L 5173:127.0.0.1:5173 you@your-server-ipפתחו את http://localhost:5173 בדפדפן המקומי שלכם בזמן שהפקודה רצה. -N מציין שהחיבור מבצע את ההעברה בלבד ללא פתיחת shell. הוסיפו -L 8090:127.0.0.1:8090 שני לאותה פקודה כאשר תרצו לגשת גם ל-executor view.
הנטייה היא להגדיר FRONTEND_BIND_ADDRESS=0.0.0.0 ולדלג על המנהרה. אל תעשו זאת. ל-backend אין מסך התחברות, לכן כל מי שיגיע לדף זה יוכל להריץ סריקות ולנצל את יתרת הקרדיט שלכם אצל ספק הענן. קיימת מלכודת נוספת: פורט של מכולה (container) שפורסם מטופל לפני שהמדיניות המוגדרת ב-ufw נכנסת לתוקף, כך שחוק ufw deny 5173 עשוי להיראות תקין אך לא לחסום דבר. פורטים של Docker שעוקפים את ufw מציג את שרשרת החוקים שגורמת לכך.
קביעת גודל ה-VPS
ENGINE_MIN_FREE_STORAGE_GB מוגדר כברירת מחדל ל-20, והמנוע מסרב להפעיל מכולת סריקה חדשה עבור משימה כאשר שטח האחסון הפנוי יורד מתחת לערך זה. הדימויים שנבנו, מטמון ה-checkout, נתוני ה-Postgres ומרחבי העבודה של המשימות נמצאים כולם על אותו דיסק, לכן VPS בנפח 20 GB לעולם לא יתחיל סריקה. התייחסו ל-40 GB כאל רף מינימלי, והקצו יותר אם אתם סורקים מאגרים גדולים.
זיכרון עובד לפי חישוב אריתמטי פשוט. ENGINE_MEMORY_RESERVE_GB=2 שומר זיכרון עבור המנוע, מסד הנתונים, ה-API ותקורות קצרות מועד, וכל מריץ סריקה (scan runner) נושא עמו הקצאה משוריינת ומגבלה קשיחה של ENGINE_SCAN_RUNNER_MEMORY_MB=1536. לכן, שני עובדים דורשים כ-5 GB עוד לפני ששום דבר אחר רץ. המנוע מאשר רק את המריצים שנכנסים בתקציב הנותר, כך שבשרת קטן הסריקות נכנסות לתור במקום להיכשל, וזהו מצב כשל עדיף בהרבה על ה-out-of-memory killer.
שתי הגדרות ניקוי (prune) מופעלות כברירת מחדל: ENGINE_AUTO_PRUNE_DOCKER_BUILD_CACHE ו-ENGINE_AUTO_PRUNE_UNUSED_DOCKER_IMAGES. לאחר השלמת משימה, המנוע מסיר מטמון בנייה שאינו בשימוש, דימויים שאינם בשימוש ומכולות סריקה שנעצרו. דימויים שאליהם מפנה מכולה רצה, bind mounts, נתוני מסד נתונים, אישורים ו-volumes נשמרים. זוהי סיבה נוספת לא לשתף את המארח: כלי ניקוי שלא הגדרתם רץ מול ה-Docker daemon הזה.
הגדרות המנוע שרוב האנשים משנים בסופו של דבר
ENGINE_WORKER_COUNT: סך כל משבצות העובדים המשותפות לשלבי הסריקה ולעיבוד שלאחר מכן. הגדירו ל-0 כדי להשהות קליטת משימות חדשות.ENGINE_MAX_CONCURRENT_SCANS: כמה סריקות מורשות לרוץ בו-זמנית. סריקות בתור ממתינות עד שמאגר המשימות הפעילות מתרוקן.ENGINE_MAX_WORKERS_PER_SCAN: 0 מחלק את סך המשבצות באופן שווה בין הסריקות.ENGINE_HARNESS_TIMEOUT_SECONDS: 7200 כברירת מחדל. זהו משך הזמן המקסימלי שמשימה בודדת שיצאה משליטה יכולה להימשך.ENGINE_MIN_FREE_STORAGE_GB: רף האחסון המינימלי.ENGINE_IGNORE_LOW_STORAGE=trueמבטל את מנגנון ההגנה, והקובץ מזהיר שפעולה זו עלולה למלא את דיסק המארח.ENGINE_SCAN_RUNNER_MEMORY_MB: מגבלת זיכרון קשיחה לכל מריץ. 0 מסיר את המגבלה.
סריקת מאגר מקומי ללא דליפת מידע
LOCAL_REPOS_PATH מוגדר כברירת מחדל ל-./local_repos ומצורף (bind-mounted) לתוך המכולות של ה-backend וה-engine בנתיב /local_repos, כך שמאגר שתניחו בתיקייה זו במערכת המארחת יופיע מיד בתוך המכולות. השתמשו ב-clone נקי, ולא בעץ העבודה (working tree) שלכם. מכולת המשימה מקבלת עותק שניתן לכתיבה, הרשאות root בתוכה, וגישה יוצאת לאינטרנט; משמעות הדבר היא שכל קובץ שנמצא בעותק זה עלול להשתנות או להישלח אל מחוץ לשרת. הסירו קובצי .env ומפתחות פרטיים לפני העתקת פרויקט לתיקייה.
מה אתם מקבלים, ומה לא
אתם מקבלים ממצאים מדורגים של מועמדים. אתם לא מקבלים פגיעויות מאומתות. דירוג וניכוי כפילויות קובעים את סדר התור לטיפול שלכם. הם אינם מוכיחים שממצא הוא אמיתי. סקריפטים של פוסט-פרוססינג יכולים לנסות לבצע אימות ולבנות הוכחת היתכנות (PoC), וזהו האות החזק ביותר שהכלי מציע, אך סקריפט שנכשל אינו מהווה הוכחה לכך שהממצא שגוי. אדם עדיין קורא כל מועמד.
מדריך זה אינו טוען דבר לגבי כמות הבאגים האמיתיים ש-open-kritt מוצא, כיוון שלא מדדנו זאת. כל מי שמצטט שיעור זיהוי עבור בסיס הקוד שלכם לא הריץ את הכלי מול בסיס הקוד שלכם. סרקו תחילה מאגר שאתם כבר מכירים היטב: ממצאים שאתם יכולים לשפוט בעצמכם הם הכיול הזול ביותר שקיים.
הרשאות חשובות כאן יותר מאשר ברוב הכלים המותקנים עצמאית (self-hosted). הסוכנים מהדרים ומריצים קוד ומגיעים לרשת, לכן שלב הוכחת ההיתכנות עלול לגעת במערכות חיות. כוונו את הכלי לקוד שבבעלותכם או לקוד שאתם מורשים לבדוק, ורשמו את היקף היעד לפני שתריצו דבר מה. אם הגדרתם את ANTHROPIC_API_KEY ואתם משתמשים במנוע Claude Code, הרגלי ה-sandboxing המפורטים ב-הרצת Claude Code בצורה בטוחה על גבי VPS חלים גם על סוכנים אלו.
FAQ
מדוע open-kritt זקוק ל-VPS משלו?
מכיוון שסוכני הניתוח שלו רצים כ-root בתוך מכולות עבודה זמניות בעלות עותקים לכתיבה של הקוד שלך וגישה ישירה לאינטרנט, ומכיוון ששירות המנוע מבצע mount ל-socket של ה-Docker המארח כדי להפעיל מכולה אחת לכל משימה. כל תהליך שמגיע ל-socket הזה יכול להפעיל מכולה שמבצעת mount למערכת הקבצים של המארח, לכן יש להתייחס לכל ה-stack כאל root על המארח שלו. ב-VPS ייעודי זהו פשרה מקובלת, ובנייה מחדש של השרת אינה עולה דבר. בתחנת העבודה היומית שלך, הדבר מציב את מפתחות ה-SSH ופרופילי הדפדפן שלך בתוך אותו גבול אמון של הקוד שאתה סורק.
האם ניתן לחשוף את פורט 5173 במקום להשתמש ב-SSH tunnel?
לא מומלץ לעשות זאת. ה-backend משוחרר ללא אימות יישום, לכן הפורט הוא הדבר היחיד שחוצץ בין האינטרנט לבין הממצאים שלך ויתרת הספק. קובץ ה-compose קושר כל שירות ל-127.0.0.1 מהסיבה הזו. הרץ את ssh -N -L 5173:127.0.0.1:5173 you@your-server-ip וגלוש ל-http://localhost:5173 באופן מקומי. חוק ufw אינו תחליף, מכיוון שפורט Docker מפורסם מטופל לפני שהמדיניות המוגדרת כברירת מחדל של ufw מיושמת.
כיצד אוכל למנוע מ-open-kritt להוציא יותר מהמתוכנן?
הגדר מגבלה קשיחה במסוף של ספק המודלים שלך לפני הסריקה הראשונה, מכיוון של-open-kritt אין הגדרת תקציב משלו. שמור על ברירות המחדל של ה-concurrency עבור הריצות הראשונות, ENGINE_WORKER_COUNT=2 ו-ENGINE_MAX_CONCURRENT_SCANS=1, וזכור שחשבון ספק אחד מאפשר עד 15 קריאות מודל root בו-זמנית כברירת מחדל, בעוד שסשן Codex עשוי להריץ עד חמישה סוכני משנה. ENGINE_WORKER_COUNT=0 משהה את איסוף המשימות החדשות ומהווה את העצירה המקומית המהירה ביותר.
באיזו גרסה כדאי להשתמש?
תמיד ב-tag, לעולם לא ב-main. git fetch --tags ולאחריו git tag --list מציגים את מה שזמין, ו-v1.3.0, שפורסמה ב-4 באוגוסט 2026, היא הגרסה החדשה ביותר נכון לכתיבת שורות אלו. קיבוע גרסה מבטיח שבנייה מחדש כעבור חודשים תייצר את אותו ה-stack, והוא הופך את השדרוג להחלטה מודעת לאחר קריאת הערות השחרור, ולא לתופעת לוואי של ביצוע clone ביום אחר.
סריקה לעולם לא מתחילה. מה עלי לבדוק?
בדוק תחילה את שטח הדיסק הפנוי, מכיוון שהמנוע לא יפעיל מכולת סריקה לכל משימה כאשר האחסון הפנוי נמוך מ-ENGINE_MIN_FREE_STORAGE_GB, שערך ברירת המחדל שלו הוא 20 GB. לאחר מכן בדוק ש-ENGINE_WORKER_COUNT אינו 0, מכיוון שערך זה משהה את איסוף המשימות החדשות. לאחר מכן ודא שפרטי ההתחברות למודל אכן מוגדרים על ידי הרצת ./kritt setup, מכיוון ש-GITHUB_TOKEN כשלעצמו אינו יכול להריץ סריקות. docker compose logs engine מציין את הסיבה לכך שהוא דילג על המשימה.