sudo
Parola olmadan çalışacak şekilde yapılandırıldım , ancak denediğimde ssh 'sudo Foo'
hata mesajı alıyorum sudo: sorry, you must have a tty to run sudo
.
Bu neden oluyor ve bunun üzerinde nasıl çalışabilirim?
sudo
Parola olmadan çalışacak şekilde yapılandırıldım , ancak denediğimde ssh 'sudo Foo'
hata mesajı alıyorum sudo: sorry, you must have a tty to run sudo
.
Bu neden oluyor ve bunun üzerinde nasıl çalışabilirim?
Yanıtlar:
Bunun nedeni muhtemelen /etc/sudoers
dosyanızda (veya içerdiği herhangi bir dosyada):
Defaults requiretty
... ki bu sudo
bir TTY gerektiriyor. Red Hat sistemlerinin (RHEL, Fedora ...) varsayılan sudoers
dosyada TTY gerektirdiği bilinmektedir . Bu hiçbir gerçek güvenlik avantajı sağlamaz ve güvenle kaldırılabilir.
Red Hat sorunu kabul etti ve gelecek sürümlerde ortadan kalkacak.
Sunucunun konfigürasyonunu değiştirmek bir seçenek değilse, bu yanlış konfigürasyon için bir çözüm olarak, uzak taraftaki bir sözde-terminalin ortaya çıktığı -t
veya -tt
seçeneklerini kullanabilirsiniz ssh
; Etkileri.
-tt
etkileşimli kullanım içindir. raw
Uzak terminalle etkileşime girebilmeniz için yerel terminali moda geçirir . Bu, eğer ssh
G / Ç bir terminalden / uçağa değilse, bunun yan etkileri olacağı anlamına gelir . Örneğin, tüm giriş geri echoed, özel uç karakterleri ( ^?
, ^C
, ^U
) özel işlem neden olur; çıkışta LF
s , s'ye dönüştürülecektir CRLF
... ( bu cevaba neden bu ikili dosya değiştiriliyor? konusuna bakın).
Etkiyi en aza indirmek için, onu şu şekilde çağırabilirsiniz:
ssh -tt host 'stty raw -echo; sudo ...' < <(cat)
< <(cat)
Yerel terminalin ayarı (varsa) önleyecektir raw
modu. Ve stty raw -echo
uzak uçbirimin hat disiplinini geçiş olarak ayarlamak için kullanıyoruz (etkili bir şekilde sözde-uçbirim yerine kullanılacak bir boru gibi davranır -tt
, ancak bu komut çalıştırıldıktan sonra da geçerlidir, Bir şey gelinceye kadar giriş için göndermeyi geciktirmek için).
Uzak komutun çıktısı bir terminale gideceğinden, bunun tamponlamayı (birçok uygulama için satır tabanlı olacak) ve açık olduğundan beri bant genişliği verimliliğini etkileyeceğini unutmayın TCP_NODELAY
. Ayrıca birlikte -tt
, ssh
hiç IPQoS setleri lowdelay
aksine throughput
. İkisiyle de çalışabilirsiniz:
ssh -o IPQoS=throughput -tt host 'stty raw -echo; sudo cmd | cat' < <(cat)
Ayrıca, uzak komutun, stdinindeki dosyanın sonunu algılayamayacağı ve uzak komutun stdout ve stderr'sinin tek bir akışta birleştirildiği anlamına geldiğine dikkat edin.
Yani, sonuçta etrafta iyi bir iş değil.
Bir uzak ana bilgisayarda sahte terminali sokacak yol var ise (olduğu gibi expect
, zsh
, socat
, perl
's IO::Pty
...), o zaman sözde-terminali eklemek oluşturmak için bu kullanmak daha iyi olurdu sudo
(ama olup I / O), ve kullanıma ssh
olmadan -t
.
Örneğin, şununla 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'
Ya da script
(burada uygulamayı varsayarsak 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'
(her ikisi için de) uzaktaki kullanıcının giriş kabuğunun Bourne benzeri olduğunu varsayarak).
Varsayılan olarak, SUDO bir TTY gerektirecek şekilde yapılandırılmıştır. Yani, SUDO'nun bir giriş kabuğundan çalıştırılması bekleniyor. -t
SSH çağrınıza anahtar ekleyerek bu gereksinimi ortadan kaldırabilirsiniz :
ssh -t someserver sudo somecommand
-t
Bir psödo-tty'nin kuvvetleri ayırma.
Bunu global olarak yapmak istiyorsanız, /etc/sudoers
belirtmek için değiştirin !requiretty
. Bu kullanıcı başına, grup başına ya da her şeyi kapsayan bir seviyede yapılabilir.
Tty tahsisini zorlamak için -t
bayrağı kullanın ssh
.
$ ssh luci tty
not a tty
$ ssh luci -t tty
/dev/ttys003
$
-t
Tahsise zorlamak için ikinci bir saniye ekleyinPseudo-terminal will not be allocated because stdin is not a terminal.
Docker ve Centos 7 kullanarak bu sorunla karşılaştım. Aşağıdakileri yaptım:
yum install -y sudo
sed -i -e 's/Defaults requiretty.*/ #Defaults requiretty/g' /etc/sudoers
Bu hack https://hub.docker.com/r/liubin/fluentd-agent/~/dockerfile adresinde buldum
İlginç bir alternatif, kullanıcılarınızı ve sudoer kurallarınızı merkezi olarak yönetmek için FreeIPA veya IdM çalıştırmaktır. Daha sonra sudo kuralları oluşturabilir ve seçeneği atayabilirsiniz.
! requiretty
Kuralda. Komut daha sonra beklendiği gibi çalışacaktır. Ayrıca, tüm sunucuları ve kullanıcıları tek bir yapılandırma kümesinden yönetme avantajlarına da sahip olacaksınız.
Ben de aynı sorunu yaşadım. Benim durumumda çözüm iki satırdı.
myscript=$(cat ssh_test.sh)
ssh -t user@host "$myscript"
Açıklama:
Çalıştırmak istediğiniz komutları (sudo komutları dahil) "ssh_test.sh" gibi bir komut dosyasına yerleştirin.
Komut dosyasının tamamını "myscript" adlı bir değişkene okuyun.
Ssh komutunu sadece one -t ile çağırın ve değişkeni komut yerine verin.
Bundan önce, stdin'den okuma kombinasyonlarını kullanarak ve heredocs kullanarak problemlerle karşılaştım.
requiretty
Varsayılan sudo'larında bulunan sudo'nun yalnızca redhat dağılımı . Yeni sürümlerde düzeltilecek