Skip to content
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

Group based query protection #1337

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

HenryGrahamRivian
Copy link

This MR introduces an interface for filtering incoming host queries based on groups in the querying host's cert and groups in the queried host's cert.

This will improve the privacy of the network for its users by preventing users from querying hosts that they are not supposed to have access to as defined by the lighthouse configuration.

Required config file additions
lighthouse:
  query_protection:
    test-protection:
      - allowed-group
Example positive interaction

mermaid-diagram-2025-02-14-140947

Example negative interaction

mermaid-diagram-2025-02-14-140746

@nbrownus
Copy link
Collaborator

nbrownus commented Mar 7, 2025

Thanks for the PR!

To clarify (mostly for myself), this is default allow any unless a protected group is specified, once a group is declared as protected then only hosts with any 1 of the allowed groups can query for it. All in common lighthouses in the mesh between the host doing the querying and the host being queried must have the same configuration or else the information this is trying to protect will leak.

I immediately look to the firewall config and consider the precedent it sets.

Naming things is hard so please try to look past the names.

lighthouse:
  query_protection:
    - target_groups: // Any host with this subset of groups 
        - "region: us-east-1"
        - "role: database"
      querying_groups: // Can only be queried by a host with this subset of groups
        - "region: us-east-1"
        - "role: webserver"
        
    // Additional identical targets_groups can be defined to allow other querying groups to query
    // This allows for easy rule appending from disparate sources, its easier for config management systems
    // to append individual rules than to roll them up into a single config stanza
    - target_groups: // Any host with this subset of groups 
        - "region: us-east-1"
        - "role: database"
      querying_groups: // Can only be queried by a host with this subset of groups
        - "region: us-east-1"
        - "role: job-worker"
        
    - target_groups: // Any host with this subset of groups 
        - "region: us-east-1"
        - "role: database"
      querying_groups: // Can only be queried by a host with this subset of groups
        - "region: us-east-1"
        - "role: database"

In the above example imagine you have a fleet of database instances in multiple aws regions. A database instance can only be discovered by a webserver, job worker, or another database within the same region.

I like the functionality but the performance of that could be quite poor.

2 other ways to accomplish this would be:

  1. Denormalizing the group to something a single value can target pg:us-east-1:job-worker.

The downsides would be:

  • Could lead to certificate bloat through having normalized and denormalized groups, this could eventually cause handshake packets to be fragmented and make it near impossible to stand up a tunnel.
  • All hosts need to have the denormalized groups before you can install the rule
  1. Introduce a non caching lighthouse mode where a host can query about another host but the lighthouse does not cache information about the host doing the query. You could then partition caching lighthouses for the groups you want to protect and allow lighthouses to cache information about them and expose all lighthouses to all hosts in a non caching way

The downsides would be:

  • Requires real infrastructure
  • Does not scale well in terms of query performance
  • Does not scale well in terms of new protected groups

TLDR

If we keep it simple, like it is now, I would suggest twisting the config to look like (forgive the naming)

lighthouse:
  query_protection:
    - target_group: "role: database"
      querying_group: "role: webserver"
        
    - target_group: "role: database"
      querying_group: "role: job-worker"
        
    - target_group: "role: database"
      querying_group: "role: database"

I am curious what @JackDoan and @wadey think

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants