Been looking at this guide to make a cron job:
https://docs.opnsense.org/development/backend/configd.html
I would like to make a job that run the script specified in the parameter field in the gui.
I've tried to create this configd file:
[start]
command:/bin/csh
parameters:-c '%s'
type:script
description:run custom script
message:run script
Restarted configd:
service configd restart
Created the job in the gui:
(https://forum.opnsense.org/index.php?action=dlattach;topic=11798.0;attach=6365;image)
But it seems not to run :-( ?
a) don't do this, command is supposed to be the command you want to run---not taking an arbitrary command and executing it as root. ;)
command: /tmp/UpdateBlacklist
b) if you must use
command: /bin/csh -c
parameters:%s
c) please don't
Cheers,
Franco
Took me a lot of time to figure this out, as the "parameter" means just ONE parameter. And "parameters" means more parameters, but must be also match in quantity. So I wasted time with bash -c / env / -- all that stuff not knowing one parameter is parsed.
Luckily, the check is only for less parameters, not more:
[reload]
command:/runner.sh
parameters:%s %s %s %s %s %s %s %s %s %s
type:script_output
message:running command "%s %s %s %s %s %s %s %s %s %s"
description:Run custom command 👍
So let's make a script (runner.sh) that will:
- run anything we the people want (as sadly there's no custom command in GUI ???)
- accept any number of parameters
- log the output to the file (as sadly there's no tracking of scheduled commands output :()
- cascade the exit code
- safer nonroot execution by default, by the admin user everyone sets up to avoid OpenWRT-like root login to the GUI
- allow changing the user (no blocking prompt in case of root, once user selection will be in the GUI)
- measure the execution time
user=myadminuser
if [ "$(echo $1 | cut -b 1)" == "@" ]; then
user=$(echo $1 | cut -b 2-16)
shift
fi
echo "Executing '$@' as $user" >> $0.log
sec=$(date +%s)
sudo -n -u $user $@ >> $0.log
exitcode=$?
sec=$(expr $(date +%s) - $sec)
echo "Finished in $sec sec and $exitcode code" >> $0.log
exit $exitcode
Do
Quoteservice configd restart
and now add a custom command and in the parameters field add your command:
Run with default user:
- e.g. touch /home/myadminuser/testfile
Run with other user (first parameter will be the user in @USER format):
- e.g. @seconduser touch /home/seconduser/testfile
Run with root user (first parameter will be the user in @USER format; if one day user can be selected in the GUI, allow the command in sudoers):
- e.g. @root touch /root/testfile
Welcome changes in the GUI:
- show crontabs per user
- allow choosing the user in the schedule
- allow playing the command instantly
- capture the command output for a proper audit
- allow custom command to avoid creating actions_MYSCRIPT.conf files or scripts like this
- capture every user's applied change in the GUI for a proper audit
I can see there is some drift between expectation and reality. It's impossible to pass a full shell command in a single batch, which is a bit strange in my opinion as it silently tries to pass all the characters down as whitespace-separated parameters. But to be honest "%s %s %s %s [...]" is totally silly.
Not sure how to clean this up. We need to talk about it internally.
> - show crontabs per user
Why? GUI Cron jobs are enforced through configd so nobody is the only relevant user.
> - accept any number of parameters
Why? You can use the script do do that. At least you haven't posted a use case for passing multiple different arguments multiple times.
> - log the output to the file
Why? The script has to do it. crontab does not return any output for its commands.
> - safer nonroot execution by default
Why? The default is secure. It's "nobody".
> - allow changing the user
Why? As I said the nobody-backed configd execution is the only one that counts. You can set up the other crontabs for users to whatever you like on the file system or write a custom plugin for it if you like a GUI.
> - capture every user's applied change in the GUI for a proper audit
Why^H^H^HThat's what we are doing? System: Configuration: History.
And don't waste time with bash on BSD please. ;)
Cheers,
Franco
A generic crontab facility that does not in any way restrict what one can run, would be an improvement, nonetheless. Look at TrueNAS > Tasks for a well designed UI example.
The solution worked for me and it means quick setup of jobs is possible. That's what I want in every solution. I was using some holes in your python code. Not silly at all, but smart, given circumstances. It was indeed running as root. I test log as nobody in a shell, and it's restricted as it should, and wouldn't be able to perform some of the commands. You can set default user as it, but it's pointless and just limits the output grab. No reason why cron or any scheduler wouldn't log, unless someone proactively doesn't want that valuable output (crontab -l).
I noticed the diff in History, it's good and sometimes even textual. I'm traversing History+Audit+Backend+General+WebUI together to get the picture. I don't see a service stop action anywhere, but the config changes can be traced by looking at the paths. Thanks.
Regarding scheduler, compared to other distros and solutions (or "appliances" like a TrueNAS Core fundamentalist would say) like TrueNAS, DSM, QTS, pfsense, ipfire etc. There's no scheduler in QTS too to my shock (fixed that too), but solutions often do have a UI scheduler with custom commands. TrueNAS, OpenWRT, pfSense have a fairly good scheduler. DSM offers the proper one: selects user, type of commands, carefully captures historical logs, can throw notifications into UI, can send emails based on exit code, play sound. Great example. Hope I can achieve that in Opnsense too (would love to find the notification routine to bake it swiftly). So I deem the suggestions as valid ;)