SSD Nodes Learn Hosting plans →
راهنماها Matt Connorتوسط Matt Connor · به‌روزرسانی شده 2026-08-27

امن‌سازی Ollama API: بستن پورت 11434

سرویس Ollama به‌صورت پیش‌فرض فاقد احراز هویت است و هر کسی با دسترسی به پورت 11434 می‌تواند مدل‌های شما را کنترل کند. در این مطلب 3 راهکار عملی برای ایمن‌سازی سرور بررسی شده است.

رابط برنامه‌نویسی Ollama فاقد رمز عبور است

رابط برنامه‌نویسی (API) Ollama هیچ‌گونه احراز هویتی ندارد. در سروری که اجرا می‌کنید، هیچ کاربر، رمز عبور، بررسی کلید یا لیست مجاز (allowlist) وجود ندارد. هر چیزی که بتواند یک اتصال TCP به پورت 11434 برقرار کند، می‌تواند مدل‌های شما را لیست کند، آن‌ها را اجرا نماید، مدل‌های جدید دانلود کند و مدل‌های موجود را حذف نماید.

مستندات رسمی به‌صراحت بیان می‌کنند: "هنگام دسترسی محلی به API Ollama از طریق http://localhost:11434، نیازی به احراز هویت نیست." کلمه محلی (locally) کل مدل امنیتی را در بر می‌گیرد. Ollama به‌صورت پیش‌فرض روی 127.0.0.1 گوش می‌دهد، بنابراین در یک لپ‌تاپ، رابط loopback همان کنترل دسترسی است. اگر این شنونده (listener) را به یک آدرس عمومی منتقل کنید، کنترل دسترسی از بین می‌رود، زیرا هیچ جایگزینی برای آن در نظر گرفته نشده است.

به همین دلیل است که این موضوع در یک VPS (سرور خصوصی مجازی) اهمیت دارد. حالت پیش‌فرض امن است. اولین تغییری که اکثر افراد ایجاد می‌کنند، یعنی باز کردن شنونده برای اینکه دستگاه دوم بتواند از مدل استفاده کند، همان تغییری است که تمام محافظت‌ها را به‌طور یکجا حذف می‌کند.

یک پورت 11434 باز چه اطلاعاتی را فاش می‌کند

تمام endpointها. هیچ حالت read-only یا پورت مدیریتی جداگانه‌ای وجود ندارد. این‌ها درخواست‌های واقعی هستند که به جای localhost، مستقیماً به آدرس سرور ارسال می‌شوند:

# List every model on the box
curl http://SERVER_IP:11434/api/tags

# See what is loaded into memory right now
curl http://SERVER_IP:11434/api/ps

# Run a prompt on your hardware
curl http://SERVER_IP:11434/api/generate -d '{"model":"llama3.2","prompt":"Why is the sky blue?"}'

# Write several gigabytes to your disk
curl http://SERVER_IP:11434/api/pull -d '{"model":"llama3.2"}'

# Remove a model
curl -X DELETE http://SERVER_IP:11434/api/delete -d '{"model":"llama3.2"}'

از دیدگاه اپراتور، چهار مشکل اصلی رخ می‌دهد:

  • پردازنده (CPU) یا کارت گرافیک (GPU) شما برای شخص دیگری عملیات استنتاج (inference) انجام می‌دهد. در پلن‌هایی که محدودیت استفاده منصفانه از CPU دارند، بار کاری مداوم به معنای مصرف سهمیه شما توسط یک غریبه است و کنترل هزینه‌های بار کاری هوش مصنوعی روی VPS زمانی که تنها کاربر سیستم نباشید، بسیار دشوارتر می‌شود.
  • /api/pull روی دیسک شما می‌نویسد. مدل‌ها بین 2 تا 40 گیگابایت حجم دارند. یک حلقه از دستورات pull، فضای دیسک را پر می‌کند و پر شدن کامل دیسک، نه تنها Ollama، بلکه تمام سرویس‌های دیگر روی سرور را از کار می‌اندازد.
  • درخواست‌ها وارد پردازش شما شده و ثبت می‌شوند. در سطح لاگ پیش‌فرض، Ollama فقط متادیتا را ذخیره می‌کند؛ بنابراین شما endpoint، وضعیت، تأخیر و آدرس کلاینت را دریافت می‌کنید، نه متن prompt را. با این حال، این همچنان سوابقی از این است که چه کسی از سرور شما استفاده کرده و برای چه منظوری، که در journal شما باقی می‌ماند و شما برای جمع‌آوری آن تصمیمی نگرفته بودید.
  • /api/delete مدل‌ها را حذف می‌کند. بازگرداندن آن‌ها به معنای دانلود مجددشان با استفاده از پهنای باند خودتان است.

هیچ‌کدام از این موارد نیازی به exploit ندارند. این همان API مستندشده است که دقیقاً طبق طراحی عمل می‌کند.

کلید Ed25519 یک ابزار کنترل دسترسی نیست

اگر عبارت "Ollama API key" را جستجو کنید، با دو مفهوم متفاوت مواجه می‌شوید. هیچ‌کدام از این دو، رمز عبور سرور شما نیستند و تفکیک آن‌ها بخش بزرگی از سردرگمی‌ها را برطرف می‌کند.

مورد اول، جفت‌کلید هویت است. Ollama در اولین اجرا یک جفت‌کلید Ed25519 تولید می‌کند. در لینوکس، اسکریپت نصب یک کاربر سیستمی به نام ollama ایجاد می‌کند که دایرکتوری خانگی آن در /usr/share/ollama قرار دارد، بنابراین این جفت‌کلید در اینجا ذخیره می‌شود:

/usr/share/ollama/.ollama/id_ed25519
/usr/share/ollama/.ollama/id_ed25519.pub

این کلید به سمت بیرون اشاره دارد. ollama signin نیمه عمومی کلید را در حساب کاربری ollama.com شما ثبت می‌کند و این همان چیزی است که به شما اجازه می‌دهد مدلی را به رجیستری ارسال (push) یا یک مدل خصوصی را دریافت (pull) کنید. این کلید، هویت دستگاه شما را برای ollama.com اثبات می‌کند. این کلید هیچ درخواستی از کلاینت‌هایی که به دستگاه شما متصل می‌شوند، ندارد. حذف کردن، تغییر دادن یا هرگز ایجاد نکردن آن، هیچ تغییری در اینکه چه کسی می‌تواند API شما را فراخوانی کند، ایجاد نمی‌کند.

مورد دوم، OLLAMA_API_KEY است. این متغیر حاوی کلیدی است که شما در https://ollama.com/settings/keys ایجاد می‌کنید و کلاینت شما هنگام فراخوانی API میزبانی‌شده در https://ollama.com/api، آن را به عنوان Authorization: Bearer $OLLAMA_API_KEY ارسال می‌کند. این یک اعتبارنامه برای سرویس آن‌هاست که توسط شما به عنوان کلاینت استفاده می‌شود. ollama serve خودتان هرگز آن را نمی‌خواند. تنظیم OLLAMA_API_KEY روی VPS، هیچ رمز عبوری روی VPS شما قرار نمی‌دهد.

بنابراین هیچ تنظیمی برای فعال‌سازی وجود ندارد. سه روش دفاعی زیر همگی به یک شکل عمل می‌کنند: پورت را غیرقابل دسترس نگه دارید و چیزی را در مقابل آن قرار دهید که عمل بررسی (احراز هویت) را انجام دهد.

بررسی وضعیت پورت‌های در حال گوش دادن سرور

sudo ss -tlnp | grep 11434

نتیجهٔ ایمن، آدرس loopback را نشان می‌دهد:

LISTEN 0  4096  127.0.0.1:11434  0.0.0.0:*  users:(("ollama",pid=812,fd=3))

نتیجهٔ در معرض دید، تمام رابط‌های شبکه را نمایش می‌دهد:

LISTEN 0  4096  0.0.0.0:11434  0.0.0.0:*  users:(("ollama",pid=812,fd=3))

عبارت 0.0.0.0 به معنای تمام آدرس‌های IPv4 روی سرور، شامل آدرس عمومی است. *:11434 و [::]:11434 نیز همین مفهوم را با احتساب IPv6 بیان می‌کنند.

اکنون از خارج از شبکه بررسی کنید. این دستور را روی لپ‌تاپ خود اجرا کنید، نه روی سرور:

curl -m 5 http://YOUR_SERVER_IP:11434/api/version

curl: (28) Connection timed out after 5001 milliseconds پاسخی است که انتظار دارید، همان‌طور که curl: (7) Failed to connect ... Connection refused نیز پاسخ درستی است. یک شیء JSON که شامل فیلد version باشد، به این معناست که کل API برای هر کسی که درخواست بفرستد، در دسترس است. تست کردن با curl روی خودِ سرور هیچ چیزی را ثابت نمی‌کند، زیرا loopback همیشه پاسخ می‌دهد.

قرار گرفتن در معرض دید معمولاً به دو روش رخ می‌دهد. روش اول یک ویرایش عمدی است، زیرا شخصی نیاز داشته است که یک ماشین دیگر به مدل دسترسی داشته باشد:

sudo systemctl edit ollama.service
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"

همان یک خط، عامل اصلی در معرض دید قرار گرفتن است. روش دوم Docker است که برای آن نیازی به ویرایش هیچ فایلی ندارید. این مورد بخش جداگانهٔ خود را در ادامه دارد.

دفاع 1: نگهداری روی localhost و استفاده از تونل

این روش را به عنوان اولین گزینه انتخاب کنید. این راهکار به نرم‌افزار جدیدی نیاز ندارد و هیچ اعتبارنامه‌ای ایجاد نمی‌کند که نشت کند. پورت هرگز روی رابط عمومی (public interface) ایجاد نمی‌شود، بنابراین اسکن کردن شبکه نمی‌تواند آن را پیدا کند.

آدرس bind را به‌جای تکیه بر پیش‌فرض، به‌صراحت تنظیم کنید:

sudo systemctl edit ollama.service
[Service]
Environment="OLLAMA_HOST=127.0.0.1:11434"

این کار /etc/systemd/system/ollama.service.d/override.conf را می‌نویسد. آن را اعمال کرده و بررسی کنید:

sudo systemctl daemon-reload
sudo systemctl restart ollama
sudo ss -tlnp | grep 11434

ss اکنون باید 127.0.0.1:11434 را نشان دهد. اگر همچنان 0.0.0.0 را نشان می‌دهد، یک فایل drop-in دیگر اولویت دارد. دستور systemctl cat ollama.service را اجرا کنید تا unit و تمام فایل‌های drop-in به همراه مسیرشان لیست شوند، سپس فایل قدیمی را حذف کنید.

برای استفاده از مدل از روی لپ‌تاپ خود، پورت را از طریق SSH فوروارد کنید:

ssh -N -L 11434:127.0.0.1:11434 you@your-server

-L 11434:127.0.0.1:11434 پورت 11434 را روی لپ‌تاپ شما باز می‌کند و هر چیزی که به آن برسد را به 127.0.0.1:11434 از دید سرور می‌فرستد. -N به SSH می‌گوید که هیچ دستور از راه دوری را اجرا نکند، بنابراین پردازش فقط تونل را باز نگه می‌دارد. تا زمانی که این دستور اجرا می‌شود، این مورد روی لپ‌تاپ شما کار می‌کند:

curl -s http://localhost:11434/api/tags

با دو خطا مواجه خواهید شد. bind [127.0.0.1]:11434: Address already in use به این معنی است که لپ‌تاپ شما در حال اجرای Ollama روی همان پورت است، بنابراین یک پورت محلی متفاوت با -L 11500:127.0.0.1:11434 انتخاب کنید و کلاینت خود را روی 11500 تنظیم کنید. پاسخ خالی از طریق تونلی که به‌درستی متصل شده، به این معنی است که SSH کار می‌کند اما Ollama در سمت سرور گوش نمی‌دهد؛ بنابراین پیش از دست زدن به دستور SSH، وضعیت ss را در آنجا بررسی کنید.

برای چندین دستگاه کلاینت، یک شبکه خصوصی بهتر از یک تونل برای هر نفر است. دستگاه‌ها را روی WireGuard یا Tailscale قرار دهید، سپس Ollama را به‌جای 0.0.0.0 به آدرس آن در شبکه متصل کنید:

[Service]
Environment="OLLAMA_HOST=10.8.0.1:11434"

در این حالت، پورت فقط روی رابطی وجود دارد که برای پیوستن به آن به یک کلید نیاز دارید. این روش حتی در صورت اشتباه در تنظیمات فایروال نیز ایمن است، زیرا قانونی که به‌طور تصادفی دسترسی عمومی را باز می‌گذارد، همچنان نمی‌تواند سرویسی را که روی رابط عمومی گوش نمی‌دهد، در معرض دید قرار دهد.

دفاع 2: استفاده از reverse proxy برای بررسی bearer token

هنگامی که سرویسی در اینترنت عمومی باید مدل را فراخوانی کند، Ollama را روی loopback نگه دارید و یک proxy در مقابل آن قرار دهید. این proxy عملیات TLS (امنیت لایه انتقال) را خاتمه می‌دهد و درخواست‌های فاقد header صحیح را رد می‌کند. Ollama همچنان فقط اتصالات از 127.0.0.1 را می‌پذیرد، بنابراین proxy تنها مسیر ورودی است.

ابتدا یک توکن واقعی تولید کنید. آن را به‌صورت دستی ابداع نکنید:

openssl rand -base64 36

یک سایت nginx که آن را بررسی می‌کند:

map $http_authorization $ollama_ok {
    default                                   0;
    "Bearer PASTE_YOUR_GENERATED_TOKEN_HERE"  1;
}

server {
    listen 443 ssl;
    server_name llm.example.com;

    ssl_certificate     /etc/letsencrypt/live/llm.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/llm.example.com/privkey.pem;

    location = /api/pull   { return 403; }
    location = /api/delete { return 403; }
    location = /api/push   { return 403; }

    location / {
        if ($ollama_ok = 0) { return 401; }

        proxy_pass http://127.0.0.1:11434;
        proxy_set_header Host 127.0.0.1:11434;
        proxy_buffering off;
        proxy_read_timeout 600s;
    }
}

پنج خط در اینجا کار اصلی را انجام می‌دهند و هر کدام از یک شکست که در غیر این صورت با آن مواجه می‌شدید، جلوگیری می‌کنند.

استفاده از if داخل یک بلوک location معمولاً در nginx ایده بدی است، اما بدنه دقیقاً return یکی از دو شکلی است که رفتار قابل پیش‌بینی دارد، بنابراین این استفاده ایمن است.

location = /api/pull یک تطابق دقیق است و nginx تطابق‌های دقیق را بالاتر از پیشوند location / رتبه‌بندی می‌کند، بنابراین آن سه endpoint پیش از آنکه توکن حتی بررسی شود، رد می‌شوند. یک توکن معتبر سپس دسترسی به استنتاج (inference) را فراهم می‌کند، نه توانایی پر کردن دیسک شما را.

proxy_set_header Host 127.0.0.1:11434; اهمیت دارد زیرا Ollama هدرهای ورودی Host و Origin را بررسی می‌کند. عبور مستقیم نام میزبان عمومی proxy می‌تواند منجر به تولید یک 403 Forbidden شود که از سمت Ollama آمده است نه از سمت nginx، که اشکال‌زدایی آن گیج‌کننده است. OLLAMA_ORIGINS اهرم دیگر است، برای کلاینت مرورگری که نیاز دارد یک origin خاص مجاز باشد.

proxy_buffering off; اهمیت دارد زیرا Ollama پاسخ خود را توکن به توکن استریم می‌کند. با فعال بودن buffering، nginx استریم را نگه می‌دارد و آن را در پایان به صورت یکجا تحویل می‌دهد، بنابراین کلاینت شما در تمام مدت تولید پاسخ، منجمد به نظر می‌رسد.

proxy_read_timeout 600s; اهمیت دارد زیرا مقدار پیش‌فرض nginx برابر با 60 ثانیه است. یک تولید طولانی روی CPU به‌راحتی از این زمان عبور می‌کند، کلاینت 504 Gateway Time-out دریافت می‌کند و /var/log/nginx/error.log مقدار upstream timed out (110: Connection timed out) while reading response header from upstream را ثبت می‌کند. درخواست همچنان در حال پردازش بود، اما nginx از آن قطع امید کرد.

پیکربندی را reload کرده و هر دو مسیر را تست کنید:

sudo nginx -t && sudo systemctl reload nginx
curl -s -o /dev/null -w '%{http_code}\n' https://llm.example.com/api/tags
curl -s -H "Authorization: Bearer YOUR_TOKEN" https://llm.example.com/api/tags

اولی باید 401 را چاپ کند. دومی باید لیست مدل‌های شما را چاپ کند. اگر اولی نیز لیست مدل‌ها را برگرداند، بلوک map در scope اشتباهی قرار دارد. این بلوک متعلق به سطح http است، بنابراین آن را در فایلی زیر /etc/nginx/conf.d/ یا بالای بلوک server قرار دهید، هرگز داخل server نباشد.

Caddy همین کار را با احراز هویت پایه (basic authentication) در چهار خط انجام می‌دهد که برای کلاینت مرورگر مناسب‌تر از bearer token است:

llm.example.com {
	basic_auth {
		apiuser PASTE_BCRYPT_HASH_HERE
	}
	reverse_proxy 127.0.0.1:11434
}

دستور caddy hash-password را اجرا کنید تا هش bcrypt مورد انتظار آن تولید شود. یک دام نام‌گذاری: این دستور پیش از Caddy v2.8 به صورت basicauth بود و اکنون basic_auth است، بنابراین پیکربندی کپی‌شده از راهنماهای قدیمی بارگذاری نمی‌شود و Caddy دستوری را که تشخیص نداده است، نام می‌برد.

هر proxy که انتخاب کنید، این یک secret مشترک برای همه است. هر کلاینتی که آن را در اختیار دارد دسترسی یکسانی دارد و ابطال آن به معنای ویرایش پیکربندی و به‌روزرسانی همزمان همه فراخوان‌کننده‌ها است.

دفاع 3: دروازه‌ای که برای هر کلاینت کلید صادر می‌کند

هنگامی که بیش از یک شخص یا برنامه مدل را فراخوانی می‌کنند، یک توکن مشترک دیگر پاسخگو نخواهد بود. در این حالت نمی‌توان تشخیص داد کدام کلاینت باعث ایجاد بار شده است و نمی‌توان دسترسی یکی از آن‌ها را بدون قطع دسترسی همه مسدود کرد. یک دروازه (gateway) در همان جایگاهی قرار می‌گیرد که پروکسی قرار داشت، از همان API سازگار با OpenAI استفاده می‌کند، برای هر کلاینت یک کلید مجزا صادر کرده و میزان مصرف هر کلید را ثبت می‌کند. یک دروازه LiteLLM خود-میزبانی‌شده راهکار معمول برای این مسئله است که علاوه بر کنترل دسترسی، امکان تعیین بودجه برای هر کلید و ثبت لاگ درخواست‌ها را نیز فراهم می‌کند.

قانون ذکر شده در دفاع 1 تغییر نمی‌کند. Ollama باید به 127.0.0.1 متصل شود، دروازه تنها فرآیندی باشد که با آن ارتباط برقرار می‌کند و دروازه تنها سرویسی باشد که دارای شنونده (listener) عمومی است. وجود دروازه روی سیستمی که پورت 11434 آن همچنان برای عموم باز است، صرفاً جنبه تزئینی دارد؛ زیرا فراخوان‌کننده‌ها می‌توانند به‌سادگی آن را دور بزنند.

تلهٔ فایروال: پورت‌های منتشرشدهٔ کانتینر، UFW را دور می‌زنند

به همین دلیل است که نمونه‌های در معرض دید، روی سرورهایی وجود دارند که مالکانشان فایروال را به‌درستی پیکربندی کرده‌اند.

ابزار UFW (فایروال ساده) قوانین خود را در زنجیرهٔ INPUT از جدول filter هسته می‌نویسد و INPUT بسته‌هایی را که خطاب به خودِ میزبان هستند، مدیریت می‌کند. فلگ -p در Docker، یک قانون NAT (ترجمه آدرس شبکه) مقصد را در زنجیرهٔ PREROUTING از جدول nat می‌نویسد که هسته پیش از تصمیم‌گیری دربارهٔ مقصد بسته، آن را ارزیابی می‌کند. زمانی که تصمیم مسیریابی اتخاذ می‌شود، مقصد قبلاً به آدرس کانتینر بازنویسی شده است؛ بنابراین بسته به جای تحویل محلی، فوروارد می‌شود و به جای INPUT از FORWARD عبور می‌کند. قوانین INPUT در UFW هرگز بررسی نمی‌شوند، بنابراین بسته به جای عبور از فایروال، آن را دور می‌زند.

به همین دلیل است که این توالی، پورت 11434 را برای اینترنت باز می‌گذارد:

sudo ufw default deny incoming
sudo ufw enable
docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama

و sudo ufw status همچنان گزارش می‌دهد که فایروال فعال است و سیاست پیش‌فرض آن deny است. هر دو گزارش همزمان درست هستند و دقیقاً به همین دلیل است که افراد به گزارش اشتباه اعتماد می‌کنند. می‌توانید قانونی که این کار را انجام داده است مشاهده کنید:

sudo iptables -t nat -L DOCKER -n

راه حل، افزودن یک آدرس در فلگ انتشار است:

docker rm -f ollama
docker run -d -v ollama:/root/.ollama -p 127.0.0.1:11434:11434 --name ollama ollama/ollama

عبارت -p 11434:11434 مخفف -p 0.0.0.0:11434:11434 است. تعیین 127.0.0.1 باعث می‌شود سمت میزبانِ نگاشت (mapping) به loopback محدود شود، بنابراین تونل SSH و reverse proxy شما همچنان به آن دسترسی دارند اما اینترنت نمی‌تواند به آن متصل شود. بازسازی کانتینر در اینجا ایمن است زیرا مدل‌ها در volume نام‌گذاری‌شدهٔ ollama قرار دارند، نه داخل کانتینر.

تأیید کنید که هر دو دیدگاه با هم توافق دارند:

docker port ollama
sudo ss -tlnp | grep 11434

دستور docker port ollama باید 11434/tcp -> 127.0.0.1:11434 را چاپ کند. اگر 0.0.0.0:11434 را چاپ کرد، شما همچنان در معرض دید هستید. این مکانیزم را یک‌بار بیاموزید تا برای هر کانتینری که منتشر می‌کنید، کاربرد داشته باشد: چرا پورت‌های منتشرشدهٔ Docker، فایروال UFW را دور می‌زنند زنجیرهٔ DOCKER-USER و قوانینی که پس از راه‌اندازی مجدد Docker باقی می‌مانند را پوشش می‌دهد. اگر همچنان در حال ساخت سیاست اصلی میزبان هستید، قوانین UFW مورد نیاز برای یک VPS جدید پایه‌ای را که این تنظیمات روی آن قرار می‌گیرد، توضیح می‌دهد. در Rocky یا AlmaLinux ابزار UFW برای پیکربندی وجود ندارد، بنابراین همان سیاست پایه نوشته‌شده در firewalld جایی است که باید از آن شروع کنید.

این پردازش با چه کاربری اجرا می‌شود

اسکریپت نصب لینوکس یک حساب کاربری اختصاصی ایجاد می‌کند و سرویس را تحت آن اجرا می‌نماید:

useradd -r -s /bin/false -U -m -d /usr/share/ollama ollama

فایل unit در مسیر /etc/systemd/system/ollama.service سپس مقادیر User=ollama و Group=ollama را تنظیم می‌کند. این تنظیمات را تغییر ندهید. اجرای سریع ollama serve به‌صورت دستی در ترمینال، با کاربری که با آن لاگین کرده‌اید اجرا می‌شود؛ اگر آن کاربر root باشد، یک API بدون احراز هویت، فایل‌ها را با دسترسی root می‌نویسد. بررسی کنید وضعیت چگونه است:

ps -o user= -C ollama

پاسخ باید ollama باشد. هر چیز دیگری به این معنی است که یک پردازشِ دستی در کنار یا به‌جای unit در حال اجراست. همین منطق برای هر daemon دیگری که بعداً اضافه می‌کنید نیز صادق است و اجرای سرویس‌ها با کاربران دارای حداقل دسترسی این موضوع را به‌درستی بررسی می‌کند.

نحوه بررسی امنیت endpoint مربوط به Ollama API

صرف‌نظر از روشی که انتخاب کرده‌اید، یک تست تکلیف را مشخص می‌کند و باید آن را از روی ماشینی دیگر اجرا کنید:

curl -m 5 http://YOUR_SERVER_IP:11434/api/version
curl -m 5 http://YOUR_SERVER_IP:11434/api/tags

هر دو دستور باید با خطای timeout یا connection refused مواجه شوند. اگر یک proxy راه‌اندازی کرده‌اید، همان دو مسیر روی نام دامنه (hostname) مربوط به proxy باید بدون اعتبارنامه، مقدار 401 و با اعتبارنامه، JSON واقعی را برگردانند.

سپس لاگ دسترسی را یک‌بار بررسی کنید، زیرا به شما می‌گوید که آیا در زمانی که پورت باز بوده، کسی آن را پیدا کرده است یا خیر:

journalctl -u ollama --since "-30 days" | grep GIN | grep -v 127.0.0.1

Ollama برای هر درخواست یک خط می‌نویسد و آدرس کلاینت را نیز شامل می‌شود:

[GIN] 2026/08/12 - 14:01:10 | 200 | 103.965898ms | 127.0.0.1 | POST "/api/generate"

هنگامی که Ollama به loopback متصل (bind) شده باشد، هر خط باید مقدار 127.0.0.1 را نشان دهد، زیرا این تنها آدرسی است که اتصال می‌تواند از آن برقرار شود. وجود یک آدرس عمومی در آن ستون به معنای درخواست از خارج است و timestamp زمان آن را به شما می‌گوید. خروجی نداشتن این دستور، نتیجه‌ای است که به دنبال آن هستید. اگر مبحث مدل‌ها برای شما جدید است، اجرای Ollama روی VPS نصب، تعیین اندازه مدل و محدودیت‌های حافظه که مشخص می‌کند چه چیزی واقعاً بارگذاری می‌شود را پوشش می‌دهد.

FAQ

آیا Ollama دارای API key یا رمز عبور است؟

خیر. سروری که اجرا می‌کنید فاقد هرگونه احراز هویت است و مستندات رسمی بیان می‌کنند که برای دسترسی به API نیازی به احراز هویت نیست. هر دو موردی که با نام "Ollama API key" شناخته می‌شوند، کاربرد متفاوتی دارند. جفت‌کلید Ed25519 در /usr/share/ollama/.ollama/ دستگاه شما را برای ollama.com احراز می‌کند تا بتوانید مدل‌ها را push کرده و مدل‌های خصوصی را pull کنید. OLLAMA_API_KEY یک اعتبارنامه است که کلاینت شما به API میزبانی‌شده در https://ollama.com/api ارسال می‌کند. ollama serve شخصی شما هیچ‌کدام را نمی‌خواند، بنابراین کنترل دسترسی باید از طریق شبکه یا یک پروکسی در لایه جلویی اعمال شود.

آیا OLLAMA_HOST=0.0.0.0 در صورت داشتن فایروال امن است؟

تنها تا زمانی که هیچ برنامه دیگری قوانین فایروال را روی آن سیستم تغییر ندهد. 0.0.0.0 به این معنی است که listener واقعاً روی اینترفیس عمومی وجود دارد و شما صرفاً به فایروال اعتماد کرده‌اید تا آن را غیرقابل‌دسترس نگه دارد. این اعتماد در لحظه‌ای که Docker یک پورت را منتشر می‌کند از بین می‌رود، زیرا قانون DNAT که Docker به جدول nat اضافه می‌کند، پیش از رسیدن بسته به زنجیره INPUT (که UFW در آن قرار دارد) ارزیابی می‌شود؛ در نتیجه بسته فوروارد شده و UFW هرگز آن را نمی‌بیند. Bind کردن روی 127.0.0.1 یا یک آدرس تونل خصوصی، listener را از اینترفیس عمومی حذف می‌کند تا در صورت بروز اشتباه در فایروال، چیزی برای افشا شدن باقی نماند.

چگونه بررسی کنم که آیا پورت Ollama من برای اینترنت باز است؟

دستور sudo ss -tlnp | grep 11434 را روی سرور و curl -m 5 http://YOUR_SERVER_IP:11434/api/version را از یک دستگاه دیگر اجرا کنید. نمایش ss به صورت 127.0.0.1:11434 و timeout شدن دستور curl از راه دور، همان نتیجه‌ای است که انتظار دارید. نمایش ss به صورت 0.0.0.0:11434 یا *:11434 در حالی که curl از راه دور پاسخ JSON برمی‌گرداند، به این معنی است که کل API در دسترس است. هرگز با curl روی خودِ سرور تست نکنید، زیرا loopback فارغ از آدرس bind شده، به درخواست‌ها پاسخ می‌دهد.

آیا می‌توانم پورت را از 11434 به یک پورت تصادفی تغییر دهم؟

خیر، و دلیل آن قابل‌تأمل است. تغییر پورت هیچ چیزی را کند نمی‌کند مگر اسکن یک پورت خاص. اسکنرها کل محدوده پورت‌ها را بررسی می‌کنند و یک درخواست به /api/tags، نوع سرویس را فارغ از پورتی که روی آن ارسال شده، شناسایی می‌کند. تغییر پورت همچنین تنظیمات پیش‌فرض تمام کلاینت‌ها را مختل کرده و درک پیکربندی شما را در آینده دشوارتر می‌کند. به جای جابه‌جایی، آن را روی loopback bind کنید تا listener کلاً حذف شود.

شخصی به Ollama باز من دسترسی پیدا کرده است. چه چیزی را باید بررسی کنم؟

ابتدا آن را روی 127.0.0.1 bind کرده و سرویس را restart کنید تا دسترسی غیرمجاز پیش از شروع بررسی متوقف شود. سپس journalctl -u ollama --since "-30 days" | grep GIN | grep -v 127.0.0.1 را اجرا کنید تا ببینید کدام آدرس‌های خارجی، چه endpointهایی را و در چه زمانی فراخوانی کرده‌اند. ollama list را با مدل‌هایی که قصد داشتید داشته باشید مقایسه کنید، زیرا /api/pull فاقد احراز هویت است و وجود مدلی که شما آن را pull نکرده‌اید، هم به معنای اشغال فضای دیسک و هم مدرکی از نفوذ است. فضای آزاد را با df -h بررسی کنید. Ollama در سطح لاگ پیش‌فرض، متن promptها را ثبت نمی‌کند؛ بنابراین شما سوابقی از اینکه چه کسی و برای چه مدلی درخواست داده دارید، اما محتوای تولیدشده ثبت نمی‌شود.