Decide and document where to install tools and scripts

Problem/Justification
There’s a learning curve on where to download and install user command-line tools. (Not through apt-get.) Lacking a source of gentle guidance, every user and every guide author needs to reinvent the wheel in whichever odd pattern comes to mind today. Unruly workarounds have caused trouble for users and iX alike.

Impact
The issue only affects command-line users. The solution only affects command-line users.

User Story
It’s poor form to group three separate requests, but these are a family that I think is best discussed in concert.

  1. User-installed tools and scripts

Users have scripts that they’ve written or downloaded. Some should be available in the active shell’s search path. I’d like to see simple official guidance on how to make that happen. Specifically: I’d like to be able to point to central documentation from a readme on GitHub.

Currently, outside projects find themselves having to tiptoe around whether to edit .bashrc or .zshrc or .profile or .zshenv or whatever. It’s a mess for users and contributors both, all of whom could benefit greatly from a common link to a short summary page about the platform’s file hierarchy norms.

FWIW the recommended standard location for user-installed scripts is ~/.local/bin. Ubuntu includes this in search paths in their default user skeleton. Debian does not. TrueNAS does not. If that remains the case, I’d still like to point to the platform’s published norms and suggestions.

  1. Local-installed tools and scripts

Similar deal: the standard path is of course /usr/local/bin and Debian has us covered there. But that’s off limits on TrueNAS. I have no desire to re-litigate that decision, but I would like clarity on the platform’s suggested alternative location.

Would it be possible to configure and document, say, a /home/.shared/bin for this? Perhaps if presented in stark terms that this should only ever symlink into somewhere on your own pool…

Importantly: none of the above is currently accessible through sudo. So for example “superbackup --start” might say “this command must be run under sudo”, while “sudo superbackup --start” then says “command not found”.

We find ourselves explaining how to edit all style of user shell resources and all style of root shell resources. Or updating independent copies of tools both in ~/.local/bin and in /root/bin. Or curating arbitrary symlinks to/from who knows where or why, across various pools and datasets…

Save us from ourselves. :stuck_out_tongue_winking_eye:

  1. Sandbox-installed tools and scripts

IMO it would be perfectly appropriate for iX to shut down shell access entirely and for good. Seriously! Don’t stop at walling off /usr/local and apt-get, but definitively state that the host environment contains no user-serviceable parts at all.

Instead: actively facilitate setting up one or more guest environments. (Of whatever kinds, be they VM or nspawn or LXC or even Docker with persistent mounts…) This could even be made seamless: funnel every tty session into a container or chroot, etc.

Until that happens we’re left with unfortunate roadblocks in the way of achieving this for ourselves. Whether standing up a full nspawn sandbox from scratch, or even a Python venv without the python3-venv package… help us get out of your way and vice-versa.

Thanks for reading and considering! :trophy:

1 Like

Since iX recommends the use of the admin user (which wasn’t present on my initial install of SCALE, instead I had to use the root user directly), I now have to use sudo with some of my own scripts. But we have established:

In principle, the standard location for user-installed scripts should be in ~/.local/bin. But that breaks down when the tool sometimes needs to be launched under sudo.

I can think of a workaround which involves overlayfs but I agree there needs to be an officially documented (in the TrueNAS docs) way to do these kinds of things.

1 Like

Root’s home directory is persisted across upgrades.

This is a good place for scripts which need to survive a pool destroy.

And they can be run via sudo.

Scripts which do not should go on your pool.

I personally have a dataset called “server” for host specific stuff, such as logs, scans and yes “scripts”, so /mnt/tank/server/scripts.

1 Like

They can, but only with the absolute path:

admin@nas:~$ sudo /root/.lxc/lxc-download.sh --help 

And the admin user can’t see the contents of /root without using sudo. So tab-completion doesn’t work either.

For example if I’d wanted to run sudo lxc-download.sh from any directory then how would you go about this?

I start bash scripts that need to be run as root with the following:

[ `/usr/bin/id -u` -ne 0 ] && /usr/sbin/sudo $0 $*
[ `/usr/bin/id -u` -ne 0 ] && exit

If the user isn’t root, then sudo tries to run this same script. When sudo returns, the next line causes the script to exit, because the effective UID isn’t 0 anymore. OTOH, if the effective UID is 0 when the script starts, both the tests drop through, and neither sudo nor exit are evaluated.

Using the full path to id and sudo means no requirement for them to be in $PATH.

2 Likes

Kudos on the clever workaround. :slightly_smiling_face:

FYI the $* can hurt you with argument splitting/escaping. Consider:

(( ! `id -u` )) || exec sudo -- "$0" "$@"

I’m troubled that the platform incentivizes scripts to contain self-escalation (and compiled tools to require launcher scripts) rather than keeping sudo firmly in the hands of the user.

I just want to mention that the LSB says that /opt would be a logical location for user scripts.

  1. The contents of /opt are considered “user data”, and thus should be maintained through a version upgrade.
  2. Packages outside the system’s package management system are expected to be installed in a subdirectory of /opt. For example, /opt/mypackage would contain everything needed to run mypackage. Many utilities for “managed Linux” (e.g., ESXi) distributions do this right now. It would be perfect for TrueNAS SCALE.
  3. A collection of user scripts could thus be installed as a “package” under /opt, even if the install is just cp.
1 Like

Why don’t you create a man page and submit it to iX (maybe it will make its way into the installer)?

Man pages are really cool! For example, it’s very (very, very) fast. It’s standard. They’re searchable. They require no extra tools to view. You can export to multiple different file formats. etc, etc.

I’m struggling to understand the point of this request. The answer is, “put them wherever you like on your pool, or in /root/.” Then add them to $PATH if desired, or just call them with a full path. I really don’t see that there’s any reason to further complicate or formalize this.

Yeah, and FreeBSD has hier(7). iX ignores both, in that they put all pools under /mnt/, which is supposed to be only for short-term, temporary mounts.

1 Like

Why would you put anything in /root? Do things the “normal way”: Create a user (call it admin or johndoe it doesn’t matter) and invite them to the wheel group. Under /home/admin/bin/ (or whatever name you want besides “bin”–I use ‘bin’ because I place compiled binaries in there) place some scripts. Add that location to your path var to make things even simpler. Edit your .rc file and add an alias entry for su to be: su -m. Now just ssh in, su, and/or run all the scripts you want.

…or just ssh in as root, and you don’t need to su. And why you’d put things in /root/ is because it’s root’s home directory, and I’m thoroughly unconvinced of the modern Linux aversion to using the root user (and I’ve been using TrueNAS long before it made the switch to Linux).

But if you’d rather put it somewhere else, go for it. That was my point. There’s no reason to “decide and document” a “standard” location for these things–put them wherever you want.

1 Like

I agree. It’s a futile thing to try and standardize.

Although, I do not agree about ssh-ing in as root. /root is volatile and gets gutted after every upgrade I think (I’m not positive because I don’t use root directory).

It is not volatile and does not get gutted with upgrades.

1 Like

And the other reason is its the ONLY directory that 1) you’re allowed to write to on the boot pool and 2) that’s maintained across upgrades.

BUT it is not included in config backups.

Still haven’t made a sales pitch. So you want to use root directory? Go for it but I’d honestly limit dolling out that historically horrible advice.

Seems to me that the sales pitch is being made in spades. :roll_eyes: Traffic laws work best when we don’t each make up our own.

There are so many polite young drivers out there just looking for best-practices advice to get started. They shouldn’t all be sent out to distill workarounds from random slugfests — the trusted platform vendor could offer some baseline guidance and working space.

2 Likes

On my system all pools are encrypted at pool level. So wanted a place outside those.

After going through this with no definite answer, I decided to take the long route and try the upgrade and analyze the results.

I tested through : SCALE-23.10.2 → SCALE-24.04.2.5 → SCALE-24.10.2.1 → SCALE-25.04-RC1

final candidates where 3 of them /mnt, /home and /root. They all kept the files but /mnt and /root the permissions were reset.

So finally I concluded as “There is no place like /home”

…which has NOEXEC set, so you can’t execute anything there.

Edit for explanation: a recent update to SCALE (I think it was 24.10, perhaps 24.10.1) sets NOEXEC on /home, meaning you can’t execute anything from /home. This doesn’t affect /root, but iX is trying more and more to discourage use of the root user, which makes me wonder whether that’s going to change too. And, as noted upthread, /root is on the boot device and is not backed up with the config database.

So, to the question that started this thread, make a directory or dataset on one of your pools and put your scripts there. I have a SSD pool for apps/VMs called software, so it’s easy enough to have a dataset of software/scripts. Put the scripts there.

If all your pools are encrypted, need a passphrase to unlock, and you need to run scripts at times when the pools are locked, the fallback would be to put them in /root. And seriously consider mirroring the boot pool in this case.

My belief (though I obviously don’t and can’t speak for iX) is that iX will never document this, because they really don’t want you doing this in the first place–their position has always been that any additional software should go in a jail/VM/sandbox/LXC. They don’t outright block it, but it’s getting harder, and I’d be very surprised indeed if they were to reverse course on this.

3 Likes

I’m on the bandwagon for use as-is.

My perspective is, if someone needs to run a command as a privileged user, does it matter if you are root or some other privileged user?

I myself place all my scripts in /mnt/farm/scripts and run as root. Is this “proper” IT security practice? Probably not, but I’m a home operated TrueNAS user, not a corporation. I know some folks use /root/ home directory as well for ease of use while I “personally” do not like that, but I have no issues with those folks who do it that way.

Would I like to see some standardization? I say yes and no. Yes just to have something documented and standardized, I say No because there will be more restrictions placed on the people who enjoy dabbling in the code and writing scripts that unfortunately require a privileged account. As TrueNAS is hardened, it has made it more difficult for me to do things. Having to find “work-arounds” is no fun.

2 Likes

Yes, indeed @dan is right. noexec does block and I noticed that while testing with #!/bin/bash in the script. But I forgot to mention that while writing. The script was called as arg to /bin/bash and it worked. (also works with sourcing)

Also as suggested, boot pool mirroring is a good idea. But in my case I keep the scripts in git, so replicating it won’t be an issue.

What I am looking for is to have a consistency between other debian systems; and that is the reason why I still believe a documented location would be good. Again, not a must - but would definitely appreciate having one place.