آموزش نصب امن DeepSeek Harness روی VPS
نحوه نصب DeepSeek Harness روی لینوکس و ایمنسازی پورت 3080 با تونل SSH را بیاموزید. با پین کردن نسخه npm و محدود کردن دسترسی، از اجرای دستورات غیرمجاز در سرور جلوگیری کنید.
DeepSeek Harness چیست
DeepSeek Harness (dsh) یک runtime برای عاملهای Node.js است که میتوانید آن را روی یک VPS (سرور مجازی خصوصی) اجرا کنید. روش امن برای اجرای آن، محدود کردن دسترسی به 127.0.0.1 است، بهطوری که مرورگر شما از طریق یک تونل SSH (پوسته امن) به آن متصل شود. این ابزار یک رابط کاربری وب (UI) را روی پورت 3080 ارائه میدهد و برخلاف ابزارهای ترمینال، در محیط گرافیکی اجرا میشود. این وبسرور بهصورت داخلی هیچ درخواستی برای رمز عبور ندارد؛ بنابراین اگر پورت 3080 را در اینترنت باز بگذارید، هر کسی که آن را پیدا کند به عاملی دسترسی خواهد داشت که میتواند فایلهای شما را بخواند و دستورات را با سطح دسترسی کاربر لینوکس شما اجرا کند.
DeepSeek این ابزار را در تاریخ 13 اوت 2026 تحت مجوز MIT و در قالب بسته npm با نام @deepseek-ai/dsh منتشر کرد. این پروژه خود را یک نسخه پیشنمایش برای توسعهدهندگان معرفی کرده و اعلام کرده است که باید انتظار تغییرات ناسازگار با نسخههای قبلی را داشت. تمام شماره نسخههای ذکرشده در ادامه، مربوط به وضعیت اوت 2026 هستند؛ بنابراین پیش از کپی کردن هر دستوری روی سروری که اهمیت دارد، مخزن پروژه را بررسی کنید.
یک ایده اصلی در کل طراحی این پروژه جریان دارد: همه چیز یک پلاگین است. آداپتور مدل، رجیستری ابزارها، لاگ نشست، محیط sandbox، زمانبند و خودِ حلقه عامل، همگی پلاگینهایی هستند که در یک context مشترک بارگذاری میشوند و هر کدام از آنها قابل جایگزینی است. هیچ هسته دارای امتیاز ویژهای وجود ندارد که پلاگینها صرفاً آن را تزئین کنند. همین ویژگی باعث میشود که Harness ارزش امتحان کردن را داشته باشد، اما در عین حال، تنها ریسک واقعی پروژه نیز در همین بخش نهفته است.
یک harness مدل نیست
این harness حلقهٔ agent را اجرا میکند. استدلال در مدلی در جای دیگری انجام میشود، بنابراین تا زمانی که یک API (رابط برنامهنویسی کاربردی) key یا آدرس endpoint مدلی که خودتان میزبانی میکنید را به آن ندهید، هیچچیز کار نخواهد کرد.
شما این مورد را در UI تحت بخش Settings و سپس Models پیکربندی میکنید. کاتالوگ دارای کارتهای آماده برای ارائهدهندگان بزرگ API (مانند DeepSeek، OpenAI، Anthropic) است که در آنجا یک key را وارد میکنید. گزینهٔ "Add a custom provider" گزینهٔ جالبتری است: این گزینه یک provider ID، یک نام نمایشی، یک base URL، یک پروتکل API و یک credential دریافت میکند و از پروتکل سازگار با OpenAI استفاده میکند، بنابراین هر gateway یا سرور محلی که این پروتکل را پیادهسازی کرده باشد، کار خواهد کرد. ارائهدهندگان سفارشی همچنین میتوانند endpoint سازگار با OpenAI یعنی GET /models را پرسوجو کنند تا لیست مدلها را برای شما تکمیل کنند.
این همان روشی است که با آن harness را به مدلی روی همان VPS متصل میکنید. Ollama یک API سازگار با OpenAI را در http://127.0.0.1:11434/v1/ ارائه میدهد و نیاز دارد که فیلد API key با هر رشتهای پر شود، که طبق قرارداد ollama است، زیرا این فیلد اجباری است و سپس نادیده گرفته میشود. اینکه آیا مدلی که به اندازه کافی کوچک است تا در VPS شما جای بگیرد برای هدایت یک agent مناسب است یا خیر، پرسش دشوارتری است و تفاوت بین Ollama و vLLM به عنوان یک سرور مدل محلی تعیین میکند که پاسخ این پرسش چقدر از RAM شما را اشغال خواهد کرد.
کلیدهایی که در UI تایپ میشوند، فقطنوشتنی (write-only) هستند. harness آنها را در $DSH_HOME/.credentials.yaml ذخیره میکند و فقط یک ارجاع به credential را در settings.yaml نگه میدارد. $DSH_HOME بهصورت پیشفرض ~/.dsh است. با آن فایل مانند یک فایل رمز عبور رفتار کنید، زیرا در واقع همینطور است: هر کسی که آن را بخواند میتواند بودجه API شما را خرج کند.
What you need before you install
- a VPS running Ubuntu 24.04 or another current Linux, with SSH access
- Node.js 22.19 or newer in the 22.x line, or Node.js 24 and above, which is what the project builds and tests against
- a normal user account, not
root, because the agent runs shell commands as whoever started the process pnpmon the PATH if you plan to install plugins, since the plugin command shells out to it- port 3080 closed on your firewall and on your provider's separate network firewall
Ubuntu's own nodejs package is older than the harness needs, so install Node from NodeSource or nvm rather than reaching for apt install nodejs. If the VPS is fresh, hardening SSH before anything else is worth ten minutes, because the tunnel you are about to depend on is only as good as the SSH server behind it.
نصب DeepSeek Harness روی یک VPS با نسخه ثابت
node --version
npx @deepseek-ai/dsh@0.1.0-rc.6 webnpx بسته را دانلود کرده و باینری dsh را اجرا میکند. web یک نام مستعار برای --profile web است که اپلیکیشن مرورگر را راهاندازی میکند و فرآیند، آدرسی که روی آن در حال گوش دادن است را چاپ میکند. مقدار پیشفرض http://127.0.0.1:3080 است.
نسخه را ثابت (Pin) کنید. npx @deepseek-ai/dsh web هر آنچه که تگ latest در لحظه اجرا به آن اشاره دارد را دریافت میکند، و این پروژه تاکنون چندین نسخه کاندیدای انتشار (release candidate) ارائه داده و اعلام کرده است که تغییرات ساختاری (breaking changes) در راه هستند. 0.1.0-rc.6 همان چیزی است که latest در تاریخ 13 August 2026 به آن اشاره داشت. نسخه ثابت به این معنی است که سروری که امروز راهاندازی میکنید، ماه آینده نیز به همان شکل عمل میکند؛ بنابراین ارتقا به تصمیمی تبدیل میشود که شما میگیرید، نه اتفاقی که ناگهان با آن مواجه میشوید.
برای استفاده روزمره، آن را یکبار نصب کنید تا در هر بار اجرا نیاز به حل مجدد وابستگیها نباشد.
npm install -g @deepseek-ai/dsh@0.1.0-rc.6
dsh --profile web --helpاجرای خط دوم ارزشمند است، زیرا لانچر و اپلیکیشن وب مجموعهفلگهای جداگانهای دارند. dsh --help گزینههای مربوط به خودِ لانچر را نمایش میدهد. dsh --profile web --help فلگهایی که اپلیکیشن وب میپذیرد را نشان میدهد؛ جایی که --port، --host و فلگ تکرارپذیر --trusted-host در آن قرار دارند.
اکنون تأیید کنید که روی چه آدرسی در حال گوش دادن است.
ss -tlnp | grep 3080ستون آدرس محلی باید 127.0.0.1:3080 را نشان دهد. اگر 0.0.0.0:3080 را نشان میدهد، رابط کاربری از طریق اینترنت در دسترس است و باید پیش از انجام هر کار دیگری، فرآیند را متوقف کنید.
چرا هرگز نباید پورت 3080 را منتشر کنید
این وبسرور فاقد لایه احراز هویت است. پیکربندی آن تنها شامل یک میزبان و پورت برای گوش دادن (listen) است و کل سطح حمله همین است. کنترل دسترسی برای استقرار در محیطهای غیر از localhost، یک تنظیم جداگانه برای میزبانهای مورد اعتماد (trusted-host) است که به هیچ وجه یک صفحه ورود (login) محسوب نمیشود.
حال در نظر بگیرید چه چیزی پشت این پورت قرار دارد. این عامل (agent) فایلها را در فضای کاری ویرایش کرده و دستورات shell را اجرا میکند، و اعتبارنامههای ارائهدهنده سرویس شما نیز در کنار آن روی دیسک قرار دارد. بنابراین، باز بودن پورت 3080 به معنای داشتن یک shell از راه دور با رابط کاربری چت است که با دسترسی کاربری که آن را اجرا کرده و با کلید API شما کار میکند. برای سوءاستفاده از این وضعیت، هیچکس به اکسپلویت نیاز ندارد. آنها فقط به شماره پورت نیاز دارند و اسکنرها شماره پورتها را تنها چند ساعت پس از آنلاین شدن یک میزبان پیدا میکنند.
رابط خط فرمان (CLI) نیز با این موضوع موافق است. از نسخه 0.1.0-rc.6 به بعد، این ابزار عمداً از --host 0.0.0.0 پشتیبانی نمیکند و بهجای اجرا، با یک خطای کاربری متوقف میشود. این امتناع یک قابلیت امنیتی است، بنابراین به دنبال وصلهای برای حذف آن نباشید.
اگر استفاده از تونل برای شما مناسب نیست، دو روش استقرار دیگر منطقی هستند. سرور را در یک شبکه overlay خصوصی قرار دهید تا فقط دستگاههای خودتان بتوانند به آدرس آن مسیریابی کنند؛ این همان کاری است که یک سرور کنترل Headscale خودمیزبان برای شما انجام میدهد. یا آن را پشت یک reverse proxy قرار دهید که پیش از رسیدن درخواست به پورت 3080، آن را احراز هویت کند؛ برای مثال استفاده از یک سرور Authentik برای single sign-on جهت انجام forward auth. یک reverse proxy بدون احراز هویت در مقابل سرویس، یک کنترل امنیتی نیست؛ بلکه صرفاً یک URL طولانیتر است.
دسترسی به رابط کاربری وب از طریق تونل SSH
این دستور را روی لپتاپ خود اجرا کنید، نه روی سرور.
ssh -N -L 3080:127.0.0.1:3080 you@your-serverدستور -L پورت 3080 را روی لپتاپ شما باز میکند و هر چیزی که به آن متصل شود را از طریق نشست رمزنگاریشده SSH هدایت میکند. بخش 127.0.0.1:3080 روی سرور تحلیل (resolve) میشود، بنابراین اتصال از طریق loopback به harness میرسد، دقیقاً همانطور که گویی پشت همان دستگاه نشستهاید. دستور -N مشخص میکند که shell از راه دور اجرا نشود، زیرا شما فقط به این forward نیاز دارید.
سپس http://127.0.0.1:3080 را در مرورگر محلی خود باز کنید. اگر پورت 3080 روی لپتاپ شما اشغال است، عدد سمت چپ را تغییر دهید: ssh -N -L 3180:127.0.0.1:3080 you@your-server، سپس به http://127.0.0.1:3180 بروید. عدد سمت چپ مربوط به سیستم محلی و عدد سمت راست مربوط به سرور است، بنابراین فقط عدد سمت چپ تغییر میکند.
آن را در ~/.ssh/config ذخیره کنید تا دیگر نیازی به تایپ کردن آن نباشد.
Host dsh
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/id_ed25519
LocalForward 3080 127.0.0.1:3080پس از آن، ssh -N dsh تونل را برقرار میکند. اگر مرورگر گزارش دهد که اتصال رد شده است (connection refused)، معمولاً به این معنی است که تونل برقرار است اما در سمت دیگر چیزی در حال گوش دادن نیست، زیرا SSH پورت را فارغ از اینکه harness در حال اجرا باشد یا خیر، forward میکند. وضعیت سرور را با دستور ss که در بالا ذکر شد، بررسی کنید.
تداوم اجرای harness پس از خروج از سیستم
یک دستور npx با بستن shell شما متوقف میشود. اما یک systemd user service پس از خروج از سیستم همچنان فعال میماند و در صورت crash یا reboot، harness را دوباره اجرا میکند.
loginctl enable-linger $USER
mkdir -p ~/.config/systemd/user
command -v dshتنظیم enable-linger اهمیت دارد، زیرا سرویسهای کاربری معمولاً با پایان آخرین session شما متوقف میشوند؛ بنابراین بدون این تنظیم، harness به محض بستن tunnel از کار میافتد. مسیر مطلق (absolute path) نمایش داده شده توسط command -v dsh را در unit قرار دهید، زیرا systemd از PATH ساخته شده توسط login shell شما استفاده نمیکند.
[Unit]
Description=DeepSeek Harness web UI
After=network-online.target
[Service]
Type=simple
WorkingDirectory=%h/projects/site
ExecStart=/usr/local/bin/dsh web
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.targetتنظیم WorkingDirectory صرفاً ظاهری نیست. فرآیند dsh از دایرکتوری فراخواننده به عنوان مکان پیشفرض فایلسیستم استفاده میکند؛ بنابراین اگر سرویس در مسیر اشتباهی اجرا شود، agent فضای کاری (workspace) پیشفرض نادرستی خواهد داشت. البته همچنان میتوانید فضای کاری را از طریق UI انتخاب کنید.
systemctl --user daemon-reload
systemctl --user enable --now dsh
systemctl --user status dshواحدی (unit) که از اجرا سر باز میزند، تقریباً همیشه به دلیل مسیر اشتباه ExecStart یا نسخه Node ناسازگار با binary است و journalctl --user -u dsh -n 50 مشخص میکند کدام مورد است. همین الگو برای زنده نگه داشتن هر coding agent روی یک VPS نیز صدق میکند و حالتهای شکست (failure modes) در همه آنها یکسان است.
یک افزونه چه کارهایی میتواند انجام دهد
افزونه ماژولی است که سرویسها، رویدادهای تایپشده و اثرات برگشتپذیر را به یک زمینه (context) مشترک اضافه میکند. نقاط توسعه (extension points) بخشهایی هستند که ارزش مطالعه دقیق دارند:
- ثبت یک ارائهدهنده مدل در
ctx.llm - افزودن ابزارهای مخصوص مدل در
ctx.tools - فراهم کردن بکاند shell در پشت
ctx.shell - فراهم کردن دسترسی به سیستم فایل یا سیاستهای امنیتی در پشت
ctx.fs - ثبت دستورات انسانی در
ctx.commands - اجرای کارهای پسزمینه از طریق
ctx.jobs - بستهبندی فرآیندهای ایجاد شده (spawned processes) با یک بکاند
ctx.sandbox - رهگیری درخواستها و فراخوانی ابزارها از طریق رویدادهای
agent/*وtools/* - گسترش وضعیت نشست (session state) پایدار
- هدایت رابط کاربری (UI) از طریق
ctx.agents
این لیست را از دید یک مهاجم بخوانید. یک افزونه میتواند لایه سیستم فایل و لایه shell را تأمین کند و در میانه هر فراخوانی ابزاری که مدل انجام میدهد، قرار بگیرد. هیچ پنجره تأیید دسترسی بین یک افزونه و این نقاط اتصال وجود ندارد، زیرا افزونه کدهای معمولی Node است که در همان فرآیندی بارگذاری میشود که سایر بخشها در آن اجرا میشوند. نصب یک افزونه به معنای اجرای کد یک غریبه با دسترسیهای عامل (agent) شماست، و دسترسیهای عامل شما همان دسترسیهای کاربر Unix شماست.
این همان تصمیم اعتماد است که هنگام اتصال یک سرور MCP به یک عامل روی VPS میگیرید، جایی که MCP پروتکل زمینه مدل (Model Context Protocol) است. به همین دلیل است که اجرای ایمن یک عامل کدنویسی روی VPS با حساب کاربری که تحت آن اجرا میشود شروع میشود، نه با مدل؛ و به همین دلیل است که حملات زنجیره تأمین npm آسیب شدیدی به سرورها میزنند: مرحله نصب همان نقطه نفوذ است و هیچ هشداری به شما داده نمیشود.
منشأ پلاگینها
پلاگینها در پروفایلها قرار دارند. پروفایل یک ترکیب نامگذاریشده است که در $DSH_HOME ذخیره میشود و مقدار پیشفرض آن ~/.dsh است. هر دایرکتوری پروفایل، پلاگینهای خارج از درخت (out-of-tree) نصبشده را در خود نگه میدارد. CLI با ارسال مستقیم آرگومانهای شما به pnpm و استفاده از دایرکتوری پروفایل به عنوان دایرکتوری کاری (working directory)، آنها را مدیریت میکند.
dsh plugin --profile web add github:deepseek-harness/turtle-ui
dsh plugin --profile web remove turtle-uiاز آنجا که آرگومانها بدون تغییر به pnpm میرسند، add، remove، update و why همانطور رفتار میکنند که در هر پروژه pnpm دیگری عمل میکنند و یک پلاگین میتواند یک بسته npm یا یک ارجاع به GitHub باشد. pnpm باید ابتدا در PATH موجود باشد. در Node 22 و نسخههای بعد از آن، corepack enable pnpm آن را در مسیر قرار میدهد.
کشف پلاگینها از طریق یک موضوع (topic) در GitHub انجام میشود. نویسندگان پلاگین، موضوع dsh-plugin را به مخزن خود اضافه میکنند و مرور آن موضوع، روشی است که میتوانید بفهمید چه چیزی موجود است. موضوع، برچسبی است که نویسنده به مخزن خود اعمال میکند. هیچکس آن را بررسی یا امضا نمیکند و صفحه موضوع بر اساس تعداد ستارهها رتبهبندی میشود که معیاری برای محبوبیت است، نه امنیت.
چهار عادت، مدیریت این موضوع را آسان میکند. پیش از نصب، سورسکد را بخوانید؛ چرا که اکثر پلاگینها به اندازهای کوچک هستند که در ده دقیقه خوانده شوند. به جای دنبال کردن یک branch، نسخه دقیق یا commit خاص را ثابت (pin) کنید. harness را تحت کاربری اجرا کنید که مالک هیچ چیز دیگری نیست و روی یک VPS باشد که آمادگی بازسازی کامل آن را دارید. به agent یک API key اختصاصی با محدودیت هزینه جداگانه بدهید که از کلیدی که سرویسهای production شما استفاده میکنند، متمایز باشد.
اگر ترجیح میدهید پیش از انتخاب نهایی، طراحیها را مقایسه کنید، harness چند-عاملی Omnigent با ساختاری متفاوت به همان مشکل پاسخ میدهد و با وارد شدن پلاگینها به بازی، تفاوتها و اولویتها کاملاً آشکار میشوند.
چه چیزی زودتر از همه دچار مشکل میشود
نسخه Node خیلی قدیمی است. این پروژه Node 22.19 و نسخههای جدیدتر در شاخه 22.x، یا Node 24 و بالاتر را هدف قرار داده است و تستهای CI نیز با این نسخهها انجام میشوند. یک runtime قدیمی هنگام شروع به کار با خطا مواجه میشود، زیرا کد از سینتکس و APIهایی استفاده میکند که در آن نسخه وجود ندارند. پیش از هر کار دیگری، node --version را اجرا کنید.
پورت 3080 قبلاً اشغال شده است. ممکن است یک harness دوم، یک پردازش معلق (stale) یا یک برنامه نامرتبط دیگر در حال استفاده از پورت 3080 باشد. آن را با ss -tlnp | grep 3080 پیدا کنید و سپس متوقفش کنید، یا harness را با استفاده از dsh web --port 3180 در جای دیگری اجرا کنید. --port متعلق به برنامه وب است، بنابراین باید بعد از web بیاید.
مرورگر نمیتواند از طریق تونل متصل شود. اطمینان حاصل کنید که به 127.0.0.1 مراجعه کردهاید و نه آدرس عمومی سرور، زیرا پورت فوروارد شده فقط روی لپتاپ شما وجود دارد. سپس بررسی کنید که آیا harness روی سرور در حال گوش دادن (listening) است یا خیر، زیرا SSH تونل را برقرار میکند، صرفنظر از اینکه در سمت دیگر پاسخی دریافت شود یا نه.
دستور dsh plugin بلافاصله با خطا مواجه میشود. این دستور یک wrapper برای pnpm است، بنابراین نبود فایل باینری pnpm باعث میشود پیش از شروع هرگونه عملیات پلاگین، اجرای آن متوقف شود.
ایجنت نمیتواند پروژه شما را ببیند. فضای کاری (workspace) بهصورت پیشفرض همان دایرکتوری است که پردازش در آن شروع شده است؛ بنابراین اگر WorkingDirectory یک واحد (unit) دایرکتوری home شما باشد، ایجنت همان دایرکتوری home را دریافت میکند. فضای کاری را در رابط کاربری انتخاب کنید یا واحد مربوطه را اصلاح کرده و دوباره بارگذاری کنید.
FAQ
آیا قرار دادن رابط کاربری وب DeepSeek Harness روی پورت 3080 امن است؟
خیر. وبسرور این برنامه فاقد سیستم احراز هویت داخلی است و عاملی (agent) که در پسزمینه اجرا میشود، فایلها را ویرایش کرده و دستورات shell را با دسترسی کاربری که پروسه را اجرا کرده است، اجرا میکند؛ ضمن آنکه کلید API ارائهدهنده شما نیز روی همان دیسک ذخیره شده است. شنونده (listener) را روی 127.0.0.1 نگه دارید و از طریق یک SSH tunnel به آن دسترسی پیدا کنید. استفاده از یک شبکه خصوصی (overlay network) یا یک reverse proxy که پیش از رسیدن درخواست به پورت، آن را احراز هویت میکند نیز راهکار مناسبی است. از نسخه 0.1.0-rc.6 به بعد، CLI استفاده از --host 0.0.0.0 را رد کرده و با یک خطای راهنما متوقف میشود که نشاندهنده دیدگاه توسعهدهندگان نسبت به این موضوع است.
آیا به کلید API سرویس DeepSeek نیاز دارم یا میتوانم از مدل محلی استفاده کنم؟
هر دو امکانپذیر است، زیرا این ابزار یک محیط اجرا (runtime) است و نه یک مدل. در بخش Settings و سپس Models، میتوانید یک کلید را در کارت ارائهدهنده کاتالوگ وارد کنید یا گزینه "Add a custom provider" را انتخاب کرده و یک base URL که از پروتکل سازگار با OpenAI پشتیبانی میکند، به آن بدهید. یک سرور محلی Ollama در آدرس http://127.0.0.1:11434/v1/ پاسخ میدهد و هر رشتهای را در فیلد کلید API میپذیرد. کلیدها در $DSH_HOME/.credentials.yaml ذخیره میشوند که مسیر پیشفرض آن ~/.dsh/.credentials.yaml است.
نصب افزونه DeepSeek Harness دقیقاً چه دسترسیهایی به آن میدهد؟
دسترسیهای همان حسابی که harness را اجرا میکند. یک افزونه در واقع کد Node است که در همان پروسه بارگذاری میشود و نقاط اتصال (extension points) آن شامل بکاند shell، لایه فایلسیستم، رجیستری ابزارها و رویدادهایی است که هر فراخوانی ابزار را در بر میگیرند. هیچ مکانیزم sandbox برای ایزوله کردن افزونه از این بخشها وجود ندارد، مگر اینکه خود افزونه sandbox اختصاصیاش را فراهم کند. پیش از نصب، سورسکد را مطالعه کنید و harness را با کاربری اجرا کنید که به هیچ فایل یا داده مهمی دسترسی ندارد.
کدام نسخه را باید نصب کنم و آیا در آینده همچنان کار خواهد کرد؟
یک نسخه دقیق را نصب کنید، برای مثال npx @deepseek-ai/dsh@0.1.0-rc.6 web. این همان نسخهای است که تگ latest در تاریخ 13 آگوست 2026 به آن اشاره داشت. این پروژه خود را یک نسخه پیشنمایش توسعهدهنده (developer preview) مینامد و اعلام کرده است که تغییرات ناسازگار در راه است؛ بنابراین یک دستور بدون نسخه ثابت (unpinned) ممکن است از یک روز تا روز بعد رفتار متفاوتی داشته باشد. پیش از ارتقا، مخزن پروژه را بررسی کنید و انتظار داشته باشید که کلیدهای پیکربندی و رابطهای افزونه تا زمانی که نسخه با 0 شروع میشود، تغییر کنند.