Autouzupełnianie nazw serwerów dla SSH i SCP


61

Mam skonfigurowanych kilka serwerów ~/.ssh/config, takich jak alphai beta. Jak mogę skonfigurować Bash, aby polecenia ssh al<tab>i scp file.tgz al<tab>autouzupełnianie nazw skonfigurowanych serwerów?

Nie chcę dodawać serwerów do innego pliku (tj. Tablicy Bash) przy każdym dodawaniu, ponieważ regularnie dodajemy i usuwamy serwery, a lista jest dość duża.


2
Czy masz zainstalowany pakiet uzupełniający dla swojej dystrybucji? Myślę, że jest to część standardowych procedur ukończenia, chociaż mogę pomylić to z Zsh.
— Caleb

Moja instalacja robi dokładnie to.
— slm

To jest na Kubuntu 12.10, a ja mam bash-completionzainstalowany.
— dotancohen

Odpowiedzi:


64

Znaleziono to !!

Wygląda na to, że w Ubuntu wpisy w ~/.ssh/known_hostssą zaszyfrowane , więc zakończenie SSH nie może ich odczytać. To funkcja, a nie błąd. Nawet dodając HashKnownHosts nodo ~/.ssh/configi /etc/ssh/ssh_confignie był w stanie zapobiec hashowania hosta.

Jednak gospodarze, którymi jestem zainteresowany, również znajdują się w ~/.ssh/config. Oto skrypt dla Bash Completion, który odczytuje wpisy z tego pliku:

_ssh() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts=$(grep '^Host' ~/.ssh/config ~/.ssh/config.d/* 2>/dev/null | grep -v '[?*]' | cut -d ' ' -f 2-)

    COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
    return 0
}
complete -F _ssh ssh

Włóż ten skrypt, /etc/bash_completion.d/ssha następnie pobierz go za pomocą następującego polecenia:

$ . /etc/bash_completion.d/ssh

Uważam ten przewodnik za nieoceniony i bez niego nie byłbym w stanie go napisać. Dziękuję Steve'owi Kempowi za napisanie tego wspaniałego przewodnika!


1
Wygląda na to, że w Centos 6 wpisy w ~ / .ssh / known_hosts zastępują wpisy w ~ / .ssh / config np. jeśli masz foo.bar.baz.com w znanym_hostach, to pasuje do całości, jeśli wykonasz "ssh foo" <tab> - jest to niepożądane, jeśli masz innego użytkownika lub inne ustawienia, które chcesz zastosować z ssh confg. Jeśli masz wpis w konfiguracji ssh, który nie uzupełnia się poprawnie, sprawdź, czy jest obecny w znanych_hostach i usuń go. Teraz powinno działać normalnie, biorąc ustawienia z config.
— Imran-UK

@ Imran-UK: Wiadomo, że Ubuntu nie robi tego rozsądnego działania pod pozorem bezpieczeństwa. Najwyraźniej chodzi o to, że złośliwy byt może, jako użytkownik, edytować ~ / .ssh / config, pomimo chmod 0600 w katalogu. Hej, to nie ja podjąłem decyzję!
— dotancohen 18.04.16

1
Używam zsh i oh-my-zsh, właśnie odkryłem, że włączenie wtyczki „ssh” i umieszczenie „HashKnownHosts yes” w moim ~ / .ssh / config wydaje się robić dobrze. Możesz zmienić powłokę niezależnie od dystrybucji, więc może to być obejście.
— Imran-UK

@ Imran-UK: W rzeczywistości próbowałem zsh w przeszłości i zamierzam spróbować ponownie. Zajrzę do tego. Shukran, mój przyjacielu!
— dotancohen 20.04.16

Wiem, że jestem trochę spóźniony na imprezę, ale RHEL 7 automatycznie uzupełni wpisy, które są w /etc/hostsśrodku, inne dystrybucje mogą zrobić to samo.
— Centimane,

16

Zapakowane

Nie mówisz, jakiej dystrybucji używasz, ale na moim systemie Fedora 19 mam zainstalowany następujący pakiet, bash-completionktóry udostępnia tę funkcję poprzez ten plik reguł uzupełniania:

/usr/share/bash-completion/completions/ssh

Oto pakiet, który zainstalowałem:

$ rpm -aq |grep completion
bash-completion-2.1-2.fc19.noarch

Jeśli przejrzysz ten plik reguł, zobaczysz sekcje, które przesłuchują ten $HOME/.ssh/configplik:

$ grep config /usr/share/bash-completion/completions/ssh
    local configfile
    local -a config
        # Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument
                    configfile="$(dequote "${1:2}")"
                    [[ $1 ]] && configfile="$(dequote "$1")"
        _known_hosts_real -a -F "$configfile" "$cur"
    local configfile
        # Search COMP_WORDS for '-F configfile' argument
                    configfile="$(dequote "${1:2}")"
                    [[ $1 ]] && configfile="$(dequote "$1")"
        _known_hosts_real -a -F "$configfile" "$cur"
    local configfile prefix
        # Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument
                    configfile="$(dequote "${1:2}")"
                    [[ $1 ]] && configfile="$(dequote "$1")"
                _known_hosts_real -c -a -F "$configfile" "$cur"

Tocząc własne

Znalazłem także Gist, known_hosts_autocomplete.sh , który robi coś podobnego oprócz $HOME/.ssh/known_hostspliku.

# add to ~/.bash_profile, and close/reopen a shell.  Will autocomplete any
# hosts found in known_hosts.

complete -W "$(echo `cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | \
    sed -e s/,.*//g | uniq | grep -v "\["`;)" ssh

Możesz zrobić coś podobnego, korzystając z $HOME/.ssh/configpliku, jeśli z jakiegoś powodu nie możesz znaleźć pliku reguły uzupełniania dla sshjuż wstępnie spakowanego.


Dziękuję Ci. Wygląda na to, że Ubuntu nie jest dostarczane /usr/share/bash-completion/completions/ssh. Czy możesz gdzieś opublikować cały plik, aby go skopiować? Dzięki!
— dotancohen

Możesz pobrać wszystkie pliki z tego archiwum: pkgs.fedoraproject.org/repo/pkgs/bash-completion/…
— slm

Przepraszam, że /usr/share/bash-completion/completions/sshprzeszkadzam , ale nawet skopiowanie pliku ssh z tego archiwum tar nie pomaga! Uruchamianie complete -W ...polecenia z wiersza polecenia Bash również nie działa . Co może być tutaj problemem?
— dotancohen

Dziękuję Ci. To wydaje się być znaną decyzją projektową w Ubuntu. Dlatego akceptuję odpowiedź, nawet jeśli nie mogę uzyskać ukończenia bashu dla sshlub scp.
— dotancohen

2
Homebrew dla OSX ma również: uzupełnianie bash i uzupełnianie zsh
— Adam Nelson

7

Odkryłem, że autouzupełnianie nie działa, ponieważ Ubuntu haszy znanych hostów. Możesz dodać

Host *
    HashKnownHosts no

Do twojego .ssh/configpliku, ale istniejące hosty nie zostaną odszyfrowane.


Dziękuję Ci. Właściwie już dodałem tę dyrektywę ~/.ssh/configi zmieniłem ją w /etc/ssh/ssh_config, i usunąłem ~/.ssh/known_hostsplik. Po ponownym zalogowaniu się na serwerach nazwy hostów są nadal zapisywane w stanie mieszanym.
— dotancohen

Zredagowałem swoją odpowiedź; musisz określić hosta i zagnieżdżić w nim dyrektywę hash; Nie wymieniłem, że tyle .ssh/configplików będzie już miało tę linię. Daj znać, jeśli to zadziała.
— M1ke

To zdecydowanie prosty sposób, aby to zrobić! Biorąc pod uwagę, że (nowsze wersje) Ubuntu mają teraz włączoną funkcję ssh uzupełniania, prawdopodobnie tego właśnie potrzeba.
— John Montgomery,

Jak dodałem poniżej, możesz to zrobić, ale prawdopodobnie nie powinieneś - nie musisz tego robić, aby ukończenie działało. Jeśli jednak nie wyrażasz zgody i chcesz po prostu usunąć haszowanie istniejących hostów po dodaniu powyższego, możesz po prostu rm ~ / .ssh / known_hosts, a to spowoduje ponowne wygenerowanie (odszyfrowanie) za każdym razem logujesz się na nowy serwer.
— Jamieson Becker

3

Aby włączyć autouzupełnianie ssh w Debianie i Ubuntu:

sudo apt-get install bash-completion

Zauważ, że nie ma to nic wspólnego z mieszaniem znanego hosta, w przeciwieństwie do tego, co zostało powiedziane powyżej i pierwotne pytanie. Jeśli chcesz autouzupełnianie ze znanych_hostów, oczywiście musisz wyłączyć haszowanie, ale jest to zdecydowanie zalecane przeciwko.

Mam na przykład:

Host *
    HashKnownHosts yes

w moim .ssh / config i nadal mam automatyczne uzupełnianie ssh działające w porządku przeciwko hostom wymienionym w .ssh / config i / etc / hosts. Musisz dodać hosta do .ssh / config, jak stwierdził OP:

Host my-awesome-host Nazwa hosta the.real.host.name

(Lub możesz dodać wpis hosta do / etc / hosts, który jest innym źródłem skryptów Debian / Ubuntu.)

Następnie możesz po prostu wpisać, ssh my-awe<tab>a zostanie ono automatycznie ukończone. Znowu dzieje się tak nawet w przypadku HashKnownHosts, co jest wysoce zalecane. (Zauważ, że ukończenie bash musi być włączone w twojej powłoce bash i musisz specjalnie zainstalować te skrypty jak wyżej dla twojej dystrybucji.)

Następnie dodaj te wiersze do swojego, .bashrcaby go włączyć (wymaga wylogowania i zalogowania się ponownie lub po prostu nowego bashwpisania w celu uruchomienia nowej powłoki. (Nie musisz włączać, jeśli jest już włączony /etc/bash.bashrci /etc/profileźródła /etc/bash.bashrc).

if [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
fi

Umożliwi to ssh autouzupełnianie (między innymi!) Z ~/.ssh/config, /etc/hostsitp

Zauważ, że Debian domyślnie używa ash zamiast bash. Możesz łatwo przejść na bash:

sudo usermod -s /bin/bash "$USER"

(Musisz się wylogować i zalogować ponownie, aby to zadziałało).


2

W systemie Ubuntu 14.04 sshautomatyczne uzupełnianie serwerów wymienionych w twoim~/.ssh/config

Zauważyłem to, gdy zdałem sobie sprawę, że tylko jeden z serwerów, do których często uzyskuję dostęp do automatycznego uzupełniania. Jedyną różnicą między nimi był wpis w pliku konfiguracyjnym ssh związany z uwierzytelnianiem. Kiedy dodałem nowy wpis do pliku konfiguracyjnego dla drugiego serwera, zaczął on również automatyczne uzupełnianie.

Oto wpis dla tych, którzy pytali:

HOST server-name 
    GSSAPIAuthentication=no

Byłbym bardzo zaskoczony, gdyby miało to znaczenie dla tego, co określiłeś w konfiguracji (o ile oczywiście jest to nadal ważne).


Dziękuję Noah, co to był za wpis? W moich systemach 14.04 i 14.10 autouzupełnianie nie działa.
— dotancohen

Nie sądzę, żeby wpis miał znaczenie - jestem pewien, że to tylko je tam zawiera - ale dodam wpis do mojej odpowiedzi.
— Noah
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.