{"id":257,"date":"2011-07-04T13:27:49","date_gmt":"2011-07-04T20:27:49","guid":{"rendered":"http:\/\/porkrind.org\/missives\/?p=257"},"modified":"2015-02-20T23:27:13","modified_gmt":"2015-02-21T07:27:13","slug":"daemon-manager-manage-your-non-privileged-daemons","status":"publish","type":"post","link":"https:\/\/porkrind.org\/missives\/daemon-manager-manage-your-non-privileged-daemons\/","title":{"rendered":"Daemon-Manager: Manage your non-privileged daemons"},"content":{"rendered":"<p>It seems I&#8217;ve been writing little daemons a lot lately&#8211;small things that don&#8217;t want to run as root but still need to be launched in the background as services. I&#8217;ve been noticing because it&#8217;s such a pain to integrate them into the system once they are written (or installed). I have to mess around as root creating \/etc\/init.d shell scripts (probably by copy and pasting&#8211;who out there can actually make those from scratch?) or maybe tweaking some upstart or systemd config file.<\/p>\n<p>And then when I&#8217;m done it annoys me that I have to be root to start or stop a daemon that ends up running as my login user anyway.<\/p>\n<h2>Enter Daemon Manager<\/h2>\n<p>So last October (2010) I sat down and wrote daemon-manager. It started from a few core ideas:<\/p>\n<ol>\n<li>It must be possible for a user to set up and configure their   daemons\u2014no root access must be required for a user to create a new  daemon or  restart one of their daemons.<\/li>\n<li>It must be secure\u2014users should not be allowed to control other users&#8217; daemons (unless they are given explicit permission).<\/li>\n<li>It should allow for good security practices\u2014users should be allowed   to launch a daemon as a user other than themselves if root has   explicitly allowed it. This is so you can run your daemons as a   &#8220;nobody&#8221; style user.<sup class='footnote'><a href='#fn-257-1' id='fnref-257-1' onclick='return fdfootnote_show(257)'>1<\/a><\/sup><\/li>\n<li>It should restart the daemons if they crash (I&#8217;m looking at you, php-cgi).<\/li>\n<li>It should be easy to use\u20141 config file per daemon and a simple command line interface to interact with the running daemons.<\/li>\n<\/ol>\n<p>There are programs out there that do parts of that list, but none that do everything:<\/p>\n<ul>\n<li><a href=\"http:\/\/cr.yp.to\/daemontools.html\">daemon tools<\/a>:   I&#8217;ve used it before and I really like its philosophy of being small  and  simple. But it seems to really want to run as root which means you  have  to be root to control it. Also, setting up new daemons is kind of a   pain.<\/li>\n<li><a href=\"http:\/\/upstart.ubuntu.com\/\">Upstart<\/a>:   It&#8217;s very similar and it makes setting up a new daemon pretty easy but   since it&#8217;s an &#8220;init&#8221; replacement it doesn&#8217;t seems very adept at  running  programs meant for non-root users. I&#8217;ve done it before but  there was a  lot of &#8220;sudo&#8221; configuration and it wasn&#8217;t easy. Also the  config files are  stored in \/etc\/init and only root can write new ones.<\/li>\n<li><a href=\"http:\/\/fedoraproject.org\/wiki\/Features\/systemd\">Systemd<\/a>: I really love systemd. Or the idea of it, really\u2014some day it will make it into Debian and I&#8217;ll start actually using it. But <a href=\"http:\/\/0pointer.de\/blog\/projects\/systemd.html\">its philosophy<\/a> is great. But again, being an &#8220;init&#8221; replacement gives it most of the same downsides as upstart.<\/li>\n<\/ul>\n<h2>A Quick Tutorial Through Examples<\/h2>\n<h3>Master config: \/etc\/daemon-manager.conf<\/h3>\n<pre><code class=\"language-ini\">[runs_as]\r\ndavid: www-data\r\nmichaelc: www-data\r\namy: www-data\r\njoann: www-data\r\njim:\r\ngreenfelt: greenfelt-daemon\r\n\r\n[manages]\r\ndavid: michaelc,amy,joann,greenfelt\r\nmichaelc: amy, joann\r\nbill: joann\r\njim: greenfelt<\/code><\/pre>\n<p>The  main section is the &#8220;runs_as&#8221; section. This section tells Daemon   Manager which users are allowed to start daemons and which users the   daemons can be run as. In the above example, &#8220;david&#8221;, &#8220;michaelc&#8221;, &#8220;amy&#8221;,   and &#8220;joann&#8221; can launch daemons as themselves and also   &#8220;www-data&#8221;. &#8220;greenfelt&#8221; can launch daemons as itself and the &#8220;greenfelt-daemon&#8221; user. &#8220;jim&#8221; is only allowed to launch daemons as himself. No   other users on the system are allowed to launch daemons at all  because  they weren&#8217;t explicitly listed.<\/p>\n<p>The &#8220;manages&#8221; section is a little  experimental at this point, but  the idea is that &#8220;david&#8221; is allowed to  manage (start, stop, or restart)  the daemons of &#8220;michaelc&#8221;, &#8220;amy&#8221;,  &#8220;joann&#8221;, and &#8220;greenfelt&#8221; in addition  to his own daemons. This is so you  can have help desk type users who  can stop or restart other users&#8217;  daemons even though they may not have  read or write access to the users&#8217;  home directories. As you might expect, &#8220;root&#8221; is always allowed to start and stop anyone&#8217;s daemons.<\/p>\n<h3>Daemon: deluged.conf<\/h3>\n<pre><code class=\"language-ini\">dir=\/home\/david\r\nstart=exec deluged -d<\/code><\/pre>\n<p>This  is a simple Daemon Manager config file that launches the deluge   bittorrent daemon. &#8220;dir&#8221; and &#8220;start&#8221; are the only required   entries in the config file. &#8220;dir&#8221; is the working directory and &#8220;start&#8221; is a one   line shell script to run. Because it is a shell script it <em>needs<\/em> to &#8220;exec&#8221;, otherwise Daemon Manager can&#8217;t manage it properly.<sup class='footnote'><a href='#fn-257-2' id='fnref-257-2' onclick='return fdfootnote_show(257)'>2<\/a><\/sup><\/p>\n<h3>Daemon: wordpress.conf<\/h3>\n<pre><code class=\"language-ini\">dir=\/home\/amy\/wordpress\r\nuser=www-data\r\nstart=exec php-cgi -q -b wordpress.socket<\/code><\/pre>\n<p>This starts a PHP FastCGI daemon in a WordPress directory and starts it running with as the &#8220;www-data&#8221; user (&#8220;amy&#8221; was given explicit permission to start daemons as the www-data user in &#8220;\/etc\/daemon-manager.conf&#8221;).<\/p>\n<h3>Daemon: greenfelt.conf<\/h3>\n<pre><code class=\"language-ini\">dir=\/var\/www\/greenfelt.net\r\nuser=greenfelt-daemon\r\nstart=exec .\/script\/greenfelt_fastcgi.pl -l greenfelt.socket -n 1\r\noutput=log<\/code><\/pre>\n<p>This is a paraphrase of the config file that runs <a href=\"http:\/\/greenfelt.net\/\">greenfelt.net<\/a> which is a <a href=\"http:\/\/www.catalystframework.org\/\">Catalyst<\/a> app that talks to nginx via FastCGI through the &#8220;greenfelt.socket&#8221; unix domain socket. It runs as the user &#8220;greenfelt-daemon&#8221; so it can have less privileges than the main &#8220;greenfelt&#8221; user. The &#8220;output&#8221; parameter  tells Daemon Manager to collect the stdout  and stderr of the daemon and  save it to a log file in the  &#8220;~\/.daemon-manager\/logs\/&#8221; directory (the default setting is to throw away stdout and stderr).<\/p>\n<h2>Controlling Daemon Manager<\/h2>\n<p>Daemon Manager is controlled using the &#8220;dmctl&#8221; command. It is   relatively simple at this point, allowing you to start, stop and restart   daemons. It also lets you scan for new config files and query for daemon  statistics. Here&#8217;s an example output the &#8220;status&#8221; command:<\/p>\n<pre>$ dmctl status\r\ndaemon-id                      state              pid respawns cooldown   uptime    total\r\ndavid\/deluge-web               running           2948        0       0s     3w3d     3w3d\r\ndavid\/deluged                  running           2950        0       0s     3w3d     3w3d\r\ndavid\/greenfelt                stopped              0        0       0s       0s       0s\r\ndavid\/minecraft                stopped              0        0       0s       0s       0s\r\ndavid\/moviefile                running           2951        0       0s     3w3d     3w3d\r\ndavid\/pytivo                   running          22905        0       0s     4d7h     4d7h\r\ndavid\/streamium                running           2958        0       0s     3w3d     3w3d\r\ndavid\/wordpress                running          27012       33       0s   12h57m     3w3d<\/pre>\n<p>Notice that the wordpress server (good old php-cgi) has crashed 33  times (and has been automatically respawned by Daemon Manager).<\/p>\n<h2>Download and Use<\/h2>\n<p>Daemon Manager is licensed under the <a href=\"http:\/\/www.gnu.org\/licenses\/gpl.html\">GPL<\/a> and <a href=\"http:\/\/porkrind.org\/daemon-manager\/\">can be downloaded here<\/a> (the <a href=\"https:\/\/github.com\/caldwell\/daemon-manager\">source is also available on github<\/a>). If you use Debian there&#8217;s a <a href=\"https:\/\/github.com\/caldwell\/daemon-manager\/tree\/debian\">Debian branch<\/a> available for building a package. The version as of this writing is 0.9  which means that there are some obvious things that need to be fixed<sup class='footnote'><a href='#fn-257-3' id='fnref-257-3' onclick='return fdfootnote_show(257)'>3<\/a><\/sup> and that I&#8217;m not  sure it&#8217;s 100% secure or bug free yet, though I have been using it for months now and I absolutely love it&#8211;it filled a void I wasn&#8217;t even sure was really there when I started.<\/p>\n<p>For a more detailed version of the history of Daemon Manager, see <a href=\"http:\/\/porkrind.org\/missives\/introducing-daemon-manager\/\">this blog post<\/a>.<\/p>\n<div class='footnotes' id='footnotes-257'>\n<div class='footnotedivider'><\/div>\n<ol>\n<li id='fn-257-1'> That way, if there is a security hole in your  code the attacker doesn&#8217;t get access to your main login account. <span class='footnotereverse'><a href='#fnref-257-1'>&#8617;<\/a><\/span><\/li>\n<li id='fn-257-2'> I  would like to change that but I&#8217;m having trouble getting dash   (\/bin\/sh  on my Debian system) to pass signals onto its child processes. Bash  seems to work correctly and so the exec is not needed if \/bin\/sh is bash  on your system. <span class='footnotereverse'><a href='#fnref-257-2'>&#8617;<\/a><\/span><\/li>\n<li id='fn-257-3'>  The dmctl commands and arguments should be reversed so it&#8217;s more like system v init scripts or the &#8220;service&#8221; command: &#8220;dmctl wordpress  stop&#8221; instead of the current &#8220;dmctl stop wordpress&#8221;. <span class='footnotereverse'><a href='#fnref-257-3'>&#8617;<\/a><\/span><\/li>\n<\/ol>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>It seems I&#8217;ve been writing little daemons a lot lately&#8211;small things that don&#8217;t want to run as root but still need to be launched in the background as services. I&#8217;ve been noticing because it&#8217;s such a pain to integrate them into the system once they are written (or installed). I have to mess around as &hellip; <a href=\"https:\/\/porkrind.org\/missives\/daemon-manager-manage-your-non-privileged-daemons\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Daemon-Manager: Manage your non-privileged daemons<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3,10],"tags":[],"class_list":["post-257","post","type-post","status-publish","format-standard","hentry","category-software","category-sysadmin"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/posts\/257","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/comments?post=257"}],"version-history":[{"count":22,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/posts\/257\/revisions"}],"predecessor-version":[{"id":501,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/posts\/257\/revisions\/501"}],"wp:attachment":[{"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/media?parent=257"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/categories?post=257"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/tags?post=257"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}