[Bug] ACL not working as expected #826

Closed
opened 2025-12-29 02:24:32 +01:00 by adam · 4 comments
Owner

Originally created by @Johnwulp on GitHub (Oct 11, 2024).

Is this a support request?

  • This is not a support request

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

When using this acl json, john is not able to connect to any customer. Which is how it should work.

{
  "acls": [
    { "action": "accept", "src": ["john"], "dst": ["john:*"] },
    { "action": "accept", "src": ["customer1"], "dst": ["customer1:*"] },
    { "action": "accept", "src": ["customer2"], "dst": ["customer2:*"] }
  ]
}

If i change the acl to below, then john is able to connect to customer1. But customer2 is also able to connect to customer1.

{
  "acls": [
    { "action": "accept", "src": ["john"], "dst": ["john:*"] },
    { "action": "accept", "src": ["customer1"], "dst": ["customer1:*"] },
    { "action": "accept", "src": ["customer2"], "dst": ["customer2:*"] },
    { "action": "accept", "src": ["john"], "dst": ["customer1:*"] }
  ]
}

Expected Behavior

When using this permission acl csutomer2 should not be able to connect to customer1

{
  "acls": [
    { "action": "accept", "src": ["john"], "dst": ["john:*"] },
    { "action": "accept", "src": ["customer1"], "dst": ["customer1:*"] },
    { "action": "accept", "src": ["customer2"], "dst": ["customer2:*"] },
    { "action": "accept", "src": ["john"], "dst": ["customer1:*"] }
  ]
}

Steps To Reproduce

Set environment up with permission json as explained

Environment

- OS: Docker container linux/arm64/v8
- Headscale version: stable (v0.23.0)
- Tailscale version: 1.76.0

Runtime environment

  • Headscale is behind a (reverse) proxy
  • Headscale runs in a container

Anything else?

No response

Originally created by @Johnwulp on GitHub (Oct 11, 2024). ### Is this a support request? - [X] This is not a support request ### Is there an existing issue for this? - [X] I have searched the existing issues ### Current Behavior When using this acl json, john is not able to connect to any customer. Which is how it should work. ``` { "acls": [ { "action": "accept", "src": ["john"], "dst": ["john:*"] }, { "action": "accept", "src": ["customer1"], "dst": ["customer1:*"] }, { "action": "accept", "src": ["customer2"], "dst": ["customer2:*"] } ] } ``` If i change the acl to below, then john is able to connect to customer1. But customer2 is also able to connect to customer1. ``` { "acls": [ { "action": "accept", "src": ["john"], "dst": ["john:*"] }, { "action": "accept", "src": ["customer1"], "dst": ["customer1:*"] }, { "action": "accept", "src": ["customer2"], "dst": ["customer2:*"] }, { "action": "accept", "src": ["john"], "dst": ["customer1:*"] } ] } ``` ### Expected Behavior When using this permission acl csutomer2 should not be able to connect to customer1 ``` { "acls": [ { "action": "accept", "src": ["john"], "dst": ["john:*"] }, { "action": "accept", "src": ["customer1"], "dst": ["customer1:*"] }, { "action": "accept", "src": ["customer2"], "dst": ["customer2:*"] }, { "action": "accept", "src": ["john"], "dst": ["customer1:*"] } ] } ``` ### Steps To Reproduce Set environment up with permission json as explained ### Environment ```markdown - OS: Docker container linux/arm64/v8 - Headscale version: stable (v0.23.0) - Tailscale version: 1.76.0 ``` ### Runtime environment - [X] Headscale is behind a (reverse) proxy - [X] Headscale runs in a container ### Anything else? _No response_
adam added the bug label 2025-12-29 02:24:32 +01:00
adam closed this issue 2025-12-29 02:24:32 +01:00
Author
Owner

@hopleus commented on GitHub (Oct 14, 2024):

I managed to achieve similar behaviour with the following actions:

  1. Initial launch of HeadScale without any ACLs
  2. Connected 3 clients
  3. changing the ACL (as a file) with rules that each node can only communicate with itself
  4. restarting HeadScale
  5. clients continue to see and communicate with each other even though the ACL prohibits them from doing so.

In my case, this behaviour is caused by the fact that after starting HeadScale (with the changed ACL) no updated information is sent to the clients, because the logic of HeadScale does not allow it. When switching ACL to Database mode, any ACL change results in updating all clients, which results in changing ACL policies and blocking traffic if required by the ACL.

It is likely that this issue may be related to #2181

From the suggestions:

  • After running HeadScale, always send update requests to clients
  • Add a CLI command to send updates to clients

In any case, @kradalby opinion is needed

@hopleus commented on GitHub (Oct 14, 2024): I managed to achieve similar behaviour with the following actions: 1. Initial launch of HeadScale without any ACLs 2. Connected 3 clients 3. changing the ACL (as a file) with rules that each node can only communicate with itself 4. restarting HeadScale 5. clients continue to see and communicate with each other even though the ACL prohibits them from doing so. In my case, this behaviour is caused by the fact that after starting HeadScale (with the changed ACL) no updated information is sent to the clients, because the logic of HeadScale does not allow it. When switching ACL to Database mode, any ACL change results in updating all clients, which results in changing ACL policies and blocking traffic if required by the ACL. It is likely that this issue may be related to #2181 From the suggestions: - After running HeadScale, always send update requests to clients - Add a CLI command to send updates to clients In any case, @kradalby opinion is needed
Author
Owner

@kradalby commented on GitHub (Oct 14, 2024):

After running HeadScale, always send update requests to clients

I am not sure if we are thinking of the same thing, but when Headscale starts, all nodes that connect will get a full new map, and that will be based on the loaded ACL so if it has been updated it should send the equivalent of the new one.

@kradalby commented on GitHub (Oct 14, 2024): > After running HeadScale, always send update requests to clients I am not sure if we are thinking of the same thing, but when Headscale starts, all nodes that connect will get a full new map, and that will be based on the loaded ACL so if it has been updated it should send the equivalent of the new one.
Author
Owner

@kradalby commented on GitHub (Oct 14, 2024):

@Johnwulp please include the tailscale debug netmap output requested in the issue template.

@kradalby commented on GitHub (Oct 14, 2024): @Johnwulp please include the `tailscale debug netmap` output requested in the issue template.
Author
Owner

@Johnwulp commented on GitHub (Oct 14, 2024):

I don't know what has changed, but i'm unable to reproduce the issue. Maybe it has something to do with restarting all the client i used for testing. I setteled on this configuration for the moment, and this works as expected.

{
  "groups": {
    "group:support": ["john"],
    "group:customers": ["customer1", "customer2"]
  },
  "acls": [
    { "action": "accept", "src": ["group:support"], "dst": ["group:customers:3389"] }
  ]
}
@Johnwulp commented on GitHub (Oct 14, 2024): I don't know what has changed, but i'm unable to reproduce the issue. Maybe it has something to do with restarting all the client i used for testing. I setteled on this configuration for the moment, and this works as expected. ``` { "groups": { "group:support": ["john"], "group:customers": ["customer1", "customer2"] }, "acls": [ { "action": "accept", "src": ["group:support"], "dst": ["group:customers:3389"] } ] } ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/headscale#826