|
I have a kitten that I start via remote control from an SSH session. Works great. I don't want all my SSH sessions to be able to remote control everything though. In this case I only want it to be able to run certain kittens. It looks like remote control is either on or off. Are there more granular controls that I'm missing? Ideally I'd love to be able to provide a Python script that determines which remote control requests to allow. That way I could do different things by host and if the rc request is targeting a window connected to the same host. Just being able to restrict it to certain kittens would be enough for my immediate needs though. |
Replies: 17 comments 9 replies
The current permission granularity only restricts remote control to a kitty window. There is currently no (asymmetric) key-based authentication. |
|
Seems overly complicated. If you want a particular host to be able to remote control just use socket based remote control and forward the socket to that host. Indeed, this could be integrated into the ssh kitten to make it seamless. Or just connect to it in a window with --allow-remote-control set on the window. If you want to allow only specific remote control commands, the way to do that would be to create a setting in kitty.conf that maps passwords to a set of command names. Then create a password with your allowed set of commands and make that password available to the host in question. If kitty gets a remote command with that password in the command metadata, it unconditionally allows it. One can make it reasonably secure by only transmitting a hash of the password with a signature of the command. So even if Eve intercepts the command, all she gets is a hash of password + command, from which extracting the password is very hard. And one can add a uuid to the command metadata to avoid replay attacks. And we have re-invented capability based security :)) |
|
On Fri, Jul 29, 2022 at 02:48:07PM -0700, Charlie Groves wrote:
Building out all of capability based security is a bit more than I want to bite off 🤣
This is now implemented in master.
|
|
On Sun, Aug 14, 2022 at 09:27:43PM -0700, page-down wrote:
@kovidgoyal
Thanks for implementing this. I would like to give some feedback.
Since kitty can operate both local and remote hosts that have gained privileges (ssh sudo), **explicitly** enabling or disabling remote control is fairly critical.
I think it would be useful to ensure that the possibility of remote control is reduced to zero by setting the option `allow_remote_control` to `no`, regardless of the other configuration options.
The `listen_on` option should ideally be kept the same as before as well, as listening can be turned on quickly with `kitty -o allow_remote_control=socket-only` after setting it in the config file. Any user who configures this option with `allow_remote_control` as `no` (including me) will not be surprised to find a unix socket opened after the version upgrade.
I have mostly implemented this.
So now there are two fine-grained configurable things:
- Remote control communication: all, escape sequences only (don't config `listen_on`), socket only
- Permissions: all, default-set (without password, default is `all rc commands`), password-protected, NONE (globally disabled and there is zero possibility of it being controlled)
Set the default set of rc commands when there is no password:
```conf
remote_control_password _NONE_ get-colors set-colors
```
This is also implemented.
The environment variable `KITTY_PUBLIC_KEY` will not be set, when rc is disabled. It also does not waste CPU cycles to generate public keys (although I believe the time saved is negligible).
KITTY_PUBLIC_KEY is generally sueful, for instance, it's on my TODO list
to use it in the file transfer protocol to secure the password there as
well.
---
How do you think remote control can be configured individually for kitty windows? Since `launch --allow_remote_control` is boolean, do we have to add new argument at this point?
Yes it would have to be a new argument, possibly,
--restrict-remote-control
But I'll look into that later.
|
|
On Sun, Aug 14, 2022 at 09:27:43PM -0700, page-down wrote:
Is it possible to label (name) the passwords? It is convenient to specify that the window can only use certain passwords (identities).
The label (identity) will be passed into `is_cmd_allowed`, which will serve as the authenticated identity for subsequent checking logic, without having to duplicate python files, or mix identities into passwords and split password strings.
Configurable with:
- passwords: allowed passwords, password for this window
- permissions: all, default-set (globally configured, default is all), password-protected
```conf
remote_control_password --label trusted PASSWORD launch
remote_control_password --label trusted PASSWORD set-*
remote_control_password --label get-cmds PASSWORD get-*
```
```shell
kitty @ launch --allow-remote-control \
--rc-permission default-set \
--rc-permission all \
--rc-permission label=my-label \
--rc-permission password=WINDOW_PASSWORD \
--rc-permission cmds=get-colors,set-colors
```
Thank you again for all your hard work. I hope you don't mind some of my thoughts, which may have been inappropriate.
I implemented --remote-control-password for launch. I didnt bother with
labels for two reasons:
1) Passwords in kitty.conf are in effect anyway, so there is no need to
repeat them in launch definitions.
2) If one wants to reuse the same password for multiple launch
definitions, the alias mechanism already exists for that.
|
Currently, the password will be printed in the confirmation prompt window. This will be publicly displayed at the conference presentation. Mouse click on the button in this confirmation prompt does not work. The reason appears to be that the lines responding to the mouse click are incorrect. (need to click a few lines above the button) Well, as long as the syntax is extensible, it will be possible to add more data to the password rules in future versions without backward compatibility limitations.
Does this work for you? In kitty @ launch --allow-remote-control --remote-control-password '"" get-colors'When It looks like the traceback cannot be printed when prewarm is enabled. The environment variable When executing |
|
On Mon, Aug 15, 2022 at 09:27:46PM -0700, page-down wrote:
> I didnt bother with labels for two reasons ...
Currently, the password will be printed in the confirmation prompt window. This will be publicly displayed at the conference presentation.
However, if there is an identifier such as a label, it will be possible to display that, rather than the password itself.
Do you have a good way to avoid passwords being displayed in plaintext?
One can simply hide the password with the text "Click to show password"
Mouse click on the button in this confirmation prompt does not work. The reason appears to be that the lines responding to the mouse click are incorrect. (need to click a few lines above the button)
Fixed.
Well, as long as the syntax is extensible, it will be possible to add more data to the password rules in future versions without backward compatibility limitations.
For example, in the future it is possible to restrict the arguments by regular expressions, and also to restrict the windows that can be controlled (filter the window, tab that the `--match` option finally returns). (E.g. `get-text` can only get the text of its own window.)
That's making this way more complicated than it needs to be. If you need
such sophisticated matching then use the python script functionality.
> I implemented --remote-control-password for launch.
Does this work for you? In `window and window.remote_control_allowed(...) `, It looks like `window` is None, so `window.remote_control_allowed` will not be called.
yes, it works. If you use remote control over a socket, it wont work,
since there is no way to know what window a socket connection is coming
from. I should update the docs to make a note of that.
```shell
kitty @ launch --allow-remote-control --remote-control-password '"" get-colors'
```
---
When `listen_on` and `allow_remote_control no` have been configured, executing `kitty @ ls` will not give error messages, ` KITTY_PREWARM_SOCKET= kitty @ ls` outputs the following.
```log
Traceback (most recent call last):
...
File ".../kitty/remote_control.py", line 256, in __enter__
self.socket.connect(self.address)
FileNotFoundError: [Errno 2] No such file or directory
```
It looks like the traceback cannot be printed when prewarm is enabled.
Odd, I'll look into it later.
The environment variable `KITTY_LISTEN_ON` is set even when not listening to a socket.
Fixed.
When executing `kitty -o allow_remote_control=password -o 'listen_on ""'` in a window with `KITTY_LISTEN_ON`, `kitty @ ls` outputs the above traceback instead of remote control via TTY.
Should the `KITTY_LISTEN_ON` environment variable be cleared when listen_on is explicitly disabled?
Fixed.
|
|
On Mon, Aug 15, 2022 at 09:27:46PM -0700, page-down wrote:
It looks like the traceback cannot be printed when prewarm is enabled.
It works for me with
kitty @ --to=unix:/tmp/does-not-exist ls
|
Apparently this was due to KITTY_LISTEN_ON= KITTY_PREWARM_SOCKET= kitty/launcher/kitty --config=NONE
I also could not reproduce the problem when cleaning up all environment variables (including LANG, though probably unrelated) and running kitty in kitty. However it can be reproduced in the following steps.
I found another issue. |
|
These issues are all fixed already, see my latest comments. Outstanding,
is to hide the password and fix the prewarm wrapper not forwarding error
output on macOS.
|
The default value of kitty --config=NONE -o allow_remote_control=noHowever I was able to execute the command via kitty shell before.
Confirmed fixed, thanks. (Except for this one above.) |
|
Now fixed.
|
|
To make Previously, however, in order to control kitty instance without also taking up TTY, a background daemon could be run, calling I found that after allowing remote control globally, the user can no longer restrict the remote control commands that are allowed in the kitty window. kitty --config=NONE -o allow_remote_control=y
kitty @ launch --allow-remote-control --remote-control-password '"" get-colors' --remote-control-password '"root" *'
# Expect that `kitty @ launch` will not work in the new kitty window.I think it makes sense to be able to enable password-protected remote control for some kitty windows, without a separate kitty instance However, since |
then it will work. |
Setting a password for the kitty window will only affect remote control via TTY. Use case:
Not sure if I understand correctly. |
|
On Mon, Aug 15, 2022 at 09:27:46PM -0700, page-down wrote:
```log
Traceback (most recent call last):
...
File ".../kitty/remote_control.py", line 256, in __enter__
self.socket.connect(self.address)
FileNotFoundError: [Errno 2] No such file or directory
```
It looks like the traceback cannot be printed when prewarm is enabled.
I think this is specific to macOS. It works on linux, but fails on
macOS. With the simpler test:
kitty +runpy 1/0
On macOS the traceback is not printed.
|
|
On Tue, Aug 16, 2022 at 12:11:45AM -0700, page-down wrote:
To make `launch --remote-control-password` work, `launch --allow-remote-control` no longer sets the environment variable `KITTY_LISTEN_ON` on kitty instances that are already listening to sockets.
Previously, however, in order to control kitty instance without also taking up TTY, a background daemon could be run, calling `kitty @ --to ${KITTY_LISTEN_ON}`.
Now the window opened by `launch --allow-remote-control` no longer has this information.
How to solve this problem? Is it possible to set `KITTY_REMOTE_CONTROL_TO=tty` for specifying `kitty @ --to` default, so it doesn't affect `kitty @` without `--to`?
No idea, you cannot have both. socket and per window password rules are
mutually exclusive. Either one or the other can work in a given window.
---
I found that after allowing remote control globally, the user can no longer restrict the remote control commands that are allowed in the kitty window.
```shell
kitty --config=NONE -o allow_remote_control=y
kitty @ launch --allow-remote-control --remote-control-password '"" get-colors' --remote-control-password '"root" *'
# Expect that `kitty @ launch` will not work in the new kitty window.
```
I think it makes sense to be able to enable password-protected remote control for some kitty windows, without a separate kitty instance `kitty -o allow_remote_control=password`.
However, since `--allow-remote-control` does not accept values, you cannot use `launch --allow-remote-control password` or even `no`.
Use
kitty -o allow_remote_control=password -o 'remote_control_password ""'
then it will work.
|
The current permission granularity only restricts remote control to a kitty window.
You can disable remote control in kitty.conf and then open a kitty window that allows remote control to run the ssh client.
There is currently no (asymmetric) key-based authentication.