以其他用户身份在其他机器上使用 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。) 没有新用户或用户欺骗。解决方案应适用于现有的用户帐户集,并且用户不得伪装成其他用户(例如通过su
或ssh
)。
如果有什么不同的话,这些机器位于私有 LAN 上,安装了(并正在运行)OpenSSH 客户端和服务器,并且所有用户都可以连接到(他们自己的帐户)所有机器,但他们没有共享文件系统。
那么,有谁知道 Emacs 服务器是否可以
向其他用户授予访问权限,或 提供远程访问?编辑
正如 rwb 的回答中所评论的,很明显,通过运行 emacsclient -c
在本地打开的新窗口实际上是由 remote Emacs 服务器进程创建的。也就是说,emacsclient
只是简单地触发了服务器中的相关行为。这会导致一些显示设置不正确的问题,因为服务器通常无法访问本地桌面(见下文)。但是,如果我使用以下命令序列,我现在可以连接到远程 Emacs 会话:
在一个终端中,其中1.22.333.44
是remotehost
的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-dir
、server-auth-key
和server-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身份验证单击登录按钮时总是会自动登录,而没有选择以其他用户身份登录的选项
如何更改 laravel 中的用户模型以使用其他表进行身份验证而不是用户?