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/qbittorrent: init #287923

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

Conversation

fsnkty
Copy link
Member

@fsnkty fsnkty commented Feb 11, 2024

Description of changes

create a module to use qbittorrent as a service.
closes #322456 and sort of? effectively, closes #296190

user notes

new serverConfig

to ensure qbit accepts a new serverConfig before rebuilding the system you should

  1. stop the qbit service
  2. remove the existing file at /var/lib/qBittorrent/qBittorrent/config/qBittorrent.conf
  3. rebuild like usual, do note that afaict the file wont be recreated if the value of serverConfig isn't changed since the last build, or maybe a reboot etc.

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

serverConfig.Preferences.WebUI = {
  AlternativeUIEnabled = true;
  RootFolder = "${pkgs.fetchzip {
    url = "https://github.com/VueTorrent/VueTorrent/releases/download/v2.7.2/vuetorrent.zip";
    hash = "sha256-bJyI7RvVCf0M5vs8Qi+uAHv74CWxSDZ0Bb6zWJ4x4CM=";
  }}";
};

use before merge example

assumes you have this (https://github.com/fsnkty/nixpkgs/tree/init-nixos-qbittorrent) branch as an input named qbit

{
  inputs,
  pkgs,
  ...
}:
{
  imports = [ "${inputs.qbit}/nixos/modules/services/torrent/qbittorrent.nix" ];
  services.qbittorrent = {
    enable = true;
    package = inputs.qbit.legacyPackages.${pkgs.system}.qbittorrent-nox;
    serverConfig.LegalNotice.Accepted = true;
  };
}

blocking issues

  • sufficient test(s,ing)
  • serverConfig
    • gendeepINI gets a fitting type to use for this option.
    • qBittorrent.conf
      • more feedback / info on what does/does not cause qbit to "take in" new config.
      • understanding where the write permission on /var/lib/qBittorrent/qBittorrent/config/qBittorrent.conf comes from / why its possible
  • openFirewall

nice to haves

  • a better way to set CapabilityBoundingSet to restrict all.
  • an explanation for PrivateTmp being disabled upstream. ( Work on Systemd service unit qbittorrent/qBittorrent#6806 (comment) )
  • some way to generate the bizare password format used independently. (Thank you Fea)
    • format conversion within the module (/on activation/ whatever else)

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 of AF_NETLINK AF_INET or AF_INET6 address families.
ProtectSystem cant be used without entirely declarative config

in 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

  • 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.

@github-actions github-actions bot added 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` labels Feb 11, 2024
@fsnkty fsnkty mentioned this pull request Feb 11, 2024
13 tasks
@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10 labels Feb 11, 2024
@fsnkty

This comment was marked as outdated.

@camilosampedro
Copy link

@nu-nu-ko

I've added you to contributors here now that I've taken parts of your work in the tests and since you had added yourself to them in your branch I assume you're still keen to? let me know if not and ill remove of course.

If you are allowed, I'd like to be a contributor, thank you!

still unsure how to do assertions for options on other options so for now I've left it be

Do you mean during tests?

@fsnkty

This comment was marked as outdated.

@camilosampedro
Copy link

camilosampedro commented Feb 18, 2024

I've seen this in deluge:

https://github.com/NixOS/nixpkgs/blob/nixos-23.11/nixos/modules/services/torrent/deluge.nix

When you use declarative = true, it tries to use the options that are required to be declarative, and if they are not set it errors:

The option `services.deluge.authFile' is used but not defined.

But it doesn't happen the other way, if authFile is declared and declarative = false

@fsnkty

This comment was marked as outdated.

@camilosampedro
Copy link

Is it weird if there were two separate sets of options?

qbittorrent-nox
qbittorrent-nox-declarative?

@camilosampedro
Copy link

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.

Copy link
Member

@nevivurn nevivurn left a 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.

@fsnkty

This comment was marked as outdated.

Copy link
Member

@nevivurn nevivurn left a 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

nixos/modules/services/torrent/qbittorrent.nix Outdated Show resolved Hide resolved
@fsnkty

This comment was marked as outdated.

@nevivurn
Copy link
Member

an empty list isn't equivalent sooo 😅

Ah, did not realize the empty list wasn't doing anything. "" should work.

there is no default? its randomly selected from within a range from what i can tell. the non default web port is questionable.. but I think defaulting to 8080 is kinda dumb, happy to change it.

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.

umask 0066

how is this opinionated? in what case may this break something?

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?

@wegank wegank added the 2.status: merge conflict This PR has merge conflicts with the target branch label Mar 20, 2024
@fsnkty fsnkty force-pushed the init-nixos-qbittorrent branch 2 times, most recently from aa2f5a4 to 145b6e3 Compare March 27, 2024 23:43
@Redhawk18
Copy link
Contributor

I'd love to see someone take on guiding this PR in the meantime if they're able to do so faster than me ^^``

Thanks man, If you have time if you could approve or give suggestions on my pr. It feels like this pr may have bitten off more than it can chew. But I understand these things are very complex and everyone has to agree on what is done. We can open a pr in the future trying to implement settings.

@alexandru0-dev
Copy link
Contributor

If you want to use nox with this module just override the pkg config to qbittorrent-nox which is also something that this PR by default should use if it's intended to use headless

ERRATA: this option already uses qbittorrent-nox as the default package

@Redhawk18

@Redhawk18
Copy link
Contributor

If you want to use nox with this module just override the pkg config to qbittorrent-nox which is also something that this PR by default should use if it's intended to use headless

ERRATA: this option already uses qbittorrent-nox as the default package

@Redhawk18

But this pr is incomplete, very complex with settings, and the author is not able to work on it.

@poperigby
Copy link
Contributor

meta.mainProgram isn't being set correctly. I'm still getting this warning when building my system:

trace: evaluation warning: getExe: Package "qbittorrent-nox-4.6.5" does not have the meta.mainProgram attribute. We'll assume that the main program has the same name for now, but this behavior is deprecated, because it leads to surprising errors when the assumption does not hold. If the package has a main program, please set `meta.mainProgram` in its definition to make this warning go away. Otherwise, if the package does not have a main program, or if you don't control its definition, use getExe' to specify the name to the program, such as lib.getExe' foo "bar".

@alexandru0-dev
Copy link
Contributor

@poperigby if I'm not mistaken it's the qbittorent package that has that warning, and it's not caused by the option itself and a discussion here wouldn't be relevant.
Can you create another issue if there isn't already one?

@fsnkty
Copy link
Member Author

fsnkty commented Sep 4, 2024

@poperigby if I'm not mistaken it's the qbittorent package that has that warning, and it's not caused by the option itself and a discussion here wouldn't be relevant.
Can you create another issue if there isn't already one?

this PR does try to change meta.mainprogram for qbit to work here, I'm assuming it's a small issue but can't look into it
no seperate issue needed, though if you want to improve that part of the package seperately that'd be fine

@alexandru0-dev
Copy link
Contributor

alexandru0-dev commented Sep 4, 2024

this PR does try to change meta.mainprogram for qbit to work here, I'm assuming it's a small issue but can't look into it

After a second look you're completely right, I was checking the files on my phone and completely missed the changes to the package

@fsnkty
Copy link
Member Author

fsnkty commented Sep 20, 2024

still unsure on exactly when I'll be able to get back to working on this but at worst sometime in 2-3 months 💀
as always if anyone's able and willing to "take over" this work as it is now, be my guest.
otherwise anyone still currently using this module, now is the best time to explain your experience problematic or not, simply knowing what's already working is helpful etc.

@fsnkty
Copy link
Member Author

fsnkty commented Sep 26, 2024

meta.mainProgram isn't being set correctly. I'm still getting this warning when building my system:

trace: evaluation warning: getExe: Package "qbittorrent-nox-4.6.5" does not have the meta.mainProgram attribute. We'll assume that the main program has the same name for now, but this behavior is deprecated, because it leads to surprising errors when the assumption does not hold. If the package has a main program, please set `meta.mainProgram` in its definition to make this warning go away. Otherwise, if the package does not have a main program, or if you don't control its definition, use getExe' to specify the name to the program, such as lib.getExe' foo "bar".

unable to replicate please link to the code that encountered this.

@fsnkty wouldn't it be best to make torrentingPort default to null? Then people wouldn't have to set it if they didn't want to.

isn't not giving the option a default null already? it is nullOr port

@fsnkty
Copy link
Member Author

fsnkty commented Sep 26, 2024

testing this again on the unstable branch of nixpkgs I'm more confident this is functional and just missing some quality / reassurance things
the type and testing would be nice but both require a little more time in learning than I can afford to spare atm.

@poperigby
Copy link
Contributor

unable to replicate please link to the code that encountered this.

This is my configuration which gives that warning: https://gist.github.com/poperigby/8e669dd14165320a81d714b673e84eae

isn't not giving the option a default null already? it is nullOr port

I don't think so, because not specifying torrentingPort makes it fail to evaluate saying that it's used but not defined, meaning there's no default value.

@fsnkty
Copy link
Member Author

fsnkty commented Oct 3, 2024

unable to replicate please link to the code that encountered this.

This is my configuration which gives that warning: https://gist.github.com/poperigby/8e669dd14165320a81d714b673e84eae

isn't not giving the option a default null already? it is nullOr port

I don't think so, because not specifying torrentingPort makes it fail to evaluate saying that it's used but not defined, meaning there's no default value.

Yeah you need to use the package from this PR. e.g.. setting config.services.qbittorrent.package = inputs.qbit.legacyPackages.${pkgs.system}.qbittorrent-nox

@nevivurn
Copy link
Member

nevivurn commented Oct 3, 2024

Even when we allow null with nullOr, we still need to set the default value as null otherwise users get the used but not defined. A value being null (by default or otherwise) is different from it never being set at all.

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
@fsnkty
Copy link
Member Author

fsnkty commented Oct 8, 2024

No longer thousands of commits behind 👍
seems to work the exact same, love to see it.

@fsnkty
Copy link
Member Author

fsnkty commented Oct 8, 2024

@fsnkty wouldn't it be best to make torrentingPort default to null? Then people wouldn't have to set it if they didn't want to.

ok that commit is named poorly, should be "default null torrentingPort" but whatever itll get squashed xP
but yeah good catch, should be alright to not specify a torrenting port now 👍

@fsnkty
Copy link
Member Author

fsnkty commented Oct 8, 2024

edit: misread comment timeline but these questions still nice to know

anyone aware of qbit writing global section config values?
also anyone aware of config value depth greater than 5?

silly copy n paste mistake

return stickybit
@fsnkty
Copy link
Member Author

fsnkty commented Oct 8, 2024

alright for now I have no clue why qbit is seemingly able to enable write permissions on that file.
if you want to reapply from config you can

  1. stop the qbit service
  2. remove the file /var/lib/qBittorrent/qBittorrent/config/qBittorrent.conf
  3. apply new system config

its hacky but for now thats whatever.
fyi custom webuis work, e.g..

serverConfig = { 
  Preferences = {
    WebUI = {
      AlternativeUIEnabled = true;
      RootFolder = "${pkgs.fetchzip {
        url = "https://github.com/VueTorrent/VueTorrent/releases/download/v2.7.2/vuetorrent.zip";
        hash = "sha256-bJyI7RvVCf0M5vs8Qi+uAHv74CWxSDZ0Bb6zWJ4x4CM=";
      }}";
    };
  };
};

@sajenim
Copy link

sajenim commented Oct 11, 2024

to help with coverage

[Application]
FileLogger\Age=1
FileLogger\AgeType=1
FileLogger\Backup=true
FileLogger\DeleteOld=true
FileLogger\Enabled=true
FileLogger\MaxSizeBytes=66560
FileLogger\Path=/app/qBittorrent/data/logs

[AutoRun]
OnTorrentAdded\Enabled=false
OnTorrentAdded\Program=
enabled=false
program=

[BitTorrent]
Session\BTProtocol=Both
Session\DHTEnabled=false
Session\DefaultSavePath=/data/torrents
Session\DisableAutoTMMByDefault=false
Session\DisableAutoTMMTriggers\CategorySavePathChanged=false
Session\DisableAutoTMMTriggers\DefaultSavePathChanged=false
Session\ExcludedFileNames=
Session\GlobalDLSpeedLimit=8000
Session\GlobalUPSpeedLimit=200
Session\LSDEnabled=false
Session\PeXEnabled=false
Session\Port=32372
Session\Preallocation=true
Session\QueueingSystemEnabled=false
Session\TempPath=/data/torrents
Session\TempPathEnabled=false

[Core]
AutoDeleteAddedTorrentFile=Never

[Meta]
MigrationVersion=6

[Network]
PortForwardingEnabled=false
Proxy\OnlyForTorrents=false

[Preferences]
Advanced\RecheckOnCompletion=false
Advanced\trackerPort=9000
Advanced\trackerPortForwarding=false
Connection\ResolvePeerCountries=true
Downloads\SavePath=/config/downloads/
Downloads\TempPath=/config/downloads/temp/
DynDNS\DomainName=changeme.dyndns.org
DynDNS\Enabled=false
DynDNS\Password=
DynDNS\Service=DynDNS
DynDNS\Username=
General\Locale=en
MailNotification\email=
MailNotification\enabled=false
MailNotification\password=
MailNotification\req_auth=true
MailNotification\req_ssl=false
MailNotification\sender=qBittorrent_notification@example.com
MailNotification\smtp_server=smtp.changeme.com
MailNotification\username=
Scheduler\days=EveryDay
Scheduler\end_time=@Variant(\0\0\0\xf\x4J\xa2\0)
Scheduler\start_time=@Variant(\0\0\0\xf\x1\xb7t\0)
WebUI\Address=*
WebUI\AlternativeUIEnabled=false
WebUI\AuthSubnetWhitelist=127.0.0.1/32, 192.168.20.0/24
WebUI\AuthSubnetWhitelistEnabled=true
WebUI\BanDuration=3600
WebUI\CSRFProtection=true
WebUI\ClickjackingProtection=true
WebUI\CustomHTTPHeaders=
WebUI\CustomHTTPHeadersEnabled=false
WebUI\HTTPS\CertificatePath=
WebUI\HTTPS\Enabled=false
WebUI\HTTPS\KeyPath=
WebUI\HostHeaderValidation=false
WebUI\LocalHostAuth=false
WebUI\MaxAuthenticationFailCount=5
WebUI\Port=8080
WebUI\ReverseProxySupportEnabled=false
WebUI\RootFolder=/app/vuetorrent
WebUI\SecureCookie=true
WebUI\ServerDomains=*
WebUI\SessionTimeout=3600
WebUI\TrustedReverseProxiesList=
WebUI\UseUPnP=false

[RSS]
AutoDownloader\DownloadRepacks=true
AutoDownloader\SmartEpisodeFilter=s(\\d+)e(\\d+), (\\d+)x(\\d+), "(\\d{4}[.\\-]\\d{1,2}[.\\-]\\d{1,2})", "(\\d{1,2}[.\\-]\\d{1,2}[.\\-]\\d{4})"

@Pandapip1 Pandapip1 added the 2.status: merge conflict This PR has merge conflicts with the target branch label Oct 23, 2024
@@ -93,5 +93,7 @@ stdenv.mkDerivation rec {
license = licenses.gpl2Plus;
platforms = platforms.unix;
maintainers = with maintainers; [ Anton-Latukha kashw2 ];
mainProgram = "qbittorrent"
Copy link
Contributor

Choose a reason for hiding this comment

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

change no longer needed on master when rebased :)

@Titaniumtown
Copy link
Contributor

In regards to the serverConfig changes, on a nixos-rebuild switch, shouldn't it stop the qbittorrent service, apply the new settings, then start it? I don't observe this functionality locally.

@fsnkty
Copy link
Member Author

fsnkty commented Nov 13, 2024

In regards to the serverConfig changes, on a nixos-rebuild switch, shouldn't it stop the qbittorrent service, apply the new settings, then start it? I don't observe this functionality locally.

that would be an approach if I was more sure of it.
my personal ideal would be the serverConfig acting as a base and then reapplying differences in the existing file as to keep both managed and unmanaged config, iirc nextcloud module here does something similar to this?
since that would afaict remove the need for the ability to disable managed config outright.

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 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.status: merge conflict This PR has merge conflicts with the target branch 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (new) This PR adds a module in `nixos/` 8.has: module (update) This PR changes an existing module in `nixos/` 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Package request: VueTorrent qbittorrent-nox: missing meta.mainProgram