מה המשמעות של http://127.0.0.1:3080 ב-DeepSeek Harness?
הכתובת http://127.0.0.1:3080 מופיעה כי הממשק מאזין ל-localhost בלבד מטעמי אבטחה. למדו כיצד לגשת ל-Web UI מרחוק באמצעות SSH tunnel ומדוע חשיפת הפורט מסוכנת.
מה המשמעות של dsh web: http://127.0.0.1:3080
כאשר מפעילים את פרופיל ה-Web של DeepSeek Harness על שרת VPS, הוא מדפיס שתי שורות וממתין:
dsh web: http://127.0.0.1:3080
Ready.127.0.0.1 היא כתובת ה-loopback. זו הכתובת שבה מכונה משתמשת כדי לתקשר עם עצמה. socket שמאוגד ל-127.0.0.1 מקבל חיבורים מתהליכים שרצים על אותה מכונה בלבד, ולא משום מקום אחר. לכן, השורה הזו מוסרת שני דברים בו-זמנית: היכן ממשק ה-Web מאזין, ומי מורשה לגשת אליו. רק המכונה שעליה רץ dsh.
זו הסיבה שה-URL לא מגיב כאשר מדביקים אותו בדפדפן במחשב הנייד שלכם. ה-127.0.0.1 של המחשב הנייד הוא המחשב הנייד עצמו. ה-harness מאזין על ה-127.0.0.1 של ה-VPS, שהיא מכונה שונה עם stack של loopback שונה. שום דבר לא תקול. עליכם להעביר את החיבור אל המכונה שלכם.
ה-README הרשמי מציין את ברירת המחדל בבירור: "הפקודה מפעילה את ממשק ה-Web, שמוגש ב-http://127.0.0.1:3080 כברירת מחדל". כתובת ה-bind מגיעה מתוסף ה-webserver host, ה-@deepseek-ai/dsh-host-webserver, שהמפתח host שלו מתועד כ-"Listen host; the two supported values are loopback and all-interfaces". ה-loopback הוא מה שתקבלו אלא אם תשנו זאת. אם נושא הפורטים חדש לכם, איך פורטים עובדים בלינוקס מכסה את מודל הכתובת-פלוס-פורט שעליו כל זה מתבסס.
מדוע ממשק ה-Web UI מאזין ל-localhost בלבד
dsh הוא רכיב תשתית של סוכן, והוא התוכנית שעוטפת את המודל: הוא מנהל את הלולאה, את קריאות הכלים ואת ההרשאות שבהן קריאות אלו מבוצעות. לשונית הדפדפן היא ממשק שליטה לתהליך שמריץ פקודות shell, קורא וכותב קבצים בספריית העבודה שבחרת, ומשתמש ב-API key של המודל שלך. כל מי שיכול לטעון את הדף הזה יכול לבצע את כל הפעולות הללו בתור המשתמש שמריץ את dsh. הרשת אינה הדרך היחידה להגיע להרשאות אלו: תוסף שאתה מתקין רץ בתוך אותו תהליך עם אותן הרשאות, וזו הסיבה ש-בדיקת תוסף dsh לפני התקנתו דורשת את אותה רמת זהירות כמו החלטה על הגדרות ההאזנה של השרת.
לכן, פורט 3080 אינו לוח בקרה לקריאה בלבד. טעינת הדף הזה מעניקה הרצת פקודות בשרת.
כשפותחים את ה-Web UI מגיעים ישירות לרשימת הסשנים. אין מסך התחברות, כיוון שגרסת ה-developer preview אינה כוללת חשבונות משתמש או אימות מרחוק. בשימוש ב-loopback זה עקבי: מערכת ההפעלה היא בקרת הגישה, ורק תהליכים מקומיים עוברים. אם תגדיר את אותו שרת להאזין ל-0.0.0.0 בשרת VPS עם כתובת IP ציבורית, אותו דף יהיה חשוף לכל האינטרנט, ללא כל הגנה לפניו. סורקים אוטומטיים סורקים פורטים לא שגרתיים ללא הפסקה, לכן יש להתייחס לפורט 3080 חשוף כפורט שכבר נמצא.
אל תפתח את פורט 3080 ב-firewall שלך, ואל תגדיר את שרת ה-web ב-hostל-0.0.0.0בשרת VPS ציבורי. שילוב כזה מעניק הרצת פקודות בשרת שלך לכל מי שמתחבר ראשון.
אותו היגיון תקף לכל סביבת הרצה של סוכן שאתה מתקין על שרת, וזו הסיבה ש-הרצת סוכן תכנות בצורה בטוחה על VPS מתחילה מאותו כלל: פורט השליטה של הסוכן נשאר פרטי, וגישה אליו מתבצעת דרך רכיב שאתה סומך עליו.
כיצד אוכל לפתוח את ממשק ה-Web UI של dsh מהמחשב הנייד שלי?
קיימות שלוש דרכים אמינות, וכל אחת מהן מותירה את ה-harness קשור ל-loopback.
- מנהרת SSH. שום דבר חדש לא מאזין בממשק הציבורי, וכבר יש ברשותך את פרטי ההזדהות. זו הדרך המומלצת לשימוש.
- רשת overlay פרטית, כך שהממשק נגיש מהמכשירים שלך בלבד ובלתי נראה לכל השאר.
- Reverse proxy שמבצע TLS termination (אבטחת שכבת תעבורה) ודורש סיסמה לפני העברת כל בקשה.
ההבדל ביניהן הוא האופן שבו הדפדפן שלך מגיע ל-loopback. באף אחת מהדרכים אין צורך להעביר את ה-harness מחוץ ל-loopback.
גישה באמצעות מנהרת SSH
הריצו פקודה זו במחשב האישי שלכם, לא ב-VPS:
ssh -N -L 3080:127.0.0.1:3080 you@your-vpsהשאירו את התהליך רץ, ולאחר מכן פתחו את http://127.0.0.1:3080 בדפדפן המקומי. ממשק ה-Web UI ייטען.
הארגומנט -L מכיל שלושה שדות המופרדים בנקודתיים. הראשון הוא הפורט לפתיחה במחשב האישי. השני והשלישי הם הכתובת והפורט שאליהם תועבר כל התקשרות. הפרט החשוב: 127.0.0.1 בשדה האמצעי מתורגם על ידי שרת ה-SSH ב-VPS, לאחר שהתעבורה שלכם כבר הגיעה לשם. המשמעות היא ה-loopback של ה-VPS, לא שלכם. זו בדיוק הכתובת ש-dsh הציג, וזו הסיבה שהמנהרה עובדת כאשר חיבור ישיר מהדפדפן נכשל.
-N מורה ל-SSH לא להריץ פקודה מרוחקת, כך שאתם מקבלים מעביר תעבורה ללא shell. עבור מנהרת רקע שנכשלת עם התראה ברורה במקום בשקט:
ssh -N -f -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -L 3080:127.0.0.1:3080 you@your-vps-f מעביר את התהליך לרקע לאחר אימות. ExitOnForwardFailure=yes חשוב יותר ממה שנראה: בלעדיו, SSH יתחבר בהצלחה גם אם העברת הפורטים לא הוגדרה, מה שיוביל לחיבור פעיל עם מנהרה מתה ללא אזהרה. ServerAliveInterval=30 שולח אות keepalive בכל 30 שניות כדי שמנהרה לא פעילה תשרוד פסקי זמן של NAT (תרגום כתובות רשת) בנתבים של בתי קפה או מלונות.
מה עליכם לראות
ב-VPS, ודאו מה באמת מאזין:
ss -ltnp | grep 3080תוצאה תקינה מציגה את כתובת ה-loopback:
LISTEN 0 511 127.0.0.1:3080 0.0.0.0:* users:(("node",pid=1042,fd=21))אם עמודת הכתובת המקומית מציגה 0.0.0.0:3080 במקום זאת, ממשק ה-Web UI חשוף בכל הממשקים, כולל הציבורי. עצרו אותו ותקנו את ה-bind לפני כל פעולה אחרת. אם ss מציג את ה-socket אך משאיר את השדה users: ריק, הריצו אותו עם sudo, כיוון ששם התהליך עבור socket בבעלות משתמש אחר מוסתר כברירת מחדל.
כאשר המנהרה מסרבת לעלות
SSH מדפיס זאת ויוצא:
bind [127.0.0.1]:3080: Address already in use
channel_setup_fwd_listener_tcpip: cannot listen to port: 3080הבעיה היא במחשב האישי שלכם, לא בשרת. משהו מקומי כבר תופס את פורט 3080, לרוב מנהרה קודמת ששכחתם. בחרו פורט מקומי פנוי במקום:
ssh -N -L 3081:127.0.0.1:3080 you@your-vpsרק השדה הראשון השתנה, לכן כעת עליכם לגלוש ל-http://127.0.0.1:3081 בזמן שה-harness ממשיך להאזין ב-3080. שני המספרים לא חייבים להיות זהים.
אם המנהרה עולה אך הדפדפן מדווח על סירוב חיבור או תשובה ריקה, התעבורה הגיעה ל-VPS ולא מצאה דבר בצד השני. או ש-dsh יצא, או שהוא מאזין בפורט אחר. בדקו זאת עם ss -ltnp | grep 3080 בשרת.
דבר נוסף שגורם לבעיות: npx @deepseek-ai/dsh web בחזית נסגר כאשר ה-shell נסגר, לכן ה-harness נעצר ברגע שאתם מתנתקים. הריצו אותו בתוך tmux או תחת שירות משתמש ב-systemd, שזו אותה בעיה שנפתרה ב-שמירה על סוכן פיתוח רץ ב-VPS. בזמן שאתם עובדים על צד ה-SSH, כדאי לבצע הקשחת SSH ב-VPS תחילה, כיוון שהמנהרה הופכת את התחברות ה-SSH שלכם לדלת היחידה לסוכן.
גישה דרך רשת Overlay פרטית
רשת Overlay מעניקה ל-VPS ולמחשב הנייד שלכם כתובות ברשת פרטית שאליה מצטרפים רק המכשירים שלכם. Tailscale היא הבחירה הנפוצה, והפקודה serve שלה מתאימה בדיוק למקרה זה: tailscaled רצה על ה-VPS ומחברת את localhost:3080 לעצמה, כך שהממשק נשאר על loopback ואתם לא משנים דבר בתצורה של dsh.
tailscale serve --bg localhost:3080
tailscale serve statusממשק המשתמש נגיש כעת בשם המחשב שלכם בתוך ה-tailnet, באמצעות HTTPS, ללא אף פורט פתוח בממשק הציבורי. פעולה זו מחייבת הפעלת תעודות HTTPS עבור ה-tailnet שלכם, אחרת ל-serve אין תעודה להציג. כדי להסיר את הגישה, חזרו על הפקודה עם off:
tailscale serve --https=443 offהשתמשו ב-serve, לעולם לא ב-funnel. הפקודה Funnel מפרסמת את אותו יעד לאינטרנט הציבורי, מה שמחזיר אתכם למצב של סוכן ללא אימות על פורט פתוח. שתי הפקודות נראות כמעט זהות ומבצעות פעולות הפוכות, לכן קראו את ההבדל בין Tailscale Serve ל-Funnel לפני שתקלידו אחת מהן. Tailscale כרשת פרטית מכסה את תהליך ההגדרה עצמו.
גישה דרך reverse proxy עם אימות סיסמה
זוהי האפשרות שחושפת פורט לאינטרנט באופן ממשי, ולכן האימות הוא המחסום היחיד שמונע מזרים להריץ פקודות על השרת שלכם. בחרו באפשרות זו כאשר כמה משתמשים זקוקים לממשק המשתמש ושימוש ב־tunnel עבור כל אחד מהם אינו מעשי.
היישום נשאר על 127.0.0.1:3080. nginx רץ על אותו שרת, לכן הוא יכול להגיע ל-loopback, והוא מאזין בפורט 443 עם תעודה וקובץ סיסמאות.
server {
listen 443 ssl;
server_name dsh.example.com;
ssl_certificate /etc/letsencrypt/live/dsh.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dsh.example.com/privkey.pem;
auth_basic "dsh";
auth_basic_user_file /etc/nginx/dsh.htpasswd;
location / {
proxy_pass http://127.0.0.1:3080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 3600s;
proxy_buffering off;
}
}צרו את קובץ הסיסמאות ובצעו טעינה מחדש:
sudo apt install -y apache2-utils
sudo htpasswd -c /etc/nginx/dsh.htpasswd you
sudo nginx -t && sudo systemctl reload nginxהפקודה nginx -t אמורה להדפיס syntax is ok ולאחריו test is successful. טעינה מחדש עם קובץ פגום תיכשל ותשאיר את התצורה הפעילה כפי שהיא, לכן קראו את השגיאה במקום לבצע restart עיוור.
שלוש משורות ה-proxy הללו אינן קישוט. ה-headers Upgrade ו-Connection מאפשרים ל-WebSocket handshake לעבור; בלעדיהם הדף ייטען אך לעולם לא יתעדכן. proxy_read_timeout 3600s מחליף את ברירת המחדל של 60 שניות, שאלמלא כן הייתה קוטעת הרצה ארוכה של סוכן באמצע התגובה ומשאירה את ממשק המשתמש במצב קפוא. proxy_buffering off שולח את פלט המודל לדפדפן ברגע הגעתו במקום להמתין עד לסיום התגובה. תצורת nginx כ-reverse proxy, שורה אחר שורה מסביר את השאר, ו-בחירה בין nginx, Caddy ו-Traefik מכסה ביצוע של אותה פעולה עם תעודות אוטומטיות.
השאירו את 3080 סגור ב-firewall ללא קשר ל-proxy שתבחרו, כך שהדרך היחידה פנימה תהיה דרך ה-proxy המאומת. יסודות ufw firewall מכסה את הכללים. אימות בסיסי מעל TLS הוא רף מינימלי, לא מודל אבטחה שלם: מי שמחזיק בסיסמה זו מחזיק בגישת shell לשרת שלכם. העדיפו את ה-tunnel בכל עת שניתן.
כיצד ניתן לשנות את הפורט שבו dsh web מאזין?
--port שייך ליישום ה-web, ולא למפעיל (launcher). תיעוד ה-CLI מציג את הדוגמה הבאה:
dsh --profile web --port 8080dsh web הוא כינוי (alias) של --profile web, לכן dsh web --port 8080 היא אותה פקודה. המפעיל מנתח רק את הדגלים שלו ומעביר את כל מה שמופיע אחריהם לפרופיל שנטען. לכן, דגלי המפעיל חייבים להופיע ראשונים, והאסימון (token) הראשון שהמפעיל אינו מזהה מתחיל את הארגומנטים של היישום. יש להציב את --port אחרי הפרופיל, לעולם לא לפניו.
מומלץ לקרוא את ה-URL שהפקודה מדפיסה במקום להניח מהו, שכן שורה זו מדווחת על הכתובת שאליה השרת חובר בפועל. לאחר מכן, יש לעדכן את השדה האחרון במנהרה (tunnel) שלכם בהתאם:
ssh -N -L 3080:127.0.0.1:8080 you@your-vpsלשינוי קבוע, הפורט מוגדר בתצורת הפרופיל ולא בשורת הפקודה. הפרופילים web ו-headless מאותחלים אוטומטית בשימוש הראשון מתוך תבניות המגיעות עם התוכנה, תחת ~/.dsh. אותה תיקייה היא המקום שבו נשמרים מפתח ה-API והגדרות ה-endpoint של המודל, לכן הגדרת מפתחות, מודלים ו-endpoints ב-dsh היא קריאת חובה אם אתם כבר עורכים קבצים אלו. כדי לראות מהן ההגדרות הפעילות לאחר שכל השכבות הורכבו:
dsh --dump-configתוסף ה-webserver חושף שני מפתחות בלבד: host ו-port. הגדרת port ל-0 מבקשת ממערכת ההפעלה פורט פנוי; התיעוד מציין כי "אפס מבקש פורט שהוקצה על ידי מערכת ההפעלה". הגדרה זו מבטיחה שלעולם לא תיתקלו בהתנגשות, אך היא אינה מתאימה לשימוש במנהרה (tunnel), כיוון שהמספר משתנה בכל אתחול.
מדוע dsh נכשל עם השגיאה address already in use?
הסיבה היא שתהליך אחר כבר תופס את הכתובת והפורט הללו, ולכן ה-kernel מסרב לבצע bind שני. Node מדווח על כך כך:
Error: listen EADDRINUSE: address already in use 127.0.0.1:3080מצאו את התהליך שמחזיק בפורט לפני שתשנו דבר מה:
sudo ss -ltnp | grep 3080השדה users:(("node",pid=1042,fd=21)) מציין את שם התהליך ואת ה-PID שלו. התשובה הנפוצה היא שמופע קודם של dsh שחשבתם שנסגר, עדיין פעיל בתוך חלון tmux מנותק. עצרו את התהליך ההוא באמצעות kill 1042, או הפעילו את המופע החדש בפורט אחר. שימו לב ש-127.0.0.1:3080 ו-0.0.0.0:3080 מתנגשים זה עם זה, כיוון שביצוע bind לכל הממשקים כבר כולל בתוכו את ה-loopback.
קבעו גרסה ספציפית, כיוון שמדובר בגרסת Developer Preview
הקובץ README מבהיר זאת ללא כחל וסרק: DeepSeek Harness נמצא בשלב ה-Developer Preview ועובר שינויים מהירים, וצפויים בו שינויים שאינם תואמים לאחור. אם קצב זה הוא הסיבה להיסוס שלכם, השוואה בין dsh לבין Claude Code ו-Omnigent בוחנת זאת אל מול שני כלים דומים הנמצאים בנקודות שונות על אותו עקומת פיתוח.
npx @deepseek-ai/dsh web מושך את הגרסה העדכנית ביותר שפורסמה בכל פעם שאתם מריצים אותו. שרת שלא נגעתם בו במשך שבוע עלול להפעיל CLI שונה בהרצה הבאה, עם דגלים (flags) שונים. קבעו גרסה ספציפית כדי שאתחול לא יהיה שווה ערך לשדרוג:
npx @deepseek-ai/dsh@0.1.0-rc.7 webנכון לאוגוסט 2026, החבילה שפורסמה היא בגרסה 0.1.0-rc.7. בדקו מה npx ללא תוספות ימשוך לפני שתאשרו את הפעולה:
npm view @deepseek-ai/dsh versionאם הקיבוע מסרב להתקין, או אם npx ממשיך להפעיל את הגרסה הישנה לאחר שקיבעתם גרסה חדשה, שגיאות התקנה וגרסה נפוצות מסביר כיצד לנקות את ה-cache של npx ולבדוק באיזה npm משתמש ה-Node שלכם.
דגלים עוברים בין ה-launcher לבין יישום ה-web לאורך גרסאות ה-preview. אם --port מפסיק להתנהג כפי שמתואר במדריך זה, בקשו מהיישום את רשימת הדגלים שלו במקום לנחש:
dsh --profile web --helpעבור ההתקנה עצמה, הגדרת סביבת העבודה ומפתח המודל, ראו התקנת DeepSeek Harness על גבי VPS. למדריך מקוצר עבור שלב הגישה בלבד, גישה ל-Web UI של dsh על גבי VPS מכסה את יצירת ה-tunnel ללא הסברים על תהליך ה-reasoning.
FAQ
Why can I not open http://127.0.0.1:3080 in my laptop browser?
Because 127.0.0.1 means the machine you are typing on. The DeepSeek Harness Web UI is bound to the VPS's loopback address, so only processes on the VPS can connect to it. Your laptop has its own separate loopback, and nothing is listening on port 3080 there. Forward the port over SSH with ssh -N -L 3080:127.0.0.1:3080 you@your-vps, then load http://127.0.0.1:3080 locally. The middle field of the -L argument is resolved on the server side, which is what makes it point at the harness.
Is it safe to bind the dsh Web UI to 0.0.0.0 on a public VPS?
No. The Web UI is the control surface for an agent that runs shell commands and edits files as the user running dsh, and the developer preview presents no login screen at all. Binding to all interfaces on a public IP means anyone who reaches port 3080 gets command execution on your server. Keep the bind on 127.0.0.1, keep 3080 closed at the firewall, and use an SSH tunnel, a private overlay network, or a reverse proxy that requires a password.
How do I keep the dsh Web UI running after I close my SSH session?
A foreground npx @deepseek-ai/dsh web is a child of your login shell, so it is killed when that shell exits. Start it inside a tmux session and detach with Ctrl-b d, or run it as a systemd user service with lingering enabled. The tunnel and the harness are independent: you can drop and rebuild the SSH tunnel as often as you like without touching the running harness, as long as the harness itself has a parent that outlives your login.
Why does the dsh Web UI freeze part way through a long agent run behind nginx?
Because nginx's default proxy_read_timeout is 60 seconds, so it closes a connection that produces no data for a minute, which a long agent step easily does. Set proxy_read_timeout 3600s; in the location block. Add proxy_buffering off; so output streams to the browser as it arrives, and pass the Upgrade and Connection headers with proxy_http_version 1.1; so the WebSocket handshake succeeds. Without those headers the page loads but never receives an update.