以其他用户身份在其他机器上使用 Emacs server 和 emacsclient

Posted

技术标签:

【中文标题】以其他用户身份在其他机器上使用 Emacs server 和 emacsclient【英文标题】:Using Emacs server and emacsclient on other machines as other users 【发布时间】:2012-09-14 19:58:10 【问题描述】:

我知道,在现有的 Emacs 会话中调用 (start-server) 之后,我可以使用 emacsclient -c(在同一台计算机上)创建连接到该服务器的新框架,以便 emacsclient 创建的每个新框架可以访问同一组共享状态(例如缓冲区)。

我发现的大部分文档都集中在“让我快速访问我的本地 Emacs”用例上,因此有两件事我还没有看到任何细节:

    emacsclient -c 可以访问由 其他 用户启动的 Emacs 服务器,还是硬连线只能检测由我自己的用户启动的会话?

    Emacs 服务器(直接或间接)是否支持远程连接?也就是说,是否有某种方法可以设置 Emacs(可能涉及 SSH),允许在 remote 机器上调用 emacsclient -c 访问我的 Emacs 的 local 状态服务器?

(如果您还没有猜到,我最终想做的是结合上述两种技术来提供基本的协作编辑支持。)


这是一个现实世界的问题,所以这是我正在处理的问题:

必要的功能应该已经内置到 Emacs 中(23.3.1,64 位)。我可以从标准的 Ubuntu 存储库扩展到 Emacs 扩展,但我不希望这样做。 (遗憾的是,我认为排除了 Rudel。) 没有新用户或用户欺骗。解决方案应适用于现有的用户帐户集,并且用户不得伪装成其他用户(例如通过sussh)。

如果有什么不同的话,这些机器位于私有 LAN 上,安装了(并正在运行)OpenSSH 客户端和服务器,并且所有用户都可以连接到(他们自己的帐户)所有机器,但他们没有共享文件系统。


那么,有谁知道 Emacs 服务器是否可以

向其他用户授予访问权限,或 提供远程访问?

编辑

正如 rwb 的回答中所评论的,很明显,通过运行 emacsclient -c 在本地打开的新窗口实际上是由 remote Emacs 服务器进程创建的。也就是说,emacsclient 只是简单地触发了服务器中的相关行为。这会导致一些显示设置不正确的问题,因为服务器通常无法访问本地桌面(见下文)。但是,如果我使用以下命令序列,我现在可以连接到远程 Emacs 会话:

在一个终端中,其中1.22.333.44remotehost的IP地址:

ssh -t -X remotehost \
  "emacs -nw --eval
   '(progn (setq server-host \"1.22.333.44\" server-use-tcp t) (server-start))'"

然后在另一个(在同一台机器上):

scp remotehost:.emacs.d/server/server /tmp/server-file
DISPLAY=localhost:10 emacsclient -c -f /tmp/server-file

emacsclient 命令使远程 Emacs 服务器(它在 /tmp/server-file 中找到详细信息)打开一个图形 Emacs 窗口(在本地显示上),该窗口与远程主机上的 Emacs 会话共享状态。

由于远程 Emacs 服务器是通过 ssh -X 启动的,SSH 为它提供了通过“假”:10 显示器访问我的本地显示器的权限。传递给它的DISPLAY=:10(通过emacsclient)因此会导致在我的本地桌面上打开一个窗口。


虽然上面的方法确实勾选了“在远程机器上运行 Emacs 服务器,在本地使用 emacsclient 连接到它”框,但它非常有限。实际上,以单个用户的身份在本地运行服务器和客户端并没有太大区别:唯一的区别是服务器现在是远程的,因此可以访问不同的系统资源。

不幸的是,通过ssh -X 启动是我能够在另一台机器的 X 服务器上成功打开窗口的唯一方法:

指定基本的DISPLAY=remote:0 无济于事(因为Ubuntu X 服务器是使用-nolisten tcp 选项启动的)。

通过 SSH 连接然后使用 DISPLAY=:0 也会失败,但这一次只是因为缺少合适的身份验证凭据。 (无论如何,我相信是这样的:错误消息神秘地写着No protocol specified / Can't open display。)

我认为找到解决第二个问题的方法可能会让我更接近解决方案。


阅读了http://comments.gmane.org/gmane.emacs.devel/103350 上的帖子(从 '25 Oct 14:50' 帖子开始,大约一半)我开始怀疑这是否可能是 Emacs 无法做到的罕见事情之一(即是不可能的 ;-) )。

但是,如果有人确实有办法在没有上述权限错误的情况下提供对远程 X 显示器的访问,我仍然愿意说服......

TL;DR

正如 rwb 的回答所指出的,我上面关于 Emacs 是否可以授予远程访问权限的问题让事情倒退了。 Emacs 授予其他用户访问权限并没有真正的问题(server-use-tcp 和合适的server-file 负责处理此问题):问题在于如何允许一台机器上的进程在其他用户上打开新的 X 窗口' X 显示(具体来说,运行(start-server) 的Emacs 需要为通过emacsclient -c 请求它的用户打开窗口)。这个答案超出了这个问题的范围。

替代解决方案

作为一种解决方法,我们使用以下方法:

机器0:tmux -S /tmp/shared-tmux-socket new-session machine1..machineN:ssh -t machine0 tmux -S /tmp/shared-tmux-socket attach

/tmp/shared-tmux-socket 上具有适当的文件权限。

然后我们在共享终端中运行一个文本模式的 Emacs。 :-) 这确实引发了一些欺骗用户的问题,但至少主人可以看到客人所做的一切。

【问题讨论】:

***.com/questions/2231902/… 有几个 - 更简单 - 答案“当我通过 ssh 连接时,如何使用 emacsclient 连接到本地 Emacs 服务器?”跨度> 【参考方案1】:

这应该为你想要的东西提供一个起点。

来自信息节点(emacs) emacsclient 选项

`--server-file=SERVER-FILE'
     Specify a "server file" for connecting to an Emacs server via TCP.

     An Emacs server usually uses an operating system feature called a
     "local socket" to listen for connections.  Some operating systems,
     such as Microsoft Windows, do not support local sockets; in that
     case, Emacs uses TCP instead.  When you start the Emacs server,
     Emacs creates a server file containing some TCP information that
     `emacsclient' needs for making the connection.  By default, the
     server file is in `~/.emacs.d/server/'.  On Microsoft Windows, if
     `emacsclient' does not find the server file there, it looks in the
     `.emacs.d/server/' subdirectory of the directory pointed to by the
     `APPDATA' environment variable.  You can tell `emacsclient' to use
     a specific server file with the `-f' or `--server-file' option, or
     by setting the `EMACS_SERVER_FILE' environment variable.

     Even if local sockets are available, you can tell Emacs to use TCP
     by setting the variable `server-use-tcp' to `t'.  One advantage of
     TCP is that the server can accept connections from remote machines.
     For this to work, you must (i) set the variable `server-host' to
     the hostname or IP address of the machine on which the Emacs server
     runs, and (ii) provide `emacsclient' with the server file.  (One
     convenient way to do the latter is to put the server file on a
     networked file system such as NFS.)

您可能还想查看变量server-auth-dirserver-auth-keyserver-port

【讨论】:

这看起来像我所追求的;我什至可以使用文件系统权限来控制对服务器文件(以及会话)的访问。将尝试此操作并报告。 服务器文件的格式相当简单,因此如果您没有共享文件系统,只要设置正确的变量,您就可以生成它。不能由服务器文件中的变量控制的一件事是进程 ID,但从查看源代码来看,如果您使用 TCP 连接,它的遗留数据应该无关紧要。 看起来我误解了 emacsclient -c 所做的事情的微妙之处。现在我有机会使用它(使用您建议的选项)并且可以通过 TCP 成功连接到另一台主机上的服务器,很明显帧本身来自远程服务器。也就是说,emacsclient不仅需要正确的授权才能连接到服务器,服务器也需要正确的授权才能在客户端显示上打开窗口。这对我来说目前不起作用。我可能会更新我的答案以反映这种新的理解。 我现在可以让远程 Emacs 服务器在本地为我打开新的图形窗口。解决方案是使用ssh -X 连接到远程服务器,然后对emacsclient 进行本地调用,设置远端所需的DISPLAY,在本例中为localhost:10。这仍然留下了 X11 身份验证的问题,但越来越近了。 已更新问题并提供更多详细信息。我开始怀疑多用户 emacsclient 的使用不会成功。【参考方案2】:

如果您这样做是为了让人们能够远程编辑文件,您可能需要查看“tramp mode”

http://emacswiki.org/emacs/TrampMode

【讨论】:

谢谢肖恩;这是一个很好的建议,特别是因为我可以通过 SSH 使用 Tramp。如果我无法获得更具交互性的工作,那么(协调良好的)重新加载 -> 编辑 -> 保存周期将是一个不错的后备。【参考方案3】:

我认为根据定义,您所要求的内容是不可能的,因为如果您让远程用户不受限制地访问您的 Emacs,这与让远程用户通过 ssh 访问 shell 一样多的“用户欺骗”。说清楚,从安全的角度来看,这可能是个坏主意。

另外,让两个用户访问一个 Emacs 的结果并不像您希望的那么好。它的设计并未考虑同时访问。自从我尝试它以来已经有好几年了,所以事情可能会有所进展,但是当我这样做时,至少可以说是古怪的。

不过,我会尽力回答你的问题。

听起来您正在考虑从后到前,因为与直觉相反,在网络术语中,X11 显示器是服务器,而 X11 应用程序是客户端。这是令人惊讶的,因为通常显示对用户来说是本地的,而应用程序正在某个远程服务器上运行。

您可以指示正在运行的 emacs 连接到远程显示器并使用 M-x make-frame-on-display 打开一个新窗口。为此,该显示器的所有者需要授予您对其的访问权限。

我们假设host-l 是运行Emacs 的计算机,并且您希望host-r 上显示0 的用户可以访问它。请注意,您已经说过您不想使用 SSH 转发,因此按照此方法会导致所有流量通过未加密的网络。

首先,确保显示 host-r:0 正在接受 TCP 连接。您没有提及您的操作系统,但这可能是 Unix 上的默认设置,并且可能不在 Linux 上(出于安全原因)。例如,如果以下提及 -nolisten tcp,则您需要更改此配置。

host-r$ ps -ef | grep X

接下来,让 host-r 的用户运行以下命令,并将输出发送给您。如果您选择,请务必警告他们,这将允许您完全控制他们当前的桌面会话。

host-r$ xauth list $DISPLAY
host-r/unix:0  MIT-MAGIC-COOKIE-1  01234567890abcdef0123456789abcd

这实际上是显示器的“密码”。在 host-l 上,将它放在 Emacs 能够找到它的位置:

host-l$ xauth add host-r:0 MIT-MAGIC-COOKIE-1  01234567890abcdef0123456789abcd

现在输入 M-x make-frame-on-display host-r:0 远程显示器上应该会弹出一个 Emacs 窗口。

【讨论】:

感谢 Mavit。从安全的角度来看,不受限制的 Emacs 访问与 shell 访问一样糟糕,这是完全正确的。由于那是 emacsclient 提供的,我想我现在很满意:这种方法不会做我最初想要的。我曾希望 emacsclient 会限制其他用户可以做的事情(例如仅更改缓冲区),但现在听起来更像是 Rudel 的领地。 我实际上并不介意 SSH X 转发本身(我已经编辑了问题以更清楚地说明我试图避免的事情)所以我可能会尝试你的 xauth 步骤然后使用 make-下次我需要这样的东西时显示框架。 [对于尝试此操作的其他人,与 localhost 的连接在 xauth 命令中使用 'hostname/unix:0' 而不是 'host-r:0',其中 hostname 是 hostname -s 输出的 localhost 的短名称。]跨度> 【参考方案4】:

Aaron Gallagher 实施了一个解决方案:http://blog.habnab.it/blog/2013/06/25/emacsclient-and-tramp/

它的工作原理(AFAIU)如下:

emacs 服务器使用 tcp 启动 他使用 tramp-sh 打开一个与远程系统的连接,打开一个正向端口(“反向通道”) 建议tramp-sh 将扩展的auth cookie 文件复制到远程系统 在远程系统上,他调用了一个特殊的 emacsclient.sh shell 脚本,该脚本模拟 emacsclient,但在文件名前加上扩展的 auth cookie 中对应的 tramp 前缀

我在他的博客文章中添加了一条评论,提出了这个想法,以便在 emacs-devel 上讨论和增强。

【讨论】:

andy.wordpress.com/2013/01/03/automatic-emacsclient 类似,但看起来更简单。

以上是关于以其他用户身份在其他机器上使用 Emacs server 和 emacsclient的主要内容,如果未能解决你的问题,请参考以下文章

使用firebase google身份验证单击登录按钮时总是会自动登录,而没有选择以其他用户身份登录的选项

O365通过图形api以其他用户身份发送

以不同用户身份运行 Linux 服务的最佳实践

如何更改 laravel 中的用户模型以使用其他表进行身份验证而不是用户?

如何使用 Powershell 'invoke-expression' 以其他用户身份运行可执行文件

Android Facebook SDK - 如何以其他用户身份登录?