Open christianhujer opened 3 years ago
BTW I managed to get it working by creating a file /etc/profile.d/sdkman.sh
with the following contents:
export SDKMAN_DIR=/usr/local/sdkman
source /usr/local/sdkman/bin/sdkman-init.sh
Maybe something like this could go in the documentation.
Hi @christianhujer. It is highly recommended not to run SDKMAN as the root user. Besides allowing a bash process to make changes on your system as a root user being highly insecure, SDKMAN also maintains state on the file system. This means that an SDKMAN installation cannot and should not be shared across all the system users, resulting in a clash of state updates.
SDKMAN was expressly designed to run in the user folder where it can't make global system changes. If you want this kind of behavior, I suggest using your operating system's preferred package manager which was built expressly for this purpose.
Hope this makes sense and that I haven't scared you off :smile:
I get all these things, and I am aware of that. Here's a few thoughts around that:
Now say I run a more traditional Unix system, a true multiuser system. There are n users in the system. I have the following choices:
/usr/local
. That's quite some effort.root
.sdkman
In case using SDKMAN! as root
is "dangerous", there's always the alternative to do this in a centralized way without running it as root
:
mkdir /usr/local/sdkman
useradd sdkman
chown sdkman /usr/local/sdkman
export SDKMAN_DIR="/usr/local/sdkman" && curl -s "https://get.sdkman.io" | su - sdkman bash
I know it will not work perfectly well. It would be great if we could make it work perfectly well for that scenario. Because SDKMAN! is just great, and that would make it even more useful.
The fact that sdkman allows on-the-fly switching of candidate versions per user makes this all very difficult. Perhaps if the archives
folder was split out to a centralized cache (and allowed configuration of its location), this could become a workable solution. That way each user would still have their own folder in their respective HOME
directory, but the zip archives would be fetched from a centralized cache.
I'm open to this sort of thing, but much work would need to be done to make it happen. If you would like to contribute such functionality, please feel free to raise a pull request.
curl -s "<URL>" | bash
has long been exceedingly dangerous, and is even more so now due to all of the recent supply chain hacks. To make matters worse, gradle itself is a tool involved in the supply chain, so this install method is especially risky for a tool like SDKMan!
See https://blog.gitguardian.com/codecov-supply-chain-breach/ for a recent example that is relevent to SDKMan!.
Running sudo curl -s "<URL>" | bash
is and incredibly bad idea for all of the reasons above, applied to the root used. If you are trying to automate some process, it would be much much better security-wise to create a script that performed this in a safe manner, which includes:
Either:
And:
if curl or wget is used to download within the script, that the execution of either is done as a non-root user su --login <nobody> -c <curl command> -o /tmp/<scriptname>
It makes me a bit queasy thinking about all of the developers piping a script from a website straight to bash with no chance of even inspecting what they are running, but when a feature request for doing this as root appeared in my google results, I felt I had to comment.
Stay safe!
As an informational update, I'm using SDKMAN! successfully for quite a while running it as root
and provisioning packages via /usr/local/sdkman
.
Using /etc/profile.d/sdkman.sh
with these contents:
export SDKMAN_DIR=/usr/local/sdkman
source /usr/local/sdkman/bin/sdkman-init.sh
(as described earlier) did the trick and works like a charm.
That said, I agree with the risks described, and I'm not promoting what I do - it is risky.
The only actions that should happen as root are things like install
, cp
, mkdir
, ln
, and so on.
I'm considering creating a dedicated sdkman
user and give them write access to /usr/local/sdkman
.
curl -s "<URL>" | bash
has long been exceedingly dangerous
I couldn't agree more, yet, I just couldn't find any way to install SDKMAN! from versioned, checksummed source.
In other words, where is the script returned by https://get.sdkman.io actually coming from?
Is it stored somewhere in a Git repository?
I would have expected to be part of the release tarball of sdkman-cli
. Or did I miss something?
And there's also the question of build reproducibility, where https://get.sdkman.io makes no guarantee on the versions it's going to install.
TL;DR: how can I install SDKMAN! from a release of sdkman-cli
?
I have also installed sdkman
as root, as I would like to share sdk's with my multiple accounts on a computer to save disk space. On a Mac, you can add also permissions for multiple users, so you can avoid running sdkman with root privileges and let you access packages installed by any user:
Install SDK Man
sudo su -
export SDKMAN_DIR="/Library/sdkman"
curl -s "https://get.sdkman.io" | bash
Use Access Control Lists (ACLs)
The best way to ensure that specific users always have read and write permissions, even for newly created files and folders, is to use ACLs.
Let's assume you have a sdkman
installed in directory /Library/sdkman
and you want users user1
and user2
to have read and write access. Here's how you can do it:
chmod +a "user1 allow read,write,delete,add_file,add_subdirectory,file_inherit,directory_inherit" /Library/sdkman
chmod +a "user2 allow read,write,delete,add_file,add_subdirectory,file_inherit,directory_inherit" /Library/sdkman
Make sure existing files and folders have the right permissions After setting up the ACLs for the main directory, you may want to apply similar permissions recursively to all existing files and subdirectories:
chmod -R +a "user1 allow read,write,delete,add_file,add_subdirectory,file_inherit,directory_inherit" /Library/sdkman
chmod -R +a "user2 allow read,write,delete,add_file,add_subdirectory,file_inherit,directory_inherit" /Library/sdkman
Set the SetGID Bit
This step ensures that new files and subdirectories created inside /Library/sdkman
inherit the group ownership of /Library/sdkman
.
chmod g+s /Library/sdkman
So, if you have a specific group (e.g., admin
) you want to use, you can chown
the directory to have that group:
chown -R :admin /Library/sdkman
Exit root
console
exit
Modify .zshrc
(or your console rc file)
Add following lines into user1
and user2
config files:
#THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!!
export SDKMAN_DIR="/Library/sdkman"
[[ -s "/Library/sdkman/bin/sdkman-init.sh" ]] && source "/Library/sdkman/bin/sdkman-init.sh"
Feature request It would be great if I could, as
root
, use SDKMAN! to provision software packages not for myself but the entire system so that other users can use them. I've tried to find information on this in:I tried to do
as root, and that works, but it does not make sdkman easily accessible to other users. I then tried
ln -s /usr/local/sdkman/bin/sdkman-init.sh /etc/profile.d/
and login as normal user, but the script would throw a lot of errors:So, it would be nice if there is a documented, automated way how to use sdkman to provision for other users in the same system.