কীভাবে ssh রিমোট কমান্ড লাইনের যুক্তিগুলি পার্স হয়


11

আমি দূরবর্তী ssh কমান্ডের যুক্তিগুলি ডাবল-পলায়ন করার প্রয়োজন সম্পর্কে প্রশ্নোত্তর দেখেছি। আমার প্রশ্ন: ঠিক কোথায় এবং কখন দ্বিতীয় পার্সিং শেষ হয়?

আমি যদি নিম্নলিখিতটি চালিত করি:

$ ssh otherhost pstree -a -p

আমি আউটপুটে নিম্নলিখিতটি দেখতে পাচ্ছি:

  |-sshd,3736
  |   `-sshd,1102
  |       `-sshd,1109
  |           `-pstree,1112 -a -p

রিমোট কমান্ড ( pstree) এর পিতামাতার প্রক্রিয়াটি হ'ল sshd, এমন কোনও শেল উপস্থিত নেই যা দূরবর্তী কমান্ডে কমান্ড লাইন আর্গুমেন্টগুলি পার্স করে চলেছে, সুতরাং মনে হয় না যে ডাবল উদ্ধৃতি বা পলায়ন প্রয়োজনীয় হবে ( তবে এটি অবশ্যই)। পরিবর্তে আমি যদি সেখানে প্রথমে ছুটে যাই এবং লগইন শেলটি pstree -a -pপাই এবং তারপরে চালানো হয় তবে আউটপুটটিতে নিম্নলিখিতটি দেখি:

  ├─sshd,3736
     └─sshd,3733
         └─sshd,3735
             └─bash,3737
                 └─pstree,4130 -a -p

সুতরাং স্পষ্টভাবে সেখানে একটি bashশেল আছে যে ক্ষেত্রে কমান্ড লাইন পার্সিং করতে হবে। তবে আমি যেখানে প্রত্যক্ষ কমান্ডটি সরাসরি ব্যবহার করি সেখানে শেল বলে মনে হয় না, তবে ডাবল উদ্ধৃতি কেন প্রয়োজনীয়?

উত্তর:


22

সবসময় একটি রিমোট শেল থাকে। এসএসএইচ প্রোটোকলে ক্লায়েন্ট সার্ভারটি চালানোর জন্য একটি স্ট্রিং প্রেরণ করে। এসএসএইচ কমান্ড লাইন ক্লায়েন্ট তার কমান্ড লাইন আর্গুমেন্ট গ্রহণ করে এবং তাদেরকে আর্গুমেন্টের মধ্যে একটি ফাঁক দিয়ে যুক্ত করে তোলে। সার্ভারটি সেই স্ট্রিং নেয়, ব্যবহারকারীর লগইন শেলটি চালায় এবং সেই স্ট্রিংটি এটি পাস করে।

রিমোট শেলটি বাইপাস করা অসম্ভব। প্রোটোকলটিতে স্ট্রিংগুলির একটি অ্যারে পাঠানোর মতো কিছু নেই যা সার্ভারে একটি আরগভি অ্যারে হিসাবে পার্স করা যায়। এবং এসএসএইচ সার্ভার রিমোট শেলকে বাইপাস করবে না কারণ এটি কোনও সুরক্ষা বিধিনিষেধ হতে পারে: ব্যবহারকারীর শেল হিসাবে একটি সীমাবদ্ধ প্রোগ্রাম ব্যবহার করা এমন একটি উপায় যা কেবলমাত্র কয়েকটি নির্দিষ্ট কমান্ড চালানোর অনুমতিপ্রাপ্ত (যেমন একটি আরএসএনসি-একাউন্ট অথবা একটি গিট-ওয়ান অ্যাকাউন্ট)।

আপনি শেলটি দেখতে পাবেন না pstreeকারণ এটি ইতিমধ্যে চলে গেছে। অনেকগুলি শেলের একটি অপ্টিমাইজেশন রয়েছে যেখানে তারা যদি সনাক্ত করে যে তারা "এই বাহ্যিক কমান্ডটি চালাচ্ছে, এটি সম্পন্ন হওয়ার জন্য অপেক্ষা করবে এবং কমান্ডের স্থিতি দিয়ে প্রস্থান করবে", তারপরে শেলটি " execveএই বাহ্যিক কমান্ডের" দিয়ে চলেছে । আপনার প্রথম উদাহরণে এটি ঘটছে। নিম্নলিখিত তিনটি আদেশের বিপরীতে:

ssh otherhost pstree -a -p
ssh otherhost 'pstree -a -p'
ssh otherhost 'pstree -a -p; true'

প্রথম দুটি অভিন্ন: ক্লায়েন্ট সার্ভারে ঠিক একই ডেটা প্রেরণ করে। তৃতীয়টি একটি শেল কমান্ড প্রেরণ করে যা শেলের এক্সিকিউট অপ্টিমাইজেশনকে পরাস্ত করে।


2
হা! বিশ্বাস করতে পারি না আপনি আমার নিজের প্রশ্নের উত্তর দেওয়ার জন্য আমাকে মারধর করেছেন। প্রশ্ন পোস্ট করার মাধ্যমে আমি এটি অর্ধেক করে বের করে ফেলেছি এবং ভেবেছিলাম যে আমি নিজেই এটি জিজ্ঞাসা করা এবং উত্তর দিয়ে যাওয়া উচিত।
21

10

আমি মনে করি আমি এটি নির্ধারণ করেছি:

$ ssh otherhost pstree -a -p -s '$$'
init,1         
  `-sshd,3736
      `-sshd,11998
          `-sshd,12000
              `-pstree,12001 -a -p -s 12001

আর্গুমেন্টগুলি pstreeহ'ল: কমান্ড লাইন আর্গুমেন্টগুলি প্রদর্শন করুন, পিডগুলি দেখান এবং প্রদত্ত পিডের কেবল পিতামাতার প্রক্রিয়াগুলি দেখান। '$$'একটি বিশেষ শেল পরিবর্তনশীল যখন ব্যাশ কমান্ড লাইন আর্গুমেন্ট মূল্যায়ন যে ব্যাশ নিজস্ব PID প্রতিস্থাপন করবে। এটি আমার স্থানীয় শেল দ্বারা ব্যাখ্যা করা বন্ধ করতে একবার উদ্ধৃত করা হয়েছে। তবে এটির দ্বিগুণ উদ্ধৃতি দেওয়া হয়নি বা দূরবর্তী শেল দ্বারা এটি ব্যাখ্যা করার জন্য অনুমতি দেওয়া হয়নি।

যেমন আমরা দেখতে পাচ্ছি এটির সাথে এটি প্রতিস্থাপন করা হয়েছে 12001যা শেলের পিড। আমরা আউটপুট থেকে এটিও দেখতে পাচ্ছি: pstree,12001যে 12001 এর পিড সহ প্রক্রিয়াটি নিজেই স্ট্রিট্রি। তাহলে pstreeখোল?

আমি যা সংগ্রহ করি সেখানে এটি bashচলছে এবং এটি কমান্ড লাইন যুক্তিগুলি পার্স করছে, তবে তারপরে এটি execকমান্ড চালানোর সাথে সাথে নিজেকে প্রতিস্থাপনের জন্য অনুরোধ করে।

মনে হচ্ছে এটি কেবল একটি একক দূরবর্তী কমান্ডের ক্ষেত্রে এটি করে:

$ ssh otherhost pstree -a -p -s '$$' \; echo hi
init,1         
  `-sshd,3736
      `-sshd,17687
          `-sshd,17690
              `-bash,17691 -c pstree -a -p -s $$ ; echo hi
                  `-pstree,17692 -a -p -s 17691
hi

এই ক্ষেত্রে, আমি দুটি কমান্ড চালানোর জন্য অনুরোধ করছি: pstreeএরপরে অনুসরণ করুন echo। এবং আমরা এখানে দেখতে পারি যা bashপ্রকৃতপক্ষে প্রক্রিয়া গাছের পিতামাতার হিসাবে প্রদর্শিত হয় pstree


হা ! + ১. গিলস আরও আনুষ্ঠানিকভাবে প্রথমে যা রেখেছেন এবং দ্বিতীয়টি উদাহরণ দিয়ে দিয়েছেন তা উদাহরণ দিয়ে। তার প্রথম উত্তরটির জন্য ক্রেডিট দেওয়া সম্ভবত ক্রমযুক্ত?
সিবিহে

0

অন্যান্য উত্তর যা বলেছে সমর্থন করে, আমি সেই কোডটি সন্ধান করেছি যা রিমোটে কমান্ড আহ্বান করে, https://github.com/openssh/openssh-portable/blob/4f29309c4cb19bcb1774931db84cacc414f17d29/session.c#L1660 ...

1660    /*
1661     * Execute the command using the user's shell.  This uses the -c
1662     * option to execute the command.
1663     */
1664    argv[0] = (char *) shell0;
1665    argv[1] = "-c";
1666    argv[2] = (char *) command;
1667    argv[3] = NULL;
1668    execve(shell, argv, env);
1669    perror(shell);
1670    exit(1);

... যা আপনি দেখতে পাচ্ছেন, নিঃশর্তভাবে shellপ্রথম যুক্তি -cএবং দ্বিতীয় যুক্তির সাথে আহ্বান জানায় command। এর আগে, shellভেরিয়েবলটি রেকর্ড করা হিসাবে ব্যবহারকারীর লগইন শেলটিতে সেট করা হয়েছিল /etc/passwdcommandএই ফাংশনটির পক্ষে একটি যুক্তি, এবং শেষ পর্যন্ত তারের বাইরে স্ট্রিং রিড ভারব্যাটিয়াম সেট করা হয় ( session_exec_reqএকই ফাইলটিতে দেখুন )। সুতরাং, সার্ভারটি কমান্ডটি মোটেই ব্যাখ্যা করে না, তবে শেল্টটি সর্বদা রিমোটে ডাকা হয়।

যাইহোক, এসএসএইচ প্রোটোকল নির্দিষ্টকরণের সম্পর্কিত অংশটি এই আচরণের প্রয়োজন বলে মনে হয় না ; এটা শুধুমাত্র বলে

 byte      SSH_MSG_CHANNEL_REQUEST
 uint32    recipient channel
 string    "exec"
 boolean   want reply
 string    command

এই বার্তাটি সার্ভারকে অনুরোধ করবে যে প্রদত্ত আদেশটি কার্যকর করবে start 'কমান্ড' স্ট্রিংয়ে একটি পথ থাকতে পারে। অননুমোদিত কমান্ড কার্যকর করা রোধ করতে সাধারণ সতর্কতা অবলম্বন করা উচিত।

এটি সম্ভবত কারণ সমস্ত অপারেটিং সিস্টেমে কমান্ড-লাইন শেলটির ধারণা নেই। উদাহরণস্বরূপ, কোনও ক্লাসিক ম্যাকোএস এসএস সার্ভারের পরিবর্তে অ্যাপলস্ক্রিপ্ট ইন্টারপ্রেটারকে "এক্সিকিউটিভ" কমান্ড স্ট্রিং সরবরাহ করা পাগল হত না ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.