-
-
Notifications
You must be signed in to change notification settings - Fork 14.8k
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/qbittorrent: init #287923
base: master
Are you sure you want to change the base?
nixos/qbittorrent: init #287923
Conversation
d4984ad
to
dc84cc2
Compare
dc84cc2
to
35bc83d
Compare
This comment was marked as outdated.
This comment was marked as outdated.
@nu-nu-ko
If you are allowed, I'd like to be a contributor, thank you!
Do you mean during tests? |
This comment was marked as outdated.
This comment was marked as outdated.
I've seen this in https://github.com/NixOS/nixpkgs/blob/nixos-23.11/nixos/modules/services/torrent/deluge.nix When you use
But it doesn't happen the other way, if |
This comment was marked as outdated.
This comment was marked as outdated.
Is it weird if there were two separate sets of options?
|
Also, related and unrelated. I was seeing that the web ui and other services were being unresponsive after a couple of hours. I thought that the IO of qbittorrent was bringing the system down, but after 2 days of trying everything, it was my network device's firmware. 😅 I'll try to retest it this week. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Afaik, it is possible to pass in the webui and torrenting port via command line arguments, and I assume these arguments take precedence over other configuration options. This should let us implement openFirewall
without forcing users to use the declarative config.
a better way to set CapabilityBoundingSet and SystemCallFilter to restrict all.
CapabilityBoundingSet
is an allowlist, the strictest setting is just the empty string. Although, given that we 1) don't run qbittorrent as root, 2) set NoNewPrivileges, 3) don't set AmbientCapabilities
, omitting it entirely is probably fine.
I personally think @system-service
is a good enough default for SystemCallFilter
.
I don't understand why it sets PrivateTmp to false
This comment in the upstream PR mentions adding torrents through the command line. Not sure if this is actually true.
ProtectSystem needs to be disabled if we aren't using declaritiveConfig
I don't think ProtectSystem
should be enabled here. It will break users with per-category/torrent save paths, no matter what.
imo, we don't need lock down every option by default. Users that want to further harden their system can easily add these options in their own nixos configuration.
d60b403
to
bc0a267
Compare
This comment was marked as outdated.
This comment was marked as outdated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why we wouldn't set it regardless personally, leaving it empty seems to do nothing as according to systemd-analyze security qbittorrent on my system.
👍
I agree to some extent, id much rather every service does at least up to "breaks as little as possible"
I completely agree, we can enable everything that probably won't break users.
There are still a couple options left that I feel like are a tad bit too opinionated, namely
- non-default torrenting port
- umask 0066
This comment was marked as outdated.
This comment was marked as outdated.
Ah, did not realize the empty list wasn't doing anything.
The bittorrent port is chosen randomly by default, and it is quite unexpected for nixos to fix an arbitrary port number by default. Similar with the web port, I don't see a reason for the NixOS module to deviate from the upstream default. With this module, it would be trivial for users to change it as needed, anyway.
I think this would break users trying to access downloaded files without needing to run as the qbittorrent user, likely a common use case. Plus, if we're going for paranoid settings, why is it not 0077? |
e3913e0
to
c289233
Compare
c289233
to
07d92b9
Compare
aa2f5a4
to
145b6e3
Compare
ok that commit is named poorly, should be "default null torrentingPort" but whatever itll get squashed xP |
edit: misread comment timeline but these questions still nice to know anyone aware of qbit writing global section config values? |
06914f9
to
ed44619
Compare
alright for now I have no clue why qbit is seemingly able to enable write permissions on that file.
its hacky but for now thats whatever.
|
61fc435
to
ed44619
Compare
to help with coverage
|
In regards to the |
that would be an approach if I was more sure of it. I haven't looked into doing either just yet as I wasn't sure they'd be whole solutions. well that and I've been very low availability to do much of anything 😅 |
Regarding (could not reply there) #357000 (comment) Legal notice was added as my train of thought went, let's add all the cli options as explicit options, and let all the rest just be set through the rfc42 style settings. (Legal notice I think might have just showed up in a log as an option and not necessarily in the help message). I do think the config file takes presidence over launch flags though. My take on the config file was that it should probably just stay mutable, and either apply a diff of changes like discussed above, or just override the config at service relaunch. (Thought I will not argue against anyone or any work done) Edit: in my testing the config file seemed to be properly owerwritten at least on rebuild if you changed options in the settings. Edit: would be cool to see a nixos native way of binding a interface with systemd, if one doesn't fully trust the binding innside qbittorrent. (At least think systemd had options for this) I'd be happy to contribute some tests or other work, when I get the time again. |
I like the idea but my first idea would be allowing arbitrary command line arguments, especially because some can take custom values right
what I atm believe to be the ideal would be the applying a diff over the existing ( remaining mutable file ) approach but don't yet know how to approach this in a reliable way applying changes at the relaunch of the service is an approach I don't have as much confidence in but if others can vouch for known good approach to it I'd like to look into it some more
love some more confirmation on that! had others confirm it to me personally earlier but haven't gotten consistency with it myself though I haven't given it a proper test in a good while
great point, definitely something to look into
sweet! would love to have your view on how and what should be tested! |
I don't see how that could be accomplished in a reliable way without a full codec for the qbittorrent config that specified serialization and merging rules (which is very likely infeasible). Just being able to generate the custom INI format is already an accomplishment! The only realistic options I see are fully mutable (just let qbittorrent create its stuff under I would also appreciate including an automatic nginx virtual host option based on other services. As a start, you could add this to the config: nginx = mkOption {
type = types.submodule {
options = {
enable = mkEnableOption "the nginx reverse proxy virtual host";
hostname = mkOption {
description = ''
The hostname for the nginx virtual host.
'';
example = "qbittorrent.example.com";
type = types.str;
};
};
};
description = "nginx config TODO";
default = { };
}; and this to the result: services.nginx = mkIf cfg.nginx.enable {
enable = true;
virtualHosts.${cfg.nginx.hostname} = {
locations."/" = {
proxyPass = "http://localhost:${toString cfg.webuiPort}/";
};
};
}; In this case I also don't want the web UI port to be opened in the firewall, but the torrenting port (if specified) should be, so having separate options there would be nice. Should we even allow specifying an absolute state path instead of the SystemD default of Just specify |
Would love to see a qbittorrent service available for NixOS. Most of the services I run on my server are already available as native NixOS services, adding qbittorrent to that list would be great. It's nice to see that there's already work done in this direction.
With regards to the config, which seems to be one of the open issues, I think @magneticflux- summarized it well. Either make it fully mutable or fully immutable. Depending on the |
For those following this thread. I made a PR with an initial testing setup at fsnkty's fork. See: fsnkty#1. |
I added an |
Wrt the blocking issue:
After a quick look at the qbittorrent source code it seems that the The |
Tried to parse the My solution was to turn the transform the ini into a TOML file, as there is a builtin Here is the proof of concept:
It is the first piece of nix code that I wrote, aside from my configuration file, so any pointers are appreciated :). Another, maybe simpler option, would be to introduce a dependency to another program/language to make the conversion to TOML a bit easier and more compact. |
optional torretingPort firewall feathecutie's improved genDeepINI update desc for Password_PBKDF2 & misc openFirewall mkEnableOption remove `.` from mkEnableOption desc update maintainer name & reword openFirewall desc
only set config if not null and remove write perm silly copy n paste mistake return stickybit Add default for serverConfig and add tests Add extraArgs option and test Make webuiPort option optional Add interaction via api to tests Use reboot instead of shutdown and start nixfmt tests Add restartTriggers so that a new config is loaded on change Use specialisations in tests To simulate module option changes nixfmt tests
c2a49e2
to
d9c2b86
Compare
huge thanks to undefined-landmark for effectively resolving a couple blocking issues here, now as far as im concerned there is just the one left, the genINI type. for now I've just included their changes, removed resolved changes, and rebased onto master once again but there does seem to be some more changes required to have tests run, I've likely missed something. as for the fitting type of genINI being a blocking issue, i would very much appreciate experienced contributors to nixpkgs comments on if thats absolutely true and why, as well as any recomendations for alternatives etc. |
I enjoyed helping out a lot, learned a lot about Nix along the way. Sound plan to make the advanced config handling into a separate PR. With my poc, posted before, I think it's possible to read the qbittorent ini format and merge it with the declarative config, but it will take some more thought to refine it and make it ready to merge. I can take a look at the queued and skipped tests. In my PR I always ran the tests manually so I didn't investigate the CI way to run tests. Seems like there needs to be a For the fitting types. You don't mean fitting types to the |
|
||
serverConfig = mkOption { | ||
default = null; | ||
type = unspecified; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to ensure merge would work correctly, but that we can also set some defaults; see https://nixos.org/manual/nixos/unstable/#sec-freeform-modules.
Also, I'd like to set Preferences.WebUI.UseUPnP = false;
as a default, as this would avoid unnecessary exposure by default.
type = unspecified; | |
type = submodule { | |
freeformType = attrsOf (attrsOf anything); | |
options.Preferences.WebUI.UseUPnP = mkEnableOption "UPnP for access to the qbittorrent WebUI"; | |
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestions! At the moment setting any settings through serverConfig
would make the settings "immutable". So on reboot or change all settings would be reset to default, except for the ones set in serverConfig
. So if we apply this suggestion someone could unexpectedly find all their settings reset on a reboot/change.
I agree that it'd be good to disable UPnP by default. Unfortunately I don't think there is any other way to enable/disable UPnP than through serverConfig
/qbittorrent.conf
. Once we make merging of serverConfig
with the current qbittorrent.conf
possible your suggestion can be added.
]; | ||
}; | ||
}; | ||
config = lib.mkIf cfg.enable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit
config = lib.mkIf cfg.enable { | |
config = mkIf cfg.enable { |
extraArgs = lib.mkOption { | ||
type = lib.types.listOf lib.types.str; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit
extraArgs = lib.mkOption { | |
type = lib.types.listOf lib.types.str; | |
extraArgs = mkOption { | |
type = listOf str; |
port | ||
path | ||
nullOr | ||
unspecified |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unspecified | |
listOf | |
attrsOf | |
anything | |
submodule |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'd also want to remove this, oops.
}; | ||
|
||
serverConfig = mkOption { | ||
default = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default = null; |
Description of changes
create a module to use qbittorrent as a service.
user notes
in ui settings changes
the config file does become editable once qbittorrent starts so changing settings within the UI does work however they will be need to be overwritten(removed) if you wish to "reapply" the exact config from setting
serverConfig
password formatting
the password format that qbittorrent expects can be generated using this tool ( thanks Fea )
alternative UI's
custom webuis managed with nix are possible, example of VueTorrent use with fetchzip
use before merge example
assumes you have this (https://github.com/fsnkty/nixpkgs/tree/init-nixos-qbittorrent) branch as an input named
qbit
blocking issues
serverConfig
gendeepINI
gets a fitting type to use for this option.qBittorrent.conf
/var/lib/qBittorrent/qBittorrent/config/qBittorrent.conf
comes from / why its possible (Thank you undefined-landmark again!)openFirewall
nice to haves
CapabilityBoundingSet
to restrict all.PrivateTmp
being disabled upstream. ( Work on Systemd service unit qbittorrent/qBittorrent#6806 (comment) )pr notes
for service hardening I don't believe any of the following can be used simply because of the services purpose.
IPAddressDeny
PrivateNetwork
or restriction ofAF_NETLINK
AF_INET
orAF_INET6
address families.ProtectSystem
cant be used without entirely declarative configin my previous attempt at this here i was advised to simply make use of the service from the package, I'm unsure how to do this.
I started with an aim to follow https://github.com/qbittorrent/qBittorrent/blob/master/dist/unix/systemd/qbittorrent-nox%40.service.in I don't understand why it sets
PrivateTmp
to false however and have otherwise changed it significantly with service hardening and nix(os) specifics.Things done
nix.conf
? (See Nix manual)sandbox = relaxed
sandbox = true
nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)Add a 👍 reaction to pull requests you find important.