Description of problem: With the latest systemd update, the VNC service fails to start when configured per the documentation. Version-Release number of selected component (if applicable): 1.8.0-17 How reproducible: consistently Steps to Reproduce: 1. Create a new user with a password. 2. Follow directions in Section 13.1 of the RHEL 7 System Administrator's Guide to install the VNC server and configure it for one user. 3. Start the VNC server service. Actual results: Service fails with the error "New main PID $PIDNUM does not belong to service, and PID file is not owned by root. Refusing." The VNC daemon is still active and can accept connections; however, it cannot be managed by systemd at this point. Expected results: Service runs normally without issue. Additional info: This appears to be the same bug as bug 1583159 filed against Fedora 27. While replacement unit files were provided in that bug, by themselves they don't appear to work completely in RHEL 7.7; the daemons start and systemd reads it as started, but attempting to log in via GDM fails. There may be additional work to be done.
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