Page MenuHomePhabricator

Investigate better protection modes for electron render service (xvfb setuid)
Closed, ResolvedPublic

Description

Currently, electron is run inside xvfb, which requires setuid permissions. This makes it incompatible with firejail, which means that we don't get as much protection as we would like for this service.

Lets track options for improving on this situation, and remind ourselves to address the issue.

Headless Chrome eliminating xvfb

The Chrome folks have started work on a headless mode, which would eliminate the need for xvfb: https://phabricator.wikimedia.org/T134205
https://bugs.chromium.org/p/chromium/issues/detail?id=625577 tracks full-page screenshots

Related Objects

StatusSubtypeAssignedTask
Resolved Jhernandez
Resolved atgo
DeclinedNone
ResolvedNone
DeclinedNone
Resolved JKatzWMF
ResolvedNone
ResolvedWMDE-Fisch
ResolvedAddshore
InvalidNone
InvalidNone
ResolvedTobi_WMDE_SW
ResolvedTobi_WMDE_SW
Resolvedgabriel-wmde
ResolvedAddshore
ResolvedTobi_WMDE_SW
ResolvedTobi_WMDE_SW
ResolvedTobi_WMDE_SW
DeclinedNone
ResolvedTobi_WMDE_SW
Resolved GWicke
Resolved mobrovac
Resolved Lea_WMDE
ResolvedAddshore

Event Timeline

GWicke renamed this task from Investigate better protection modes for electron render service to Investigate better protection modes for electron render service (xvfb setuid).Aug 18 2016, 4:50 PM
mobrovac changed the task status from Open to Stalled.Aug 18 2016, 4:53 PM
mobrovac removed mobrovac as the assignee of this task.

Setting as stalled, since there is no real action on our side for the moment.

Has Electron gone through security review at least?

GWicke edited projects, added Services (next); removed Services.

I got the electron render service running in firejail on the pdf.services labs instance. This avoids the use of xvfb, and instead uses a dummy & unprivileged Xorg server, plus xpra for isolation. Notes:

  • apt-get install xpra firejail
  • Disable anything non-essential in /etc/xpra/xpra.conf:
#
# This is the default configuration file for Xpra
#
# You can provide default values for most command line
# options here.
# Each user can also define its own options in the file
# ~/xpra/xpra.conf which will take precedence over this file.
# Most options can also be overriden on the xpra command line.
# See "xpra -h" or the man page for details.
#
# Syntax:
# - Options which can be turned on or off will accept
#   the following values: 1, 0, true, false, yes, no
# - Options which can accept multiple values
#   may just be specified multiple times.
# - You may break a long line into multiple lines
#   by ending each line with a backslash '\'.


################################################################################
# General Options

# Enable clipboard forwarding:
clipboard = no

# Enable forwarding of notifications:
notifications = no

# Enable forwarding of system tray icons:
system-tray = no

# Forward sound output to clients:
speaker = no

# Debugging:
#debug =
#debug = keyboard,clipboard,tray

# Send ping packets more regularly (every second):
pings = no


################################################################################
# Picture Encoding

# Encodings allowed:
# (not all encodings may be available in your environment):
#encodings = h264, vp8, png, png/P, png/L, webp, rgb, jpeg, h265, vp9
#encodings = all
#encodings = rgb
encodings = all

# Default encoding
# (not all encodings may be available in your environment):
#encoding = h264
#encoding = vp8
#encoding = png
#encoding = jpeg
#encoding = rgb
#encoding = webp

# Used by the server to encode video:
# video-encoders = x264, vpx, nvenc
# video-encoders = none
# video-encoders = all
video-encoders = all

# Used by both the client and server for colourspace conversion:
# csc-modules = swscale, cython, opencl
# csc-modules = none
# csc-modules = all
csc-modules = all

# Used the client for decoding:
# video-decoders = avcodec2, vpx
# video-decoders = avcodec, vpx
# video-decoders = none
# video-decoders = all
video-decoders = all

# Use fixed quality
# (value is a percentage or "auto"):
#quality = 80
quality = auto

# For auto quality only:
#min-quality = 50
min-quality = 30

# Use fixed speed
# (value is a percentage or "auto"):
#speed = 90
speed = auto

# For auto speed only:
#min-speed = 20
min-speed = 0

# Idle delay in seconds before doing an automatic lossless refresh:
auto-refresh-delay = 0.15

# Default DPI:
dpi = 96


################################################################################
# Sound Encoding

# Codec(s) to use for forwarding speaker sound:
#speaker-codec = mp3
#speaker-codec = flac
#speaker-codec = wav
#speaker-codec = wavpack
#speaker-codec = speex
#speaker-codec = opus

# Forward sound input to server:
# microphone = yes

# Codec(s) to use for forwarding microphone sound:
#microphone-codec = mp3
#microphone-codec = flac
#microphone-codec = wav
#microphone-codec = wavpack
#microphone-codec = speex
#microphone-codec = opus


################################################################################
# Network Connection

# Enable shared memory transfers:
mmap = yes

# Use server group ownership for mmap file:
mmap-group = no

# Share session with other users:
sharing = no

# Compressors:
#compressors = all
#compressors = none
#compressors = zlib
compressors = lz4, zlib, lzo

# Default compression (0 to 9):
compression_level = 1

# Packet encoders (at least one is required):
#packet-encoders = bencode
#packet-encoders = all
packet-encoders = rencode, bencode, yaml

# Socket directory:
#socket-dir = /tmp
#socket-dir = ~/.xpra


################################################################################
# Client Options

# OpenGL accelerated rendering:
#opengl = yes
#opengl = no
opengl = no

# Client window title:
title = @title@ on @client-machine@

# Icon used by the system tray:
#tray-icon = /path/to/icon.png

# Keyboard synchronization:
keyboard-sync = yes

# Client ssh command:
#ssh = /usr/bin/ssh

# Key Shortcuts:
key-shortcut = Meta+Shift+F4:quit
key-shortcut = Meta+Shift+F8:magic_key
key-shortcut = Meta+Shift+F11:show_session_info


########################################################################
# Server Options:

# Commands to start by default
#  (may be specified more than once):
# examples:
#start-child = /usr/bin/xterm
#start-child = /usr/bin/xeyes
# Xsession can take care of initializing dbus, keyring-daemon,
# gpg-agent or whatever else might be usually started together with X
#start-child = /etc/X11/Xsession true

# Video encoders loaded by the server
# (all of them unless specified)
# examples:
#video-encoders=x264,vpx,nvenc
#video-encoders=x264

# Colourspace conversion modules loaded by the server
# (all of them unless specified)
# examples:
#csc-modules=swscale,cython,opencl
#csc-modules=swscale

# Where to send non xpra clients:
# (can be used to share the port with a web server)
#tcp-proxy = 127.0.0.1:80

# Log file:
log-file = $DISPLAY.log

# Publish sessions:
mdns = no

# Input methods
# To disable input method completely:
#input-method=none
# To keep the environment unchanged:
#input-method=keep
# Other possible options:
#input-method=IBus
#input-method=SCIM
#input-method=uim
input-method=none

# Start a pulseaudio server with each session:
pulseaudio = no

# pulseaudio server start command:
pulseaudio-command = pulseaudio --start --daemonize=false --system=false \
                --exit-idle-time=-1 -n --load=module-suspend-on-idle \
                --load=module-null-sink --load=module-native-protocol-unix \
                --log-level=2 --log-target=stderr

# Virtual display command:
# - Old Xvfb option:
# xvfb=Xvfb +extension Composite -screen 0 3840x2560x24+32 -nolisten tcp -noreset -auth $XAUTHORITY
# - With Xorg 1.12 or newer and the dummy driver:
# xvfb=/usr/bin/Xorg -dpi 96 -noreset -nolisten tcp +extension GLX +extension RANDR +extension RENDER -logfile ${HOME}/.xpra/Xorg.${DISPLAY}.log -config /etc/xpra/xorg.conf
#
# Selecting virtual X server:
xvfb=Xorg -dpi 96 -noreset -nolisten tcp +extension GLX +extension RANDR +extension RENDER -logfile ${HOME}/.xpra/Xorg.${DISPLAY}.log -config /etc/xpra/xorg.conf

# Does the xvfb command support the "-displayfd" argument?
displayfd = yes
  • From within the electron-render-service checkout, start the service via: CONCURRENCY=6 TIMEOUT=1200 RENDERER_ACCESS_KEY=secret firejail --noprofile --whitelist=/home/gwicke/electron-render-service --whitelist=/home/gwicke/.fonts.conf --x11=xpra /home/gwicke/electron-render-service/bin/electron-render-service.js
    • .fonts.conf is needed to enable anti-aliasing.

Afaik --noprofile removes a lot of protections we usually have in place. Eg. this is the profile currently used for thumbor: https://phab.wmfusercontent.org/file/data/hckmlkhjilkrjff7gn6k/PHID-FILE-4bb4ss23mafhmkvcapd5/thumbor.profile.firejail

@MoritzMuehlenhoff might be able to provide somed advice about how firejail should be set up.

I added --noprofile to get around this error:

libudev: udev_monitor_new_from_netlink_fd: error getting socket: Operation not supported

This might be related to the sandbox layering discussed in https://github.com/netblue30/firejail/issues/554. Chrome provides a sandbox very similar to firejail itself, which means that firejail's chrome profile focuses on adding to this, rather than replacing it.

Looking into this some more, I followed the hints in this discussion and added netlink to the protocol line in /etc/firejail/default.profile:

protocol unix,inet,inet6,netlink

With this change, the service starts without requiring the --noprofile option.

FWIW, I'm currently in the process of packaging firejail 0.9.44 for jessie and trusty, there have been quite a few X11-related changes between the 0.9.40 version that was previously in the archive.

mobrovac edited projects, added Services (doing); removed Services (next).

Thank you @GWicke for the awesome work-around! I am currently in the process of integrating firejail as part of T143129: New service request - PDF Render so assigning to myself.

Just for the record, firejail 0.9.44 is available on carbon.

Change 305256 had a related patch set uploaded (by Mobrovac):
PDF Render Service: Role and module

https://gerrit.wikimedia.org/r/305256

Change 305256 merged by Giuseppe Lavagetto:
PDF Render Service: Role and module

https://gerrit.wikimedia.org/r/305256

The integration has been completed, resolving.