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.

dotancohen
źródło
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!

dotancohen
źródło
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.

slm
źródło
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.

M1ke
źródło
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).

Jamieson Becker
źródł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).

Noah
źródło
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