Sending CLI email using Webmin

SYSTEM INFORMATION
OS type and version Debian 12
Webmin version 2.303

Hello,
Tired of receiving hundreds of email from Fail2Ban I decided to try some scripts in order to build a daily digest of banned IP’s that would be sent from the server.

I have almost everything up and running using /usr/sbin/sendmail but I would like to use Webmin to send these emails using the built-in notification email parameters so I can use a specific SMTP.

IA suggested to install sendemail because sendmail.pl wich is supposedly included with Webmin is nowhere to be seen (should be in /usr/share/webmin/sendmail.pl, I have a /usr/share/webmin/sendmail-lib.pl which apparently I cannot use …).

My question is about knowing if there is a script accessible lib to send email using the parameters defined in “Webmin Configuration → Sending Email” … sendemail would allow me to specify a SMTP server but I’d rather use the internals of Webmin so all my notifications are sent the same way through the same SMTP …

Any idea welcome, thanks …
Pierre

I don’t know what IA is, but it lied to you. I don’t know what sendmail.pl is supposed to be, but it is not supposedly included in Webmin. There is no such file in Webmin, and there never has been.

That also does not exist, but /usr/share/webmin/sendmail/sendmail-lib.pl does. It is a library of functions for the Sendmail Webmin module. Unless you’re using Sendmail (the MTA, not the CLI sendmail command), you’d have no reason to use it.

If you have Postfix or Sendmail installed (and maybe other MTAs, I don’t know), you have a mail injection command called sendmail which allows sending mail from the command line using the local mail server (assuming you have a local mail server configured).

But, you can also send mail the way Webmin sends it (using mailboxes-lib.pl, generally, I think). There are many examples in Webmin of how email gets sent. e.g. this one sends email when the user is approaching their quota:

Or here, which may be simpler to follow since it’s just a few lines (and is very recent code, so it’s using somewhat streamlined API calls): webmin/forgot_send.cgi at f5ff544439bd79cf35b35b6e05074711b23c423c · webmin/webmin · GitHub

Another example in the Upload/Download module where it’s wrapped in a function (though this feels kinda clunky…it’s a wrapper for an already pretty simple function…feels weird to make a function for something that only takes two or three lines of code):

1 Like

Hi,
Thks for taking the time to answer.

IA=AI … sorry, so just chatgpt wich seems to be pretty sure I should have a sendmail.pl … I don’t know why …

Ok for sendmail-lib.pl, I missed one “sendmail” in the path, that’s the one I was talking about.

Ok I will try with perl instead of bash using the forgot_send.cgi example as a model and will report here :slight_smile:

Pierre

LLMs hallucinate. They’ll waste a lot of your time, if you think something they say “should” be true. And, they’ll always answer…they don’t have the ability to say, “I don’t know” or “that’s not the right way to solve the problem” or “there is no such feature”.

If you want to use bash, just use sendmail (the mail injection command, not the MTA). Using it is a one-liner if the mail server is correctly configured (but if you’re making software for other users, you probably can’t count on the mail server being properly configured, which is why Webmin uses quite a bit more code to do it).

e.g. you can do something like:

sendmail -f from-user@example.tld to-user@example.tld < message.txt

Or, if you’re dynamically constructing the message in your script, you can do something like:

cat <<EOF | sendmail -t
To: to-user@example.tld
Subject: Testing
From: from-user@example.tld

Tested!
EOF

There are many ways to send email from the command line. You could even send it without involving a mail server, it’s only a few lines of code to connect and send a message, it can be done with telnet or nc (netcat) and nothing else. SMTP is a stupidly simple protocol, though to achieve good delivery, it generally should go through a well-configured MTA or relay, so it gets SPF, DKIM, etc. right.

1 Like

That’s my goal, I want my script to use the SMTP parameters defined in webmin Configuration so SPF/DKIM/Dmarc are properly set …
If I use sendmail as you say, is it using the SMTP defined in the webmin config ? (My guess is no …).
Pierre.

How about a simple script to scan the fail2ban.log and send a list of IP from that?

sendmail injects mail into the outgoing mail queue of the local MTA. That’s usually a great way to send email.

Webmin will consider a lot of options for sending mail, but if the system has a sendmail, I believe it will generally use that. webmin/mailboxes/boxes-lib.pl at 5395dc57fe1b85f35e91ca9ece6506b92c913b1a · webmin/webmin · GitHub

Webmin has other ways to send email, but if you have sendmail and a correctly configured local mail server, that is the best way to send email. But, again, Webmin does not assume the user has a correctly configured local email server and offers others ways to send email. That said, if the server doesn’t have a correctly configured mail local mail server, Webmin may not be able to reliably send email without jumping through some hoops to configure it in a way that’ll work (which you can’t bet on users having done…mail and users are both tricky).

But, anyway, there are many examples of sending mail using the Webmin functions. If you want to use those, you just need to jump in and start reading the code.

At this time my script is up and running using sendmail (after a long fight) but as I said, my main question was about using an external SMTP. I thought the simple way would be to use the Webmin Send Email configuration but that seems not so easy.

ChatGPT did propose me (sorry I’m not that fluent with mail or perl technicalities ) with a perl script (the current one working is bash) but we couldn’t succeed after hours of testing to make that script work as a standalone script, last error we couldn’t suppress was “Failed to determine Webmin root from SERVER_ROOT, SCRIPT_FILENAME or the full command line” even though we did try to define all the proper variables …

Our last attempt started with (thats before the script for the Fail2ban log parsing):

#!/usr/bin/perl

use strict;
use warnings;
use POSIX qw(strftime);

# Configuration manuelle de l'environnement Webmin
$ENV{'WEBMIN_CONFIG'} ||= '/etc/webmin';
$ENV{'WEBMIN_VAR'}    ||= '/var/webmin';
$ENV{'WEBMIN_ROOT'}   ||= '/usr/share/webmin';
$ENV{'SCRIPT_NAME'}   ||= $0;

# Initialisation Webmin sans passer par la validation CGI
use lib '/usr/share/webmin';
use WebminCore;

# Forcer un mode autonome pour contourner les dépendances sur CGI et l’interface Webmin
$no_acl_check = 1;
$gconfig{'standalone'} = 1;

init_config();   # Initialiser la config Webmin sans tests supplémentaires

Anyway I will continue digging :slight_smile: Pierre

Yeah, if your scripts are not being started by Webmin, it’s not immediately obvious how to make them load Webmin code in a way that works. But, you only need to specify the config path, everything else is specified in there.

But, we have a structure for commands that work with Webmin, as well, in the webmin command. That allows you to bundle scripts with a module in the bin directory (within your module, you can’t modify the Webmin bin dir safely) and webmin can then run them in the context of Webmin. webmin/bin at master · webmin/webmin · GitHub

I made the webmin command because I wanted to be able to run Webmin functions from the command line more easily and in a standard way. Files in a module bin directory can be run something like webmin modulename-scriptname I think (though it’s been a long time since I implemented that part of it, I know it’s in there).

But, also we have a lot of examples in Virtualmin of using Webmin functions in the Virtualmin installer config step (GitHub - virtualmin/Virtualmin-Config: A modern rewrite of the Virtualmin postinstall configuration script) though I guess that’s a little abstract because it’s basically a plugin-runner and not standalone scripts, you kind of have to look at a few files to get the gist of it. But, most of the plugins in the lib/Config/Plugin directory are calling Webmin functions.

Thanks for these ideas, I didn’t have the time today to dig further but I will definitely try and report here. Thks.
Pierre.