{"id":2589,"date":"2021-06-18T22:09:25","date_gmt":"2021-06-19T06:09:25","guid":{"rendered":"http:\/\/wonghoi.humgar.com\/blog\/?p=2589"},"modified":"2025-11-30T23:17:53","modified_gmt":"2025-12-01T07:17:53","slug":"run-vnc-server-before-logging-to-linux-gui","status":"publish","type":"post","link":"https:\/\/wonghoi.humgar.com\/blog\/2021\/06\/18\/run-vnc-server-before-logging-to-linux-gui\/","title":{"rendered":"Run VNC server before logging to Linux GUI"},"content":{"rendered":"\n<p>I installed <a href=\"https:\/\/linux.die.net\/man\/1\/x11vnc\" target=\"_blank\" rel=\"noreferrer noopener\">X11vnc<\/a> and to my dismay, there isn&#8217;t a easy option that automatically configures VNC as a service like most Windows VNC software does (so you can VNC into a computer before you login as a user graphically and launch the X11vnc executable). <\/p>\n\n\n\n<p>I had to manually create a service and I ran into a few problems as the <a rel=\"noreferrer noopener\" href=\"https:\/\/unix.stackexchange.com\/questions\/402201\/creating-x11vnc-system-service\" target=\"_blank\">instructions<\/a> on StackExchange and other forums are missing critical pieces. <\/p>\n\n\n\n<p>In here, I will use X11vnc server on Ubuntu Cinnamon (systemd) as an example. Instead of blindly pasting code here without context, I&#8217;ll sketch out the ideas here:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Establish a password in a password file stored in common areas such as \/etc\/x11vnc.pwd instead of using the user-specific home folder default ~\/.vnc\/passwd<\/li>\n\n\n\n<li>Create a service (such as systemd) pointing to x11vnc program with the right parameters, which includes the path to the password file stored in common areas<\/li>\n\n\n\n<li>Start the service<\/li>\n<\/ol>\n\n\n\n<p>It&#8217;s worth nothing that the X11server connection is unencrypted. I tried the -ssl options but my RealVNC clients complained about their version <\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>First of all, <code><code data-enlighter-language=\"shell\" class=\"EnlighterJSRAW\">x11vnc -storepasswd<\/code><\/code> creates the encrypted password file at the current home folder where you run the code. You are going to call the said password file with <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">x11vnc -rbfauth {path to password file}<\/code> parameter when launching the X11vnc server program.<\/p>\n\n\n\n<p>One way to do it is to copy the created password to a system-specific configuration folder instead of user&#8217;s home folder:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo cp ~\/.vnc\/passwd \/etc\/x11vnc.pwd<\/code><\/pre>\n\n\n\n<p>Alternatively (which I do not recommend), is to specify the password AND the password-file path directly with optional specifiers of the <code>-storepasswd<\/code> parameter. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Directly create the password file without a prompt that hides the password entry\nx11vnc -storepasswd my_pASSword \/etc\/x11vnc.pwd\n# Clean up your terminal command history since you've exposed the password visually\nhistory -c<\/code><\/pre>\n\n\n\n<p>Unfortunately, if you want to specify the path to the password-file, you have to specify type the plain text password in the command line, which you should do it when nobody&#8217;s watching and clear the history immediately afterwards. If you are in a public place, just do it the old way and copy the password file over <\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>The core part of setting (doing the data-entry) for <a href=\"https:\/\/wiki.archlinux.org\/title\/X11vnc\" target=\"_blank\" rel=\"noreferrer noopener\">registering a service<\/a> is the figuring out the command line parameters executing x11vnc program. At minimal, you&#8217;ll need<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>-rfbauth<\/code> specifies where the password file is (or you can directly specify the password with <code>-passwd<\/code>, which I do not recommended)<\/li>\n\n\n\n<li>&#8211;<code>auth<\/code>: authentication means (prefers &#8211;<code>auth guess<\/code>, but you can specify where your <code><a href=\"https:\/\/askubuntu.com\/questions\/300682\/what-is-the-xauthority-file\">.Xauthority<\/a><\/code> file is)<\/li>\n\n\n\n<li><code><span style=\"text-decoration: underline;\"><span class=\"has-inline-color has-primary-color\">-display: 0<\/span><\/span><\/code> connects to the X11 server display, which is usually 0 <\/li>\n\n\n\n<li><code><strong><span style=\"text-decoration: underline;\"><span style=\"color:#ff0004\" class=\"has-inline-color\">-create<\/span><\/span><\/strong><\/code> is the missing link! you must absolutely use this tell the VNC server to make a Xvfb (X virtual framebuffer) session if no display session is found (which is the case when you are running X11vnc as a service before logging in the a Desktop Environment like Cinnamon)<\/li>\n<\/ul>\n\n\n\n<p>You&#8217;ll typically want this for a constant-on VNC server<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>-forever<\/code>: x11server instances are by default (<code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">-once<\/code>) killed after the client disconnects. <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">-forever<\/code> option keeps it there<\/li>\n<\/ul>\n\n\n\n<p>My personal preferences<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>-shared<\/code>: I might have a few computer VNC&#8217;ing into the linux computer and I don&#8217;t want to make sure I remember to close the ones I&#8217;m not using.<\/li>\n\n\n\n<li><code>-noxdamage<\/code>: <a href=\"https:\/\/freedesktop.org\/wiki\/Software\/XDamage\/\">XDamage<\/a> is a system that only updates the changed parts of the screen. Don&#8217;t need it when bandwidth isn&#8217;t super tight. <\/li>\n\n\n\n<li><code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">-repeat<\/code>: allow hold and repeat keystrokes just like what we are used to. By default it&#8217;s set to <code>-norepeat<\/code> to avoid stuck key scenarios.<\/li>\n<\/ul>\n\n\n\n<p>For debugging (useful! that&#8217;s how I figured out the missing part that I have to use <code>-create<\/code> to make a dummy screen when using x11vnc as a service):<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>-o<\/code> {output log file}: typically <code>-o \/var\/log\/x11vnc.log<\/code><\/li>\n\n\n\n<li><code>-loop<\/code>: if the program crashes for any reason, it&#8217;ll try to auto-restart for robustness. Might not need it if you use<code> -forever<\/code><\/li>\n<\/ul>\n\n\n\n<p>So the core command needed is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>x11vnc -repeat -noxdamage -create -display :0 -auth guess -rfbauth \/etc\/x11vnc.pwd -shared -forever<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>Now after we&#8217;ve decided the exact launch command, we will have to create the service entry. In systemd Linux, it&#8217;s done by writing a service configuration file in text format very much like Windows INI files under <code>\/etc\/systemd\/system<\/code> and the filename MUST end with suffix &#8220;<code>.service<\/code>&#8221; <\/p>\n\n\n\n<p>In short, create \/etc\/systemd\/system\/x11vnc.service. Basic file without logging is like this:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[Unit]\nDescription=VNC Server for X11\nRequires=display-manager.service\n# The two below are for performance (make sure everything is ready before launching)\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nExecStart=\/usr\/bin\/x11vnc -repeat -noxdamage -create -display :0 -auth guess -rfbauth \/etc\/x11vnc.pwd -shared -forever\n# The 3 lines below are option, but for robustness\nExecStop=\/usr\/bin\/x11vnc -R stop\nRestart=on-failure\nRestartSec=2\n\n# For automatically creating symlinks with \"sudo systemctl enable\" only\n[Install]\n# Start at runlevel 5 (multi-user)\nWantedBy=multi-user.target<\/pre>\n\n\n\n<p>This is the minimum skeleton that does the same less robustness against the unexpected:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[Unit]\nDescription=VNC Server for X11\nRequires=display-manager.service\n\n[Service]\nExecStart=\/usr\/bin\/x11vnc -repeat -noxdamage -create -display :0 -auth guess -rfbauth \/etc\/x11vnc.pwd -shared -forever\n\n[Install]\nWantedBy=multi-user.target<\/pre>\n\n\n\n<p>The default permissions 644 (everybody reads but only root can write is standard for services. 640, denying unknown people the read access is also <a href=\"https:\/\/www.howtogeek.com\/687970\/how-to-run-a-linux-program-at-startup-with-systemd\/\">acceptable<\/a> if you are paranoid) should be correct if you use sudo creating the file in the<code> \/etc\/systemd\/system<\/code> folder.<\/p>\n\n\n\n<p>There are some older tutorials using the <code>(\/usr)\/lib\/systemd\/system<\/code> folder, which are now reserved for automatic entry by programs instead of manual service entry like what we are doing now. Technically either way works, but follow the convention so people know where to find the entries.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>After that enable the service file you&#8217;ve created (the &#8220;.service&#8221; suffix is optional when calling), preferably do a <code>daemon-reload<\/code> to make sure edits in the service file are reflected. If you don&#8217;t want to wait until the next boot, you can start it with <code>systemctl<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl enable x11vnc\nsudo systemctl daemon-reload\nsudo systemctl start x11vnc<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>This kind of stuff in Linux is bitchworthy. It&#8217;s 2021 now. How come users need to mess with defining their custom services for such a common VNC use case (start before logging in graphically)? Never have to deal with this kind of nonsense in Windows with VNCs: Windows expect users have the computer to themselves and always offer the option to set up the service automatically!<\/p>\n<div class=\"pvc_clear\"><\/div><p id=\"pvc_stats_2589\" class=\"pvc_stats all  \" data-element-id=\"2589\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/wonghoi.humgar.com\/blog\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p><div class=\"pvc_clear\"><\/div>","protected":false},"excerpt":{"rendered":"<p>I installed X11vnc and to my dismay, there isn&#8217;t a easy option that automatically configures VNC as a service like most Windows VNC software does (so you can VNC into a computer before you login as a user graphically and &hellip; <a href=\"https:\/\/wonghoi.humgar.com\/blog\/2021\/06\/18\/run-vnc-server-before-logging-to-linux-gui\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_2589\" class=\"pvc_stats all  \" data-element-id=\"2589\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/wonghoi.humgar.com\/blog\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[39],"tags":[],"class_list":["post-2589","post","type-post","status-publish","format-standard","hentry","category-linux"],"_links":{"self":[{"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/posts\/2589","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/comments?post=2589"}],"version-history":[{"count":17,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/posts\/2589\/revisions"}],"predecessor-version":[{"id":6645,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/posts\/2589\/revisions\/6645"}],"wp:attachment":[{"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/media?parent=2589"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/categories?post=2589"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wonghoi.humgar.com\/blog\/wp-json\/wp\/v2\/tags?post=2589"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}