google / santa

A binary authorization and monitoring system for macOS
https://santa.dev
Apache License 2.0
4.42k stars 297 forks source link

Allow managing ruleset via `.mobileconfig` #285

Closed jesseendahl closed 2 years ago

jesseendahl commented 6 years ago

We manage Santa centrally and we want to ensure that the only rules loaded are only the ones that are currently defined in the config. Phrased differently—we want to ensure there no locally set rules: the Santa rules should match the desired state as defined in config management. Currently have to do some crazy stuff to achieve that goal. Specifically, we load a LaunchDaemon that runs a script every five minutes. That script:

All this happens without interrupting Santa, and is fairly lightweight, especially in the event that no differences are found—which is most the time. But we're concerned that it's pretty brittle, since it will break if the database structure changes.

It would be really ideal if we could just set the rules via the .mobileconfig and then Santa handled making sure they were loaded/reloaded every time the config changes.

What would also be really ideal is if local rule changes were blocked whenever the ruleset is being managed by the .mobileconfig.

Curious to hear what y'all think of this idea!

cc @tburgin @aidanpm

tburgin commented 6 years ago

I like the idea. local rules < mobileconfig rules < sync server rules All are mutually exclusive.

aidanpm commented 6 years ago

@jesseendahl 💯 👍

@tburgin, In the case of a .mobilesonfig used to configure Santa with a sync server, it would be nice if rules supplied in that same profile would be used until Santa has completed it's first sync with the configured server. Basically allowing the admin to guarantee a basic list of rules upon install until a synced rule set takes precedence.

Though I'm not sure how valuable that truly is 🤷‍♂️

russellhancox commented 6 years ago

I have a few concerns about this, mostly because our experience with mobileconfig files has been terrible - a change to any installed profile will cause a drop and refresh of all settings for all profiles. We handle this by waiting 5s after noticing a config change before doing anything (and resetting that timer if another change happens before it fires) but currently 'doing anything' is just reading the list of forced values so it's not particularly time consuming if we repeat the process a few times. This change would make 'doing anything' also resetting all rules in the database, which could take a lot longer, especially if the list of rules is large.

An alternative approach:

  1. Add a key to the .mobileconfig called RulesFile which points at a root-owned file on disk with appropriate permissions (probably 0600). Having this key set will have the same effect as having SyncBaseURL set, insofar as the rule command will be disabled.

  2. We define a JSON 'pack' format for rules, which was already requested in #56 but that we haven't got around to yet. This format would be documented and not change in backwards-incompatible ways.

  3. When santad notices the RulesFile key has changed it creates a file watcher on the file pointed to and when the file changes it ensure the permissions are correct, then parses the JSON file to create an array of rules, it adds the 2 mandatory rules and then flushes the database and re-adds all rules in a single transaction.

A slight variation would be to overload the SyncBaseURL key so that a local file URL can be specified instead which will cause the sync command to read from that file and the sync --daemon flag would cause sync to watch the file instead of registering for FCM notifications. That might be cleaner from a code point of view and make it clear that Santa is syncing with something.

Would this approach be suitable for what you're trying to achieve?

jesseendahl commented 6 years ago

@russellhancox breaking out the rules into a separate place sounds way better than what I proposed, but I think there's a problem with having it be a file on disk that's in JSON, which is that a JSON RulesFile wouldn't be deliverable over MDM.

Would splitting out the rules into a separate .mobileconfig still allow you to address the problems you described around the way .mobileconfigs get reloaded by macOS? Perhaps some indicator for what the latest ruleset is can be stored within the main .mobileconfig so that Santa knows whether it needs to reload the ruleset from Rules.mobileconfig or not?

If there would be a way to accomplish that, then what are your thoughts on supporting both a RulesFile on disk that allows for JSON, but also a Rules.mobileconfig that allows specifying the rules in plist format?

A nice additional (very small) security benefit of allowing the rules to be delivered within a .mobileconfig is that the ruleset can be encrypted with a device-specific public key.

russellhancox commented 6 years ago

which is that a JSON RulesFile wouldn't be deliverable over MDM.

Couldn't the MDM deliver the rules file in a package using InstallApplication? I imagine generating a package within an MDM gets ugly pretty fast.

Would splitting out the rules into a separate .mobileconfig still allow you to address the problems you described around the way .mobileconfigs get reloaded by macOS

That doesn't really help, it just means we're watching 2 different preference suites instead of 1.

We could have 2 different keys , 1 which contains the actual rules and 1 that contains an identifier of some sort and we can make it so the former is only read and processed when the latter changes. This at least alleviates the problem of repeatedly processing the rules un-necessarily at the expense of requiring the profile creator to maintain a second field identifying the rules. I'd suggest Rules and RulesIdentifier as key names.

If there would be a way to accomplish that, then what are your thoughts on supporting both a RulesFile on disk that allows for JSON, but also a Rules.mobileconfig that allows specifying the rules in plist format?

If we're going to handle the rules in the mobileconfig I'd rather stick with that than also supporting a file on-disk. However, a JSON pack format has a number of benefits over adding nested dictionaries in the profile, so a nice way to still support the JSON form would be to make the Rules key a data type where the data is expected to be base64-encoded JSON. Does that work for you?

jesseendahl commented 6 years ago

Couldn't the MDM deliver the rules file in a package using InstallApplication? I imagine generating a package within an MDM gets ugly pretty fast.

Yeah unfortunately delivering the rules within a .pkg would indeed get ugly fast, for multiple reasons—the most painful of which is that we'd have to rebuild the .pkg every time someone changed their ruleset in our web UI.

We could have 2 different keys , 1 which contains the actual rules and 1 that contains an identifier of some sort and we can make it so the former is only read and processed when the latter changes. This at least alleviates the problem of repeatedly processing the rules un-necessarily at the expense of requiring the profile creator to maintain a second field identifying the rules. I'd suggest Rules and RulesIdentifier as key names.

I love this idea. The only tweak I'd make is to change RulesIdentifier to RulesNonce or RulesUUID to make it clear that it's just a relatively meaningless value. The word "identifier" gives it more weight than it really has—it doesn't matter what the value is, just that whenever it changes it triggers a reload of the Rules. Maybe something even more explicit like RulesReloadTriggerNonce.

If we're going to handle the rules in the .mobileconfig I'd rather stick with that than also supporting a file on-disk. However, a JSON pack format has a number of benefits over adding nested dictionaries in the profile, so a nice way to still support the JSON form would be to make the Rules key a data type where the data is expected to be base64-encoded JSON. Does that work for you?

Totally. I actually had the same thought about using the data type with base64 encoded JSON when I was writing my last comment, but then didn't include it as a possible approach for some reason. But I agree that would be a great way to support JSON for those people for whom it would be useful. Were you imagining that would be the only way to define rules (base 64 JSON), or would you also allow regular nested dictionaries?

apizz commented 5 years ago

Currently work at a school and this would a very welcome addition.

While we don't currently deploy Santa, having a way via a config profile to manage Santa rules on our endpoints would be huge for us, as this would allow us to manage our rule configurations the same way we do for other apps and services. We don't have the resources to spin up one of the listed open source server sync tools just for this one purpose, and given the limitations with Apple's config profiles as far as blocking applications goes, as well as our MDM, this would make Santa a huge value add and viable option for us.

Know it's much easier to say "wouldn't it be nice to have..." than actually coding the thing, so if there are thoughts about building this functionality this I would happily test.

russellhancox commented 5 years ago

Sorry, this fell off of my radar. I'm quite busy right now but I'm going to try and take a day to work on this and see how much I can get done. I'll try and post an update in a few weeks, but feel free to ping this issue if I don't.

russellhancox commented 2 years ago

It took 3 years longer than expected but a PR is finally up to resolve this, which I'm hoping to get in for the 2022.7 release.

russellhancox commented 2 years ago

Done, the example config at https://github.com/google/santa/blob/main/docs/deployment/com.google.santa.example.mobileconfig now has a StaticRules key.

On Wed, Aug 3, 2022 at 12:35 AM jasmineAnthropic @.***> wrote:

Hi @russellhancox https://github.com/russellhancox this looks great, however I'm confused how to add this in. Can we please edit the example .mobileconfig file within Github to have a staticRules allow key (e.g for Goolge Chrome). I have also been using the example .mobileconfig at this site https://santa.dev/deployment/configuration.html.

— Reply to this email directly, view it on GitHub https://github.com/google/santa/issues/285#issuecomment-1203473983, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAQ4A7W4CCMPQCHUZGQEKTVXHZKHANCNFSM4FH7IVOA . You are receiving this because you were mentioned.Message ID: @.***>