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

[Feature Request] LAN Access Control #1207

Open
nolancarougepro opened this issue Oct 9, 2024 · 9 comments
Open

[Feature Request] LAN Access Control #1207

nolancarougepro opened this issue Oct 9, 2024 · 9 comments
Labels
feature a whole new feature

Comments

@nolancarougepro
Copy link

As part of a university project, I’m working on adding a permission and rules specifically for controlling local network access. We want to get early feedback on this to increase the chances of our patches being merged into OpenSnitch.

Our extension is motivated by the observation that LAN network access can be more sensitive than Internet access because the user's LAN may contain (insecure) devices such as smart TVs, IoT gadgets, security cameras, and so on. While it’s already possible to block internal network access with custom rules, we believe simplifying this process and making it more user-friendly would be a great improvement.

Proposed Solution

For the GUI, when a prompt appears, alongside the existing options for internet access, users will see three additional radio buttons for local network access :

  • Reject access to the local network.
  • Deny access to the local network.
  • Allow access to the local network.

These options wouldn’t be mandatory. If the user doesn’t select anything, the default will be the same as the option selected for accessing the Internet (this ensures backwards compatibility in the behaviour of OpenSnitch).

@nolancarougepro nolancarougepro added the feature a whole new feature label Oct 9, 2024
@gustavo-iniguez-goya
Copy link
Collaborator

hi @nolancarougepro !

that sounds great. What did you have in mind for the daemon part? any changes to the rules?

@nolancarougepro
Copy link
Author

Hi,

Thanks for the feedback ! For now, I’ve mainly focused on how we could modify the rule structure.

I’m proposing to add a new field, "lan_action", to control local network (LAN) access. The existing "action" field will continue to manage internet access, while "lan_action" will specifically control LAN access. This allows users to independently set permissions for LAN and internet connections.

For example :

{
  "action": "allow",
  "lan_action": "deny",
  "operator": {
    "type": "simple",
    "data": "/opt/google/chrome/chrome"
  }
}

By doing this, we can keep things backward-compatible, as older rules without the "lan_action" field will continue working by defaulting to the "action" for both LAN and internet access.

That’s the current thinking ! Open to any feedback.

@gustavo-iniguez-goya
Copy link
Collaborator

The problem I see with adding a new action item is that we may end up with more groups like "lan_action", "vpn_action", etc.
The action item should be agnostic of where it's being applied, weather it's a domain, ip, network range, etc.

I guess the "lan_action" would check internally if the destination IP is private IP, right?
Could you explain in detail what rule would be sent from the GUI to the daemon when the user selects [reject/deny/allow] to LAN?

From the RulesEditor dialog you can create rules to allow/deny connections/apps by private network ranges:

classA_net = r'10\.\d{1,3}\.\d{1,3}\.\d{1,3}'
classB_net = r'172\.1[6-9]\.\d+\.\d+|172\.2[0-9]\.\d+\.\d+|172\.3[0-1]+\.\d{1,3}\.\d{1,3}'
classC_net = r'192\.168\.\d{1,3}\.\d{1,3}'
others_net = r'127\.\d{1,3}\.\d{1,3}\.\d{1,3}|169\.254\.\d{1,3}\.\d{1,3}'
multinets = r'2[32][23459]\.\d{1,3}\.\d{1,3}\.\d{1,3}'
MULTICAST_RANGE = "^(" + multinets + ")$"
LAN_RANGES = "^(" + others_net + "|" + classC_net + "|" + classB_net + "|" + classA_net + "|::1|f[cde].*::.*)$"

Maybe the new options could just create a new rule to block/allow the connection by Path + dst.network: LAN?

@nolancarougepro
Copy link
Author

I understand your concerns regarding the potential for creating multiple action groups (like lan_action, vpn_action). We can take the following approach :

Proposed Solution

  • Unified Action Structure : Instead of introducing new action types, we can retain the existing options (allow, deny, reject) for all connection types.

  • IP Verification : The daemon can check if the destination IP falls within private IP ranges (using the regex patterns defined in LAN_RANGES) to determine if it’s a LAN connection.

  • Rule Creation : When a user selects an action for a LAN connection, we can create a rule that includes :

    • Path : The application attempting the connection.
    • Destination : Marked as LAN.

For example :

    {
      "action": "allow/deny/reject",
      "operator": {
        "type": "simple",
        "data": "/path/to/application"
      },
      "dst": {
        "network": "LAN"  // or "WAN", "VPN", "Internet", etc.
      }
    }

This approach avoids cluttering our rule structure with multiple action types while maintaining straightforward logic and modularity. We won’t need to modify the GUI or introduce radio buttons for LAN action selection in the prompts.

Although multiple prompts for a single application provide granular control, improve security, raise user awareness, and allow for future scalability, they can also overwhelm users. However, this is necessary since each network destination (e.g., LAN, WAN, VPN, Internet) requires its own set of prompts for effective permission management.

What do you think about that ?

@gustavo-iniguez-goya
Copy link
Collaborator

gustavo-iniguez-goya commented Oct 15, 2024

Thank you for the explanation @nolancarougepro.

Let's focus for a moment in this sentence, which I think is the key of this enhancement request: "we believe simplifying this process and making it more user-friendly would be a great improvement.". I want to understand better what was the problem you had when creating rules for the LAN.

It'd be useful if you could describe your use case step by step of what you expected, for example:

  • a new pop-up appears to allow/deny an app/connection.
  • the user expects / wants to deny or approve it by default to the LAN, by just clicking on a button.

With this in mind, we could let the users customize the options of the pop-ups, by letting them choose the destination in the Preferences dialog:
image

Adding new "aliases" as needed:

image

The main use of opensnitch is to allow/deny connections to The Internet, but I think we can offer options to customize that behaviour.

By the way, who's going to use the opensnitch, uni students on uni computers? because the settings could be copied to the machines in advance.

On the other hand, having "aliases" also in the daemon it's not a bad idea (LAN, MULTICAST, etc) . It would help to write rules manually on servers, instead of having to write the regexp of the hell:

{   
    "type": "regexp",
    "operand": "dest.ip",
    "data": "^(127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|169\\.254\\.\\d{1,3}\\.\\d{1,3}|192\\.168\\.\\d{1,3}\\.\\d{1,3}|172\\.1[6-9]\\.\\d+\\.\\d+|172\\.2[0-9]\\.\\d+\\.\\d+|172\\.3[0-1]+\\.\\d{1,3}\\.\\d{1,3}|10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|::1|f[cde].*::.*)$"
}  

And adding a new options outside of the operator{} item probably is not a good idea, because it'd open a new path in the code for checking connections, and it'd limit how the new option can be used. Placing it within the operator{} item allows for combination with additional options.

Right now the rule could be written as:

{
  "action": "allow/deny/reject",
  "operator": {
    "type": "list",
    "operand": "list",
    "sensitive": false,
    "data": "", 
    "list": [
      { 
        "type": "simple",
        "operand": "process.path",
        "data": "/path/to/application"
      },
      { 
        "type": "simple",
        "operand": "dest.network",
        "data": "LAN"
      } 
    ]
  }  
}  

@nolancarougepro
Copy link
Author

Thanks for your feedback and examples. Our aim is to simplify LAN access management for non-technical users, similar to iOS, where a pop-up prompts them to allow or deny LAN access. We want to streamline this process so users can make decisions with a single click.

We initially considered adding a new checkbox to the GUI, but as you mentioned, that could lead to one for VPN and other options. We believe your example is a great solution. Adding a LAN alias when the daemon detects an attempt to access the internal network will simplify rule creation and avoid complex regex, making configuration much easier.

If this approach works for you, I’ll move forward with development.

Thanks again !

@gustavo-iniguez-goya
Copy link
Collaborator

perfect @nolancarougepro , start working on it!

@nolancarougepro
Copy link
Author

Hi there ! Just wanted to share a quick update on the alias feature progress.

To start, I created a network_aliases.json file in /etc/opensnitchd/, which defines aliases with associated IP address ranges. Here’s a sample of how it’s set up:

{
    "LAN": [
        "10.0.0.0/8",
        "172.16.0.0/12",
        "192.168.0.0/16",
        "127.0.0.0/8",
        "::1",
        "fc00::/7"
    ],
    "MULTICAST": [
        "224.0.0.0/4",
        "ff00::/8"
    ]
}

I modified prompt.py to load these aliases and check if the destination IP of new connections matches any alias ranges. If it does, users can save the rule with the alias (e.g., for LAN). Here’s an example of a saved rule:

{
    "created": "2024-11-05T08:11:40.000000Z",
    "name": "allow-until-restart-simple-lan-firefox",
    "enabled": true,
    "action": "allow",
    "duration": "until restart",
    "operator": {
        "type": "list",
        "operand": "list",
        "list": [
            {
                "type": "simple",
                "operand": "process.path",
                "data": "/snap/firefox/4848/usr/lib/firefox/firefox"
            },
            {
                "type": "network",
                "operand": "dest.network",
                "data": "LAN"
            }
        ]
    }
}

Now, I’m working on updating main.go to load the JSON file and operator.go to support the new alias logic.

Let me know if you have any thoughts or feedback!

@gustavo-iniguez-goya
Copy link
Collaborator

hey @nolancarougepro ,

Bear in mind that the GUI may run on a different computer than the daemon(s), so it won't have access to /etc/opensnitchd/ directory in some cases.

Due to this I think there should be 2 network_aliases.json, one for the daemon and one for the GUI (maybe under utils/ for example).

Having the definitions as a json file will allow us to extend it easily, so it's a good idea 👍

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

No branches or pull requests

2 participants