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

nixos/gns3-server: fix ubridge support #303442

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

Conversation

anthonyroussel
Copy link
Member

@anthonyroussel anthonyroussel commented Apr 11, 2024

Description of changes

Fixes #292258
See this comment for explanations.

The usage of SUID wrappers is incompatible with SystemD DynamicUser & hardenings.
And GNS3 needs to call ubridge via its SUID Wrapper to work.

⚠️ These changes are not backwards compatible, but are needed to fix the module. You will need to run chown -R gns3:gns3 /var/lib/gns3 /etc/gns3 /var/log/gns3 to fix the permissions (see release notes).

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 24.05 Release Notes (or backporting 23.05 and 23.11 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

Add a 👍 reaction to pull requests you find important.

@anthonyroussel
Copy link
Member Author

@ofborg test gns3-server

@dani0854
Copy link
Contributor

I am still getting

Could not start auxiliary console process: [Errno 2] No such file or directory: 'script'

Seems to be this line of code:
https://github.com/GNS3/gns3-server/blob/5bab4131e186fbaa08943987fa9f7deb6a409642/gns3server/compute/docker/docker_vm.py#L530C1-L530C25

It looks like GNS3 depends on a script util, not included in NixOS by default.
unixtools.script provides that util (as well as some others), but simply adding it to system environment doesn't seem to work, not sure why.

I guess it might require a patch to the package in order to work. Or it has to be available in the environment.
There are also some other commands it depends on (not a complete list):

  • docker
  • telnet
  • vncviewer
  • remote-viewer (spice)

Copy link
Contributor

@dani0854 dani0854 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from above, those changes do fix the ubridge problem in the issue.

@dani0854
Copy link
Contributor

Unfortunately there seemed to many layers of problems hidden under each other, and it might be quite tricky to get GNS3 fully working with docker on NixOS.

Perhaps a more general issue to get GNS3 to work with docker is needed.

@anthonyroussel
Copy link
Member Author

Unfortunately there seemed to many layers of problems hidden under each other, and it might be quite tricky to get GNS3 fully working with docker on NixOS.

@dani0854 Thanks for the review.

I made a PR to fix the "Auxiliary console not available" error: #303472

@anthonyroussel anthonyroussel changed the title nixos/gns3-server: disable SystemD hardening & DynamicUser nixos/gns3-server: fix ubridge integration, disable SystemD hardening & DynamicUser Apr 12, 2024
@anthonyroussel anthonyroussel changed the title nixos/gns3-server: fix ubridge integration, disable SystemD hardening & DynamicUser nixos/gns3-server: fix ubridge support, disable SystemD hardening & DynamicUser Apr 12, 2024
@anthonyroussel anthonyroussel changed the title nixos/gns3-server: fix ubridge support, disable SystemD hardening & DynamicUser nixos/gns3-server: fix ubridge support Apr 12, 2024
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/prs-ready-for-review/3032/3859

@lugeha
Copy link

lugeha commented May 21, 2024

I did some testing. This is the minimal set of hardening to remove to make uBridge work.

systemd.services.gns3-server.serviceConfig = let
  f = lib.mkForce false;
in {
  DynamicUser = f;
  NoNewPrivileges = f;
  RestrictSUIDSGID = f;
};

Might as well keep any protections that can be on turned on.

@SuperSandro2000
Copy link
Member

Please implement the above suggestion

@haras-unicorn
Copy link
Contributor

haras-unicorn commented Jun 3, 2024

    services.gns3-server.enable = true;
    services.gns3-server.ubridge.enable = true;
    services.gns3-server.vpcs.enable = true;

    services.gns3-server.settings = {
      Server.ubridge_path = pkgs.lib.mkForce "/run/wrappers/bin/ubridge";
    };
    users.groups.gns3 = { };
    users.users.gns3 = {
      group = "gns3";
      isSystemUser = true;
    };
    systemd.services.gns3-server.serviceConfig = {
      User = "gns3";
      DynamicUser = pkgs.lib.mkForce false;
      NoNewPrivileges = pkgs.lib.mkForce false;
      RestrictSUIDSGID = pkgs.lib.mkForce false;
    };

tried with this in my config but ended up with

Error while sending command 'bridge add_nio_tap bridge0 tap-gns3-e0': unable to create NIO TAP for bridge 'bridge0': uBridge version 0.9.18 running with libpcap version 1.10.4 (with TPACKET_V3) Hypervisor TCP control server started (IP 0.0.0.0 port 36861). create_nio_tap: unable to open TAP device tap-gns3-e0 (Operation not permitted)

EDIT: using the web gui on localhost:3080 when i try start a docker container node

@lugeha
Copy link

lugeha commented Jun 5, 2024

I just tried this in a container too,

It also requires PrivateUsers = lib.mkForce false;

@anthonyroussel
Copy link
Member Author

anthonyroussel commented Jun 5, 2024

DeviceAllow = [
  "/dev/net/tun rw"
  "/dev/net/tap rw"
] ++ lib.optionals flags.enableLibvirtd [
  "/dev/kvm"
];

is also required for ubridge to work (because it requires access to nio tap devices).

I will also check whether this configuration works with KVM, QEMU and Docker.

@haras-unicorn
Copy link
Contributor

alright tyvm this works for me for now until this pr gets merged:

    services.gns3-server.ubridge.enable = true;
    services.gns3-server.settings = {
      Server.ubridge_path = pkgs.lib.mkForce "/run/wrappers/bin/ubridge";
    };
    users.groups.gns3 = { };
    users.users.gns3 = {
      group = "gns3";
      isSystemUser = true;
    };
    systemd.services.gns3-server.serviceConfig = {
      User = "gns3";
      DynamicUser = pkgs.lib.mkForce false;
      NoNewPrivileges = pkgs.lib.mkForce false;
      RestrictSUIDSGID = pkgs.lib.mkForce false;
      PrivateUsers = pkgs.lib.mkForce false;
      DeviceAllow = [
        "/dev/net/tun rw"
        "/dev/net/tap rw"
      ] ++ pkgs.lib.optionals config.virtualisation.libvirtd.enable [
        "/dev/kvm"
      ];
    };

@anthonyroussel
Copy link
Member Author

anthonyroussel commented Jun 13, 2024

Unfortunately, these changes are not backwards compatible.
And there is no official way within SystemD to revert the DynamicUser setting.

Here are the commands I use to migrate the GNS3 state files out of /var/lib/private:

rm /var/lib/gns3
mv /var/lib/private/gns3 /var/lib/gns3
chown -R gns3:gns3 /var/lib/gns3

rm /var/log/gns3
mv /var/log/private/gns3 /var/log/gns3
chown -R gns3:gns3 /var/log/gns3

chown -R gns3:gns3 /etc/gns3

I could add a system.stateVersion check in the systemd.services.gns3-server.preStart and execute these commands automatically once if the version is greater than 24.05.

Or just raise a warning to the user to let him know, the state files of GNS3 Server needs manual intervention to make GNS3 Server works.

What do you think?

@haras-unicorn
Copy link
Contributor

I was trying to run some docker services with this thing and came to the conclusion that UMask needs to be "0022" or something along those lines.
The reason is that if you try to run a docker service that runs via a user other than root that they don't have the permissions to start. The GNS3 init script tries to run another one of the scripts as that user via su. The other script is put there via a bind to a subdir in the GNS3 working directory. If UMask is 0077 as it is currently that other script doesn't have permissions so that the user declared in the docker image can execute it and the docker image entrypoint can never start.
I hope this all makes sense. I added this to the config I posted above if anyone wants to get around this:

      UMask = pkgs.lib.mkForce "0022";

@anthonyroussel
Copy link
Member Author

@haras-unicorn Thanks for the review. I changed UMask to its default value (0022).

@TafkaMax
Copy link

Will this be taken into account for the 24.11 release?

@anthonyroussel
Copy link
Member Author

  • Rebased the PR against master branch
  • Also added some release notes stating that this is a breaking change required to fix the GNS3 module

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/prs-ready-for-review/3032/4601

Comment on lines 240 to 243
DynamicUser = lib.mkForce false;
NoNewPrivileges = lib.mkForce false;
RestrictSUIDSGID = lib.mkForce false;
PrivateUsers = lib.mkForce false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these using lib.mkForce? If users have to change them to adapt their needs, do they have to use lib.mkVmOverride? Just false would be okay.

Copy link
Member Author

@anthonyroussel anthonyroussel Sep 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your review! :)

We set this to false with mkForce because GNS3 is incompatible with these hardening flags.

I changed these flags to:

Suggested change
DynamicUser = lib.mkForce false;
NoNewPrivileges = lib.mkForce false;
RestrictSUIDSGID = lib.mkForce false;
PrivateUsers = lib.mkForce false;
DynamicUser = false;
NoNewPrivileges = false;
RestrictSUIDSGID = false;
PrivateUsers = false;

Usage of DynamicUser is compatible with SUID wrappers.
GNS3 needs to call ubridge via its SUID Wrapper to work.
Copy link
Contributor

@dani0854 dani0854 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ubridge seems to work correctly now as far I have tested.

Although there are many other problems I have discovered with docker based appliances, but I think it's better to merge this PR, and start a separate issue/pr for those problems.

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.

nixos/gns3-server: ubridge doesn't work
9 participants