sudo usage and even attempt to replace system library?
sdettmer opened this issue · 5 comments
Hi,
thank you for your great work. I took a look to SetupMinecraft.sh
to check if I could safely execute it. First, it attempts several sudo, for example to create a systemd unit (I guess to start a user process). Why not simply using a user unit, the minecraftbe.service sets a user anyway and should not need any root access.
A bit later I met:
sudo mkdir /lib64
# Create soft link ld-linux-x86-64.so.2 mapped to ld-2.31.so, ld-2.33.so, ld-2,35.so
sudo rm -rf /lib64/ld-linux-x86-64.so.2
sudo ln -s $DirName/minecraftbe/$ServerName/ld-2.31.so /lib64/ld-linux-x86-64.so.2
sudo ln -s $DirName/minecraftbe/$ServerName/ld-2.33.so /lib64/ld-linux-x86-64.so.2
sudo ln -s $DirName/minecraftbe/$ServerName/ld-2.35.so /lib64/ld-linux-x86-64.so.2
NB: "ln -s" (without -f) will not overwrite the file, so typically it will use the first that exists and fail afterwards (apparently there is no error handling in the script). Usually the most recent version should be used, so they should be tried in reverse order I think, but to make it functionally safe, "-f" would be needed, which then could overwrite a system library, as I like to describe in a bit more detail:
I think this attempts (for ARM / amd64 emu, but anyway) to overwrite the system-wide linux loader "ld-linux" for all system processes by a version from unknown source with unknown properties (possibly a Microsoft version). The systems version would be available as "libc6:amd64:" (Debian 11, name could differ in Ubuntu, but I think it is unlikely). Also it should not be needed. I know that stand-alone mode could be disabled at build time, Debian does not do so, so any binary can be ran by ~/ld-linux-alt.so ~/mybinary
, beside that QEMU surely offers a correct way to run a binary without all that.
I propose to remove the need for root access and instead recommend to create a dedicated user where to install and run everything. Instead of installing packages, the script could tell to please run apt install curl unzip screen net-tools gawk openssl pigz
(if the latter is really needed; the others possible are often already installed).
I saw you also worked on a container. Possibly a very similar approach could be used here without a container based on debootstrap and schroot if there should really a need to replace system's libraries. By this, the installation would not interfere with other processes on the system.
However, I think this is not needed, so any need for root permissions can be removed.
You can't run the script as root. You can only run the script as sudo. There is a check to prevent you from setting this up as root.
The server doesn't run with root permissions. They are only used during setup to create the /etc/sudoers.d/minecraftbe file and the systemd service.
These 3 commands are the only ones allowed to be ran as sudo:
$UserName ALL=(ALL) NOPASSWD: /bin/bash $DirName/minecraftbe/$ServerName/fixpermissions.sh -a, /bin/systemctl start $ServerName, /bin/bash $DirName/minecraftbe/$ServerName/start.sh
The correct way to do this is to create a special account to run the setup file. You can't run it as root anyway.
Most people create a "minecraft" account that doesn't have permissions to anything else. You can temporarily add that account to the sudoers group and then run SetupMinecraft.sh. After it's finished people remove the account from the sudoers group altogether.
None of the QEMU stuff is used unless you are using an ARM platform. This is a legacy project. I always recommend people use Docker.
It's been like this for a long time but any security issues like this were resolved years ago. It's a sudoers whitelist. No, you cannot set it up as root, that is not allowed. You are supposed to create a user to run it as sudo with just like you said and then kick them out of the sudoers group. This is a pretty standard service setup.
If you are concerned about any of this you don't need to use the script. It's just a helpful way to set it up for beginners who don't understand dependencies or setting up a startup service and things like that. You know you can just run the server on the command line right? You don't need any of this stuff. If you have concerns like this and don't understand how this one is working it would be a far better idea to just do your own custom setup. There's really not much to these scripts. You do not need them for this.
It's already intended to work the way you are saying. Don't attempt to set it up as root. Use a special user and then remove them from the sudoers group afterward and it works exactly the way you're saying.
Again, if you are on ARM I highly, highly recommend using Docker and not worrying about this or how any of it is working. The Docker version has a lot of enhancements this one doesn't as well such as Box64. It's literally faster than QEMU.
If you are serious about security at all you want to containerize your Minecraft instances (whether it's with Docker or whatever it is). We just had the big log4j exploit on Java a year or however long it's been ago. People running it in Docker would have been protected. Any of these standalone versions would not have been (although setting it up with a new user with no permissions to anything else would help a lot as you should with this one and SetupMinecraft.sh).
Even if you set this up exactly as I'm saying with a custom "minecraft" user that doesn't have rights to anything else regular users still have more rights and more access to see and talk to things in your environment than Docker. Way more.
Docker is intentionally isolated with it's own copy of an operating system running in memory. Attackers end up nowhere even if they find a exploit (such as log4j) when containerized whereas even with a very limited account they are still in your real system with a limited user if there's a breach on standalone. There's just no comparison between standalone and containerization as far as security goes here. You want it as isolated as possible.
Hopefully that helps!
Hi,
thank you for your quick reply. I'm afraid to completly misunderstood what I tried to say.
First, let me emphasize that I really like you big effort to make it available in an easy way. I hope many will find and use it and apparently there is a huge, happy and growing user base.
However, I'm afraid they open a security treat by utilizing root powers that should not be needed. Technically a binary must be started a user process, and for this, no root permissions are needed. Users can enforce libraries without root, users can setup systemd units without root and even install and download packages without root (not to system's default directories of course, so it will not affect other users, but to their own directories).
So actually, the script requires sudo
, possibly for no real need. Giving any root access to a dedicated minecraft user breaks the security of the system, and be it only for the purpose of running one single shell script. For example, the minecraft account has write access to the fixpermissions.sh script, so the account can easily modify it and use it to get any access it wants to.
So to put it clear, the variable-replaced version of:
$UserName ALL=(ALL) NOPASSWD: /bin/bash $DirName/minecraftbe/$ServerName/fixpermissions.sh
in sudoers gives any (malicous) process running under $UserName full root access; all it needs to do is to modify fixpermissions.sh
or replace it (cp install-backdoor.sh fixpermissions.sh
).
(I don't see recommendation of a decicated user in https://jamesachambers.com/minecraft-bedrock-edition-ubuntu-dedicated-server-guide/; if creating one, this user will have no way to gain priviledges by sudo; so I'm sure many less experienced users just execute the curl | bash
chain under their normal account, because only on this, sudo works by default)
I think in standard service setups there is no way for the service to gain any root access; everything else usually can be considered a security issue and should be fixed (and that's why I wrote).
So I think it would be good trying to protect the users as much as possible, and I think removing root access is a good protection.
You are free to change them and see what problems it creates. If you are concerned about fixpermissions.sh then remove it from your script. You can fix the permissions manually if they break. Most people don't want to deal with that.
These are just templates. People change them to suit their needs. Your needs are not the same as everyone needs and what I've been trying to tell you is that we know 100% for a fact that standalone is not a good security model for Minecraft.
In other words I'm saying with your needs you shouldn't even be willing to accept standalone. That's why I might have seemed a little dismissive. You can't know much if you don't understand how dangerous standalone is vs. containerization and that's not just true for Minecraft. There are all kinds of other permissions on your system related to security that people miss with just the basic permissions. Read (and even write) access to /proc, /sys and that kind of thing.
This script is designed so that when it starts the server will work 100% of the time no matter how messed up the permissions have got on the Minecraft files. I will not be removing that feature to fix ownership of the server files and yes that requires sudo.
Most people don't want to deal with any of this stuff though which is why I literally recommend using Docker. If you want to fork the script then by all means. I don't recommend using standalone period. Even in the documentation. I will continue to recommend using Docker to everyone for both ease of setup and security.
I'd never make this today. I'd never use anything like this today. I don't use anything like this today. I use Docker. I wouldn't make your version either. We literally know better now. I haven't added a single feature to this since log4j made it so clear that you really need to have a server like this isolated in a modern environment. Isolated for real. Account based isolation isn't enough.
I appreciate what you're saying about the standalone version here but understand that it was made before log4j happened. It's not a smart way to do it. I still support it because a lot of people depend on it and most people are running it securely like we're saying. I don't mean to be mean / rude / dismissive.
I think I'm trying to convince you it's actually worse than you're saying. I'm trying to convince you to isolate it through containerization because I support your security-conscious mind. I actually agree with you and think it's worse than you're saying.
The trade-off you're asking though is losing the ability to fix really messed up permissions. I get it. It would make it more secure.
Hi, thanks again for your quick and detailed answer. Thank you for suggestions how to change things and explanations. I don't like to fork (if so, only to propose patches, but I'd ask you before if there is a chance you merge them, as it costs efforts of course).
My target was trying to help by making proposals. For example, instead of creating a system wide systemd unit, someone could use:
mkdir -p ~/.config/systemd/user/
cat << EOT > ~/.config/systemd/user/bedrock.service
[Unit]
Description=Bedrock Server
After=multi-user.target
[Service]
RemainAfterExit=True
WorkingDirectory=$DirName/minecraftbe/$ServerName
ExecStart=$DirName/minecraftbe/$ServerName/bedrock_server
[Install]
WantedBy=default.target
EOT
systemctl --user enable bedrock.service
systemctl --user start bedrock.service
there is no root needed.
There's no root needed now. It is a user mode service. Look at the code:
[Service]
User=userxname
WorkingDirectory=dirname/minecraftbe/servername
Type=forking
ExecStart=/bin/bash dirname/minecraftbe/servername/start.sh
ExecStop=/bin/bash dirname/minecraftbe/servername/stop.sh
GuessMainPID=no
TimeoutStartSec=1800
See the User section under service? It will be the account you run the script as. This is why you run it as a new "minecraft" user for example.
Have you tried this? It will work exactly as you're saying as long as you are the minecraft user or whatever user you ran the script as. This is not a root service!
You won't even need to enter your password to do it. That's why it has the /etc/sudoers.d/minecraftbe file. That allows passwordless sudo to start the server.
It has nothing to do with root. The service is not running as root.
root and sudo are not the same thing. Sudo can allow you to run things as other users. That is how this script works. It is set up as the account you run SetupMinecraft.sh as. Not as root!
In other words anyone can start the server without having to put in a password. It's using passwordless sudo but only for that command. The service does not run as root though. It will always run as the minecraft user no matter who starts it.
That's specified in the service file and the user running the script is inserted in place of userxname. It doesn't matter who starts it. It won't be root. It will only be the user specified in the minecraftbe.service file. That's the advantage of using systemctl. Systemctl will start it as the user I told it to in the minecraftbe.service file so it will never have any permissions outside of what was intended at installation.
The one thing that could probably be improved is fixpermissions.sh. The way to improve it would be to put that entire nasty script in the sudoers file and eliminate the fixpermissions.sh file altogether. In other words you'd probably add the chown lines and all of that in one nasty one liner in the sudoers.sh file.
That would eliminate that attack surface altogether but if you think you could possibly be attacked by someone that isn't running some kind of bot or pre-made exploit and is a real hacker then you need to be running Docker. If you have reason to believe you are going to be targeted you should run Docker. If it's a bot then no it's not going to figure out how my script's fixpermissions and all of that is called internally and they would have to have a working Minecraft exploit first to even get the chance (which very few have ever been found on Bedrock).