अगर मुझे बिना पासवर्ड के सूडो किया जा सकता है, तो मुझे sudo चलाने के लिए tty की आवश्यकता क्यों है?


226

मैंने sudoपासवर्ड के बिना चलने के लिए कॉन्फ़िगर किया है, लेकिन जब मैं प्रयास करता हूं, तब ssh 'sudo Foo'भी मुझे त्रुटि संदेश मिलता है sudo: sorry, you must have a tty to run sudo

ऐसा क्यों होता है और मैं इसके आसपास कैसे काम कर सकता हूं?

जवाबों:


290

ऐसा शायद इसलिए है क्योंकि आपकी /etc/sudoersफ़ाइल (या इसमें शामिल किसी भी फ़ाइल में) है:

Defaults requiretty

... जिसके लिए sudoTTY की आवश्यकता होती है। Red Hat सिस्टम (RHEL, Fedora ...) को डिफॉल्ट sudoersफाइल में TTY की आवश्यकता होती है । यह कोई वास्तविक सुरक्षा लाभ प्रदान नहीं करता है और सुरक्षित रूप से हटाया जा सकता है।

रेड हैट ने समस्या को स्वीकार किया है और इसे भविष्य के रिलीज में हटा दिया जाएगा।

यदि सर्वर के कॉन्फ़िगरेशन को बदलना एक विकल्प नहीं है, तो उस गलत कॉन्फ़िगरेशन के लिए काम के आसपास, आप उन विकल्पों -tया -ttविकल्पों का उपयोग कर सकते हैं, sshजो रिमोट साइड पर एक छद्म टर्मिनल को जन्म देते हैं, लेकिन सावधान रहें कि इसका एक नंबर है प्रभाव।

-ttइंटरैक्टिव उपयोग के लिए है। यह स्थानीय टर्मिनल को rawमोड में रखता है ताकि आप दूरस्थ टर्मिनल के साथ बातचीत करें। इसका मतलब है कि अगर sshI / O किसी टर्मिनल से / से नहीं है, तो इसके दुष्प्रभाव होंगे। उदाहरण के लिए, सभी इनपुट वापस गूँजती किया जाएगा, विशेष टर्मिनल वर्ण ( ^?, ^C, ^U) विशेष प्रसंस्करण का कारण होगा; आउटपुट पर, LFs को CRLFs में परिवर्तित किया जाएगा ... ( इस जवाब को देखें कि बाइनरी फ़ाइल को क्यों बदला जा रहा है? अधिक विवरण के लिए।

प्रभाव को कम करने के लिए, आप इसे निम्न प्रकार से लागू कर सकते हैं:

ssh -tt host 'stty raw -echo; sudo ...' < <(cat)

< <(cat)स्थानीय टर्मिनल की स्थापना (यदि हो) में से बचने जाएगा rawमोड। और हम stty raw -echoरिमोट टर्मिनल की लाइन अनुशासन को पास से गुजरने के लिए उपयोग कर रहे हैं (प्रभावी रूप से इसलिए यह उस पाइप की तरह व्यवहार करता है जिसका उपयोग बिना छद्म टर्मिनल के बजाय किया जाएगा -tt, हालांकि यह केवल उस कमांड के चलने के बाद लागू होता है, इसलिए आपको आवश्यकता है ऐसा होने तक इनपुट के लिए कुछ भेजने में देरी)।

ध्यान दें कि जब से रिमोट कमांड का आउटपुट टर्मिनल पर जाएगा, तब भी इसकी बफरिंग (जो कई अनुप्रयोगों के लिए लाइन-आधारित होगी) और बैंडविड्थ दक्षता प्रभावित होगी TCP_NODELAY। इसके साथ ही -tt, sshIPQoS को lowdelayविरोध के अनुसार सेट करता है throughput। आप दोनों के साथ काम कर सकते हैं:

ssh -o IPQoS=throughput -tt host 'stty raw -echo; sudo cmd | cat' < <(cat)

यह भी ध्यान दें कि इसका मतलब है कि रिमोट कमांड अपने स्टड पर एंड-ऑफ-फाइल का पता नहीं लगा सकता है और रिमोट कमांड के स्टडआउट और स्टडर को एक स्ट्रीम में मर्ज कर दिया जाता है।

तो, सब के बाद इतना अच्छा काम नहीं है।

आप एक दूरस्थ होस्ट पर एक छद्म टर्मिनल अंडे देने के लिए एक तरह से मिल गया है, तो (के साथ की तरह expect, zsh, socat, perlकी IO::Pty...), तो इसका इस्तेमाल करने की है कि छद्म टर्मिनल संलग्न करने के लिए बनाने के लिए बेहतर होगा sudoकरने के लिए (लेकिन I / O) के लिए नहीं, और sshबिना उपयोग करें -t

उदाहरण के लिए, साथ expect:

ssh host 'expect -c "spawn -noecho sh -c {
     exec sudo cmd >&4 2>&5 <&6 4>&- 5>&- 6<&-}
 exit [lindex [wait] 3]" 4>&1 5>&2 6<&0'

या script(यहाँ से क्रियान्वयन मानकर util-linux):

ssh host 'SHELL=/bin/sh script -qec "
              sudo cmd <&3 >&4 2>&5 3<&- 4>&- 5>&-
            " /dev/null 3<&0 4>&1 5>&2'

(यह मानते हुए (दोनों के लिए) कि दूरस्थ उपयोगकर्ता का लॉगिन शेल बॉर्न-जैसा है)।


30

डिफ़ॉल्ट रूप से, SUDO को TTY की आवश्यकता के लिए कॉन्फ़िगर किया गया है। यानी, SUDO को एक लॉगिन शेल से चलाया जा सकता है। आप -tअपने SSH आह्वान पर स्विच जोड़कर इस आवश्यकता को पराजित कर सकते हैं :

ssh -t someserver sudo somecommand

-tएक छद्म ट्टी का बल आवंटन।

यदि आप इसे विश्व स्तर पर प्रदर्शन करना चाहते हैं, तो /etc/sudoersनिर्दिष्ट करने के लिए संशोधित करें !requiretty। यह प्रति उपयोगकर्ता, प्रति समूह या सभी-स्तर पर किया जा सकता है।


5
नहीं, यह डिफ़ॉल्ट नहीं है। यह केवल सुडो का रेडहैट डिस्ट्रीब्यूशन है जो requirettyइसके डिफॉल्ट सुडोर्स में था। इसे नए रिलीज में तय किया जाएगा
स्टीफन चेज़लस

1
@StephaneChazelas +1 ने मुझे सूचित करने के लिए कि यह Red Hat और उसके भाई-बहनों के लिए काफी हद तक स्वदेशी है और एक और ++ अगर मैं वर्तमान बग रिपोर्ट के लिए कर सकता हूं!
JRFerguson

18

-tझंडे के sshआवंटन को बाध्य करने के लिए ध्वज का उपयोग करें ।

$ ssh luci tty
not a tty
$ ssh luci -t tty
/dev/ttys003
$

एक दूसरे जोड़े -tजब आवंटन के लिए मजबूर करनेPseudo-terminal will not be allocated because stdin is not a terminal.
Samveen

11

मैं डॉकटर और सेंटोस 7 का उपयोग करके इस समस्या में भाग गया। मैंने निम्नलिखित कार्य पूरा किया:

yum install -y sudo

sed -i -e 's/Defaults requiretty.*/ #Defaults requiretty/g' /etc/sudoers

मुझे यह हैक https://hub.docker.com/r/liubin/fluentd-agent/~/duberile पर मिला।


1
इस उत्तर ने मेरे लिए सबसे अधिक समझदार बना दिया, साथ ही डॉकटर और सेंटोस 7 का भी उपयोग किया। यह समझने में आसान था और साथ ही कॉपी / पेस्ट फ्रेंडली भी!
Dahahaun 18

1

एक दिलचस्प विकल्प यह है कि आप अपने उपयोगकर्ताओं और केंद्र के नियमों का प्रबंधन करने के लिए FreeIPA या IdM चलाएं। फिर आप sudo नियम बना सकते हैं और विकल्प निर्दिष्ट कर सकते हैं

! requiretty

नियम में। कमान फिर उम्मीद के मुताबिक चलेगी। आपको कॉन्फ़िगरेशन के एक सेट से सभी सर्वर और उपयोगकर्ताओं को प्रबंधित करने के भी लाभ होंगे।


0

मेरी भी यही समस्या थी। मेरे मामले में, समाधान दो लाइनें थीं

myscript=$(cat ssh_test.sh)
ssh -t user@host "$myscript"

स्पष्टीकरण:

  • उन कमांड्स को रखें जिन्हें आप (sudo कमांड्स सहित) स्क्रिप्ट में चलाना चाहते हैं जैसे "ssh_test.sh"।

  • पूरी स्क्रिप्ट को "myscript" नामक एक चर में पढ़ें।

  • केवल एक-टी के साथ ssh को आमंत्रित करें और कमांड के बजाय वेरिएबल की आपूर्ति करें।

इससे पहले, मैं स्टड से पढ़ने के संयोजन और हेरेडोक्स का उपयोग करके समस्याओं में भाग गया


-1

मुझे Googling के दौरान यह प्रश्न मिला और मुझे पूरी तरह से भिन्न कारण के लिए इस त्रुटि का सामना करना पड़ा।

मेरा फिक्स यह था कि sudoमैं अपने पेरेंट शेल स्क्रिप्ट से डाउनस्ट्रीम शेल स्क्रिप्ट को कॉल करना बंद कर दूं, जब पेरेंट शेल स्क्रिप्ट को पहले से ही कहा जाता था sudo

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.