vfclists · 2022-05-08 09:52
When I'm typing a remote `:dir` value used in `org-babel` eg `/ssh:user@host:~` Emacs tries to make the connection automatically as though the directory is a local one.
This results in repeated SSH connection attempts which in this case has resulted in `fail2ban` locking me out the server for a set duration.
Is there some way to disable this behaviour? It should be able to distinguish a remote server from a local one and not attempt to connect to the remote unless requested eg `C-c C-c`.
Hamilton950B · 2022-05-08 13:23
I don't know, but it seems to me at the very least it should be caching the ssh connections. Probably hard to do without moving the ssh protocol into emacs.
bigfig · 2022-05-08 14:01
There are ways to set the ssh config to [multiplex and reuse existing connections](https://www.tutorialspoint.com/how-to-use-openssh-multiplexer-to-speed-up-openssh-connections-on-linux). Then OP should be able to set a long enough timeout so reconnects are not made, or use a heartbeat connection.
TheDrownedKraken · 2022-05-08 14:37
I’m not sure, but this feels like it could be the fault of a “modern” completion framework polling for completions to display rather than Emacs itself. Just a hunch, not founded on anything.
by_wicker · 2022-05-08 14:37
That should happen by default though: `tramp-use-ssh-controlmaster-options`.
by_wicker · 2022-05-08 14:41
All sorts of things can cause excessive ssh activity. e.g. packages that augment your completing-reads, like `marginalia`, or `ivy-rich`. Also the likes of `projectile` sometimes goes off looking for project-root.
You can get a lot of tramp debug information by setting `tramp-verbose` to 6 or higher and looking in the buffer `*debug tramp.*`.
I identified where I could make some improvements by advising `tramp-send-command` to enter the debugger to catch it doing things I didn't want e.g.:
(defun intercept-tramp-send-command (vec command &rest args)
(when (string-match "\\(.projectile\\|/git\\)" command)
(debug)))
(advice-add 'tramp-send-command :before 'intercept-tramp-send-command) no
vfclists · 2022-05-08 15:21
I don't think it is a caching issue. Say I'm typing `:dir /ssh:user@remote.com`. Emacs will try to connect to `/ssh:us@remote.com` before I finish typing. For some reason this didn't happen before. It started happening when I upgraded to Emacs 27 followed by another org upgrade.
nullmove · 2022-05-08 16:02
Turn on the profiler and look at the call stack.
noman_032018 · 2022-05-08 16:48
While this doesn't solve the problem on the Emacs side, setup keepalive for SSH connections and ensure multiplexing works.
edit: I notice I gave no direct suggestion for how to do so. The multiplex controlmaster ControlPersist option is a good way to set this up reliably (see [ssh_config manual](https://www.man7.org/linux/man-pages/man5/ssh_config.5.html)).
00-11 · 2022-05-08 17:02
Do you see this problem when you start with `emacs -Q` (no init file)? If not, bisect your init file to find the culprit.
----
A guess is that you're using some completion package that *automatically tries to complete input as you type it* (incremental completion), and that package (or at least the way you're using it) doesn't take into account trying to resolve remote file names. If so, it's *pedaling in the sauerkraut*, and maybe needs to be toned down a bit.
----
[Icicles](https://www.emacswiki.org/emacs/Icicles), for example, avoids this problem by automatically turning off incremental completion whenever a remote file name is read, that is, whenever your file-name input is likely to
match a remote-file syntax. You can still complete remote file names. This turn-off just prevents eagerly going off automatically to remote locations to try to search for matching file names each time you type or remove an input character.
----
Standard function `file-remote-p` tests a file name for likelihood of being remote, without accessing anything remotely.
Icicles uses this improved version of that function to deal with incremental completion:
;; NOTE: This is *not* a general substitute for `file-remote-p'.
(defun icicle-file-remote-p (filename)
"Non-nil means FILENAME is likely to name a remote file or directory.
For MS Windows, if `icicle-network-drive-means-remote-flag' is non-nil
then this includes a file on a mapped network drive.
Otherwise, use `file-remote-p' if defined, or return nil if not.
FILENAME is normally a string, but it can also be a cons whose car is
a string. This is so that the function can be used to filter absolute
file-name completion candidates."
(when (consp filename) (setq filename (car filename)))
(or (and (eq system-type 'windows-nt)
(let ((case-fold-search t)) (string-match "\\`\\([a-z]:\\)" filename))
(eq 0 (condition-case nil
(icicle-ms-windows-NET-USE (match-string 1 filename))
(error nil)))
icicle-network-drive-means-remote-flag)
(and (fboundp 'file-remote-p) (file-remote-p filename))
(and (stringp filename) (string-match "\\`/[^/]+:" filename) (match-string 0 filename))))
And there's also standard function `ffap-file-remote-p`:
(defun ffap-file-remote-p (filename)
"If FILENAME looks remote, return it (maybe slightly improved)."
;; (ffap-file-remote-p "/user@foo.bar.com:/pub")
;; (ffap-file-remote-p "/cssun.mathcs.emory.edu://dir")
;; (ffap-file-remote-p "/ffap.el:80")
(or (and ffap-ftp-regexp
(string-match ffap-ftp-regexp filename)
;; Convert "/host.com://dir" to "/host:/dir", to handle a dying
;; practice of advertising ftp files as "host.dom://filename".
(if (string-match "//" filename)
;; (replace-match "/" nil nil filename)
(concat (substring filename 0 (1+ (match-beginning 0)))
(substring filename (match-end 0)))
filename))
(and ffap-rfs-regexp
(string-match ffap-rfs-regexp filename)
filename)))
worthless-trash · 2022-05-10 06:39
This was the same solution that I ended up using.
I additionally used passphrase protected keys with ssh-askpass to ensure that it didn't abuse multiple SSH attempts.
noman_032018 · 2022-05-10 07:06
Key or cert-based authentication is more convenient overall, on top of being more secure too.