systemd service file and CapabilitiesBoundingSet - linux

I am trying to reduce the root user capabilities by using the CapabilityBoundingSet option in my service file. Anyway, it seems I cannot prevent root from writing a file.
For example, with this service file:
$ cat test.service
[Unit]
Description=Test
After=basic.target
[Service]
ExecStart=/bin/sh -c "echo 172 > /target"
CapabilityBoundingSet=CAP_DAC_READ_SEARCH
so, if I have this original file:
$ cat /target
I am the original file
$ systemctl start test.service
$ cat /target
172
$ whoami
root
My kernel version is 3.1.10.
I have also tried with an empty set, or other capabilities, but is not working.. what could be wrong?

My problem was simple: the file I was trying to modify is owned by root, and this is why I am able to perform the change. If I change the owner, then I am no more allowed to modify it.

Related

ubuntu 18 custom service does not load

ubuntu 18
I have created a custom service at /etc/systemd/system/mycustomservice.service
and enable it : sudo systemctl enable /etc/systemd/system/mycustomservice.service
but the service does not load at start up, the content is:
[Unit]
After=mysql.service
[Service]
ExecStart=/home/myuser/runupdate.sh
[Install]
WantedBy=default.target
I try to execute the file /home/myuser/runupdate.sh without any issue
the permission of
/home/myuser/runupdate.sh is -rwxr--r--
/etc/systemd/system/mycustomservice.service is -rw-rw-r--
Please advise, thank you!
Systemd will need to know how to execute the script and what shell to use, hence there are two options Add:
#!/bin/bash
or
#!/bin/sh
to the top line of the script depending on the shell you are using. Alternatively, you can use:
ExecStart=/bin/bash -c /home/myuser/runupdate.sh

How do I run a python script on boot on Google Coral?

I have written a simple test code in python to toggle two of the I/O pins on and off every few seconds. I would like to be able to run this code whenever the board powers on so that I don't need to bring a keyboard, mouse, and monitor everywhere I want to run the simple test. How do I do this on Mendel OS on a google coral?
On Mendel OS, your systemd service should look like this:
myservice.service:
[Unit]
Description=Example systemd service.
After=weston.target
[Service]
Environment=DISPLAY=:0
PAMName=login
Type=simple
User=mendel
WorkingDirectory=/home/mendel
ExecStart=/bin/bash /usr/bin/test_service.sh
Restart=always
[Install]
WantedBy=multi-user.target
Regarding how to create a service and how to deploy it, you can follow this article.
Change 'ExecStart' line with your python file that you want to get executed.
Using crontab has been working consistently for me, you may want to add a time.sleep in the beginning of your python file
edit crontab
crontab -e
select nano editor
add
#reboot sudo python3 <path_to_your_script>
I had same issue.
This might be useful for you.
https://askubuntu.com/questions/919054/how-do-i-run-a-single-command-at-startup-using-systemd
I was able to add new service into systemd, but the script didn't run properly, but perhaps this won't be your problem.
I copied the instruction from the Nam Vu's note in Gist. This is like the details of Nanoj's answer above.
This is an example of starting a systemd object detection service on boot on the Coral Dev Board.
create a file called "detects.service" with similar with the following contents:
[Unit]
Description=systemd object detection service
After=weston.target
[Service]
PAMName=login
Type=simple
User=mendel
WorkingDirectory=/home/mendel
Environment=DISPLAY=:0
ExecStart=/bin/bash /usr/bin/detect_service.sh
Restart=always
[Install]
WantedBy=multi-user.target
Copy the file to "/lib/systemd/system/detects.service"
$ sudo cp -i detects.service /lib/systemd/system
Create a file called "detect_service.sh" with similar to following content:
edgetpu_detect --model fullpath/mobilenet_ssd_v2_coco_quant_postprocess_edgetpu.tflite --label fullpath/coco_labels.txt
or
python detect.py --model fullpath/mobilenet_ssd_v2_coco_quant_postprocess_edgetpu.tflite --label fullpath/coco_labels.txt
Make it executable and copy it to "/usr/bin":
$ sudo chmod u+x detect_service.sh
$ sudo cp -i detect_service.sh /usr/bin
enable the service with the systemctl command:
$ sudo systemctl enable detects.service
This would be useful when your python code called the Google "gstreamer code" example. The gstreamer code not able to be executed with sudo command, so you may not able to use with "sudo crontab -e" method for example Danny Dasilva's answer above.

Shell complains about file permissions when creating a config file

I'm not completely sure if I should ask here, over at the Unix forums or somewhere completely different but, here we go.
I'm using Packer to create a set of images (running Debian 8) for AWS and GCE, and during this process I want to install HAProxy and set up a config file for it. The image building and package installation goes smooth, but I'm having problems with file permissions when I'm trying to either create the config file or overwrite the existing one.
My Packer Shell Provisioner runs a set of scripts as the user admin (as far as I know I can't SSH into this setup with root), where as the one I'm having trouble with looks like this:
#!/bin/bash
# Install HAProxy
sudo apt-get update
sudo apt-get install -y haproxy
# Create backup of default config file
sudo mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
# Write content over to new config file
OLDIFS=$IFS
IFS=''
sudo cat << EOF > /etc/haproxy/haproxy.cfg
# Content line 1
# Content line 2
# (...)
EOF
IFS=$OLDIFS
The log output gives me this error: /tmp/script_6508.sh: line 17: /etc/haproxy/haproxy.cfg: Permission denied
I've also thought of having a premade config file moved over to the newly created image, but I'm not sure how to do that. And that wouldn't work without writing permissions either, right?
So, does anyone know how I can set up my Shell script to fix this? Or if there is another viable solution?
The problem with the script is the line
sudo cat << EOF > /etc/haproxy/haproxy.cfg
The redirection to /etc/haproxy/haproxy.cfg happens before sudo is called, and thus requires that the file can be created and written to by whatever user is running the script.
Your idea of changing the permissions and ownership of that file solves this issue by making the file writable by the user running the script, but really, you seem to be executing every single line of the script as root in any case, so why not just drop all the sudos altogether and run the whole thing as root?
$ sudo myscript.sh # executed by the 'admin' user
EDIT: Since this script isn't run on the target machine manually, there are two solutions:
Go with the chmod solution.
Write the config file to a temporary file and move it with sudo.
The second solution involves changing the line
sudo cat << EOF > /etc/haproxy/haproxy.cfg
to
cat <<EOF >/tmp/haproxy.cfg.tmp
and then after the EOF further down
sudo cp /tmp/haproxy.cfg.tmp /etc/haproxy/haproxy.cfg
rm -f /tmp/haproxy.cfg.tmp
This is arguably "cleaner" than messing around with file permissions.
As Kusalananda pointed out, the problem is that output redirection happens in the shell which calls sudo.
In such situations I generally use this simple trick:
TMPFILE=`tempfile`
cat << EOF > $TMPFILE
# Content line 1
# Content line 2
# (...)
EOF
sudo cp $TMPFILE /etc/haproxy/haproxy.cfg
rm $TMPFILE
I create a temp file and put content there (no need for sudo for that step). And then with sudo, copy the temp file to the final destination. Finally: delete the temp file. (I use the copy to make the file ownership to belong to the root; the move would keep the user/group of the calling user. Alternatively, one can use the chmod/chown to fix the permissions.)
The solution to this was quite simple, and 123's comment gave me the right answer: chown
By changing this
sudo mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
to this
sudo chown admin /etc/haproxy/haproxy.cfg
sudo chmod 644 /etc/haproxy/haproxy.cfg
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
I now have both the permissions and ownership I need for my setup to work.
EDIT
Other users have provided better and more viable solutions, as well as answered some issues around my script.

CoreOS - Cloud-Config not saving file

I'm trying to write an "initial" cloud-config file that does a bit of setup before my default Cloud-Config file replaces it and takes over. This is what it looks like, however whenever it runs the "clustersetup.service", it can't find the clustersetup.sh file that was supposed to save. Course if I run this from a terminal it works just fine. What am I doing wrong?
#cloud-config
coreos:
etcd:
addr: $private_ipv4:4001
peer-addr: $private_ipv4:7001
fleet:
public-ip: $private_ipv4
units:
- name: clustersetup.service
command: start
content: |
[Unit]
Description=Cluster Setup
[Service]
ExecStartPre=/usr/bin/wget -q http://10.0.2.2:8080/clustersetup.sh -O ~/clustersetup.sh
ExecStart=/usr/bin/bash ~/clustersetup.sh
ExecStop=/usr/bin/bash
Paths specified by systemd cannot be relative. Try this again specifying the full path /home/core/clustersetup.sh.
In my distribution (ubuntu), bash is in /bin. One thing you could do is:
ExecStartPre=/bin/bash -c '/usr/bin/wget -q http://10.0.2.2:8080/clustersetup.sh -O ~/clustersetup.sh'
ExecStart=/bin/bash -c ~/clustersetup.sh'
I think you will get the proper expansion of the ~ when pushing it through the shell. However, ~ will be relative to the process id executing the script (I don't know for certain that is core). If you wanted to be sure, you could:
ExecStartPre=/bin/bash -c '/usr/bin/wget -q http://10.0.2.2:8080/clustersetup.sh -O ~core/clustersetup.sh'
ExecStart=/bin/bash -c ~core/clustersetup.sh'
I haven't tested this. I agree with #Brian in that the explicit path would be a better idea. In general it is best not to get a shell involved with execution.

Upstart - unable ro read /etc/shadow unelss sudo

In the following script in Upstart, I'm unable to read /etc/shadow in pre-script phase, unless I use $(echo mypass | sudo -S cat /etc/shadow | grep myusername)
The script works fine if I provide my sudo pass, but I'm wondering if there is a way to do this without having to write my pass in the conf file?
node-example.conf
description "Starting Node with Upstart and Forever"
start on filesystem or runlevel [2345]
stop on runlevel [06]
expect fork
respawn
respawn limit 5 30
console output
setuid myusername
env HOME=/home/myusername
env ARGS_FILE=/etc/shadow
. /etc/shadow
script
cd $HOME
exec forever start -a -l /tmp/forever.log -o /tmp/forever.stdout.log -e /tmp/forever.stderr.log --watch --watchDirectory /home/myusername/myapp/server /home/myusername/myapp/server/server.js
end script
pre-start script
ori='myusername:$6$P...'
# cur=$(echo mypass | sudo -S cat /etc/shadow | grep myusername) -> this works
cur=$(cat $ARGS_FILE | grep myusername) -> this doesn't work
if [ "$ori" = "$cur" ]
then encfs code
else rm -rf somefile
fi
end script
There is a good reason why shadow is accessible only by root: Anybody who can change it can easily get root access. Given some time, oldish MD5 passwords can even be calculated. Bottom line: don't fiddle with /etc/shadow unless you absolutely have to. Basically, this reduces the need to changing passwords.
I am not too sure what you are trying to achieve, but doing a grep $username /etc/passwd should give you all information you need except for the hashed password.
And upstart scripts don't have to be run as root. It is perfectly fine to run a daemon as whichever user. This is achieved using the setuid stanza (there is an according setgid). So you install the service as root and let it drop privileges.
Another option would be to use a user-job. Make sure you enable user-jobs.
Whatever you do : Don't fiddle with /etc/shadow!

Resources