Bug 1747191
| Summary: | tigervnc service via unit file fails with PID file error | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 7 | Reporter: | Andrew Mike <amike> | ||||
| Component: | tigervnc | Assignee: | Jan Grulich <jgrulich> | ||||
| Status: | CLOSED ERRATA | QA Contact: | Desktop QE <desktop-qa-list> | ||||
| Severity: | urgent | Docs Contact: | |||||
| Priority: | urgent | ||||||
| Version: | 7.7 | CC: | alanm, ayadav, benc, brclark, casantos, jgrulich, jwright, lcaparel, lnykryn, mboisver, mkolbas, mkrajnak, rmetrich, systemd-maint-list, tpelka, tpopela, vpakolu, yuokada | ||||
| Target Milestone: | rc | ||||||
| Target Release: | --- | ||||||
| Hardware: | Unspecified | ||||||
| OS: | Linux | ||||||
| Whiteboard: | |||||||
| Fixed In Version: | tigervnc-1.8.0-19.el7 | Doc Type: | If docs needed, set a value | ||||
| Doc Text: | Story Points: | --- | |||||
| Clone Of: | Environment: | ||||||
| Last Closed: | 2020-03-31 19:53:12 UTC | Type: | Bug | ||||
| Regression: | --- | Mount Type: | --- | ||||
| Documentation: | --- | CRM: | |||||
| Verified Versions: | Category: | --- | |||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||
| Embargoed: | |||||||
| Attachments: |
|
||||||
|
Description
Andrew Mike
2019-08-29 21:20:50 UTC
So the state is that we have no idea what to do here. The change was introduced because CVE-2018-16888 so we are not going to revert it. Also as you mentioned there is no support for --user in rhel7. There is a solution (not crappier than actual service anyway): run the vncserver without creating a user session: ExecStart=/usr/sbin/runuser rmetrich -c "/usr/bin/vncserver %i" (no "-l" to runuser anymore) With this, the VNC server will run in /system.slice/system-vncserver.slice/vncserver@:1.service which is anyway better: Is that a service or not? it's a service, so should run as a service. Note: I say "not crappier" because currently if you start an instance vncserver@:1 and ":1" is already used, then vncserver starts as ":2", but waits for PID of ":1", which is broken. Also if a service cannot use :1 as the port, it shouldn't start on another port anyway. This was reported some time ago (maybe 1 year or 2) ... (In reply to Renaud Métrich from comment #14) > There is a solution (not crappier than actual service anyway): run the > vncserver without creating a user session: > > ExecStart=/usr/sbin/runuser rmetrich -c "/usr/bin/vncserver %i" > > (no "-l" to runuser anymore) > > With this, the VNC server will run in > /system.slice/system-vncserver.slice/vncserver@:1.service which is anyway > better: > Is that a service or not? it's a service, so should run as a service. Can anyone from systemd confirm whether this will work just fine? The only consequence is that no $XDG_RUNTIME_DIR is set up (since no session is created), but I don't see any impact at all. (In reply to Renaud Métrich from comment #17) > The only consequence is that no $XDG_RUNTIME_DIR is set up (since no session > is created), but I don't see any impact at all. Wouldn't this be a problem for both GNOME and KDE? Honestly I don't know. I tried and it worked. Maybe Desktop specialists can tell. There are AVCs popping up, but these are unrelated to not having a session, but related to the SELinux context the session is running into, i.e. "unconfined_service_t" instead of "unconfined_t", which was already the case in the past. I believe not having XDG_RUNTIME_DIR set might be a problem for some applications and we would most likely hit some other issue if we go this way in future. Can we workaround this issue in systemd somehow? Add tigervnc into a whitelist or something like that so we can use the service file as it is now and was until now? I can propose a solution, which consists in executing vncserver@ service through a wrapper, as shown below:
/etc/systemd/system/vncserver@\:1.service: (also attached)
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
[Unit]
Description=Remote desktop service (VNC) instance %i
After=syslog.target network.target
[Service]
Type=simple
ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :'
ExecStart=/usr/local/bin/vncserver_wrapper user1 %i
ExecStop=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :'
[Install]
WantedBy=multi-user.target
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
/usr/local/bin/vncserver_wrapper: (also attached)
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
#!/bin/sh
THISPROG=$(basename $(readlink -f $0))
USER="$1"
INSTANCE="$2"
die() {
echo "FATAL: ${@:-}" >&2
exit 2
}
cleanup() {
[ -n "$VNCPID" ] || return
if kill -0 $VNCPID 2>/dev/null; then
kill $VNCPID
fi
}
trap cleanup TERM INT HUP
[ -n "$USER" -a -n "$INSTANCE" ] || die "Invalid usage!"
/usr/sbin/runuser -l "$USER" -c "/usr/bin/vncserver ${INSTANCE}"
[ $? -eq 0 ] || die "'runuser -l $USER' failed!"
# Wait up to 5 seconds for vncserver to be up
for tries in $(seq 1 50); do
[ -e "~$USER/.vnc/$(hostname)${INSTANCE}.pid" ] && break
sleep 0.1
done
eval HOME=~$USER
VNCPID=$(cat "$HOME/.vnc/$(hostname)${INSTANCE}.pid" 2>/dev/null || true)
[ -n "$VNCPID" ] || die "'vncserver ${INSTANCE}' failed to start after 5 seconds!"
echo "'vncserver ${INSTANCE}' has PID $VNCPID, waiting until it exits ..."
while kill -0 $VNCPID 2>/dev/null; do
sleep 5
done
echo "PID $VNCPID exited, exiting ..."
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
The script will monitor the Xvnc process and exit if it dies.
Created attachment 1623444 [details]
Proposed updated service and wrapper
Note: updated service comments have not been modified accordingly
Awesome thing, I just tested it and it works. I don't see any downside of using this approach so I will update everything accordingly and try to provide a scratch build so more people can test it easily. Thank you for your help. (In reply to Jan Grulich from comment #23) > Awesome thing, I just tested it and it works. I don't see any downside of > using this approach so I will update everything accordingly and try to > provide a scratch build so more people can test it easily. Thank you for > your help. Btw. what about using this approach, or at least providing it additionally on RHEL 8 to workaround the unlocking issue we have thanks to using systemd --user? I thought that unlocking issue was solved. (In reply to Renaud Métrich from comment #25) > I thought that unlocking issue was solved. Nope, the bug was just closed because there was no way how to solve it. At least I thought there is none. Verified by:
1. Created new user test2, set vncpasswd for test2
2. configured unitfile:
# cat /etc/systemd/system/vncserver@:1.service
[Unit]
Description=Remote desktop service (VNC)
After=syslog.target network.target
[Service]
Type=forking
User=test2
Group=test2
# Clean any existing files in /tmp/.X11-unix environment
ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :'
ExecStart=/usr/bin/vncserver %i
PIDFile=/home/test2/.vnc/%H%i.pid
ExecStop=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :'
[Install]
WantedBy=multi-user.target
3.Running the service
# systemctl daemon-reload
# systemctl status vncserver@:1.service
4.Verify the session is running
# systemctl status vncserver@:1.service
● vncserver@:1.service - Remote desktop service (VNC)
Loaded: loaded (/etc/systemd/system/vncserver@:1.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2019-10-15 12:20:32 CEST; 2h 1min ago
Process: 1150 ExecStart=/usr/bin/vncserver %i (code=exited, status=0/SUCCESS)
Process: 1093 ExecStartPre=/bin/sh -c /usr/bin/vncserver -kill %i > /dev/null 2>&1 || : (code=exited, status=0/SUCCESS)
Main PID: 1179 (Xvnc)
CGroup: /system.slice/system-vncserver.slice/vncserver@:1.service
├─1179 /usr/bin/Xvnc :1 -auth /home/test2/.Xauthority -desktop loc...
├─1631 /bin/sh /home/test2/.vnc/xstartup
├─1632 /usr/libexec/gnome-session-binary --session=gnome-classic
├─1643 dbus-launch --sh-syntax --exit-with-session
├─1644 /usr/bin/dbus-daemon --fork --print-pid 5 --print-address 7...
├─1690 /usr/libexec/imsettings-daemon
├─1698 /usr/libexec/gvfsd
├─1705 /usr/libexec/gvfsd-fuse /home/test2/.gvfs -f -o big_writes
├─1756 /usr/bin/ssh-agent /etc/X11/xinit/Xclients
├─1772 /usr/libexec/at-spi-bus-launcher
├─1777 /usr/bin/dbus-daemon --config-file=/usr/share/defaults/at-s...
├─1780 /usr/libexec/at-spi2-registryd --use-gnome-session
├─1805 /usr/bin/gnome-keyring-daemon --start --components=secrets
├─1820 /usr/bin/gnome-shell
├─1874 /usr/bin/pulseaudio --start --log-target=syslog
├─2039 ibus-daemon --xim --panel disable
├─2043 /usr/libexec/ibus-dconf
├─2045 /usr/libexec/ibus-x11 --kill-daemon
├─2050 /usr/libexec/ibus-portal
├─2059 /usr/libexec/xdg-permission-store
├─2061 /usr/libexec/gnome-shell-calendar-server
├─2075 /usr/libexec/evolution-source-registry
├─2088 /usr/libexec/mission-control-5
├─2094 /usr/libexec/goa-daemon
├─2096 /usr/libexec/gvfs-udisks2-volume-monitor
├─2105 /usr/libexec/gvfs-mtp-volume-monitor
├─2110 /usr/libexec/gvfs-afc-volume-monitor
├─2121 /usr/libexec/gvfs-goa-volume-monitor
├─2146 /usr/libexec/goa-identity-service
├─2179 /usr/libexec/gvfs-gphoto2-volume-monitor
├─2186 /usr/libexec/gsd-power
├─2189 /usr/libexec/gsd-print-notifications
├─2190 /usr/libexec/gsd-rfkill
├─2192 /usr/libexec/gsd-screensaver-proxy
├─2196 /usr/libexec/gsd-sharing
├─2198 /usr/libexec/gsd-smartcard
├─2204 /usr/libexec/gsd-account
├─2207 /usr/libexec/gsd-xsettings
├─2212 /usr/libexec/gsd-wacom
├─2216 /usr/libexec/gsd-sound
├─2224 /usr/libexec/gsd-a11y-settings
├─2225 /usr/libexec/gsd-clipboard
├─2229 /usr/libexec/gsd-color
├─2231 /usr/libexec/gsd-datetime
├─2234 /usr/libexec/gsd-housekeeping
├─2238 /usr/libexec/gsd-keyboard
├─2240 /usr/libexec/gsd-media-keys
├─2242 /usr/libexec/gsd-mouse
├─2261 /usr/libexec/gsd-printer
├─2293 /usr/bin/spice-vdagent
├─2295 nautilus-desktop --force
├─2306 /usr/libexec/gvfsd-trash --spawner :1.4 /org/gtk/gvfs/exec_...
├─2313 /usr/libexec/dconf-service
├─2343 /usr/libexec/gsd-disk-utility-notify
├─2347 rhsm-icon
├─2350 /usr/bin/seapplet
├─2359 /usr/bin/gnome-software --gapplication-service
├─2367 /usr/libexec/tracker-extract
├─2369 /usr/libexec/tracker-miner-apps
├─2371 /usr/libexec/tracker-miner-fs
├─2372 /usr/libexec/gconfd-2
├─2373 /usr/libexec/tracker-miner-user-guides
├─2379 /usr/libexec/tracker-store
├─2401 /usr/libexec/evolution-calendar-factory
├─2402 abrt-applet
├─2482 ./escd --key_Inserted="/usr/bin/esc" --on_Signal="/usr/bin/...
├─2510 /usr/libexec/evolution-calendar-factory-subprocess --factor...
├─2512 /usr/libexec/ibus-engine-simple
├─2546 /usr/libexec/evolution-addressbook-factory
├─2572 /usr/libexec/evolution-addressbook-factory-subprocess --fac...
└─2613 /usr/libexec/gvfsd-burn --spawner :1.4 /org/gtk/gvfs/exec_s...
Oct 15 14:20:42 localhost.localdomain gnome-software[2359]: hiding category a...
Oct 15 14:20:42 localhost.localdomain gnome-software[2359]: alternate-tab@gno...
Oct 15 14:20:42 localhost.localdomain gnome-software[2359]: launch-new-instan...
Oct 15 14:20:42 localhost.localdomain gnome-software[2359]: window-list@gnome...
Oct 15 14:20:42 localhost.localdomain gnome-software[2359]: apps-menu@gnome-s...
Oct 15 14:20:42 localhost.localdomain gnome-software[2359]: top-icons@gnome-s...
Oct 15 14:20:42 localhost.localdomain gnome-software[2359]: places-menu@gnome...
Oct 15 14:20:42 localhost.localdomain gnome-software[2359]: horizontal-worksp...
Oct 15 14:20:43 localhost.localdomain gnome-software[2359]: Only 5 apps for p...
Oct 15 14:21:23 localhost.localdomain gsd-color[2229]: no xrandr-Virtual-0 de...
Hint: Some lines were ellipsized, use -l to show in full.
5. Logged to session as user test, open Remote viewer, connected to localhost:1 session,
Furthermore, I enabled the service, rebooted, logged in again, service was running and I was still able to connect, moving to verified.
tigervnc-1.8.0-19.el7.x86_64
tigervnc-icons-1.8.0-18.el7.noarch
tigervnc-server-module-1.8.0-19.el7.x86_64
tigervnc-server-minimal-1.8.0-19.el7.x86_64
tigervnc-debuginfo-1.8.0-19.el7.x86_64
tigervnc-license-1.8.0-18.el7.noarch
tigervnc-server-1.8.0-19.el7.x86_64
*** Bug 1774244 has been marked as a duplicate of this bug. *** I think we have an opportunity to provide something better;
========= /usr/lib/systemd/system/vncserver@.service =========
[Unit]
Description=Remote desktop service (VNC) instance %i
After=syslog.target network.target
[Service]
Type=simple
ExecStart=/usr/bin/vncserver_wrapper start %i
ExecStop=/usr/bin/vncserver_wrapper stop %i
[Install]
WantedBy=multi-user.target
=========
========= /usr/bin/vncserver_wrapper ==========
#!/bin/sh
usage() {
echo "Usage: $0 {start|stop} <display>"
exit 1
}
die() {
echo "FATAL: ${*}" >&2
exit 2
}
VNCPID=
cleanup() {
[ -n "$VNCPID" ] || return
kill -0 "$VNCPID" 2>/dev/null && kill "$VNCPID"
}
trap cleanup TERM INT HUP
# Do not accept display :0, since it may conflict with hardware display
check_display() {
case "$1" in
:[1-9]|:[1-9][0-9]|:[1-9][0-9][0-9]|:[1-9][0-9][0-9][0-9]) :;;
*) die "invalid display '$1'"
esac
}
get_user() {
[ -f /etc/vncusers ] || die "/etc/vncusers: file not found"
lineno=0
while read -r tmp_display tmp_user dummy; do
lineno=$((lineno + 1))
# ignore comments and blank lines
case "$tmp_display" in
''|\#*) continue;;
esac
# there must be exactly two words
[ -n "$tmp_user" ] || die "syntax error in /etc/vncusers, line $lineno"
[ -z "$dummy" ] || die "syntax error in /etc/vncusers, line $lineno"
case "$tmp_display" in
"$1") break;;
:[1-9]|:[1-9][0-9]|:[1-9][0-9][0-9]|:[1-9][0-9][0-9][0-9]) continue;;
*) die "syntax error in /etc/vncusers, line $lineno";;
esac
done < /etc/vncusers
[ -n "$tmp_user" ] || die "user for display '$1' not found in /etc/vncusers"
tmp_id=$(id -u "$tmp_user" 2>/dev/null)
[ "$tmp_id" -ge 0 ] || die "unknown user '$tmp_user' for display '$1'"
echo "$tmp_user"
}
start() {
display="$1"
check_display "$display"
user="$(get_user "$display")" || exit 2
home=
eval home=~"$user"
pidfile="$home/.vnc/$(hostname -f)$display.pid"
/usr/sbin/runuser -l "$user" -c "/usr/bin/vncserver -kill '$display'" > /dev/null 2>&1
/usr/sbin/runuser -l "$user" -c "/usr/bin/vncserver '$display'" \
|| die "'runuser -l $user' failed!"
# Wait up to 5 seconds for vncserver to be up
timeleft=50
while [ "$timeleft" -gt 0 ] && [ ! -e "$pidfile" ]; do
timeleft=$((timeleft - 1))
sleep 0.1
done
read -r VNCPID < "$pidfile" 2>/dev/null
[ -n "$VNCPID" ] || die "vncserver '$display' failed to start after 5 seconds!"
echo "vncserver '$display' has PID '$VNCPID', waiting until it exits ..."
while kill -0 "$VNCPID" 2>/dev/null; do sleep 5; done
echo "PID $VNCPID exited, exiting ..."
}
stop() {
display="$1"
check_display "$display"
user="$(get_user "$display")" || exit 2
home=
eval home=~"$user"
pidfile="$home/.vnc/$(hostname -f)$display.pid"
[ -f "$pidfile" ] || die "PID file '$pidfile' not found"
/usr/sbin/runuser -l "$user" -c "/usr/bin/vncserver -kill '$display'" > /dev/null 2>&1 \
|| die "vncserver '$display' failed to stop"
}
case "$1" in
start|stop)
[ -n "$2" ] || usage
"$1" "$2"
;;
*) usage
esac
==========
========== /etc/vncusers ==========
#
# /etc/vncusers
#
# Syntax:
# <display> <user>
#
# Example:
#
# :1 user1
#
:1 user
:2 cruiser
:3 chooser
==========
So each time we need to add a VNC user we just need to run
# systemctl enable vncserver@:4.service
add a lile to /etc/vncusers containing
:4 gooser
and ask user "gooser" to run vncpasswd.
As a more simplistic alternative, I would suggest the following unit file: [Unit] Description=Remote desktop service (VNC) After=syslog.target network.target Requires=systemd-logind.service [Service] Type=oneshot RemainAfterExit=yes # Clean any existing files in /tmp/.X11-unix environment ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :' ExecStart=/usr/sbin/runuser -l test -c "/usr/bin/vncserver %i" ExecStop=/usr/sbin/runuser test -c '/usr/bin/vncserver -kill %i' [Install] WantedBy=multi-user.target It keeps us from having to add an additional wrapper script, and it allows users to continue to use VNC the way they have been if they don't want the additional complexity of forcing tunneling through SSH, as this would potentially cause problems for non-technical users I also understand the downsides of oneshot, but we're only looking at a stopgap. The real solution will be to get tigervnc/Xvnc rebuilt to be properly daemonized under systemd IMO (In reply to Joe Wright from comment #38) > I also understand the downsides of oneshot, but we're only looking at a > stopgap. The real solution will be to get tigervnc/Xvnc rebuilt to be > properly daemonized under systemd IMO This is being worked on in upstream, it's just not merged yet. Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2020:1075 |