Itu mungkin karena /etc/sudoers
file Anda (atau file apa pun yang termasuk) memiliki:
Defaults requiretty
... yang membuatnya sudo
membutuhkan TTY. Sistem Red Hat (RHEL, Fedora ...) telah diketahui membutuhkan TTY dalam sudoers
file default . Itu tidak memberikan manfaat keamanan nyata dan dapat dihapus dengan aman.
Red Hat telah mengakui masalahnya dan itu akan dihapus di rilis mendatang.
Jika mengubah konfigurasi server bukanlah suatu opsi, sebagai solusi untuk kesalahan konfigurasi tersebut, Anda dapat menggunakan opsi -t
atau -tt
opsi ssh
yang memunculkan terminal semu di sisi jarak jauh, tetapi berhati-hatilah bahwa ia memiliki sejumlah sisi. efek.
-tt
dimaksudkan untuk penggunaan interaktif. Ini menempatkan terminal lokal dalam raw
mode sehingga Anda berinteraksi dengan terminal jarak jauh. Itu berarti bahwa jika ssh
I / O bukan dari / ke terminal, itu akan memiliki efek samping. Misalnya, semua masukan akan bergema kembali, karakter terminal khusus ( ^?
, ^C
, ^U
) akan menyebabkan pengolahan khusus; pada output, LF
s akan dikonversi ke CRLF
s ... (lihat jawaban untuk Mengapa file biner ini diubah? untuk lebih jelasnya.
Untuk meminimalkan dampak, Anda dapat memintanya sebagai:
ssh -tt host 'stty raw -echo; sudo ...' < <(cat)
The < <(cat)
akan menghindari pengaturan dari terminal lokal (jika ada) di raw
modus. Dan kami menggunakan stty raw -echo
untuk menetapkan disiplin garis terminal jarak jauh sebagai lewat (efektif sehingga berperilaku seperti pipa yang akan digunakan sebagai pengganti terminal semu tanpa -tt
, meskipun itu hanya berlaku setelah perintah itu dijalankan, jadi Anda perlu untuk menunda pengiriman sesuatu untuk input sampai itu terjadi).
Perhatikan bahwa karena output dari perintah jarak jauh akan menuju terminal, itu masih akan mempengaruhi buffering-nya (yang akan berbasis garis untuk banyak aplikasi) dan efisiensi bandwidth sejak TCP_NODELAY
dinyalakan. Juga dengan -tt
, ssh
atur IPQoS lowdelay
sebagai lawan throughput
. Anda dapat mengatasi keduanya dengan:
ssh -o IPQoS=throughput -tt host 'stty raw -echo; sudo cmd | cat' < <(cat)
Juga, perhatikan bahwa itu berarti perintah jarak jauh tidak dapat mendeteksi end-of-file pada stdin dan stdout dan stderr dari perintah jarak jauh digabung menjadi satu aliran.
Jadi, tidak begitu bagus untuk bekerja.
Jika Anda sudah suatu punya cara untuk menelurkan sebuah pseudo-terminal di remote host (seperti dengan expect
, zsh
, socat
, perl
's IO::Pty
...), maka itu akan lebih baik untuk menggunakannya untuk membuat pseudo-terminal untuk melampirkan sudo
ke (tapi bukan untuk I / O), dan digunakan ssh
tanpa -t
.
Misalnya dengan 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'
Atau dengan script
(di sini dengan asumsi implementasi dari 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'
(dengan asumsi (untuk keduanya) bahwa shell login dari pengguna jarak jauh adalah seperti Bourne).
requiretty
di sudoers default-nya. Ini akan diperbaiki dalam rilis yang lebih baruGunakan
-t
benderassh
untuk memaksa alokasi tty.sumber
-t
untuk memaksa alokasi ketikaPseudo-terminal will not be allocated because stdin is not a terminal.
Saya mengalami masalah ini menggunakan Docker dan Centos 7. Saya akhirnya melakukan hal berikut:
yum install -y sudo
sed -i -e 's/Defaults requiretty.*/ #Defaults requiretty/g' /etc/sudoers
Saya menemukan retasan ini di https://hub.docker.com/r/liubin/fluentd-agent/~/dockerfile
sumber
Alternatif yang menarik adalah menjalankan FreeIPA atau IdM untuk mengelola pengguna Anda dan aturan sudoer secara terpusat. Anda kemudian dapat membuat aturan sudo dan menetapkan opsi
! Persyaratan kecil
dalam aturan. Perintah kemudian akan berjalan seperti yang diharapkan. Anda juga akan mendapat manfaat mengelola semua server dan pengguna dari satu set konfigurasi.
sumber
Saya memiliki masalah yang sama. Dalam kasus saya, solusinya adalah dua baris
Penjelasan:
Tempatkan perintah yang ingin Anda jalankan (termasuk perintah sudo) ke dalam skrip misalnya "ssh_test.sh".
Baca seluruh skrip ke dalam variabel yang disebut "skrip".
Laksanakan ssh hanya dengan satu -t dan berikan variabel alih-alih perintah.
Sebelum ini, saya mengalami masalah menggunakan kombinasi membaca dari stdin dan menggunakan heredocs
sumber
Saya menemukan pertanyaan ini ketika Googling dan saya menemukan kesalahan ini karena alasan yang sangat berbeda.
Perbaikan saya adalah berhenti memanggil skrip shell hilir
sudo
dari skrip shell induk saya, ketika skrip shell induk sudah dipanggil dengansudo
.sumber