امنیت
امنیت TelegramOS: جداسازی مستأجرها، احراز هویت، رمزنگاری در حالت سکون، ردپای ممیزی و کنترلهای درخواستهای خروجی.
پلتفرم کنترلهای امنیتی را در چند لایه پیادهسازی میکند تا از دادههای مستأجرها (tenant) محافظت کند، از دسترسی غیرمجاز جلوگیری کند و عملکرد ایمن را تضمین کند. این صفحه آنچه را که واقعاً در کد در حال اجرا اعمال میشود شرح میدهد.
جداسازی مستأجرها
| لایه | سازوکار | از چه چیزی جلوگیری میکند |
|---|---|---|
| مرز مستأجر | هر ردیف منبع (اکانت، پروکسی، بات، گفتگو، کیف پول) شناسهی کاربر مالک را حمل میکند. کوئریهای خواندن و نوشتن به مستأجر خودِ فراخوان بهعلاوهی هر مستأجر تیمی که دسترسی مشخص را اعطا کرده (برای مثال inbox:read، accounts:delete) محدود میشوند؛ در صورت شکست جستجو، دامنه به فقطمالک برمیگردد. شناسهی بیگانه یا بدشکل 404 برمیگرداند، نه 403. | خواندن یا تغییر دادههای یک مستأجر توسط مستأجر دیگر از طریق API یا UI. |
| زمان اجرای هر اکانت | هر اکانت فعال بهعنوان پردازهی فرزند جداگانهای درون worker manager اجرا میشود، با نشست (session) رمزگشاییشدهی خودش، اتصال MTProto خودش، اثر انگشت دستگاه خودش و پروکسی خودش. هیچ اتصالی بین اکانتها مالتیپلکس نمیشود. همهی workerها محدودیتهای CPU و حافظهی کانتینر worker-manager را به اشتراک میگذارند؛ sandbox جداگانهای برای هر پردازه وجود ندارد. | مشاهده یا استفادهی مجدد از نشست تلگرام یک اکانت توسط worker اکانت دیگر. |
| پروکسی هر اکانت | هر اکانت دقیقاً به یک پروکسی متصل است؛ تخصیص چند اکانت به یک پروکسی رد میشود. پروکسیهای اجارهشده از پلتفرم بهصورت زیرکاربر (sub-user) ارائهدهنده برای هر اکانت فراهم میشوند و هنگام آزادسازی اکانت برچیده میشوند. چرخش برای هر اکانت جداگانه است. | مرتبطکردن اکانتها توسط تلگرام از طریق IP خروجی مشترک. |
| بازیافت اکانتهای اجارهای | مستأجر فقط اکانتی را دریافت میکند که در حال حاضر در استخر (pool) تخصیصنیافته است. وقتی اجاره پایان مییابد (انقضای اشتراک یا باندل بهعلاوهی 5 روز مهلت، یا بازگرداندن صریح)، worker بازپسگیری همهی چتها را در هر دو طرف حذف میکند، اتصال به مستأجر را پاک میکند و اکانت را با نشست دستنخورده به استخر برمیگرداند تا مستأجر بعدی بتواند آن را دریافت کند. اکانتهایی که نشستشان از بین رفته قرنطینه میشوند و هرگز دوباره فروخته نمیشوند. حذف دائمی پولی ($1) نشست را logout میکند، بلاب رمزنگاریشدهی نشست را پاک میکند و اکانت را برای همیشه بازنشسته میکند. | بهارثبردن گفتگوهای مستأجر قبلی توسط مستأجر جدید، و باقیماندن راه بازگشتی به اکانت برای مستأجر قبلی. |
| اعمال نشستهای فعال | هر 6 ساعت، برای هر اکانت اجارهای، پلتفرم نشستهای فعال تلگرام آن اکانت را فهرست میکند. نشستهای ناشناخته یک اعلان امنیتی با دو اقدام «It's me» و «Terminate» ایجاد میکنند. تا وقتی شما تصمیم نگیرید چیزی خاتمه داده نمیشود، بهجز نشستهای تأییدشده توسط مستأجر قبلی که هنگام دستبهدستشدن اکانت باطل میشوند. | دسترسی غیرمجاز به اکانت اجارهای از طریق نشستی که خارج از پلتفرم باز شده است. |
| peerهای سرویس پنهان | گفتگو با اکانت سیستمی تلگرام (peer 777000، بهعلاوهی هر شناسهای در جدول hidden_telegram_peers) توسط API اینباکس فقط برای اکانتهای اجارهای فیلتر میشود. اکانتهای مالکیتی همیشه آنها را میبینند. فیلتر هنگام خواندن اعمال میشود؛ خود ردیفها ذخیره میشوند. | خواندن کدهای ورود شماره تلفن زیرین توسط دارندهی اجاره. |
احراز هویت
الزامات رمز عبور
| الزام | مقدار |
|---|---|
| حداقل طول | 12 نویسه |
| حداکثر طول | 72 بایت (محدودیت bcrypt)؛ حروف غیرانگلیسی و ایموجی بیش از یک بایت میگیرند |
| ترکیب نویسهها | بدون قاعدهی ترکیبی؛ رمز عبور نباید با ایمیل یا نام شما یکسان باشد |
| رمزهای افشاشده | رمزهای جدید با فهرست Have I Been Pwned بررسی میشوند؛ فقط 5 نویسهی اول هش SHA-1 ارسال میشود و اگر آن سرویس ظرف 2 ثانیه پاسخ ندهد، بررسی نادیده گرفته میشود |
| رمزهای موجود | رمزهایی که با قواعد قبلی تنظیم شدهاند تا زمان تغییر همچنان کار میکنند |
| ذخیرهسازی | bcrypt، ضریب هزینهی 12 |
| حسابهای ورود اجتماعی | ممکن است تا زمانی که در Settings رمزی تنظیم شود رمز عبور نداشته باشند |
ورود ناموفق چه ایمیل وجود داشته باشد چه نه زمان یکسانی میبرد، پس نمیتوان از endpoint ورود برای شمارش حسابها استفاده کرد.
نشستها و توکنها
| مورد | مقدار |
|---|---|
| توکن دسترسی | JWT با RS256، 15 دقیقه |
| توکن refresh | توکن تصادفی 512 بیتی، 7 روز، در هر استفاده چرخانده میشود با مهلت 30 ثانیهای استفادهی مجدد |
| کوکیها | HttpOnly، Secure، SameSite=None؛ کوکی refresh به /auth محدود است |
| رکوردهای نشست سمت سرور | رکوردهای منقضیشده پس از 7 روز پاک میشوند |
| کلیدهای API | پیشوند tgp_، ذخیرهشده بهصورت هش SHA-256، انقضای پیشفرض 90 روز، حداکثر 20 عدد برای هر کاربر |
| کاربران غیرفعالشده | کاربری با is_active = false در ورود، refresh و احراز هویت با کلید API رد میشود |
احراز هویت دومرحلهای (TOTP)
| تنظیم | مقدار |
|---|---|
| الگوریتم | TOTP (RFC 6238)، 6 رقم، گام 30 ثانیهای، یک گام انحراف ساعت پذیرفته میشود |
| محافظت در برابر replay | کدی که قبلاً پذیرفته شده برای باقی پنجرهاش رد میشود |
| کدهای بازیابی | 8 کد، هر کدام یک بار معتبر، ذخیرهشده بهصورت هش SHA-256 |
| ذخیرهسازی راز | رمزنگاریشده با Fernet در حالت سکون (at rest) وقتی کلید رمزنگاری TOTP پیکربندی شده باشد |
| محدودیت تلاش | 10 تلاش ناموفق برای هر حساب، سپس قفل 15 دقیقهای صرفنظر از IP مبدأ |
محدودیت نرخ
| مسیر (endpoint) | محدودیت |
|---|---|
| POST /auth/login | 10 درخواست در دقیقه برای هر IP |
| POST /auth/register | 5 درخواست در دقیقه برای هر IP، بهعلاوهی سقف ارسال ایمیل در زیر |
| POST /auth/forgot-password, /resend-verification | 5 ایمیل در ساعت برای هر IP؛ برای هر آدرس: یک ارسال در هر 60 ثانیه، 10 در روز |
| POST /auth/reset-password, /verify-email | 30 درخواست در دقیقه برای هر IP؛ هر کد 10 دقیقه معتبر است و پس از 5 تلاش اشتباه از بین میرود |
| تغییرات تیم (دعوت، بهروزرسانی، حذف) | محدودکنندهی تغییرات برای هر کاربر |
محدودیتها از یک پنجرهی لغزان اتمی در Redis استفاده میکنند. وقتی محدودیتی رد شود پلتفرم HTTP 429 را با هدر Retry-After برابر طول پنجره برمیگرداند. پس از 429های مکرر هیچ قفلی در سطح اپلیکیشن وجود ندارد. در لبه، پلتفرم پشت Cloudflare قرار دارد، nginx با HSTS به TLS 1.2/1.3 خاتمه میدهد و fail2ban هاستهایی را که درخواستهای بدشکل تولید میکنند بن میکند.
رمزنگاری
در حالت سکون
| داده | رمزنگاری |
|---|---|
| رشتههای نشست تلگرام | Fernet (AES-128-CBC + HMAC-SHA256) زیر کلید نشست پلتفرم. قالب envelope اختیاری: یک کلید داده برای هر اکانت که یا با کلید پلتفرم (استاندارد) یا با کلید Argon2id مشتقشده از عبارت عبور مالک (حالت vault، در زیر ببینید) پوشانده میشود. |
| اعتبارنامههای پروکسی | Fernet، همان کلید پلتفرم |
| توکنهای Bot API | AES-256-GCM با کلیدی که از طریق HKDF-SHA256 از راز اصلی پلتفرم مشتق شده است |
| رازهای امضای وبهوک خروجی | Fernet |
| رازهای TOTP | Fernet، وقتی کلید رمزنگاری TOTP پیکربندی شده باشد |
| رمزهای عبور، کدهای بازیابی، توکنهای refresh، کلیدهای API | فقط بهصورت هش ذخیره میشوند (bcrypt برای رمزهای عبور، SHA-256 برای بقیه) |
| متن پیامها، متادیتای گفتگو، مخاطبین | در لایهی اپلیکیشن رمزنگاری نمیشوند؛ ردیفهای ساده در Postgres |
| پیوستها (MinIO، 20 MB برای هر فایل) | سمت سرور رمزنگاری نمیشوند؛ دسترسی از طریق یک endpoint استریم محدود به مستأجر انجام میشود |
| بکاپهای پایگاه داده | رمزنگاری نمیشوند؛ روی والیومهای محلی هاست پایگاه داده ذخیره میشوند و نسخهای خارج از این هاست وجود ندارد |
KMS خارجی و چرخش خودکار کلید وجود ندارد. کلیدهای رمزنگاری رازهای محیطی هستند که توسط اپراتور مدیریت میشوند و بیرون از پایگاه داده نگه داشته میشوند. چرخاندن کلید یک عملیات دستی است.
حالت vault (نشستهای رمزنگاریشده با عبارت عبور)
برای اکانتهای مالکیتی میتوانید نشست را زیر یک عبارت عبور (حداقل 10 نویسه) دوباره بپوشانید. کلید پوشاننده با Argon2id (t=3, m=64 MiB, p=4) مشتق میشود؛ کلید پلتفرم دیگر نمیتواند نشست را رمزگشایی کند، پس دامپ پایگاه داده بدون عبارت عبور بیفایده است. بدهبستان آن: اتوماسیون فقط تا وقتی اجرا میشود که یک پنجرهی بازشدن (unlock) باز باشد (پیشفرض 1 ساعت، حداکثر 24 ساعت). کلید مشتقشده در حافظه به worker داده میشود و هرگز ذخیره نمیشود. تا وقتی حالت vault فعال است خروجیگرفتن نشست رد میشود. اکانتهای اجارهای نمیتوانند از حالت vault استفاده کنند.
در حال انتقال
همهی ترافیک عمومی HTTPS (TLS 1.2 یا 1.3، HSTS با preload) پشت Cloudflare است. ترافیک تلگرام از طریق پروکسی اکانت بهصورت MTProto خارج میشود که با پروتکل خود تلگرام بهصورت end-to-server رمزنگاری شده است.
پایش اتصال و نشست
- هر تلاش اتصال به تلگرام برای هر اکانت در
connection_audit_logنوشته میشود، همراه با هاست و پورت پروکسی، API ID، مدل دستگاه، نوع اتصال، موفقیت یا خطا، مدت زمان و اینکه آیا اتصال از IP سرور آمده است یا نه. - اکانتهای اجارهای اسکن 6 ساعتهی نشستهای فعال را که در بالا شرح داده شد دریافت میکنند؛ درخواستهای در انتظار زیر Notifications با نوع
securityظاهر میشوند. - هشدار مبتنی بر موقعیت جغرافیایی، تشخیص انحراف اثر انگشت دستگاه و خاتمهی خودکار نشست بر اساس امتیاز سلامت وجود ندارد.
ردپای ممیزی
| لاگ | چه چیزی ثبت میشود | چه کسی میتواند بخواند | نگهداری |
|---|---|---|---|
| لاگ ممیزی تیم | team.create، team.member.invite، team.member.update، team.member.remove، team.member.leave همراه با عامل، آدرس IP، user agent و اسنپشات قبل/بعد | Owner و admin (audit:logs:read)؛ هر کاربر میتواند اقدامات خودش را بخواند | نامحدود نگه داشته میشود |
| لاگ ممیزی پلتفرم | session_export، چرخهی عمر پروکسی (proxy_created، proxy_updated، proxy_deleted، proxy_assigned، proxy_unassigned، proxy_rotated)، اعمال نشست (enforcement_check، prompt_emitted، check_failed) | اپراتورها | نامحدود نگه داشته میشود |
| ممیزی اتصال | رکورد هر اتصال که در بالا شرح داده شد | اپراتورها | نامحدود نگه داشته میشود |
| لاگ سلامت اکانت | ورودیهای امتیاز سلامت برای هر اکانت | اپراتورها | 90 روز |
| تحویلهای وبهوک | نوع رویداد، payload، وضعیت HTTP، 400 بایت اول پاسخ، تعداد تلاشها | فضای کاری | 7 روز برای تحویلشده، 30 روز برای ناموفق |
لاگ ممیزی تیم در GET /audit/logs در دسترس است (فیلتر بر اساس team_id، action، resource_type). API را ببینید.
محافظتهای SSRF
پلتفرم در چهار جا از طرف شما درخواستهای HTTP خروجی میفرستد. هر کدام محافظ خودش را دارد:
| فراخوان | محافظ |
|---|---|
| وبهوکهای رویداد (اینباکس) | URLهای جدید باید https:// باشند. میزبان هنگام ثبت و دوباره پیش از هر تحویل resolve میشود و تحویل به همان نشانی بررسیشده فرستاده میشود؛ نشانیهای loopback، خصوصی، link-local، carrier-NAT، رزروشده و multicast (IPv4 و IPv6)، localhost و *.local رد میشوند. endpoint ذخیرهشدهای که اکنون به نشانی ردشده resolve شود، بهجای تحویل با خطای روشن شکست میخورد. تحویلها ریدایرکتها را دنبال نمیکنند، پس از 10 ثانیه timeout میشوند، تا 6 بار طی حدود 8 ساعت تلاش مجدد میکنند و endpoint پس از 5 شکست نهایی متوالی خاموش میشود. |
| URL وبهوک بات | هنگام ثبت از طریق DNS resolve میشود؛ اگر هر آدرس resolveشدهای خصوصی، loopback، link-local، multicast، unspecified یا رزروشده باشد رد میشود. |
| نود درخواست HTTP در فلو | هنگام درخواست resolve میشود و اتصال به IP عمومی اعتبارسنجیشده پین میشود (DNS rebinding را میبندد)؛ timeout کل 15 ثانیه و timeout اتصال 5 ثانیه. درخواستها امضا نمیشوند. |
| کانکتورهای API | فقط http:// یا https://. میزبان هنگام ذخیره و آزمایش کانکتور resolve میشود و درخواست به همان نشانی بررسیشده فرستاده میشود؛ نشانیهای loopback، خصوصی، link-local، carrier-NAT، رزروشده و multicast (IPv4 و IPv6، از جمله IPv4-mapped و نمایشهای عددی)، localhost و *.local رد میشوند. ریدایرکت دنبال نمیشود. |
| URLهای ریدایرکت پرداخت | resolve میشوند و اگر به آدرس خصوصی یا loopback برسند رد میشوند. |
مقصدهای وبهوک با http:// ساده پذیرفته میشوند؛ هر جا میتوانید از HTTPS استفاده کنید.
تأیید وبهوک بات
آپدیتهای ورودی بات با راز X-Telegram-Bot-Api-Secret-Token مخصوص هر بات تأیید میشوند (باتها را ببینید). وبهوکهای رویداد خروجی امضا میشوند: هر تحویل X-TGP-Signature را حمل میکند که HMAC-SHA256 از timestamp و بدنهی خام زیر راز endpoint است، بهعلاوهی X-TGP-Timestamp و X-TGP-Delivery — API › وبهوکها را ببینید. درخواستهایی که نود درخواست HTTP یک فلو میفرستد امضا نمیشوند؛ آن endpointها را با یک مسیر مخفی یا فهرست مجاز محافظت کنید.
گزارش آسیبپذیری
از طریق پشتیبانی درونبرنامهای (حباب Support در داشبورد) گزارش دهید، یا اگر حساب ندارید از طریق @TelOsNotif_Bot. صندوق ایمیل امنیتی وجود ندارد. مراحل بازتولید و endpoint آسیبدیده را بگنجانید. روی اکانتها یا فضاهای کاریای که مالکشان نیستید تست نکنید. دامنه، موارد خارج از دامنه و اهداف پاسخدهی (تأیید دریافت در 24 ساعت، هدف رفع مشکلات تأییدشدهی با شدت بالا در 14 روز) در /security هستند. همچنین پشتیبانی را ببینید.