
#include "bacula_template.inc" title="Security Issues"

<h1>Bacula Security Issues</h1>
<ul>
<li>The Clients (<b>bacula-fd</b>) must run as root to be able to access
    all the system files.</li>
<li>It is not necessary to run the Director as root.</li>
<li>It is not necessary to run the Storage daemon as root, but you
    must ensure that it can open the tape drives, which are often
    restricted to root access by default.</li>
<li>You should restrict access to the Bacula configuration files,
    so that the passwords are not world-readable. The <b>Bacula</b>
    daemons are password protected using CRAM-MD5 (i.e. the password is not
    sent across the network). This will ensure that not everyone
    can access the daemons. It is a reasonably good protection, but
    can be cracked by experts.</li>
<li>If you are using the recommended ports 9101, 9102, and 9103, you
    will probably want to protect these ports from external access
    using a firewall and/or using tcp wrappers (<b>etc/hosts.allow</b>).
    </li>
<li>Currently all data that is sent across the network is unencrypted.
    As a consequence, unless you use <b>ssh</b> or <b>stunnel</b> for
    port forwarding, it is not recommended to do a backup across an
    insecure network (e.g.  the Internet).  In a future version, we plan
    to have <b>ssl</b> encryption built-in.</li>
<li>You should ensure that the Bacula working directories are
    readable and writable only by the Bacula daemons.</li>
<li>If you are using <b>MySQL</b> it is not necessary for it to
    run with <b>root</b> permission. </li>
<li>The default Bacula <b>grant-mysql-permissions</b> script
    grants all permissions to use the MySQL database without a 
    password. If you want security, please tighten this up! </li>
<li>Don't forget that Bacula is a network program, so anyone anywhere
    on the network with the console program and the Director's password
    can access Bacula and the backed up data.</li>
<li>You can restrict what IP addresses Bacula will bind to by using the
    appropriate <b>DirAddress</b>, <b>FDAddress</b>, or <b>SDAddress</b>
    records in the respective daemon configuration files.</li>
</ul>


<a name="wrappers"></a>
<h2>Configuring and Testing TCP Wrappers with Bacula</h2>
TCP Wrappers are implemented if
you turn them on when configuring (<b>./configure --with-libwrap</b>).
With this code enabled, you may control who may access your daemons.
This control is done by modifying the
file: <b>/etc/hosts.allow</b>. The program name that <b>Bacula</b>
uses when applying these access restrictions is the name you
specify in the daemon configuration file. You must not use
the <b>twist</b> option in your <b>/etc/hosts.allow</b> or it
will terminate the Bacula daemon when a connection is refused.
<p>
Dan Languille has provided the following information on configuring
and testing TCP wrappers with Bacula.
<p>
If you read hosts_options(5), you will see an option called twist.  
This option replaces the current process by an instance of the
specified shell command. Typically, something like this is used:

<pre>
ALL : ALL \\
 : severity auth.info \\
 : twist /bin/echo &quot;You are not welcome to use %d from %h.&quot;
</pre>

The libwrap code tries to avoid <b>twist</b> if it runs in a resident 
process, but that test will not protect the first hosts_access() 
call. This will result in the prcess (e.g. bacula-fd, bacula-sd, 
bacula-dir) being terminated if the first connection to their port 
results in the twist option being invoked. The potential, and I 
stree potential, exists for an attacker to prevent the daemons from 
running.

This situation is eliminated if your /etc/hosts.allow file contains 
an appropriate ruleset. The following example is sufficent:

<pre>
undef-fd : localhost : allow
undef-sd : localhost : allow
undef-dir : localhost : allow

undef-fd : ALL : deny
undef-sd : ALL : deny
undef-dir : ALL : deny
</pre>

You must adjust the daemon names to those found in the respective 
daemon configuration files. In these examples, the Director is undef-
dir, the Storage Daemon is undef-sd, and the File Daemon is undef-fd. 
Adjust to suit your situation. 

The above example rules assume that the SD, FD, and DIR all reside on 
the same box. If you have a remote FD client, then the following 
ruleset on the remote client will suffice:

<pre>
undef-fd : director.example.org : allow
undef-fd : ALL : deny
</pre>

where director.example.org is the host which will be contacting the 
client (ie. the box on which the Bacula Director daemon runs).

The use of "ALL : deny" ensures that the twist option (if present) is 
not invoked. 

To properly test your configuration, start the daemon(s), then 
attempt to connect from an IP address which should be able to 
connect. You should see something like this:

<pre>
$ telnet undef 9103
Trying 192.168.0.56...
Connected to undef.example.org.
Escape character is '^]'.
Connection closed by foreign host.
$
</pre>

This is the correct response. If you see this:

<pre>
$ telnet undef 9103
Trying 192.168.0.56...
Connected to undef.example.org.
Escape character is '^]'.
You are not welcome to use undef-sd from xeon.example.org.
Connection closed by foreign host.
$
</pre>

then twist has been invoked and your configuration is not correct and 
you need to add the deny statement.

It is important to note that your testing must include restarting the 
daemons after each connection attempt.

You can also tcpdchk(8) and tcpdmatch(8) to validate your 
/etc/hosts.allow rules. Here is a simple test using tcpdmatch:

<pre>
$ tcpdmatch undef-dir xeon.example.org
warning: undef-dir: no such process name in /etc/inetd.conf
client: hostname xeon.example.org
client: address 192.168.0.18
server: process undef-dir
matched: /etc/hosts.allow line 40
option: allow
access: granted
</pre>

If you are running Bacula as a standalone daemon, the warning above 
can be safely ignored.

Here is an example which indicates that your rules are missing a deny 
statement and the twist option has been invoked.

<pre>
$ tcpdmatch undef-dir 10.0.0.1
warning: undef-dir: no such process name in /etc/inetd.conf
client: address 10.0.0.1
server: process undef-dir
matched: /etc/hosts.allow line 91
option: severity auth.info
option: twist /bin/echo &quot;You are not welcome to use 
  undef-dir from 10.0.0.1.&quot;
access: delegated
</pre>


<h2>Running as non-root</h2>
Security advice from Dan Languille:
<p> 
<p>

  <tr>
        <td>
        It is a good idea to run daemons with the lowest possible privileges.
        In other words, if you can, don't run applications as root which do 
        not have to be root.
        The Storage Daemon and the Director Daemon do not need to be root.  The
        File Daemon needs to be root in order to access all files on your system.
        In order to run as non-root, you need to create a user and a group.
        Choosing <code class="code">bacula</code> as both the user name and the group name sounds like
        a good idea to me.

        <p>

        The FreeBSD port creates this user and group for you (actually, as I 
        write this, the port doesn't do that, but it soon will). Here is what those
        entries looked like on my FreeBSD laptop:

<pre>
bacula:*:1002:1002::0:0:Bacul Daemon:/var/db/bacula:/sbin/nologin
</pre>

        <p>
        I used vipw to create this entry.  I selected a User ID and Group ID
        of 1002 as they were unused on my system.

        <p>
        I also created a group in /etc/group:
        </p>

<pre>
bacula:*:1002:
</pre>

        <p>
        The bacula user (as opposed to the Bacula daemon) will have a home
        directory of <code class="code">/var/db/bacula</code> which is the
        default location for the Bacula database.

        <p>
        Now that you have both a bacula user and a bacula group, you can
        secure the bacula home directory by issuing this command:

<pre>
chown -R bacula:bacula /var/db/bacula/
</pre>

        This ensures that only the bacula user can access this directory.
        It also means that if we run the Director and the Storage daemon
        as bacula, those daemons also have restricted access.  This would not be
        the case if they were running as root.

        <p>

        It is important to note that the storage daemon actually needs
        to be in the operator group for normal access to tape drives etc (at
        least on a FreeBSD system, that's how things are set up by default)
        Such devices are normally chown root:operator.  It is easier and less
        error prone
        to make Bacula a member of that group than it is to play around
        with system permissions.

        </td>
  </tr>


        <tr>
                <td height="10"></td>
        </tr>

  <tr>
    <td>

    <div class="section">Starting the Bacula daemons</div>
    </td>
  </tr>

  <tr>
        <td>
To start the bacula daemons on a FreeBSD system, issue the following command:

<pre>
/usr/local/etc/rc.d/bacula.sh start
</pre>

To confirm they are all running:

<pre>
$ ps auwx | grep bacula<br>
root&nbsp;63416&nbsp;0.0&nbsp;0.3&nbsp;2040 1172&nbsp;??&nbsp;Ss&nbsp;4:09PM 0:00.01 
    /usr/local/sbin/bacula-sd -v -c /usr/local/etc/bacula-sd.conf<br>
root&nbsp;63418&nbsp;0.0&nbsp;0.3&nbsp;1856 1036&nbsp;??&nbsp;Ss&nbsp;4:09PM 0:00.00 
    /usr/local/sbin/bacula-fd -v -c /usr/local/etc/bacula-fd.conf<br>
root&nbsp;63422&nbsp;0.0&nbsp;0.4&nbsp;2360 1440&nbsp;??&nbsp;Ss&nbsp;4:09PM 0:00.00 
    /usr/local/sbin/bacula-dir -v -c /usr/local/etc/bacula-dir.conf<br>
</pre>


<page_prev name="Using Stunnel of Comm Encryption" url="stunnel.html">
<page_next name="Firewalls" url="firewalls.html">
