setsockopt for systemd unit - error: "Operation not permited" - systemd

I'm trying to run BindToInterface in a script as part of a systemd service that runs under its own separate user.
The service file looks like this:
[Unit]
Description=Deluge Bittorrent Client Daemon
Documentation=man:deluged
After=network-online.target mnt-storage.mount
Requires=mnt-storage.mount
BindsTo=mnt-storage.mount
[Service]
Type=simple
UMask=000
ExecStart=/bin/bash /media/bti/deluged.sh
Restart=on-failure
# Time to wait before forcefully stopped.
TimeoutStopSec=300
[Install]
WantedBy=multi-user.target
The script is as follows:
#!/bin/bash
BIND_INTERFACE=eno2 DNS_OVERRIDE_IP=8.8.8.8 BIND_EXCLUDE=127.0.0.1,192.168. LD_PRELOAD=/media/bti/bindToInterface.so /usr/bin/deluged -d -l /var/log/deluge/daemon.log -L warning
when executing:
systemctl status deluged
I get the following output:
bash[503711]: setsockopt: Operation not permitted
Is there a way to run your tool without elevated privileges? How would "setsockopt" be run for a systemd unit without elevated privileges
Thanks

Linux as a strict limitation: Only root can open ports below 1024. If your daemon is doing this, you can only do it by root.

Related

RaspberryPi - error when trying to reference a user directory on boot service?

I am trying to reference a user directory on boot for my raspberry pi 4 32 bit bullseye desktop with a service setup on systemctl. This service maps my ip address to an .env file. The process is as follows:
setup.service attempts to create a .env file using setup.sh with my current ip address
setup.timer fires off the service 1 minute after boot
This works flawlessly when my setup.sh looks like this:
...
destdir=/home/me/my_directory/.env
echo "REACT_APP_MACHINE_HOST_IP=$REACT_APP_MACHINE_HOST_IP" > "$destdir"
But when I try to replace the value of "me" with the machine user in order to make this more transferrable I get this error on boot:
...
destdir=/home/"$USER"/my_directory/.env
echo "REACT_APP_MACHINE_HOST_IP=$REACT_APP_MACHINE_HOST_IP" > "$destdir"
/home//my_directory/.env does not exist...
Not sure where I'm off because I made a quick test.sh script and the following echoed the directory correctly:
#!/bin/bash
mydir=/home/"$USER"/my_directory/
echo $mydir
It seems like no user is recognized. I am assuming this has something to do with system running on root? Or is my syntax off?
EDIT:
My setup.service below:
[Unit]
Description=setup mcw
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/setup.sh
[Install]
WantedBy=multi-user.target
And what I run to automate aka automate.sh:
# copy ip file to task and authorize
sudo cp /home/${USER}/my_directory/setup.sh /usr/local/bin/setup.sh
sudo chmod 744 /usr/local/bin/setup.sh
# create setup files
sudo cp /home/${USER}/my_directory/setup.service /etc/systemd/system/setup.service
sudo cp /home/${USER}/my_directory/setup.timer /etc/systemd/system/setup.timer
# add permissions for the service
sudo chmod 644 /etc/systemd/system/setup.service
# setup and reload systemctl
sudo systemctl daemon-reload
sudo systemctl enable setup.timer
sudo systemctl start setup.timer

How to run bash script as background process on system forever?

I have a script(sync.sh) which runs a while loop inside for syncing.
#!/bin/bash
while :
do
#my PHP scripts runs parallel
wait
sleep 60
done
I want to run this script independently forever in my vm.
I know I can run this sh file as a background process by using nohup, disown command.
But what I want to know is? How can I run this .sh file on system restart or it process is killed. How to start .sh file automatically without terminal command in Ubuntu VM.(Like we have starting Apache, MySQL services on system start)
Thanks in advance.
If you're using systemD, you should create a service for your script sync.sh, this file will be:
/lib/systemd/system/sync.service
You can edit this file (with 'root' or 'sudo' privileges) so it contains:
[Unit]
Description=My Shell Script for Sync
[Service]
ExecStart=/usr/bin/sync.sh
[Install]
WantedBy=multi-user.target
Then, you re-load your systemD daemon (so it knows that a service has been added) :
sudo systemctl daemon-reload
Then you can enable your service (so it will be launched at every system start:
sudo systemctl enable sync.service
Then you can start it manually so it will be started right away, not waiting for the next system restart :
sudo systemctl start sync.service
(of course, you can change the name of your service and it's not necessarily called "sync.service"

is it possible to run shell command inside the service

under /etc/systemd/system , we have the service - cc_check.service
in the service we activate the script - /home/cc_start_daemon.sh
as the following
ExecStart=/home/cc_start_daemon.sh
is it possible inside the service to add a shell command - bash /home/second_try.sh as
[Service]
Restart=on-failure
StartLimitInterval=5min
StartLimitBurst=4
LimitMEMLOCK=infinity
LimitNOFILE=65535
Type=simple
ExecStart=/home/cc_start_daemon.sh
bash /home/second_try.sh
[Install]
WantedBy=multi-user.target
the target is to run another script after - /home/cc_start_daemon.sh
That is not valid SystemD syntax, so I would just make a new script that runs both
#!/bin/bash
/home/cc_start_daemon.sh
/home/second_try.sh

Running Binary on EC2 Instance Start

I'm trying to run meilisearch on an ec2 instance, but having a lot of trouble getting it to start automatically and was wondering if somebody might be able to assist.
https://docs.meilisearch.com/guides/advanced_guides/installation.html#usage
My current user data is the following, but I'm not setting the env variable be set and the process is then starting up listening on a different port. Is there another way to set env variables in an ec2 start up script? Or is there something else I'm doing wrong?
#!/bin/bash
export MEILI_HTTP_ADDR="0.0.0.0:80"
curl -L https://install.meilisearch.com | sh
# Write systemd unit file
cat << EOF > /etc/systemd/system/meilisearch#ecs-agent.service
[Unit]
Description=Meilisearch Service %I
[Service]
Restart=always
ExecStart=/meilisearch
[Install]
WantedBy=default.target
EOF
systemctl enable meilisearch#ecs-agent.service
systemctl start meilisearch#ecs-agent.service
I think that the env variable that you export on line 2 of your script is not being used by Systemd.
Instead, you should provide the env variable in the service file like this:
[Service]
Restart=always
ExecStart=/meilisearch
Environment=MEILI_HTTP_ADDR=0.0.0.0:80
Please let me know if that solves your problem :)

systemd: start service after the previous one have finished

I have installed certbot, and certbot makes it's own systemd service file "certbot.service" for auto cert renew, which is started trough a .timer file once a day.
After this "certbot.service" is sucessfully executed I like to execute a second one ("cert-copy-after-certbot.service") that copys the certificate to another place.
Currently my setting looks like this:
"certbot.service" (gernerated by certbot):
pi#raspberrypi:/lib/systemd/system $ cat certbot.service
[Unit]
Description=Certbot
Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
Documentation=https://letsencrypt.readthedocs.io/en/latest/
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot -q renew
PrivateTmp=true
"cert-copy-after-certbot.service":
pi#raspberrypi:/etc/systemd/system $ cat cert-copy-after-certbot.service
[Unit]
Description=crt update after certbot has run
Wants=certbot.service
After=certbot.service
[Service]
Type=simple
ExecStart=/bin/sh -c "cat /etc/letsencrypt/live/<mydomain>/privkey.pem /etc/letsencrypt/live/<mydomain>/fullchain.pem > /etc/ejabberd/ejabberd.pem"
If i run this files with:
systemctl start <unitname>
Both services are working.
But when I start certbot with "systemctl start certbot" and check
systemctl status cert-copy-after-certbot
the cert-copy-after-certbot.service didn't run.
Did i configured something wrong?
I found the solution, so here the answer just if someone has the same issue.
The problem is that the "certbot.service" unit don't know about "cert-copy-after-certbot.service". So if "certbot.service" is called no one calls the inactive "cert-copy-after-certbot.service" because the "Wants=" is never executed.
So if you don't wan't to alter the "certbot.service" unit (with "Wants=cert-copy-after-certbot.service", you can do the following.
Add an additional [Install] section in "cert-copy-after-certbot.service", with a line "WantedBy=cerbot.service". So that the file look like this:
pi#raspberrypi:/etc/systemd/system $ cat cert-copy-after-certbot.service
[Unit]
Description=crt update after certbot has run
After=certbot.service
[Service]
Type=simple
ExecStart=/bin/sh -c "cat /etc/letsencrypt/live/<mydomain>/privkey.pem/etc/letsencrypt/live/<mydomain>/fullchain.pem > /etc/ejabberd/ejabberd.pem"
[Install]
WantedBy=certbot.service
An install section requires an enable or disable call by systemctl (or start or stop for temporary testing).
systemctl enable cert-copy-after-certbot
This [Install] section will create a symbolic link as soon as you enable the unit that informs the systemd deamon if "certbot.service" is called, he have to call "cert-copy-after-certbot.service" to. (And the "After=" in the unit section tells systemd the row in which the sould called, without it, both units would run simultaneously)
You might find that cert-copy-after-certbot.service is started before cerbot.service is complete unless you also set RemainAfterExit=yes in cerbot.service

Resources