لماذا يفشل ssh من crontab ولكنه ينجح عند تنفيذه من سطر الأوامر؟

StackOverflow https://stackoverflow.com/questions/869589

  •  22-08-2019
  •  | 
  •  

سؤال

لدي برنامج نصي bash يقوم بإجراء ssh على جهاز بعيد وينفذ أمرًا هناك، مثل:

ssh -nxv user@remotehost echo "hello world"

عندما أقوم بتنفيذ الأمر من سطر الأوامر، فإنه يعمل بشكل جيد، لكنه يفشل عندما يتم تنفيذه كجزء من crontab (رمز الخطأ = 255 - لا يمكن إنشاء اتصال SSH).تفاصيل:

...
Waiting for server public key.
Received server public key and host key.
Host 'remotehost' is known and matches the XXX host key.
...
Remote: Your host key cannot be verified: unknown or invalid host key.
Server refused our host key.
Trying XXX authentication with key '...'
Server refused our key.
...

عند التنفيذ محليًا، فأنا أعمل كجذر، ويعمل crontab كجذر أيضًا.تنفيذ "id" من crontab وسطر الأوامر يعطي النتيجة نفسها تمامًا:

$ id
> uid=0(root) gid=0(root) groups=0(root),...

أقوم بإجراء ssh من بعض الأجهزة المحلية إلى الجهاز الذي يقوم بتشغيل crond.لدي مفتاح ssh وبيانات اعتماد لـ ssh to crond وأي جهاز آخر تتصل به البرامج النصية.

ملاحظة.من فضلك لا تسأل/تشكو/تعلق بأن تنفيذ أي شيء كجذر أمر سيء/خطأ/وما إلى ذلك - ليس هذا هو الغرض من هذا السؤال.

هل كانت مفيدة؟

المحلول

وأنا على التخمين بأن عادة عند SSH من الجهاز المحلي إلى الجهاز تشغيل crond، يتم تحميل المفتاح الخاص في سه وكيل وإرسالها عبر اتصال. وذلك عند تنفيذ الأمر من سطر الأوامر، فإنه يجد المفتاح الخاص في سه وكيل ويستخدم لتسجيل الدخول إلى الجهاز البعيد.

عند تنفيذ crond الأمر، أنه ليس لديه الوصول إلى سه وكيل، لذلك لا يمكن استخدام المفتاح الخاص.

وسيكون لديك لإنشاء مفتاح خاص جديد للالجذر على الجهاز تشغيل crond، ونسخ الجزء العلني من أن الملف authorized_keys المناسب على الجهاز البعيد الذي تريد crond لتسجيل الدخول إلى.

نصائح أخرى

keychain

يحل هذا بطريقة غير مؤلمة.إنه موجود في مستودعات Debian/Ubuntu:

sudo apt-get install keychain

وربما بالنسبة للعديد من التوزيعات الأخرى (يبدو أنها نشأت من Gentoo).

سيبدأ هذا البرنامج ssh-agent إذا لم يكن هناك أي شيء قيد التشغيل، وقم بتوفير نصوص shell التي يمكن تشغيلها sourced وقم بتوصيل الغلاف الحالي بهذا بالذات ssh-agent.

ل bash, ، بمفتاح خاص اسمه id_rsa, ، قم بإضافة ما يلي إلى الخاص بك .profile:

keychain --nogui id_rsa

سيبدأ هذا ssh-agent وإضافة id_rsa مفتاح عند تسجيل الدخول الأول بعد إعادة التشغيل.إذا كان المفتاح محميًا بعبارة المرور، فسيطلب أيضًا عبارة المرور. لا حاجة لاستخدام مفاتيح غير محمية بعد الآن! بالنسبة لعمليات تسجيل الدخول اللاحقة، سوف يتعرف على الوكيل ولن يطلب عبارة المرور مرة أخرى.

أضف أيضًا ما يلي كسطر أخير من ملفك .bashrc:

. ~/.keychain/$HOSTNAME-sh

سيسمح هذا لـ Shell بمعرفة مكان الوصول إلى وكيل SSH المُدار بواسطة keychain.تأكد من أن .bashrc مصدرها .profile.

ومع ذلك، يبدو أن cron الوظائف لا تزال لا ترى هذا.كعلاج، قم بتضمين السطر أعلاه في crontab, ، قبل الأمر الفعلي مباشرةً:

* * * * * . ~/.keychain/$HOSTNAME-sh; your-actual-command

لا تعرض مفاتيح SSH الخاص بك دون مرور. استخدام سه-كرون بدلا من ذلك، والذي يسمح لك لجدولة المهام باستخدام وكلاء SSH.

وهكذا كان لي مشكلة مماثلة. جئت الى هنا ورأيت إجابات مختلفة ولكن مع بعض التجارب هنا هو كيف حصلت عليه العمل مع sshkeys مع مرور، سه وكيل وكرون.

أولا، يستخدم الإعداد سه بلدي النصي التالي في بلدي النصي باش الحرف الأول.

# JFD Added this for ssh
SSH_ENV=$HOME/.ssh/environment

    # start the ssh-agent
    function start_agent {
        echo "Initializing new SSH agent..."
        # spawn ssh-agent
        /usr/bin/ssh-agent | sed 's/^echo/#echo/' > "${SSH_ENV}"
        echo succeeded
        chmod 600 "${SSH_ENV}"
        . "${SSH_ENV}" > /dev/null
        /usr/bin/ssh-add
    }


    if [ -f "${SSH_ENV}" ]; then
         . "${SSH_ENV}" > /dev/null
         ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
            start_agent;
        }
   else
        start_agent;
   fi

عند I تسجيل الدخول، أقوم بإدخال عبارة المرور مرة واحدة ثم من بعد ذلك على أنها سوف تستخدم سه وكيل لمصادقة لي تلقائيا.

ويتم الاحتفاظ تفاصيل سه وكيل في .ssh / البيئة. هنا هو ما الذي النصي سيبدو:

SSH_AUTH_SOCK=/tmp/ssh-v3Tbd2Hjw3n9/agent.2089; export SSH_AUTH_SOCK;
SSH_AGENT_PID=2091; export SSH_AGENT_PID;
#echo Agent pid 2091;

وفيما يتعلق كرون، يمكنك إعداد وظيفة كمستخدم عادي بطرق مختلفة. إذا قمت بتشغيل -e كرونتاب كمستخدم جذر وسوف الإعداد كرون المستخدم الجذر. إذا قمت بتشغيل كما كرونتاب -u ديفيس -E سيكون إضافة مهمة كرون كما معرف المستخدم ديفيس. وبالمثل، إذا قمت بتشغيل كمستخدم ديفيس ولا كرونتاب -e فإنه سيتم إنشاء وظيفة كرون الذي يعمل على معرف المستخدم ديفيس. يمكن التحقق من ذلك مع دخول التالي:

30 *  *   *   *     /usr/bin/whoami

وهذا سوف ترسل نتيجة whoami كل 30 دقيقة إلى المستخدم ديفيس. (لقد فعلت ذلك ل-e crontabe كمستخدم ديفيس).

إذا كنت في محاولة لمعرفة ما مفاتيح تستخدم كمستخدم ديفيس، قيام بذلك:

36 *  *   *   *     /usr/bin/ssh-add -l

ووسوف تفشل، وسجل ترسل عن طريق البريد ويقول

To: davis@xxxx.net
Subject: Cron <davis@hostyyy> /usr/bin/ssh-add -l

Could not open a connection to your authentication agent.

والحل هو مصدر السيناريو الحياة الفطرية لسه وكيل أعلاه. هنا هو دخول كرون الناتجة:

55 10  *   *   *     . /home/davis/.ssh/environment; /home/davis/bin/domythingwhichusesgit.sh

وهذا سوف تشغيل البرنامج النصي الساعة 10:55. لاحظ الرائدة. في البرنامج النصي. وتقول لتشغيل هذا البرنامج النصي في بيئتي على غرار ما هو في البرنامج النصي .bash الحرف الأول.

ويوم أمس كان لي مشكلة مماثلة ...

ولدي وظيفة كرون على خادم واحد، والتي تبدأ بعض الإجراءات على خادم آخر، وذلك باستخدام سه ... المشكلة كانت أذونات المستخدم، ومفاتيح ...

وفي كرونتاب كان لي

* * * * * php /path/to/script/doSomeJob.php

وببساطة لم تنجح (لم يكن لديها أذونات). أنا tryed لتشغيل كرون كمستخدم معين، وهذا مرتبط إلى ملقم آخر

* * * * * user php /path/to/script/doSomeJob.php

ولكن مع عدم وجود تأثير.

وأخيرا، أنا navicate إلى البرنامج النصي ومن ثم تنفيذ ملف بي، وانها عملت ..

* * * * * cd /path/to/script/; php doSomeJob.php
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top