CH-J ToolsSSH-এর মাধ্যমে সার্ভার ব্যবস্থাপনা
মেনু

রিমোট এডিটরে সংরক্ষণ ও লেটেন্সি মনিটরিং

ফাইল ডাউনলোড করুন

এই অনুবাদের ভাষাগত পর্যালোচনা চলছে। কোনো অংশ অস্পষ্ট হলে ইংরেজি মূল পাঠ-এর সঙ্গে মিলিয়ে নিন।

মূল কারণ

আগের এডিটর তার কার্য-ফাইলটি লক্ষ্যের প্যারেন্ট ডিরেক্টরিতে আপলোড করত, যেখানে /etc বা /var-এর ভেতরে SSH অ্যাকাউন্ট প্রায়ই লিখতে পারে না। SFTP rename-এ কোনো অনুমোদিত sudo পথ, বেসলাইন সংঘাত যাচাই, নিরাপত্তা মেটাডেটা যাচাই বা নির্ভরযোগ্য ওভাররাইট আচরণ ছিল না। এর ত্রুটি-হ্যান্ডলার অস্থায়ী কপিটি মুছে ফেলত, ফলে সম্পূর্ণ হওয়া অনিশ্চিত থাকলেও পুনরুদ্ধারের উপকরণ হারিয়ে যেত।

সেশনের অবস্থা আগে শুধু সংযোগের অবস্থা দেখাত। টার্মিনাল নির্দেশককে তথ্য দেওয়ার মতো কোনো ICMP বা প্রমাণীকৃত SSH প্রতিক্রিয়া পরিমাপ ছিল না।

সংরক্ষণের প্রোটোকল

  1. একটি নির্দিষ্ট SSH হেল্পার ডেসক্রিপ্টর-আপেক্ষিক কার্যক্রম এবং প্রতিটি পাথ উপাদানের জন্য O_NOFOLLOW ব্যবহার করে একটি সাধারণ, একক-লিংকের ফাইল খোলে। এটি বিষয়বস্তু, SHA-256 হ্যাশ, ডিভাইস/inode, UID, GID, সম্পূর্ণ অনুমতি বিট, ন্যানোসেকেন্ড স্তরের পরিবর্তন/বদলের সময় এবং পাঠযোগ্য সব বর্ধিত অ্যাট্রিবিউট লিপিবদ্ধ করে। Core হ্যাশ যাচাই করে এবং BOM অক্ষুণ্ণ রেখে কঠোর UTF-8 ডিকোড করে। প্রতিটি ডকুমেন্ট একটি অস্বচ্ছ editId পায়, যার পরিধি এর প্লাগইন, টার্মিনাল সেশন ও সার্ভার পরিচয়ে সীমিত।
  2. একটি বিশেষাধিকারহীন প্রস্তুতি-ধাপ pwd.getpwuid(os.getuid()) দিয়ে প্রমাণীকৃত অ্যাকাউন্টের হোম নির্ধারণ করে, 0700 মোডে $HOME/ch-j-sm/ তৈরি করে এবং একটি ব্যক্তিগত, একচেটিয়া পুনরুদ্ধার জার্নাল তৈরি করে। অনিরাপদ হোম, সিমলিংক ওয়ার্কস্পেস বা অন্য অ্যাকাউন্টের মালিকানাধীন ওয়ার্কস্পেস প্রত্যাখ্যাত হয়।
  3. Core একচেটিয়া সৃষ্টি (wx), মোড 0600 এবং ষাট সেকেন্ডের চ্যানেল/আপলোড টাইমআউট দিয়ে SFTP-র মাধ্যমে একটি লুকানো, এলোমেলো 128-বিট নামের .tmp কার্য-ফাইল আপলোড করে। জার্নালে থাকে লক্ষ্য, মূল বেসলাইন ও প্রত্যাশিত কার্য-ফাইলের হ্যাশ; এতে কোনো ক্রেডেনশিয়াল থাকে না।
  4. একটিমাত্র SSH exec সম্পূর্ণ চূড়ান্ত ধাপ সম্পাদন করে, ঐচ্ছিকভাবে বিদ্যমান sudo এক্সিকিউটরের মাধ্যমে। হেল্পার নিরাপদে ব্যক্তিগত কার্য-কপিটি খোলে, এর হ্যাশ বের করে এবং ডিস্কে ফ্লাশ করে। এটি মূল inode লক করে, এর বেসলাইন যাচাই করে, লক্ষ্যের পাশে একটি একচেটিয়া গন্তব্য-ফাইল তৈরি করে, সব বিষয়বস্তু লেখে, মেটাডেটা প্রয়োগ ও যাচাই করে, মূল ফাইলটি আবার যাচাই করে এবং প্রতিস্থাপন-ফাইলটি ফ্লাশ করে।
  5. একই ডিরেক্টরিতে os.replace লক্ষ্যটিকে অ্যাটমিকভাবে প্রতিস্থাপন করে। প্যারেন্ট ডিরেক্টরি ফ্লাশ করা হয় এবং চূড়ান্ত পাথ, হ্যাশ, inode ও মেটাডেটা যাচাই করা হয়। প্রতিস্থাপন পর্যন্ত মূল পাথ উপলব্ধ থাকে। কার্য-ফাইলটি কখনো ফাইল সিস্টেমের সীমা পেরিয়ে সরানো হয় না এবং চূড়ান্ত ধাপে কখনো মুছে ফেলা হয় না।
  6. Core যাচাইকৃত সাফল্য পাওয়ার পর একটি আলাদা পরিষ্কারকরণ-ধাপ কার্য-ফাইল ও জার্নাল মুছে ফেলার আগে চূড়ান্ত বিষয়বস্তু ও নিরাপত্তা মেটাডেটা আবার যাচাই করে। পরিষ্কারকরণ ব্যর্থ হলেও recoveryAvailable: true-সহ নিশ্চিত সংরক্ষণ জানানো হয়।

আপলোড ব্যর্থ, sudo ব্যর্থ, সংঘাত, মেটাডেটা ত্রুটি বা প্রতিস্থাপন ব্যর্থ হলে মূল ফাইল ও প্রস্তুত সব উপকরণ রক্ষিত থাকে। অসম্পূর্ণ আপলোড অসম্পূর্ণ হিসেবেই চিহ্নিত হয় এবং সম্পূর্ণ সম্পাদিত ডকুমেন্ট হিসেবে পুনরুদ্ধার করা যায় না। SSH যোগাযোগ বিচ্ছিন্ন হওয়া, এক্সিট স্ট্যাটাস না পাওয়া, টাইমআউট ও অপ্রত্যাশিত চূড়ান্ত ফলাফলকে অজানা হিসেবে জানানো হয়, কখনো "সংরক্ষিত" হিসেবে নয়। অনিশ্চিত ডকুমেন্টে Core পরবর্তী সংরক্ষণ আটকে দেয়; প্রতিস্থাপনের কোনো স্বয়ংক্রিয় পুনঃচেষ্টা নেই।

মেটাডেটা, বিশেষাধিকার ও নিরাপত্তার সীমা

হেল্পার UID, GID এবং executable, setuid, setgid ও sticky বিটসহ সব POSIX অনুমতি বিট সংরক্ষণ ও যাচাই করে। এটি POSIX ACL, capabilities ও SELinux লেবেলসহ Linux বর্ধিত অ্যাট্রিবিউট বাইট-বাই-বাইট পুনরুৎপাদন করে। মালিকানা ও ফাইলের বিষয়বস্তু নিরাপত্তা অ্যাট্রিবিউটের আগে সেট করা হয়, কারণ লেখা/chown capabilities বা বিশেষ অনুমতি বিট মুছে দিতে পারে। গন্তব্যে উত্তরাধিকারসূত্রে আসা যেসব অ্যাট্রিবিউট মূল ফাইলে নেই, সেগুলো সরানো হয়। পরিবর্তনের সময় নতুন লেখাকে প্রতিফলিত করে এবং মূল থেকে কপি করা হয় না।

অপাঠ্য বা উপস্থাপন-অযোগ্য অ্যাট্রিবিউট কার্যক্রম থামিয়ে দেয়; মেটাডেটা নীরবে বাদ দেওয়া হয় না। IMA/EVM স্বাক্ষর স্পষ্টভাবে প্রত্যাখ্যাত হয়, কারণ বিষয়বস্তু/inode-এর সঙ্গে বাঁধা অখণ্ডতা স্বাক্ষর কপি করলে সেগুলো অবৈধ হয়ে যাবে। লক্ষ্য বা হোম পাথে সিমলিংক, হার্ড-লিংক করা ফাইল এবং অসাধারণ ফাইল প্রত্যাখ্যাত হয়। কোনো ইন-প্লেস বা দুর্বলতর SFTP ওভাররাইট বিকল্প ব্যবহৃত হয় না।

সাধারণ লেখাযোগ্য সংরক্ষণ SSH অ্যাকাউন্ট হিসেবে চলে। সুরক্ষিত সংরক্ষণের জন্য স্পষ্ট { sudo: true } প্রয়োজন; পাসওয়ার্ডবিহীন sudo-র ক্ষেত্রে sudo পাসওয়ার্ড ঐচ্ছিক। পাসওয়ার্ড যাচাই করে শুধু চ্যানেলের stdin-এ পাঠানো হয়, কখনো কমান্ড, জার্নাল, কার্য-ফাইল, লগার বা রিমোট ত্রুটিতে নয়। root SSH সেশন বিদ্যমান সরাসরি root এক্সিকিউটর ব্যবহার করে। অনুমোদন ব্যর্থ হলে মূল ফাইল ও কার্য-কপি অক্ষত থাকে। root হিসেবে চালানো সব সংরক্ষণ (সরাসরি root SSH বা sudo) সেইসব লক্ষ্য ডিরেক্টরি/পূর্বপুরুষ ডিরেক্টরিও প্রত্যাখ্যান করে যেগুলো অন্য অ্যাকাউন্টের মালিকানাধীন বা তাদের দ্বারা লেখাযোগ্য অথবা যেগুলোতে access ACL আছে, অন্য অ্যাকাউন্টের নিয়ন্ত্রিত বিশেষাধিকারপ্রাপ্ত পাথনেমে আস্থা না রেখে।

নির্দিষ্ট হেল্পারটি python3 -I -B দিয়ে চলে: এটি ব্যবহারকারীর Python পাথ, কার্য-ডিরেক্টরি ও ব্যবহারকারীর site-packages উপেক্ষা করে এবং কোনো বাইটকোড লেখে না। পাথ ও JSON আর্গুমেন্ট Core-এ শেল-কোট করা হয়। প্লাগইন কখনো যথেচ্ছ SSH exec বা SFTP হ্যান্ডেল পায় না। বিদ্যমান স্যান্ডবক্স, CSP, ম্যানিফেস্ট অনুমতি, হোস্ট-কী যাচাই ও আপডেট যাচাই বহাল থাকে।

Plugin API ও অবশিষ্ট Monaco একীকরণ

আলাদাভাবে বিতরণ করা Monaco/File Manager UI এই চেকআউটে নেই। এর UI একীকরণ, sudo প্রম্পট, অসংরক্ষিত বাফারের ব্যবস্থাপনা ও অনুবাদ এখানে বাস্তবায়ন বা পরীক্ষা করা যায়নি। বান্ডেল করা প্লাগইন সোর্স হলো Hash & Checksum প্লাগইন। কোনো বিকল্প File Manager সোর্স বানানো হয়নি।

বিদ্যমান মেথডগুলো উপলব্ধ থাকে। অতিরিক্ত মেথড/বিকল্প স্যান্ডবক্সড preload ও অনুমতি-যাচাইকারী রানটাইমের মাধ্যমে উন্মুক্ত করা হয়:

const opened = await chjPlugin.files.readText(sessionId, path);
// For a protected read, explicitly pass { sudo: true, sudoPassword }.

const result = await chjPlugin.files.saveText(sessionId, path, editor.getValue(), {
  editId: opened.editId,
  sudo: true,           // Include only after the user authorizes elevation.
  sudoPassword         // Omit for passwordless sudo; never persist this value.
});

if (result.ok && result.value.status === "saved") {
  // Mark this exact submitted editor version as saved. Later edits stay dirty.
} else {
  // Keep the Monaco model dirty. Translate result.error.code/status.
  // result.error.recoveryId/recoveryPath identify retained working material.
}

await chjPlugin.files.closeText(opened.editId);
const recovery = await chjPlugin.files.listRecovery(sessionId);
const copy = await chjPlugin.files.readRecovery(sessionId, recoveryId);
// Review copy.status and copy.text; open a fresh document before another save.
await chjPlugin.files.cleanupRecovery(sessionId, recoveryId);
// Cleanup rejects anything whose target is not currently confirmed.

লক্ষ্য পরিদর্শনে বিশেষাধিকার বাড়ানোর প্রয়োজন হলে পুনরুদ্ধার মেথডগুলো শেষে একটি ঐচ্ছিক { sudo: true, sudoPassword } আর্গুমেন্ট গ্রহণ করে। sudo-র মাধ্যমে চালালেও এগুলো প্রমাণীকৃত ব্যবহারকারীর ওয়ার্কস্পেসই ধরে রাখে। জার্নাল অ্যাপ রিস্টার্ট ও SSH পুনঃসংযোগের পরও টিকে থাকে; পুনরুদ্ধার কখনো স্বয়ংক্রিয়ভাবে চূড়ান্ত ধাপ পুনরাবৃত্তি করে না। পুনরুদ্ধার করা বাফার স্পষ্টভাবে সংরক্ষণের আগে নতুন করে খোলা লক্ষ্যের সঙ্গে মিলিয়ে দেখুন।

files.read পড়া, পরিদর্শন ও হ্যান্ডেল মুক্তি রক্ষা করে। files.write সংরক্ষণ ও পুনরুদ্ধার পরিষ্কারকরণ রক্ষা করে। বিদ্যমান প্লাগইনের জন্য writeText ব্যর্থ হলে এখনো reject করে; saveText একটি কাঠামোবদ্ধ { ok, value/error } এনভেলপ ফেরত দেয়, কারণ Electron reject করা Error অবজেক্টের কাস্টম প্রপার্টি বাদ দেয়। পুরোনো তিন-আর্গুমেন্টের writeText একটিমাত্র খোলা ডকুমেন্টের বেসলাইন ব্যবহার করতে পারে। একই পাথে একাধিক সক্রিয় ডকুমেন্টের জন্য editId প্রয়োজন; অস্পষ্ট পুরোনো কল অন্য ডকুমেন্টের বেসলাইন বেছে না নিয়ে নিরাপদে ব্যর্থ হয়। প্লাগইনের উচিত অব্যবহৃত হ্যান্ডেল মুক্ত করা।

বাহ্যিক UI-কে অবশ্যই সঙ্গে সঙ্গে সংরক্ষণের অবস্থা দেখাতে হবে, ব্যর্থতায় বাফার অসংরক্ষিত রাখতে হবে, শুধু অনুমতি/প্রমাণীকরণ ব্যর্থতার পর sudo প্রস্তাব করতে হবে, ওভাররাইট না করে সংঘাত দেখাতে হবে এবং সংযোগ হারানো বা অজানা ফলাফলের পর পুনরুদ্ধার প্রস্তাব করতে হবে। এই অবস্থাগুলো চেক, জার্মান ও ইংরেজিতে অনুবাদ করতে হবে। প্রস্তাবিত অবস্থার পাঠ:

অবস্থা চেক জার্মান ইংরেজি
সংরক্ষণ চলছে Ukládání… Wird gespeichert… Saving…
নিশ্চিত Uloženo Gespeichert Saved
ব্যর্থতা Uložení selhalo Speichern fehlgeschlagen Save failed
sudo প্রয়োজন Vyžadováno oprávnění sudo sudo-Autorisierung erforderlich Sudo authorization required
সংঘাত Původní soubor byl změněn Originaldatei wurde geändert Original file changed
বিচ্ছিন্ন Spojení bylo přerušeno Verbindung unterbrochen Connection lost
অজানা Výsledek uložení není znám Speicherergebnis unbekannt Save result unknown
পুনরুদ্ধার Obnova je dostupná Wiederherstellung verfügbar Recovery available

লেটেন্সির সংজ্ঞা ও জীবনচক্র

Ping হলো SSH-এর ব্যবহৃত রিজলভ করা IP-তে পাঠানো ICMP echo-র ক্লায়েন্ট-পাশে প্রকৃতপক্ষে পাওয়া উত্তরের মাধ্যমে জানানো লেটেন্সি। Core প্ল্যাটফর্মের ping এক্সিকিউটেবলকে একটি নির্দিষ্ট আর্গুমেন্ট অ্যারে দিয়ে অ্যাসিঙ্ক্রোনাসভাবে চালায়, শেল ছাড়া এবং প্রশাসক হিসেবে চালু করার শর্ত ছাড়াই। Linux, macOS (ping6-সহ) ও Windows-এর আর্গুমেন্ট আলাদাভাবে বেছে নেওয়া হয়। ব্লক করা ICMP, অনুপস্থিত এক্সিকিউটেবল, টাইমআউট, অবৈধ আউটপুট বা <1ms-এর মতো শুধু ঊর্ধ্বসীমাসহ Windows উত্তর একটি "অনুপলব্ধ" মান দেয়, বানানো কোনো সংখ্যা নয়।

SSH RTT হলো বিদ্যমান প্রমাণীকৃত SSH ক্লায়েন্টে একটি নির্দিষ্ট true exec অনুরোধের মনোটোনিক performance.now() সময়কাল। এতে চ্যানেল সেটআপ, সার্ভারের প্রক্রিয়াকরণ ও উত্তর পৌঁছানো অন্তর্ভুক্ত; এটি বিশুদ্ধ নেটওয়ার্ক RTT বা SSH লগইনের সময়কাল নয়। অনূদিত নির্দেশকের টুলটিপ এই পার্থক্য ব্যাখ্যা করে।

টার্মিনাল সংযুক্ত হওয়ামাত্র মনিটরিং শুরু হয়। প্রোবগুলো একই সময়ে ও অ্যাসিঙ্ক্রোনাসভাবে চলে, পাঁচ সেকেন্ডের অনুরোধ/প্রসেস টাইমআউটসহ। ওভারল্যাপ ঠেকাতে পরবর্তী নমুনা আগের নমুনা শেষ হওয়ার বারো সেকেন্ড পরে নির্ধারিত হয়। বিচ্ছিন্নকরণ ICMP বন্ধ করে, টাইমার মুছে দেয়, অপেক্ষমাণ SSH কাজ বাতিল করে এবং মান মুছে দেয়। রেকর্ড-পরিচয় যাচাই পুনঃসংযোগের পর আগের সংযোগকে মান প্রকাশ করতে দেয় না। ICMP ব্যর্থতা কখনো SSH সংযোগের অবস্থা বদলায় না।

লেটেন্সি বিদ্যমান state ইভেন্ট / ssh:state IPC পেলোডের ভেতরে পাঠানো হয়:

latency: { pingMs: 24.1, sshRttMs: 31.25, measuredAt: "…" }

অনুপলব্ধ সংখ্যাগুলো null। কম্প্যাক্ট টার্মিনাল নির্দেশক মিলিসেকেন্ড, স্থানীয়কৃত "অনুপলব্ধ" পাঠ এবং চেক/জার্মান/ইংরেজি লেবেল ব্যবহার করে। বিচ্ছিন্ন হলে এটি লুকিয়ে যায়। কোনো অতিরিক্ত রেন্ডারার সম্পাদন-ক্ষমতা বা IPC অনুরোধের প্রয়োজন হয়নি।

যাচাই ও পরিচালনাগত সীমাবদ্ধতা

ব্যবহারকারী বিদ্যমান ওয়ার্কিং ট্রি-তে (বর্তমানে feature/hash-checksum-plugin) পরিবর্তন রাখার অনুরোধ করেছিলেন; কোনো শাখা বদলানো বা অসম্পর্কিত পরিষ্কারকরণ করা হয়নি।

এই কাজে পরিবর্তিত ফাইল