Jump to content

Secure SHell for Alfred 3: SSH (plus SFTP, mosh & ping) with autosuggest


Recommended Posts

Secure SHell for Alfred 3

Open SSH/SFTP/mosh connections from Alfred with autosuggestions based on SSH config files, /etc/hosts and your history.

demo.gif
 

 

Features

  1. Auto-suggest hostnames from ~/.ssh/* and /etc/hosts (sources can be individually disabled).
  2. Remembers usernames, so you don't have to type them in every time. (You can also remove connections from your history or disable it entirely.)
  3. Alternate actions:
      - Open connection with mosh instead of SSH.
      - Open SFTP connection instead of SSH.
      - Ping host.

 

Data sources

The workflow reads hosts from the following sources (in this order of priority):

  1. ~/.ssh/config
  2. History (i.e. username + host addresses previously entered by the user)
  3. ~/.ssh/known_hosts
  4. /etc/hosts
  5. /etc/ssh/ssh_config


Installation

Download from Packal or GitHub releases and double-click the file to install in Alfred.

Source code is on GitHub.

 

Usage

Keyword is ssh:

  1. ssh [<query>] — View and filter known SSH connections.
      - or ⌘+<NUM> — Open the connection.
      - — Expand query to selected connection's title. Useful for adding a port number.
      - ⌘+↩ — Open an SFTP connection instead.
      - ⌘+⌥ — Open a mosh connection instead.
      - ⇧+↩ — Ping host.
      - ^+↩ — Forget connection (if it's from history).

 

 

Configuration

There are several options available in the workflow's configuration sheet. Notably, you can turn off individual autosuggestion sources. Please see the GitHub README for details.
 

Please note: The workflow generates an ssh:// (or sftp://) URL and asks Alfred to open it. Similarly, the ping and mosh features uses Alfred 3's Terminal Command feature. If it's not opening in the right app, it's not the workflow's fault.

 

Licencing & thanks

This workflow is released under the MIT Licence.


It uses the following libraries and resources:

  1. The icon is based on Octicons by Github (SIL Licence).
  2. ssh_config (MIT Licence) to parse SSH config files.
  3. awgo (MIT Licence) for the workflowy stuff.

 

This workflow started as a port of @isometry's Python SSH workflow to Go as a testbed for awgo. It has since gained some additional features.

 

If you need Alfred 2 support, check out @isometry's workflow.

 

Changelog

  1. v0.6.0 — 2016-11-09
      - Add in-workflow updates
  2. v0.5.0 — 2016-10-31
      - Add support for SSH configuration files (~/.ssh/config and /etc/ssh/ssh_config)
      - Alternate action: open connection with mosh
  3. v0.4.0 — 2016-05-27
      - Add ability to turn sources of suggestions off #1
  4. v0.3.0 — 2016-05-26
      - Alternate action: Open SFTP connection
      - Alternate action: Ping host
      - Remember connections with usernames, so you don't have to type the username each time
  5. v0.2.0 — 2016-05-23
      - First public release
Edited by deanishe
New release
Link to comment
Thank you, this looks really great. I was looking into go myself but I didn't know I could make workflows in it for Alfred. A 'go library' sounds really exciting.

 

Also what should I change in the workflow to have the connections open in iTerm instead of default Terminal?

-- NORMAL --

Edited by nikivi
Link to comment

Thank you, this looks really great. I was looking into go myself but I didn't know I could make workflows in it for Alfred. A 'go library' sounds really exciting.

The library's nowhere near done. I change the API nearly every day. The JSON output isn't even complete yet.

Go's a very nice language for workflows. It's so fast (20x faster than Python/Ruby).

Also what should I change in the workflow to have the connections open in iTerm instead of default Terminal?

-- NORMAL --

That has nothing to do with the workflow. It just passes the system an ssh://… URL. You have to change that on your system, e.g. via iTerm > Preferences > Profiles > General > URL Schemes.

Link to comment

Added a few new features today while adding support for workflow variables to the library.
 
First up, History. If you open a connection with a username, the workflow remembers it, and will suggest it if you start typing the username again. Very handy if you need to use usernames. Use ⌥+↩ to forget a connection from the history.
 
Also, you can now open an SFTP connection, instead of an SSH one, with ⌘+↩, or ping the host with ⇧+↩

Link to comment
  • 2 weeks later...

That's a good idea.
 
I'll look into it, but parsing the config file is much more complicated than /etc/hosts or known_hosts, and I think it would require a significant re-write of the workflow due to the way usernames are currently handled.

 

Currently, the workflow will remember usernames (and ports), but you'd have to open each connection manually once.

 

Alternatively, you could add the URLs by hand to ~/Library/Application Support/Alfred 3/Workflow Data/net.deanishe.alfred-ssh/history.json.
Edited by deanishe
Link to comment
  • 4 months later...
  • 4 weeks later...

Thank you for sharing this fantastic workflow.

 

I have an issue with Localforward options in the ~/.ssh/config file, it looks like they are ignored. This is what my configuration look like:

 

IdentityFile ~/.ssh/key.pem

Host myserver
    HostName x.x.x.x
    Port yyyy
    User zzzz
    LocalForward 127.0.0.1:12345 127.0.0.1:8080
    LocalForward 127.0.0.1:5555 127.0.0.1:55555

If I manually connect with "ssh myserver" the port forwarding work just fine, but it won't work through Alfred (I'm using the shortcut from ~/.ssh/config).

Link to comment

The workflow generates an ssh URL based on the hostname, port etc. (in this case ssh://zzzz@x.x.x.x:yyyy).

 

As such, ssh will read the options for Host x.x.x.x, not for Host myserver.

 

I'll look into changing the workflow, so hosts read from ~/.ssh/config will have URLs matching the Host, e.g. ssh://myserver instead of ssh://zzzz@x.x.x.x:yyyy.

Link to comment
3 hours ago, deanishe said:

I'll look into changing the workflow, so hosts read from ~/.ssh/config will have URLs matching the Host, e.g. ssh://myserver instead of ssh://zzzz@x.x.x.x:yyyy.

 

I'll stay tuned, thanks!

Edited by gotenks
Link to comment
  • 3 weeks later...

Hi Dean,

 

since 0.7.1 I get runtime error: invalid memory address or nil pointer dereference

 

 

[2016-12-29 12:42:22][ERROR: input.scriptfilter] Code 1: ?

12:42:22 workflow.go:705: -------- Secure SHell/0.7.1 (AwGo/0.5.0) ---------

12:42:22 update.go:153: 32m since last check for update

12:42:22 assh.go:338: query=, username=, port=0

12:42:22 update.go:141: Latest release: 0.7.1

12:42:22 sources-config.go:94: [source/load/config] 1 host(s) in '~/.ssh/config'

12:42:22 sources-known.go:37: [source/load/known_hosts] 148 host(s) in 'known_hosts'

12:42:22 sources-history.go:76: [source/load/history] 20 host(s) in 'history'

12:42:22 sources-config.go:94: [source/load/config] 0 host(s) in '/etc/ssh'

12:42:22 sources-hosts.go:37: [source/load/hosts] 3 host(s) in '/etc/hosts'

12:42:22 workflow.go:711: ------------------ FATAL ERROR -------------------

12:42:22 workflow.go:712: runtime error: invalid memory address or nil pointer dereference : goroutine 1 [running]:

runtime/debug.Stack(0xc420053698, 0x1, 0x1)

/usr/local/opt/go/libexec/src/runtime/debug/stack.go:24 +0x79

gogs.deanishe.net/deanishe/awgo.(*Workflow).Run.func1(0xc4201101c0)

/Users/daj/src/gogs.deanishe.net/deanishe/awgo/workflow.go:712 +0x12b

panic(0x2a70c0, 0xc4200160d0)

/usr/local/opt/go/libexec/src/runtime/panic.go:458 +0x243

github.com/deanishe/alfred-ssh.(*Deduplicator).IsDuplicate(0xc420053920, 0x0, 0x0, 0x0)

/Users/daj/src/github.com/deanishe/alfred-ssh/hosts.go:61 +0x33

github.com/deanishe/alfred-ssh.FilterDuplicateHosts(0xc4200a3500, 0xac, 0x150, 0xa7, 0xc420166d50, 0x3)

/Users/daj/src/github.com/deanishe/alfred-ssh/hosts.go:73 +0xb6

github.com/deanishe/alfred-ssh.Sources.Hosts(0xc42001b200, 0x5, 0x8, 0x4, 0x5, 0xc42001b200)

/Users/daj/src/github.com/deanishe/alfred-ssh/sources.go:36 +0x251

main.loadHosts(0xc42001cbd0, 0x0, 0xc420053d50, 0x3)

/Users/daj/src/github.com/deanishe/alfred-ssh/cmd/assh/assh.go:553 +0x3a5

main.runSearch(0xc42001cbd0)

/Users/daj/src/github.com/deanishe/alfred-ssh/cmd/assh/assh.go:351 +0x30b

main.run()

/Users/daj/src/github.com/deanishe/alfred-ssh/cmd/assh/assh.go:429 +0xc0

gogs.deanishe.net/deanishe/awgo.(*Workflow).Run(0xc4201101c0, 0x31ce98)

/Users/daj/src/gogs.deanishe.net/deanishe/awgo/workflow.go:724 +0x3cc

main.main()

/Users/daj/src/github.com/deanishe/alfred-ssh/cmd/assh/assh.go:573 +0x39

12:42:22 workflow.go:713: ---------------- END STACK TRACE -----------------

12:42:22 feedback.go:464: Sent 1 results to Alfred

12:42:22 workflow.go:870: [ERROR] runtime error: invalid memory address or nil pointer dereference

12:42:22 workflow.go:873: Get help at https://github.com/deanishe/alfred-ssh

12:42:22 workflow.go:908: ---------------------- 5ms -----------------------

 

 

Link to comment
  • 1 month later...

This is not working for me. I have alfred 3 Build 801, Wednesday 1st February 2017, Secure SHell v0.7.1, and iterm2 Build 3.0.14. 

 

iTerm2 is handling my ssh:// and opens when i choose a connection in the workflow but nothing happens. I am taken to a blank bash prompt. 

Starting debug for 'Secure SHell'

[2017-02-22 12:35:24][STDERR: input.scriptfilter] ?
12:35:24 workflow.go:705: -------- Secure SHell/0.7.1 (AwGo/0.5.0) ---------
12:35:24 update.go:153: 73m since last check for update
12:35:24 assh.go:338: query=, username=, port=0
12:35:24 update.go:141: Latest release: 0.7.1
12:35:24 sources-config.go:94: [source/load/config] 9 host(s) in '~/.ssh/config'
12:35:24 sources-known.go:116: [known_host] Invalid hostname: 
12:35:24 sources-known.go:116: [known_host] Invalid hostname: 
12:35:24 sources-known.go:37: [source/load/known_hosts] 327 host(s) in 'known_hosts'
12:35:24 sources-history.go:76: [source/load/history] 1 host(s) in 'history'
12:35:24 sources-config.go:94: [source/load/config] 0 host(s) in '/etc/ssh'
12:35:24 sources-hosts.go:37: [source/load/hosts] 6 host(s) in '/etc/hosts'
12:35:24 sources.go:39: 3 duplicate(s) ignored
12:35:24 assh.go:555: 340 host(s) loaded in 2ms
12:35:24 feedback.go:464: Sent 340 results to Alfred
12:35:24 workflow.go:910: ---------------------- 78ms ----------------------
[2017-02-22 12:35:34][utility.debug] .
/-------- SSH ---------\
query="ssh://qa3-combined.iseatz.com"
variables=
{
    "DISABLE_CONFIG" = 0;
    "DISABLE_ETC_CONFIG" = 0;
    "DISABLE_ETC_HOSTS" = 0;
    "DISABLE_HISTORY" = 0;
    "DISABLE_KNOWN_HOSTS" = 0;
    "EXIT_ON_SUCCESS" = 1;
    "EXTERNAL_TRIGGER" = 0;
    "MOSH_CMD" = mosh;
    "SFTP_APP" = "";
    "SSH_APP" = "";
    hostname = "qa3-combined.iseatz.com";
    name = "qa3-combined.iseatz.com";
    port = 22;
    query = "";
    "shell_cmd" = 0;
    source = "known_hosts";
    url = "ssh://qa3-combined.iseatz.com";
}
\-------- SSH ---------/
[2017-02-22 12:35:34][ERROR: action.script] ?
12:35:34 workflow.go:705: -------- Secure SHell/0.7.1 (AwGo/0.5.0) ---------
12:35:34 update.go:153: 73m since last check for update
12:35:34 assh.go:256: Opening URL ssh://qa3-combined.iseatz.com
12:35:34 assh.go:264: Command: /usr/bin/open [open ssh://qa3-combined.iseatz.com]
12:35:34 workflow.go:910: ---------------------- 50ms ----------------------

 

Link to comment
8 minutes ago, deanishe said:

Doesn't appear to be an issue with the workflow.

 

What happens when you run ssh qa3-combined.iseatz.com in a shell? I can't establish a connection to that system (or ping it).

 

My shell functions normally for all commands. I have attached a GIF of me using the workflow, then typing ssh xxxx into the shell, and then opening a new shell and issuing the same command. 

screen_grab.gif

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...