-
-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Salt Managment Inter VM Communication #1541
Comments
On Fri, Dec 25, 2015 at 08:44:01AM -0800, nrgaway wrote:
If SaltVM (which is generally a good idea) would have power to control
Yes, this is exactly the idea.
Not sure how proceed with this. But I think for the first iteration we Best Regards, |
Okay, thanks for the feedback. I won't dive too deep into this until I can present a recommendation or two for further analysis based on some of my research and experiments I will be performing over the next couple of weeks. My main goal will be as requested; to process the minimum amount of untrusted data. |
I recommend not running the bombshell client in dom0. It's possible, but I would advise running it on a non-networked, domU AppVM instead. You can then use nice editors and whatnot to manage your formulas and playbooks, without contaminating dom0 with extra software. Always treat your VM as you would treat any VM that is going to be running qubes.VMShell commands, because that is what bombshell is -- a proper stdin/stdout/stderr proxy that uses qubes.VMShell to provide for batch and interactive sessions across VMs (and even across computers, with the right by-hand network setup). |
Note that, when used in conjunction with the Qubes Ansible plugin, or as a salt-ssh backend, bombshell-client is almost certainly going to be a return transport for JSON or YAML data from the modules. While it's conceivable that a malicious VM could fudge the Ansible / Salt modules copied into the VM for execution, such that those malicious'd modules would return bogus data:
Key point: at no point in the use of Ansible or salt-ssh is there any way for the target hosts to call back into the manager host. |
On Fri, Dec 25, 2015 at 08:51:34PM -0800, Rudd-O wrote:
That's true in theory, but we still want to be on a safe side. What is Best Regards, |
At least Ansible explicitly removes all nonprintable characters before passing results to the renderer. Reducing the risk is why I recommend running the bombshell and its Ansible / Salt connection modules in a non-networked domU. |
On 26 December 2015 at 09:03, Rudd-O [email protected] wrote:
Would it be overkill to use a DisposibleVM, maybe a special type of In this senerio, the SaltManagementVM stay safe since it never needs to The DisposibleVM can then parse output from updating TemplateVM and save Using a process like this means we would not have to write too much custom Any thoughts? |
On Sat, Dec 26, 2015 at 03:42:22PM -0800, nrgaway wrote:
That's a good idea in terms of security. Some technical detail would be It isn't optimal for performance or resources, but if it would be much Best Regards, |
I think the dispvm is overkill, frankly. A regular VM with no network access should be more than okay. the ansible and salt connection plugins fill a great niche that the qubes salt system cannot by itself fill -- the actual setup and configuration of the contents of the VMs -- because it would be too risky to have dom0 reach into the VMs and run commands, then parse the outputs. |
I've created major hack for salt-ssh qrexec transport (something like bombshell): Differences vs bombshell:
Usage - in some "MgmtVM" (I've tested it from a VM, but it's trivial to use the same from dom0):
It is PoC only, do not use for anything else than testing. It is also ugly, sorry. There is also extensive logging to General
Conclusions:
The last one is particularly important, because a lot of states depends on it, at least to have I see two options here:
I'm slightly for the second option, although it has slightly bigger attack surface. @rootkovska any strong opinion here? |
BTW @Rudd-O I was able to use qrexec-client-vm directly, without need for any serializer like yout bombshell. Probably signals are not carried through, but it doesn't matter for Salt, fortunately. |
The serializer is necessary to multiplex stdout and stderr in the same channel. If you don't care about stderr (I do), you don't need bombshell. I fail to see what the problem is with parsing the returned data. It's JSON. If you don't trust what salt-ssh does with the returned data, because you feel that the returned data can be leveraged into dom0 execution (I don't see how based on your own gists) -- then you can write your own custom Salt runner which takes the data returned by the VMs verbatim and raw, then ditches all of them to a file or something. How to do this is well-documented by the SaltStack folks. Needless to say, the returned data is fundamental to using Salt state modules and their highstates. Also grains break with the mechanism you outlined here. :-( Note that I'm not using bombshell in dom0 at all. I use bombshell from a non-networked trusted VM, and I point it at other VMs and to dom0 (to configure hardware settings). |
On Feb 7, 2016 11:18 PM, "Rudd-O" [email protected] wrote:
You show me a deserialization library, I'm about 90% sure I can find you a We all agree an issue here is small. But I posit that with millions of eyes |
On Sun, Feb 07, 2016 at 08:18:38PM -0800, Rudd-O wrote:
Raw qrexec can pass stderr as a separate stream. In case of RPC Anyway, I don't care about stderr here (as long as it is available
We don't want to think about it, that's the point. If salt-ssh does not Some example attack vectors would be:
I'm not sure if the "runner" is what we need here. It looks like it
Fortunately it isn't true, as I've outlined above. salt-ssh collect all
Yes, this is the problem we need to solve somehow.
If that "non-networked trusted VM" has ability to run any command in any As said before, in the feature we want to add an API to allow having Best Regards, |
I would think that - ultimately - we are only interested in Succeed/Fail response from the VM machinery, so a single 0 or 1 bit, no? I really, really don't like parsing of all these stuff you linked to :( |
The point is salt needs some information about the target VM to send right states. At least target distribution to select appropriate modules (for example whether to use apt-get or yum). If you don't like parsing that salt-minion output directly, we can think of what informations is really needed, extract them from a VM using for example separate qrexec service, using some Simple Representation (TM), then provide it to salt the way I've described (my ugly PoC shell script does that - but instead of extracting that info, use hardcoded values in there). |
How about creating a DispVM, with a copy of all the info from Dom0, and then let the salt in the target VM talk to the DispVM only? Then destroy the DispVM (after retrieving 0 or 1 from it)? |
That DispVM would have control over everything that salt may control, right? Or at least will have all the salt configuration - which can for example contain VPN credentials the user want to configure in some selected ProxyVM.
I think the information needed to extract from a VM (using whatever mechanism) is a really small set. In my PoC it is:
I guess in practice, maybe two or three more values are needed, but that would be all. |
Ok, if there is no easy way to create a subset with all the info for the specific VM, which I understand is not trivial on Salt, then perhaps just have the parser of the return channel in the DispVM? So, the DispVM in this picture doesn't hold any config, only is tasked with simplification of the output returned from the VM. |
It may be an option. But I think it can be also done in the managed VM itself - simply put salt-minion output through a "converter" there and return to dom0 simplified version. Dom0 would need to validate that simplified output anyway regardless it comes from the target VM or DispVM, right? |
Yeah, right. So the point is not to run json parser and the like in Dom0. Perhaps return some very simplified strings and reconstruct JSON in Dom0 from it? |
Exactly. |
I think also about extracting the info using other mechanism - simplar to qubes.NotityTools (used by Windows Tools for now, but planning to extend also for Linux - #1637). It already covers remote OS info. That way, hopefully, we could construct the most important grains without using that JSON output in any way (not even in VM, simply redirect to /dev/null there). Will look into it later. |
There is a big difference between:
It can be simply logged somewhere in the VM. For debugging purposes (if that 0/1 flag show you there was an error). You can
Of course you can do that if you want. You can also configure salt/ansible whatever way you want. I think further discussion on this matter, here is senseless. If you want to continue, switch to mailing list. |
This sort of argument can be applied to pretty much every software package shipping in Qubes, Xen, kernel, coreutils, Python, anything used in the Qubes utilities, whatever. Under your rationale, the problem isn't Salt itself -- the problem is that software updates to code that has already been reviewed happen, and those updates can bring security holes. Philosophically speaking, your argument qualifies as what's called an "isolated demand for rigor". http://slatestarcodex.com/2014/08/14/beware-isolated-demands-for-rigor/ Note that I do really understand this: future Salt updates can introduce problems processing with minion returndata and minion grains. I do not deny this. I'm merely saying that's just a cost of doing business, just as much as it is a cost of doing business when you update libxenvchan, xen-core, or any of the myriad packages that qubes-dom0-* depend (I believe there's an icon converter in the pipeline, and that could totally be exploited if the libraries used to convert icons somehow gained a security vulnerability via updates...).
That's effectively unusable because such a user interface is that much harder to do compared to vanilla Salt. It's actually less usable than writing a dirty shell script, truly. I know this from experience because I developed bombshell doing exactly that kind of "tail across VMs" crap, and it was not pleasant, and it gave me many headaches. Avoiding that sort of terrible user experience is in fact the initial motivation for my writing of bombshell. I predict this sort of crippled user interface will doom the product to be entirely unused, as people will naturally default to using something else entirely to automate their needs. Even shell scripts! At least with shell scripts piped through qvm-run, the user gets the chance to 2>&1 and see stdout+stderr. Then, at this point, you might begin to hear about people getting their dom0s exploited by ANSI escape sequences from a compromised VM, because they understandably forgot -- unlike the Salt developers -- to filter them out of the output printed in dom0. After all, no one single developer who wants something automated quickly has the time to reimplement an ANSI escape filter on every one of their shell scripts. The general rule is: that you can do something doesn't mean people are going to tolerate it.
It's probably a good idea to avoid having any management stack then. Salt is a complex beast as it is right now, you can guarantee that it will become more complex over time, and its direction within the Qubes ecosystem doesn't seem to be defined to be user-friendly or usable like the actual SaltStack product is -- in fact, right now, it seems to be an option only for the hardest of hardcore geeks who do inter-VM Given those minimal benefits, it looks like stripping Salt from the Qubes TCB has the undeniable advantage that the TCB would measurably and objectively shrink. This is all in the context of us all waiting for capability OSes like Genode to take over and provide better security by compartmentation. It would be wise to choose well what we all invest our efforts in. |
Related salt-users topic on salt-ssh data flow: https://groups.google.com/d/msg/salt-users/gDvuc-5v8Hw/dmniH1eQBAAJ In short:
Given the above confirmation, here is what we discussed internally recently:
This gives us the following properties:
Configuration leak (which would require salt-ssh exploit in the first place) can be even further limited using additional steps:
Some implementation details/ideas:
|
One unanswered question: what template should be used for that DispVM? Having that template compromised means compromise of every salt-managed VM (probably all the templates or so). Also choosing "DispVM based on the same template as the target VM" is not good, because of configuration leak ("red-crappy-install-every-curl-pipe-bash" template based VM would learn all the Salt configuration, even that targeting "secret-project-xyz" VM). |
In case of some services it makes much sense for caller to receive also stderr in addition to stdout. For example: - qubes.VMShell (stderr required for salt-ssh over qrexec) - qubes.OpenInVM - especially when called to DispVM - otherwise diagnosing errors can be hard And generally all sort of error reporting (the purpose of stderr). It would ease debugging - instead of message "error occurred, check here and there for more details", it could be "error occurred: the reason". QubesOS/qubes-issues#1541
Targeting with grains (especially pillars) is insecure by design, because grains are provided by target system. In our case it doesn't matter in theory since dom0 doesn't receive VM grains. But this have another problem - such targeting is inaccurate then. QubesOS/qubes-issues#1541
We plan to use salt-ssh based approach to manage VMs, so no salt configuration will be present there. QubesOS/qubes-issues#1541
All the configuration is managed from dom0 - here top.* commands are useful. But in VMs we have simplified jinja-based version to only render top. QubesOS/qubes-issues#1541
Implement simplified version of top.get_top in pure jinja and use it when plain list of tops to include (`tops.yaml`) is present. This is to avoid using topd module, which isn't available over salt-ssh (because 'utils' directory required by it isn't copied over by salt-ssh). Such list of tops can be easily generated using `find` or similar tool. For example: cd /srv/salt; find _tops ! -type d -printf '- %p\n' > tops.yaml QubesOS/qubes-issues#1541
Implemented in marmarek/qubes-mgmt-salt-connector repository. It depends on minor changes in:
This implementation is based on core2 API. But migration to core3 API should be easy (DispVM creation) |
Todo:
@woju is it possible (and if so, is it a good idea?) to install additional ("external") subpackages into the same package as core ( |
Combining one python package from different distro packages is generally a bad idea. I wouldn't discount it altogether, however the need is very rare. Note that there are similar solutions like drop-in directories for plugins (vide I also don't think we need a "naming policy" precisely because the names aren't changing anything (this wouldn't be the case if we put those modules in single package). The gain is purely cosmetic. That said, we could name all our packages as |
It will be really useful for fine-grained targeting. QubesOS/qubes-issues#1541
Finally integrated into qubes-mgmt-salt repository (where
Then, |
Enable usage of Debian template for "DispVMs" from which salt-ssh is called. QubesOS/qubes-issues#1541
This will make it easier to reuse states where both dom0 and VMs are configured from the same formula. QubesOS/qubes-issues#1541
This will make it easier to reuse states where both dom0 and VMs are configured from the same formula. QubesOS/qubes-issues#1541
Do this using python API instead of separate process. This saves time spent on importing all that modules, which is about half of all the time spent on `state.show_top` call. QubesOS/qubes-issues#1541
Even in fc23-based dom0 it is needed to apply them (see QubesOS/qubes-issues#2048), to correctly render top file. Otherwise qubesctl doesn't correctly detect which VMs have any configuration to apply. QubesOS/qubes-issues#1541
On 25 December 2015 at 07:40, Marek Marczykowski-Górecki [email protected] wrote:
I totally agree. I was thinking of bombshell for vm to vm communication where there could be a SaltVM for user formulas where the SaltVM would have no network access or communication to dom0. That still may be risky though, but I wanted to at least experiment with a couple of different ideas to at least eliminate some of them.
I totally agree. What about dom0 sending configurations to a SaltVM master, which could communicate with TemplateVM's? Or would you rather not introducing a SaltVM in case it gets infected.
I have not considered salt.modules.state.pkg, but will look into it as well. I was thinking of using either a modified salt-ssh or creating a simple client on the TemplateVM. The salt-master can reside in dom0 that will create specific states based on pillar configuration and tops, etc. Based on your comment, I will look into the best way of creating the required data and sending it to TemplateVM without any parsing. So, the salt-master will create some type of state package, upload it only, the templateVM will unpack and execute it and can notify Salt Master when completed with a result code.
Another thing we can consider is using git to receive formulas from web which the TemplateVM can download and install which means we don't need to package it for each distribution. The formulas can be downloaded as a git repo or salt package (one file). Both methods have no existing security other than checksums, but we could verify git repos in a similar fashion to what qubes-builder does, but adding requirement and verification on each commit as well as tag and possibly a checksum on each file and overall?
I have copied this reply to qubes-issues to allow further discussions.
The text was updated successfully, but these errors were encountered: