#871969 leafnode: using su in cronjob runs pam_systemd, starts a whole session, causes errors

Package:
leafnode
Source:
leafnode
Description:
NNTP server for small sites
Submitter:
Jakobus Schürz
Date:
2017-09-23 22:27:06 UTC
Severity:
normal
#871969#5
Date:
2017-08-13 05:17:51 UTC
From:
To:
Dear Maintainer,

I have some systemd --user services from other packages.
The units are located in /etc/systemd/user/ or /usr/lib/systemd/user/
and enabled on installing.

When a daemon uses su or sudo on debian, it starts a service
user@$UID.service which is a systemd-daemon for the user-session. This
sessions are normally not started for Daemons with UID below 1000
(except Debian-gdm).

I asked on the systemd-mailinglist, whats the problem, because sometimes
leafnode starts an user-session (and with this the user-services which are
thought for login-users with UID greater-equal 1000).
They told me, there must be the use of su or sudo in some scripts from
the daemon.
I looked around and found, that there is su used in
/etc/cron.daily/leafnode

Just change from su to runuser, the cronjob also does his job, but
without invoking pam_systemd!

You find my changes below to use runuser instead of su, which solves the
problems comming from the su-command.
Your original command is commented below my new line.

cu

Jakob

#871969#10
Date:
2017-08-27 09:23:49 UTC
From:
To:

Hello,

In its current form, leafnode is invoked through inetd. Are you saying
that there is an issue with Debian Stretch + Systemd + leafnode/inted ?

#871969#15
Date:
2017-08-28 11:07:38 UTC
From:
To:
Am 2017-08-27 11:23, schrieb Ritesh Raj Sarraf:

I wrote a socket-Unit for systemd, because I don't use inetd.

But that's not the point. It's the cronjob in /etc/cron.daily/leafnode,
which makes a Problem using su.

su invokes a whole User-Session via pam-systemd.

And you can change su to runuser (which is made out of the code from su
to avoid some Problems using su, especially this one), and do the same
job in cron.daily.

A sesseion invoked by su and pam-systemd starts to create xdg-userdirs
in the $HOME for leafnode (/var/lib/leafnode) and starts systemd --user
services, which are only made for Login-Users wiht UID above 1000 (Real
Users...)

In my bugreport you can find the changed code with runuser instead of
su, which works for me. runuser is part of util-linux since version 2.23
or so... a very long time. (2013...)

You can find an answer here:
https://unix.stackexchange.com/questions/269254/why-does-util-linux-runuser-su-fork

"Unlike su, IMO, runuser is made to be used in scripts (so never ask for
password, handle error status better, and also separate signals handling
(new session) from caller"

Would you be so pleasant, to test this and even fix it from su to
runuser?

Regards

Jakob

#871969#20
Date:
2017-08-28 15:17:40 UTC
From:
To:
Hello Jakbous,

Would you be kind to share your, working, socket based unit file for
leafnode ?

IIRC, long back there was some effort by the leafnode maintainer to add
something like this. But from what I recollect, there were some issues.

I am currently testing with the changes you've mentioned (And would
like to move to a socket based setup).

Thanks

#871969#25
Date:
2017-09-07 19:06:12 UTC
From:
To:
For sure :-)

Here are all my units for leafnode:

# systemctl cat leafnode.socket
# /etc/systemd/system/leafnode.socket
[Unit]
Description=Leafnode NNTP Socket

[Socket]
ListenStream=127.0.0.1:119
Accept=true

[Install]
WantedBy=sockets.target
-----------------------------------------

# systemctl cat leafnode@.service
# /etc/systemd/system/leafnode@.service
[Unit]
Description=Leafnode NNTP service
#After=syslog.target
After=systemd-journald.service

[Service]
ExecStart=/usr/sbin/leafnode
StandardInput=socket
User=news
---------------------------------

# systemctl cat leafnode-texpire.service
# /etc/systemd/system/leafnode-texpire.service
[Unit]
Description=leafnode daily texipre newsgroups
ConditionPathExists=

[Service]
User=news
ExecStart=/usr/sbin/texpire

[Install]
WantedBy=timer-daily.target
----------------------------------

# systemctl cat leafnode-touch_groups.service
# /etc/systemd/system/leafnode-touch_groups.service
[Unit]
Description=leafnode daily touch newsgroups
ConditionPathExists=/etc/news/leafnode/touch_groups

[Service]
User=news
ExecStart=/usr/bin/touch_newsgroup -f /etc/news/leafnode/touch_groups
ExecStartPost=/usr/bin/newsq -f

[Install]
WantedBy=timer-daily.target
--------------------------------

# systemctl cat fetchnews.timer
# /lib/systemd/system/fetchnews.timer
[Unit]
Description=Run fetchnews every 10 minutes
DefaultDependencies=false
PartOf=connection-online.target
After=connection-online.target

[Timer]
OnCalendar=*:0/15
AccuracySec=5min
#Persistent=true

[Install]
WantedBy=network-online.target
--------------------------------

# systemctl cat fetchnews.service
# /lib/systemd/system/fetchnews.service
[Unit]
Description=Fetch news for leafnode

[Service]
ExecStart=/usr/sbin/fetchnews


This setup works on my Laptop. I use an own leafnode, becaue i need
groups from more than one news-server, but i only want only one
news-server in my thunderbird.

With sudo in the cron-job, i get the described problems. runuser works
for me (no xdg-user-dirs, no pam-systemd-session...)

regards
Jakob

#871969#30
Date:
2017-09-23 11:08:29 UTC
From:
To:
Hello Jakobus,

Thank you very much. With your setup in place, I have been able to
successfully run leafnode with systemd integration. I tested it for
around a week now and everything is working perfect.

If I could add a wishlist, it is dependency of the fetchnews service
unit/timer to runtime depend on network-online.target.

As I understand it now, fetchnews will be triggered only if the
network-online.target is active. So it does solve the service startup
at boot time, ensuring that fetchnews does not get triggered until and
unless a working operational network setup is in place.

But like yours', my leafnode setup is on my laptop. Which goes through
multiple suspend/resume and network cycles. There are also times, when
upon resume there is no network (networkless location, airplane mode
etc). Under such scenarios, systemd should only invoke such timers if
an active network connection is available.

Do you happen to know if we could configure the units/timers in such a
way that it probes the network-online.target for actual network
connectivity, and only then invoke the timers ?

This would help not just fetchnews timer but also many user defined
timers, that are dependent on network availability.

I think this (systemd) integration work is good enough to be included
for Debian. Hopefully, Moritz will agree with these changes and
integrate it.

#871969#35
Date:
2017-09-23 16:53:25 UTC
From:
To:
Ack, I need to find some time to review and test this, then we can
integrate this into the package.

debdiffs welcome :-)

Cheers,
	Moritz

#871969#40
Date:
2017-09-23 22:26:07 UTC
From:
To:
Am 2017-09-23 um 13:08 schrieb Ritesh Raj Sarraf:

This is a good point. I also asked on the systemd list for this (not
only leafnode should be only started, only when a network-connection is
available... fetchmail is the same).

They said me, systemd starts services and can restart a service, if it
stops working in case of a failure. But systemd is not designed to watch
available network-connections...

So network-online.target ist started, when for example
network-manager.service ist started successfully... not when the
connection is up and running.

Network-Manager has to start and stop a special target, when
connection-state is changing. But that is not as easy as I thougt... How
to check, if a connection is up? How to check, if a connection is
working? Ping some servers? Ping a special server? What is, if a server
is configured, not to answer ICMP?

I'm also working on a solution to use an own target, which i call
"connection-online.target" and "connection-online@.target" to
instantiate this target for every network-device.

The instantiated targets (connection-online@eth0.target,
connection-online@wlan0.target or for tun0...) have the option, to start
a service only if a certain device is online. Bind a service to
"connection-online.target", it will start if any connection is online.

The dependecy for fetchnews.timer can be "connection-online.target".
Connection-online.target gets started from a network-manager-dispatcher
script, and also gets stopped on such a script.
The dependencies for fetchnews.timer are
"PartOf=connection-online.target
After=connection-online.target"

So every time, connection-online.target is started, fetchnews.timer is
also startet. The same for stopping connection-online.target.

You need a dispatcher-script which checks the online-state with
"nm-online", and depending on the result, connection-online.target is
started or stopped...

But what, if some doesn't use NetworkManager? If someone is using wicd
or systemd-networkd?
Ok, for the last, there could be a native solution... but I do not use
systemd-networkd, because it is not practicable on Laptops...
For wicd, there is also a possibility for starting scripts on
statechanges... so connection-online should also be working.

But I haven't finnished this solution.

For now, the dependecy to network-online.target should be enough.

Best regards

Jakob