Problem with sudoers file

Hello,

i’m using a small pc as a computer to host servers on. I’m using Garuda on it, like on my main computer.

I’ve been searching the web for days now, because I wanna automate as much as possible on this server pc, including updating and restarting. Since these two commands ask for a password, i’ve been searching for ways to execute a script with these two commands (pacman -Syu --noconfirm && shutdown -r 15) without needing to put in a password.

I’ve always been finding the same thing in different variations, which is: Editing the sudoers-file with visudo. Which I did in all variations I found. My additions to this file are atm these:

[username] ALL=(ALL) NOPASSWD: /home/[username]/root-scripts/update-and-restart.sh
[username] ALL=(ALL) NOPASSWD: /home/[username]/root-scripts/

Following the most upvoted answer here, I also put sudo chown root:root and sudo chmod 700 on the folder “root-scripts” and the file “update-and-restart.sh” - although that didn’t seem to change the outcome in the slightest.

I’ve also been here, here and here (not including the tabs I already closed), but to no avail. It doesn’t matter if I run my script and it tries to execute sudo /home/[username]/root-scripts/update-and-restart.sh or if I do it myself in the console: It asks for my password.

It doesn’t seem to be the “root-scripts” folder either, since that’s just a late addition in trying to fix this problem. I’ve also run sudo visudo -c, had some permission problems, changed the files to 0440 (as instructed by visudo), everything’s parsed OK now, but I still can’t run that script without being asked for the password.

I’m completely at my wits end here. I refuse(d) to supply the password via the script, since it’s a python script and my password would be saved in basically clear text, which to me sounds like a huge security issue on a server pc. But the correct way of doing it just, straight up, ain’t doin’ it for some unknown reason.

When trying to execute /home/[username]/root-scripts/update-and-restart.sh (so without the sudo in front), I get zsh: permission denied: /home/[username]/root-scripts/update-and-restart.sh - could this have something to do with the problem or is this irrelevant?

Thanks to everyone in advance for reading and for your help.

garuda-inxi:

System:
  Kernel: 6.12.34-1-lts arch: x86_64 bits: 64 compiler: gcc v: 15.1.1
    clocksource: tsc avail: hpet,acpi_pm
    parameters: BOOT_IMAGE=/@/boot/vmlinuz-linux-lts
    root=UUID=e2c7e3c3-c687-4aea-b5c4-92149b9abd86 rw rootflags=subvol=@
    quiet resume=UUID=b48b0442-80f9-4b1d-829e-4abfe9010e8b loglevel=3 ibt=off
  Desktop: Xfce v: 4.20.1 tk: Gtk v: 3.24.48 wm: xfwm4 v: 4.20.0
    with: xfce4-panel tools: xfce4-screensaver avail: xautolock vt: 7
    dm: LightDM v: 1.32.0 Distro: Garuda base: Arch Linux
Machine:
  Type: Desktop System: GEEKOM product: AE8 v: N/A
    serial: <superuser required>
  Mobo: N/A model: AE8 serial: <superuser required> part-nu: GEEKOM AE8
    uuid: <superuser required> UEFI: American Megatrends LLC. v: 0.45
    date: 04/07/2024
CPU:
  Info: model: AMD Ryzen 7 8845HS w/ Radeon 780M Graphics bits: 64
    type: MT MCP arch: Zen 4 gen: 4 level: v4 note: check built: 2022+
    process: TSMC n5 (5nm) family: 0x19 (25) model-id: 0x75 (117) stepping: 2
    microcode: 0xA705206
  Topology: cpus: 1x dies: 1 clusters: 1 cores: 8 threads: 16 tpc: 2
    smt: enabled cache: L1: 512 KiB desc: d-8x32 KiB; i-8x32 KiB L2: 8 MiB
    desc: 8x1024 KiB L3: 16 MiB desc: 1x16 MiB
  Speed (MHz): avg: 1468 min/max: 400/5137 boost: enabled scaling:
    driver: amd-pstate-epp governor: performance cores: 1: 1468 2: 1468 3: 1468
    4: 1468 5: 1468 6: 1468 7: 1468 8: 1468 9: 1468 10: 1468 11: 1468 12: 1468
    13: 1468 14: 1468 15: 1468 16: 1468 bogomips: 121419
  Flags: avx avx2 ht lm nx pae sse sse2 sse3 sse4_1 sse4_2 sse4a ssse3 svm
  Vulnerabilities: <filter>
Graphics:
  Device-1: Advanced Micro Devices [AMD/ATI] Phoenix3 driver: amdgpu v: kernel
    arch: RDNA-3 code: Phoenix process: TSMC n4 (4nm) built: 2023+ pcie: gen: 4
    speed: 16 GT/s lanes: 16 ports: active: HDMI-A-2 empty: DP-1, DP-2, DP-3,
    DP-4, DP-5, DP-6, HDMI-A-1, Writeback-1 bus-ID: 65:00.0 chip-ID: 1002:1900
    class-ID: 0300 temp: 47.0 C
  Display: x11 server: X.Org v: 21.1.18 compositor: xfwm4 v: 4.20.0 driver:
    X: loaded: amdgpu unloaded: modesetting alternate: fbdev,vesa dri: radeonsi
    gpu: amdgpu display-ID: :0.0 screens: 1
  Screen-1: 0 s-res: 1920x1080 s-dpi: 96 s-size: 509x286mm (20.04x11.26")
    s-diag: 584mm (22.99")
  Monitor-1: HDMI-A-2 mapped: HDMI-A-1 model: Asus VG248 serial: <filter>
    built: 2014 res: mode: 1920x1080 hz: 60 scale: 100% (1) dpi: 92 gamma: 1.2
    size: 531x299mm (20.91x11.77") diag: 609mm (24") ratio: 16:9 modes:
    max: 1920x1080 min: 720x400
  API: Vulkan v: 1.4.313 layers: 7 device: 0 type: integrated-gpu name: AMD
    Radeon 780M Graphics (RADV PHOENIX) driver: mesa radv v: 25.1.4-arch1.1
    device-ID: 1002:1900 surfaces: N/A device: 1 type: cpu name: llvmpipe
    (LLVM 20.1.6 256 bits) driver: mesa llvmpipe v: 25.1.4-arch1.1 (LLVM
    20.1.6) device-ID: 10005:0000 surfaces: N/A
  API: OpenGL Message: Unable to show GL data. glxinfo is missing.
  Info: Tools: api: vulkaninfo de: xfce4-display-settings
    x11: xdpyinfo, xprop, xrandr
Audio:
  Device-1: Advanced Micro Devices [AMD/ATI] Radeon High Definition Audio
    [Rembrandt/Strix] driver: snd_hda_intel v: kernel pcie: gen: 4
    speed: 16 GT/s lanes: 16 bus-ID: 65:00.1 chip-ID: 1002:1640 class-ID: 0403
  Device-2: Advanced Micro Devices [AMD] Family 17h/19h/1ah HD Audio
    driver: snd_hda_intel v: kernel pcie: gen: 4 speed: 16 GT/s lanes: 16
    bus-ID: 65:00.6 chip-ID: 1022:15e3 class-ID: 0403
  API: ALSA v: k6.12.34-1-lts status: kernel-api tools: N/A
  Server-1: PipeWire v: 1.4.5 status: active with: 1: pipewire-pulse
    status: active 2: wireplumber status: active 3: pipewire-alsa type: plugin
    4: pw-jack type: plugin tools: pactl,pw-cat,pw-cli,wpctl
Network:
  Device-1: Realtek RTL8125 2.5GbE driver: r8169 v: kernel pcie: gen: 2
    speed: 5 GT/s lanes: 1 port: f000 bus-ID: 01:00.0 chip-ID: 10ec:8125
    class-ID: 0200
  IF: enp1s0 state: up speed: 1000 Mbps duplex: full mac: <filter>
  Device-2: MEDIATEK MT7922 802.11ax PCI Express Wireless Network Adapter
    vendor: AzureWave driver: mt7921e v: kernel pcie: gen: 2 speed: 5 GT/s
    lanes: 1 bus-ID: 02:00.0 chip-ID: 14c3:7922 class-ID: 0280
  IF: wlp2s0 state: down mac: <filter>
  Info: services: NetworkManager, nfsd, smbd, systemd-timesyncd,
    wpa_supplicant
Bluetooth:
  Device-1: IMC Networks Wireless_Device driver: btusb v: 0.8 type: USB
    rev: 2.1 speed: 480 Mb/s lanes: 1 mode: 2.0 bus-ID: 3-1:2 chip-ID: 13d3:3585
    class-ID: e001 serial: <filter>
  Report: btmgmt ID: hci0 rfk-id: 0 state: down bt-service: enabled,running
    rfk-block: hardware: no software: yes address: N/A
Drives:
  Local Storage: total: 476.94 GiB used: 25.89 GiB (5.4%)
  SMART Message: Required tool smartctl not installed. Check --recommends
  ID-1: /dev/nvme0n1 maj-min: 259:0 vendor: Kingston model: OM8PGP4512N-A0
    size: 476.94 GiB block-size: physical: 512 B logical: 512 B speed: 63.2 Gb/s
    lanes: 4 tech: SSD serial: <filter> fw-rev: ELFK7N.7 temp: 41.9 C
    scheme: GPT
Partition:
  ID-1: / raw-size: 442.94 GiB size: 442.94 GiB (100.00%)
    used: 25.89 GiB (5.8%) fs: btrfs dev: /dev/nvme0n1p2 maj-min: 259:2
  ID-2: /boot/efi raw-size: 300 MiB size: 299.4 MiB (99.80%)
    used: 616 KiB (0.2%) fs: vfat dev: /dev/nvme0n1p1 maj-min: 259:1
  ID-3: /home raw-size: 442.94 GiB size: 442.94 GiB (100.00%)
    used: 25.89 GiB (5.8%) fs: btrfs dev: /dev/nvme0n1p2 maj-min: 259:2
  ID-4: /var/log raw-size: 442.94 GiB size: 442.94 GiB (100.00%)
    used: 25.89 GiB (5.8%) fs: btrfs dev: /dev/nvme0n1p2 maj-min: 259:2
  ID-5: /var/tmp raw-size: 442.94 GiB size: 442.94 GiB (100.00%)
    used: 25.89 GiB (5.8%) fs: btrfs dev: /dev/nvme0n1p2 maj-min: 259:2
Swap:
  Kernel: swappiness: 133 (default 60) cache-pressure: 100 (default) zswap: no
  ID-1: swap-1 type: zram size: 30.63 GiB used: 0 KiB (0.0%) priority: 100
    comp: zstd avail: lzo-rle,lzo,lz4,lz4hc,deflate,842 max-streams: 16
    dev: /dev/zram0
  ID-2: swap-2 type: partition size: 33.7 GiB used: 0 KiB (0.0%)
    priority: -2 dev: /dev/nvme0n1p3 maj-min: 259:3
Sensors:
  System Temperatures: cpu: 53.0 C mobo: N/A gpu: amdgpu temp: 49.0 C
  Fan Speeds (rpm): N/A
Info:
  Memory: total: 32 GiB note: est. available: 30.63 GiB used: 7.02 GiB (22.9%)
  Processes: 461 Power: uptime: 20m states: freeze,mem,disk suspend: s2idle
    wakeups: 0 hibernate: platform avail: shutdown, reboot, suspend, test_resume
    image: 12.23 GiB services: upowerd,xfce4-power-manager Init: systemd
    v: 257 default: graphical tool: systemctl
  Packages: pm: pacman pkgs: 1583 libs: 465 tools: pamac,paru Compilers:
    gcc: 15.1.1 Shell: garuda-inxi default: Zsh v: 5.9
    running-in: xfce4-terminal inxi: 3.3.38
Garuda (2.7.2-1):
  System install date:     2024-11-01
  Last full system update: 2025-06-24
  Is partially upgraded:   No
  Relevant software:       snapper NetworkManager dracut
  Windows dual boot:       No/Undetected
  Failed units:            

TL’DR :smiley:

On your own risk, change the user name!

su
echo 'sgs ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

Not tested.

1 Like

Some notes before we continue:

ALLOWING SUDO EXECUTION VIA NOPASSWD ON A SCRIPT FILE POTENTIALLY ALLOWS FOR ROOT ESCALATION OF ARBITRARY CODE WITHOUT A PASSWORD
This is generally a very unsafe way to handle this. You should instead look into running this as a systemd service and then allowing the user account to start the systemd service without root. Alternatively, you can also do the same with pkexec. The setup is very similar for both, here’s a link regarding how to do the systemd service one: https://serverfault.com/a/841150
Here’s a link on a setup for both pkexec and rootless systemd service management that we use in the Garuda Linux project, you can use it as a reference: garuda-system-maintenance.rules · master · Garuda Linux 🦅 / Applications / Garuda System Maintenance · GitLab

You need to have the x bit set with chmod +x [file to be made executable]

You also must not forget a bash shebang.

You also should be using garuda-update --noconfirm, not pacman -Syu --noconfirm.

Also remember that sudo sees the last matching condition as the most important condition, so some entries in sudoers.d might be interfering as well, but I hope I’ve convinced you to not use sudo for this. The pkexec method is what I would recommend for your specific use case here, it’s probably the simplest to set up.

4 Likes

I was thinking about trying this too, but I don’t feel good not being asked for a password in general - thank you nonetheless!

I did that in the beginning, but since I moved the file in between, I just tried this again, unfortunately didn’t work

I had actually forgotten to put #!/bin/bash in the script, which I now added - unfortunately also no change, even after making it executable again

This I also changed for when the script works. Thanks for telling me!

I thought since I also did sudo chown root:root and sudo chmod 700 on the file and folder, this should prevent editing without a password, does it not? That’s how I understood it at least - but since this method isn’t working anyway, I’ll try the way you described and refrain from further editing the sudoers file. Thanks!

You’ll need a policy file that lets pkexec know what command you’re referring to:

https://gitlab.com/garuda-linux/applications/snapper-tools/-/blob/main/org.garuda.snapper-tools.pkexec.policy?ref_type=heads

Then you can use the bottom part of this file:
https://gitlab.com/garuda-linux/applications/garuda-system-maintenance/-/blob/master/garuda-system-maintenance.rules?ref_type=heads

You should be able to see the overlap between the two files when it comes to the ID it checks.

You’ll just replace the IDs in those files with your own command and a custom ID and you should be good to go! The files need to be in their appropriate directories of course.

2 Likes

Thank you very much for your extended help!

Unfortunately, I got no idea how pkexec and the .policy files work, no clue about action ids and all that “org.x.y.z” I’m seeing either, so I’ll have to go research that for a bit. At least I already found some directories!

I’ll research and test and I’ll mark this question solved as soon as I’m able to solve it. Thanks again!

The one-liner you shared in your post is a shell command, not a Python script. Unless there is another script?

You have given your user permission to run this script without sudo, however the script itself calls other binaries which you have not granted your user permission to run without sudo. These ones:

When you run the script, the script runs pacman -Syu and:

To accomplish what you are trying to do, you would need to give your user permission to run these binaries without entering the sudo password.

[username] ALL=(ALL) NOPASSWD: /usr/bin/pacman -Syu --noconfirm, /usr/bin/shutdown

Or the same with garuda-update:

[username] ALL=(ALL) NOPASSWD: /usr/bin/garuda-update --noconfirm, /usr/bin/shutdown

If you would like, you can give ownership of the script back to your user and take the script out of the sudoers file altogether.

To briefly address what is happening here:

This is because your user does not even have permission to look in this directory anymore. 700 is the same as rwx------, which means:

  • Owner: rwx (read, write, execute)
  • Group: --- (no permissions)
  • Others: --- (no permissions)

Since the root user is the owner now, only the root user can view these files.

A couple notes:

:warning: You should never run unattended updates.

After updating your system, you should read through the output and determine if any additional intervention is required. If there is an issue with the update you should address it before shutting the PC down.

If you suddenly can’t boot up your PC one day, you will have no idea why because you didn’t read the output from your system upgrade before shutting down.

This section of the ArchWiki has some general advice for upgrading your system carefully: System maintenance - ArchWiki

:face_with_peeking_eye: Root-owned directories and files shouldn’t be stored in the user’s home directory

In general, only stuff that is owned by your user should be stored in the user’s home directory. In this specific case it might not be causing any problems, but you can definitely mess stuff up by causing root to write in user-owned spaces.

It is conventional to store root-owned custom scripts in /usr/local/bin, which is on $PATH already (so you can just run update-and-restart.sh, instead of /path/to/script/update-and-restart.sh).

Or, the root user has their own home directory (/root) where you can store files and configs if you wish.

Or, you can probably just keep your script in the user’s home directory and give ownership back to your user. In this specific example, the script should work just as well if your user owns it instead of root.

I hope that helps, welcome to the community @Kirschi. :waving_hand:

5 Likes

Yes, there actually is another script, which I didn’t post because it only uses os.system(command) to execute the command in a shell

Damn, I was thinking if that could be my error, now I know for sure. Thanks for telling me!

So the permissions were, indeed, set too high to execute - I was guessing that might be the case but I didn’t know for sure. Thanks!

There is a way though to log the output to a file, right? Because that’s what I’ll have to do then - I got enough USBs with linux laying around to go in and fix problems myself, but you’re right: When I don’t know what went wrong, imma have to search for myself and be lucky to find what went wrong; I’ll have to auto-update the server for my own sanity unfortunately, but with a log I at least got something to start at

Luckily I already gave permissions back to user yesterday since I realized my original approach won’t work

It helped a lot, thank you very much for your help and welcoming!

Two questions remain though: Would I have to add /usr/bin/shutdown to the file or could I add /usr/bin/shutdown -r instead? I wanna give as few unnecessary permissions as possible and I’d only be using garudaupdate --noconfirm and shutdown -r 15 in my script

And: It would still be better to use pkexec, or would it? I tried to write my own .policy- and .rule-file yesterday and I wasn’t able to get it to run correctly, I was still asked for my password, although the contents looked fine to me - I’d rather be as secure as possible, but it seems I don’t know enough (yet) about linux to go down that route

Test and see if your user can run this command, or if you get prompted for a password. You may not need it to be added to the sudoers file at all.

I guess so, but I think the risk originally identified was that you were adding user-owned script file to run with no password in sudoers. If your user account were compromised, the attacker could modify the script to add /bin/bash or something to it and pop a root shell when the script is run with sudo.

The risk of just adding garuda-update --noconfirm to sudoers is appreciably less; an attacker would need root access to maliciously modify /usr/bin/garuda-update (and if they have root access, you are already hosed anyway).

Of course, like most security-related questions, it ultimately depends on your personal threat model.

If you want help getting the Polkit solution working, go ahead and paste what you have into the thread so we can take a look. Maybe someone will be able to spot a mistake, or have an idea you can try for getting it working.

4 Likes

I tested this and you’re right: The shutdown command doesn’t need sudo, so that’s a good start, thanks for telling me!

I see, makes sense;
I’ve tried adding garuda-update to the sudoers file like this:

[username] ALL=(ALL) NOPASSWD: /usr/bin/garuda-update --noconfirm

but no matter if I add or remove the --noconfirm, I somehow still get asked for my password unfortunately - any idea what I could do to circumvent that?
I’ve changed my python script to use os.system('garuda-update --noconfirm >> /home/[username]/update-logs/"$(date +"%Y-%m-%d_%H.%M.%S,%3N")".log'), has the creation of the log file become the new problem?

Thank you very much for your offer!
I’ll have to take you up on that, since I seem unable to stop running into problems.

I’ve got one file in /usr/share/polkit-1/actions/, called org.[username].update-and-restart.policy, its contents are:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
 "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
 "http://www.freedesktop.org/software/polkit/policyconfig-1.dtd">
<policyconfig>

  <action id="org.[username].update-and-restart">
    <defaults>
      <allow_any>yes</allow_any>
      <allow_inactive>yes</allow_inactive>
      <allow_active>yes</allow_active>
    </defaults>
    <annotate key="org.freedesktop.policykit.exec.path">/home/[username]/scripts/update-and-restart</annotate>
    <annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
</action>

</policyconfig>

allow_any, allow_inactive and allow_active all were at auth_admin at one point, but since I wanted to see if it’ll even work at all, I temporarily changed them to yes instead

I’ve got a second file at /etc/polkit-1/rules.d called 05-local.rules and its contents are:

polkit.addRule(function(action, subject) {
    if (action.id == "org.[username].update-and-restart" && subject.user == "[username]") {
            return polkit.Result.YES;
    }
});

I’ve had that file check if a user is in the wheel group before, but changed it to only work with my user.
It didn’t matter though because I always get a prompt to enter my password, no change to any of the files changed this unfortunately.

I might just be too inexperienced with pkexec to get it to work, but since I can’t get it to work with the sudoers file either, I’m at a loss at the moment.
Thank you very much for helping me thus far, I’m thankful for every idea!

I tested real quick and in my case it works fine.

In /etc/sudoers:

[...]
##
## User privilege specification
##
root ALL=(ALL:ALL) ALL
bluish ALL=(ALL) NOPASSWD: /usr/bin/garuda-update --noconfirm
[...]

Create a script:

micro update_script.sh
#!/bin/bash
garuda-update --noconfirm

Make it executable:

chmod +x update_script.sh

Now my user can run this script without entering a sudo password.

 ╭─bluish@quickemu in ~
 ╰─λ ./update_script.sh
:: Synchronizing package databases...
 garuda is up to date
 core is up to date
 extra                                                  7.9 MiB  20.9 MiB/s 00:00 [-----------------------------------------------] 100%
 multilib is up to date
 chaotic-aur is up to date

--> Refreshing mirrorlists using rate-mirrors, please be patient..🍵

:: Synchronizing package databases...
 garuda downloading...
 core downloading...
 extra downloading...
 multilib downloading...
 chaotic-aur downloading...
spawn pacman -Su
:: Starting full system upgrade...
 there is nothing to do

System updated! 🐧

Yes. Your user is only allowed to run this exact command:

Adding all that other stuff is a different command than what you have permitted your user to run without a password.

Continuing with my example from above, if I add a redirection command to it:

#!/bin/bash
garuda-update --noconfirm >> log.txt

Now when I run the script I am prompted for a password.

 ╭─bluish@quickemu in ~
 ╰─λ ./update_script.sh
[sudo] password for bluish:

As an additional complicating factor, sudoers only permits the exact binary path and arguments, not other shell features like redirection, pipes, or command substitution. So you can’t just add that whole whopping line to your sudoers file (actually, it wouldn’t even pass the strict syntax requirements of the file if you did).

You can try adding a wrapper script to sudoers in addition to garuda-update (and any other binaries it calls that require elevation), but as mentioned earlier this is not secure. If the user account were compromised, the attacker could exploit this configuration to get root on the box.

If you want to use pkexec, the script should be owned by root and in a root-owned directory which is not writable by other users or groups.

Try moving the script to /usr/local/bin, then update the permission set:

sudo chown root:root /usr/local/bin/update-and-restart
sudo chmod 755 /usr/local/bin/update-and-restart

Don’t forget to update the path in the policy annotation as well.

3 Likes

Fk, I’m good at complicating things, aren’t I?

Since I don’t want to put my system in danger, I did all this, even tried to change the security level in the .policy file back up (since I got the 05-local.rules file), had to change back down to just yes again, should work now but unfortunately still doesn’t;

Imma send you the contents of all my files again, expecting I must’ve missed something or done something wrong unintentionally:

/usr/local/bin/update-and-log.sh (ownership changed to root):

#!/bin/bash
garuda-update --noconfirm >> /home/[username]/update-logs/"$(date +"%Y-%m-%d_%H.%M.%S,%3N")".log

/usr/share/polkit-1/actions/org.[username].update-and-log.policy:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
 "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
 "http://www.freedesktop.org/software/polkit/policyconfig-1.dtd">
<policyconfig>

  <action id="org.[username].update-and-log">
    <defaults>
      <allow_any>yes</allow_any>
      <allow_inactive>yes</allow_inactive>
      <allow_active>yes</allow_active>
    </defaults>
    <annotate key="org.freedesktop.policykit.exec.path">/usr/local/bin/update-and-log.sh</annotate>
    <annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
</action>

</policyconfig>

/etc/polkit-1/rules.d/05-local.rules:

polkit.addRule(function(action, subject) {
    if (action.id == "org.[username].update-and-log" && subject.user == "[username]") {
            return polkit.Result.YES;
    }
});

And my python script tries to run it like this:

logger.log(f"Update command finished with code {os.system('/usr/local/bin/update-and-log.sh')}.")

Thank you so much for continuously helping me, I can’t imagine how annoying and/or exhausting that must be, especially since so much goes wrong and I’ve been changing small things in between.

Since this is becoming increasingly challenging, I’m gonna try to explain my setup a bit:

The python script I’m working on will be run on 3 devices:

  • My server-pc (whose garuda-inxi I sent in my first message and where I’m testing everything you help me with)
  • my personal computer (where it won’t update the system automatically though, this is just so I can monitor the other 2 devices in case something goes wrong)
  • my raspberry pi 5

What I intend to do is I want to host gaming servers on my server-pc, while the raspberry pi 5 puts a website to one of my domains which will show how busy the server is, which game-servers are online and which are not, how much CPU is being used and how much RAM is being used.

The raspberry pi 5 is supposed to get this information around every minute from the server-pc via my python script and update the website.

Additionally, all 3 devices are supposed to monitor each other and if one of them stops responding without a stated reason (or takes too long to restart after an update), at least one device will know and try to inform me about that.

All traffic generated by my script is local though, the local IPs of all 3 devices are hardcoded and every other IP (even the external IPs of these 3 devices) will be ignored.

Additionally, I’m using AMP (by CubeCoders) to host said game-servers, which means they always run on their own user called amp, which doesn’t have sudo permissions afaik.

My script is running as my user though (whose name I replaced with [username] everywhere so far), so the game-servers and my script should have no actual overlap.

The question now is: How secure do I have to / should I be?

The game-servers are either mostly or exclusively not going to be public, but rather private and password protected servers, just so my friends and I can play together.

I’ll still have to be extra careful with my raspberry pi 5, since that’ll have port 80 open to provide the website.

Forwarded ports to server-pc are only the specific ports needed for the specific games of which I intend to provide game-servers though. So the server-pc should (hopefully) be mostly secure.

What do you think? How cautious do I have to be? Did I forget important details and/or do you have questions concerning my setup? And what might I have done wrong that pkexec just won’t work?

Thank you sincerely in advance.

Polkit only works when the command is invoked with pkexec.

You’re currently doing:

os.system('/usr/local/bin/update-and-log.sh')

But that bypasses Polkit entirely, it just executes the script directly.

Instead, run the script with pkexec like this:

os.system('pkexec /usr/local/bin/update-and-log.sh')

That is a somewhat unanswerable question! No one can really define your threat model for you. You are the only one who knows how much of a risk your setup poses.

If I were to offer only one single piece of advice for hardening a stock Garuda Linux install, I would say set up a software firewall like firewalld. A firewall can make your setup a lot more secure with not very much extra work or complication involved. firewalld in particular is fairly easy to get started with and pretty simple to understand.

For your game server you probably don’t need to make it Fort Knox by any means, but if you want to learn more about different ways you can harden your system then this article is a great place to start: Security - ArchWiki

Port 80 is HTTP, which is not encrypted. I wouldn’t serve that over the internet if it is a page that people need to interact with (like if they need to log in or enter any information that you don’t want people to be able to see). You should get a certificate for encrypting the traffic and put up your website on 443.

It’s pretty easy to get a Let’s Encrypt certificate, especially with Certbot which takes care of a lot of the nitty gritty stuff for you. It can even do renewals and everything.

Certbot can be installed a thousand different ways. Check the docs or forums for whatever OS you are using on the Raspberry Pi to see what solutions other people are using for this.

Overall it sounds like a pretty cool setup!

3 Likes

Oh my god, that’s all it took. It finally works now, thank you so very much!!

I see, I’ll check that out right away! I already have Portmaster installed, so I’ll have to check if that’s enough and/or if firewalld and Portmaster might clash, but I’m sure I’ll be able to figure that out. :slight_smile:

Luckily, the website the raspberry pi 5 will provide is supposed to be as simple as it gets: One singular page, no logins, no other pages, just some technical data on a single page. But since a) it actually sounds pretty interesting and b) I like to learn new stuff, I’ll try to make it https right away. Thanks for the hint!

Thanks! And thanks to you I’ll now be able to actually make it a thing! You have my utmost gratitude. :slight_smile:

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.