commit 5940999a49af50ff49aeabb1103543889c598312 Author: Arturo Filastò arturo@filasto.net Date: Mon May 30 15:24:07 2016 +0200
Fix privilege shedding and daemonisation of oonibackend (#80)
* Fix privilege shedding and daemonisation of oonibackend
* Rewrite to use twistd
* Launch tor only after we have forked
* Set the UID of when starting tor
This fixes #65
* Add gitignore files and remove empty.txt files
* Drop support for super old versions of txtorcon
* Remove now unnecessary hacks to maintain backward compatibility
* Fix permissions on temporary tor data directory --- bin/oonib | 38 ++----- data/archive/.gitignore | 2 + data/archive/empty.txt | 2 - data/decks/.gitignore | 3 + data/inputs/.gitignore | 3 + data/reports/.gitignore | 2 + data/tor/.gitignore | 2 + data/tor/empty.txt | 2 - oonib.conf.example | 4 - oonib/config.py | 2 + oonib/log.py | 61 +---------- oonib/onion.py | 63 +++++------ oonib/oonibackend.py | 280 ++++++++++++++++++++++++++---------------------- requirements.txt | 2 +- setup.py | 6 +- 15 files changed, 213 insertions(+), 259 deletions(-)
diff --git a/bin/oonib b/bin/oonib index 109c74e..ccbe246 100755 --- a/bin/oonib +++ b/bin/oonib @@ -2,55 +2,35 @@
import sys import os -from twisted.python import log, usage -from twisted.internet import reactor -from twisted.application import app
# Hack to set the proper sys.path. Overcomes the export PYTHONPATH pain. sys.path[:] = map(os.path.abspath, sys.path) sys.path.insert(0, os.path.abspath(os.getcwd()))
-from oonib import errors as e +from oonib import errors from oonib.config import config -from oonib.log import LoggerFactory - try: config.load() -except e.ConfigFileNotSpecified: +except errors.ConfigFileNotSpecified: print "Config file not specified!" print "Use -c to specify one!" config.usageOptions() sys.exit(1) -except e.ConfigFileDoesNotExist, path: +except errors.ConfigFileDoesNotExist, path: print "Config file "%s" does not exist!" % path sys.exit(2) -except e.InvalidReportDirectory, path: +except errors.InvalidReportDirectory, path: print "Invalid report directory: %s!" % path sys.exit(3) -except e.InvalidArchiveDirectory, path: +except errors.InvalidArchiveDirectory, path: print "Invalid archive directory: %s!" % path sys.exit(4) -except e.InvalidInputDirectory, path: +except errors.InvalidInputDirectory, path: print "Invalid input directory: %s" % path sys.exit(5) -except e.InvalidDeckDirectory, path: +except errors.InvalidDeckDirectory, path: print "Invalid deck directory: %s" % path sys.exit(6)
-if config.main.chroot: - sys.argv.append('--chroot') - sys.argv.append(config.chroot) - -if not config.main.nodaemon: - sys.argv.append('-y') - -from oonib.oonibackend import application - -from twisted.scripts._twistd_unix import UnixApplicationRunner -class OBaseRunner(UnixApplicationRunner): - temporary_data_dir = None - def createOrGetApplication(self): - return application - -OBaseRunner.loggerFactory = LoggerFactory -OBaseRunner(config.main).run() +from oonib import oonibackend +oonibackend.start() diff --git a/data/archive/.gitignore b/data/archive/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/data/archive/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/data/archive/empty.txt b/data/archive/empty.txt deleted file mode 100644 index 9a166f9..0000000 --- a/data/archive/empty.txt +++ /dev/null @@ -1,2 +0,0 @@ -In here will end up the archived reports. -This file may be deleted at any time. diff --git a/data/decks/.gitignore b/data/decks/.gitignore new file mode 100644 index 0000000..514e47a --- /dev/null +++ b/data/decks/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!README diff --git a/data/inputs/.gitignore b/data/inputs/.gitignore new file mode 100644 index 0000000..a0991ff --- /dev/null +++ b/data/inputs/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!Makefile diff --git a/data/reports/.gitignore b/data/reports/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/data/reports/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/data/tor/.gitignore b/data/tor/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/data/tor/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/data/tor/empty.txt b/data/tor/empty.txt deleted file mode 100644 index ec3be8f..0000000 --- a/data/tor/empty.txt +++ /dev/null @@ -1,2 +0,0 @@ -In here will end up all tor related files. -This file may be deleted at any time. diff --git a/oonib.conf.example b/oonib.conf.example index 6f4c7f3..bcf8393 100644 --- a/oonib.conf.example +++ b/oonib.conf.example @@ -7,8 +7,6 @@ main: bouncer_file: data/bouncer.yaml
logfile: null - database_uri: 'sqlite://oonib_test_db.db' - db_threadpool_size: 10 tor_binary: null socks_port: 9055 tor2webmode: false @@ -21,9 +19,7 @@ main: euid: null uid: null gid: null - uuid: null no_save: true - profile: null debug: false stale_time: 3600
diff --git a/oonib/config.py b/oonib/config.py index 31128a9..be29ec1 100644 --- a/oonib/config.py +++ b/oonib/config.py @@ -28,6 +28,8 @@ class Config(object): raise e.ConfigFileDoesNotExist(config_file)
self.main = Storage(configuration['main'].items()) + if self.main.logfile is None: + self.main.logfile = 'oonib.log'
self.helpers = Storage() for name, helper in configuration['helpers'].items(): diff --git a/oonib/log.py b/oonib/log.py index a79199e..c229f35 100644 --- a/oonib/log.py +++ b/oonib/log.py @@ -6,18 +6,14 @@ Twisted logger for the ooni backend system. """
-import os import sys import codecs import logging import traceback
from twisted.python import log as txlog -from twisted.python import util from twisted.python.failure import Failure -from twisted.python.logfile import DailyLogFile
-from oonib import otime from oonib.config import config
# Get rid of the annoying "No route found for @@ -47,56 +43,21 @@ def log_encode(logmsg): repr(logmsg)))
-class LogWithNoPrefix(txlog.FileLogObserver): - def emit(self, eventDict): - text = txlog.textFromEventDict(eventDict) - if text is None: - return - - util.untilConcludes(self.write, "%s\n" % text) - util.untilConcludes(self.flush) # Hoorj! - - -def start(application_name="oonib"): - daily_logfile = None - - if not config.main.logfile: - logfile = 'oonib.log' - else: - logfile = config.main.logfile - - log_folder = os.path.dirname(logfile) - log_filename = os.path.basename(logfile) - - daily_logfile = DailyLogFile(log_filename, log_folder) - - txlog.msg("Starting %s on %s (%s UTC)" % (application_name, - otime.prettyDateNow(), - otime.utcPrettyDateNow())) - txlog.msg("oonib version %s" % config.backend_version) - txlog.startLoggingWithObserver(LogWithNoPrefix(sys.stdout).emit) - txlog.addObserver(txlog.FileLogObserver(daily_logfile).emit) - - -def stop(): - print "Stopping OONI" - - def msg(msg, *arg, **kw): - print "%s" % log_encode(msg) + txlog.msg("%s" % log_encode(msg))
def debug(msg, *arg, **kw): if config.main.get('debug'): - print "[D] %s" % log_encode(msg) + txlog.msg("[D] %s" % log_encode(msg))
def warn(msg, *arg, **kw): - print "[W] %s" % log_encode(msg) + txlog.msg("[W] %s" % log_encode(msg))
def err(msg, *arg, **kw): - print "[!] %s" % log_encode(msg) + txlog.err("[!] %s" % log_encode(msg))
def exception(error): @@ -109,17 +70,3 @@ def exception(error): else: exc_type, exc_value, exc_traceback = sys.exc_info() traceback.print_exception(exc_type, exc_value, exc_traceback) - - -class LoggerFactory(object): - """ - This is a logger factory to be used by oonib - """ - def __init__(self, options): - pass - - def start(self, application): - start("OONIB") - - def stop(self): - txlog.msg("Stopping OONIB") diff --git a/oonib/onion.py b/oonib/onion.py index 0a7a155..9a5c2c3 100644 --- a/oonib/onion.py +++ b/oonib/onion.py @@ -1,31 +1,17 @@ +import pwd import tempfile + from oonib import log from oonib.config import config -from twisted.internet import reactor, endpoints, defer +from twisted.internet import defer import os
from random import randint import socket
-from txtorcon import TCPHiddenServiceEndpoint, TorConfig +from txtorcon import TorConfig from txtorcon import launch_tor
-from txtorcon import __version__ as txtorcon_version -if tuple(map(int, txtorcon_version.split('.'))) < (0, 9, 0): - """ - Fix for bug in txtorcon versions < 0.9.0 where TCPHiddenServiceEndpoint - listens on all interfaces by default. - """ - def create_listener(self, proto): - self._update_onion(self.hiddenservice.dir) - self.tcp_endpoint = endpoints.TCP4ServerEndpoint(self.reactor, - self.listen_port, - interface='127.0.0.1') - d = self.tcp_endpoint.listen(self.protocolfactory) - d.addCallback(self._add_attributes).addErrback(self._retry_local_port) - return d - TCPHiddenServiceEndpoint._create_listener = create_listener - def randomFreePort(addr="127.0.0.1"): """ Args: @@ -56,11 +42,15 @@ def txSetupFailed(failure): def _configTor(): torconfig = TorConfig()
- if config.main.socks_port: - torconfig.SocksPort = config.main.socks_port - if config.main.control_port: - torconfig.ControlPort = config.main.control_port - if config.main.tor2webmode: + if config.main.socks_port is None: + config.main.socks_port = int(randomFreePort()) + torconfig.SocksPort = config.main.socks_port + + if config.main.control_port is None: + config.main.control_port = int(randomFreePort()) + torconfig.ControlPort = config.main.control_port + + if config.main.tor2webmode is True: torconfig.Tor2webMode = 1 torconfig.CircuitBuildTimeout = 60 if config.main.tor_datadir is None: @@ -68,26 +58,29 @@ def _configTor(): log.warn("Option 'tor_datadir' in oonib.conf is unspecified!") log.warn("Using %s" % temporary_data_dir) torconfig.DataDirectory = temporary_data_dir + uid = -1 + gid = -1 + if config.main.uid is not None: + uid = config.main.uid + if config.main.gid is not None: + gid = config.main.gid + os.chown(temporary_data_dir, uid, gid) else: if os.path.exists(config.main.tor_datadir): torconfig.DataDirectory = os.path.abspath(config.main.tor_datadir) else: raise Exception("Could not find tor datadir")
+ if config.main.uid is not None: + try: + user = pwd.getpwuid(config.main.uid)[0] + except KeyError: + raise Exception("Invalid user ID") + torconfig.User = user + tor_log_file = os.path.join(torconfig.DataDirectory, "tor.log") torconfig.Log = ["notice stdout", "notice file %s" % tor_log_file] torconfig.save() - if not hasattr(torconfig, 'ControlPort'): - control_port = int(randomFreePort()) - torconfig.ControlPort = control_port - config.main.control_port = control_port - - if not hasattr(torconfig, 'SocksPort'): - socks_port = int(randomFreePort()) - torconfig.SocksPort = socks_port - config.main.socks_port = socks_port - - torconfig.save() return torconfig
# get_global_tor is a near-rip of that from txtorcon (so you can have some @@ -110,7 +103,7 @@ def get_global_tor(reactor):
# start Tor launching def updates(prog, tag, summary): - print("%d%%: %s" % (prog, summary)) + log.msg("%d%%: %s" % (prog, summary)) yield launch_tor(_global_tor_config, reactor, progress_updates=updates, tor_binary=config.main.tor_binary) diff --git a/oonib/oonibackend.py b/oonib/oonibackend.py index ebf3c52..a57bf92 100644 --- a/oonib/oonibackend.py +++ b/oonib/oonibackend.py @@ -7,7 +7,9 @@ # In here we start all the test helpers that are required by ooniprobe and # start the report collector
-from distutils.version import LooseVersion +import os +import sys +
from oonib.api import ooniBackend, ooniBouncer from oonib.config import config @@ -15,107 +17,22 @@ from oonib.onion import get_global_tor from oonib.testhelpers import dns_helpers, ssl_helpers from oonib.testhelpers import http_helpers, tcp_helpers
-import os - +from twisted.scripts import twistd +from twisted.python import usage from twisted.application import internet, service -from twisted.internet import reactor, endpoints, ssl, defer +from twisted.internet import reactor, endpoints, ssl from twisted.names import dns
-from txtorcon import TCPHiddenServiceEndpoint, TorConfig -from txtorcon import __version__ as txtorcon_version - -if config.main.uid and config.main.gid: - application = service.Application('oonibackend', uid=config.main.uid, - gid=config.main.gid) -else: - application = service.Application('oonibackend') - -multiService = service.MultiService() - -if config.helpers['ssl'].port: - print "Starting SSL helper on %s" % config.helpers['ssl'].port - ssl_helper = internet.SSLServer(int(config.helpers['ssl'].port), - http_helpers.HTTPReturnJSONHeadersHelper(), - ssl_helpers.SSLContext(config)) - multiService.addService(ssl_helper) - ssl_helper.startService() - -# Start the DNS Server related services -if config.helpers['dns'].tcp_port: - print "Starting TCP DNS Helper on %s" % config.helpers['dns'].tcp_port - tcp_dns_helper = internet.TCPServer(int(config.helpers['dns'].tcp_port), - dns_helpers.DNSTestHelper()) - multiService.addService(tcp_dns_helper) - tcp_dns_helper.startService() - -if config.helpers['dns'].udp_port: - print "Starting UDP DNS Helper on %s" % config.helpers['dns'].udp_port - udp_dns_factory = dns.DNSDatagramProtocol(dns_helpers.DNSTestHelper()) - udp_dns_helper = internet.UDPServer(int(config.helpers['dns'].udp_port), - udp_dns_factory) - multiService.addService(udp_dns_helper) - udp_dns_helper.startService() - -if config.helpers['dns_discovery'].udp_port: - print ("Starting UDP DNS Discovery Helper on %s" % - config.helpers['dns_discovery'].udp_port) - udp_dns_discovery = internet.UDPServer( - int(config.helpers['dns_discovery'].udp_port), - dns.DNSDatagramProtocol(dns_helpers.DNSResolverDiscovery()) - ) - multiService.addService(udp_dns_discovery) - -if config.helpers['dns_discovery'].tcp_port: - print ("Starting TCP DNS Discovery Helper on %s" % - config.helpers['dns_discovery'].tcp_port) - tcp_dns_discovery = internet.TCPServer( - int(config.helpers['dns_discovery'].tcp_port), - dns_helpers.DNSResolverDiscovery() - ) - multiService.addService(tcp_dns_discovery) - tcp_dns_discovery.startService() - - -# XXX this needs to be ported -# Start the OONI daphn3 backend -if config.helpers['daphn3'].port: - print "Starting Daphn3 helper on %s" % config.helpers['daphn3'].port - daphn3_helper = internet.TCPServer(int(config.helpers['daphn3'].port), - tcp_helpers.Daphn3Server()) - multiService.addService(daphn3_helper) - daphn3_helper.startService() - - -if config.helpers['tcp-echo'].port: - print "Starting TCP echo helper on %s" % config.helpers['tcp-echo'].port - tcp_echo_helper = internet.TCPServer(int(config.helpers['tcp-echo'].port), - tcp_helpers.TCPEchoHelper()) - multiService.addService(tcp_echo_helper) - tcp_echo_helper.startService() - -if config.helpers['http-return-json-headers'].port: - print ("Starting HTTP return request helper on %s" % - config.helpers['http-return-json-headers'].port) - http_return_request_helper = internet.TCPServer( - int(config.helpers['http-return-json-headers'].port), - http_helpers.HTTPReturnJSONHeadersHelper()) - multiService.addService(http_return_request_helper) - http_return_request_helper.startService()
def getHSEndpoint(endpoint_config): + from txtorcon import TCPHiddenServiceEndpoint hsdir = endpoint_config['hsdir'] hsdir = os.path.expanduser(hsdir) hsdir = os.path.realpath(hsdir) - if LooseVersion(txtorcon_version) >= LooseVersion('0.10.0'): - return TCPHiddenServiceEndpoint(reactor, - get_global_tor(reactor), - 80, - hidden_service_dir=hsdir) - else: - return TCPHiddenServiceEndpoint(reactor, - get_global_tor(reactor), - 80, - data_dir=hsdir) + return TCPHiddenServiceEndpoint(reactor, + config=get_global_tor(reactor), + public_port=80, + hidden_service_dir=hsdir)
def getTCPEndpoint(endpoint_config): return endpoints.TCP4ServerEndpoint( @@ -159,35 +76,146 @@ def createService(endpoint, role, endpoint_config): endpoint, factory ) service.setName("-".join([endpoint_config['type'], role])) - multiService.addService(service) - service.startService() - -# this is to ensure same behaviour with an old config file -if config.main.tor_hidden_service and \ - config.main.bouncer_endpoints is None and \ - config.main.collector_endpoints is None: - base_dir = '.' - if config.main.tor_datadir is not None: - base_dir = config.main.tor_datadir - bouncer_hsdir = os.path.join(base_dir, 'bouncer') - collector_hsdir = os.path.join(base_dir, 'collector') - config.main.bouncer_endpoints = [ {'type': 'onion', 'hsdir': bouncer_hsdir} ] - config.main.collector_endpoints = [ {'type': 'onion', 'hsdir': collector_hsdir} ] - -for endpoint_config in config.main.get('bouncer_endpoints', []): - if config.main.bouncer_file: - print "Starting bouncer with config %s" % endpoint_config - endpoint = getEndpoint(endpoint_config) - createService(endpoint, 'bouncer', endpoint_config) - else: - print "No bouncer configured" - -for endpoint_config in config.main.get('collector_endpoints', []): - print "Starting collector with config %s" % endpoint_config - endpoint = getEndpoint(endpoint_config) - createService(endpoint, 'collector', endpoint_config) - -for endpoint_config in config.helpers.web_connectivity.get('endpoints', []): - print "Starting web_connectivity helper with config %s" % endpoint_config - endpoint = getEndpoint(endpoint_config) - createService(endpoint, 'web_connectivity', endpoint_config) + return service + +class StartOONIBackendPlugin: + tapname = "oonibackend" + def makeService(self, so): + ooniBackendService = service.MultiService() + + if config.helpers['ssl'].port: + print "Starting SSL helper on %s" % config.helpers['ssl'].port + ssl_helper = internet.SSLServer(int(config.helpers['ssl'].port), + http_helpers.HTTPReturnJSONHeadersHelper(), + ssl_helpers.SSLContext(config)) + ooniBackendService.addService(ssl_helper) + + # Start the DNS Server related services + if config.helpers['dns'].tcp_port: + print "Starting TCP DNS Helper on %s" % config.helpers['dns'].tcp_port + tcp_dns_helper = internet.TCPServer(int(config.helpers['dns'].tcp_port), + dns_helpers.DNSTestHelper()) + ooniBackendService.addService(tcp_dns_helper) + + if config.helpers['dns'].udp_port: + print "Starting UDP DNS Helper on %s" % config.helpers['dns'].udp_port + udp_dns_factory = dns.DNSDatagramProtocol(dns_helpers.DNSTestHelper()) + udp_dns_helper = internet.UDPServer(int(config.helpers['dns'].udp_port), + udp_dns_factory) + ooniBackendService.addService(udp_dns_helper) + + if config.helpers['dns_discovery'].udp_port: + print ("Starting UDP DNS Discovery Helper on %s" % + config.helpers['dns_discovery'].udp_port) + udp_dns_discovery = internet.UDPServer( + int(config.helpers['dns_discovery'].udp_port), + dns.DNSDatagramProtocol(dns_helpers.DNSResolverDiscovery()) + ) + ooniBackendService.addService(udp_dns_discovery) + + if config.helpers['dns_discovery'].tcp_port: + print ("Starting TCP DNS Discovery Helper on %s" % + config.helpers['dns_discovery'].tcp_port) + tcp_dns_discovery = internet.TCPServer( + int(config.helpers['dns_discovery'].tcp_port), + dns_helpers.DNSResolverDiscovery() + ) + ooniBackendService.addService(tcp_dns_discovery) + + # XXX this needs to be ported + # Start the OONI daphn3 backend + if config.helpers['daphn3'].port: + print "Starting Daphn3 helper on %s" % config.helpers['daphn3'].port + daphn3_helper = internet.TCPServer(int(config.helpers['daphn3'].port), + tcp_helpers.Daphn3Server()) + ooniBackendService.addService(daphn3_helper) + + if config.helpers['tcp-echo'].port: + print "Starting TCP echo helper on %s" % config.helpers['tcp-echo'].port + tcp_echo_helper = internet.TCPServer(int(config.helpers['tcp-echo'].port), + tcp_helpers.TCPEchoHelper()) + ooniBackendService.addService(tcp_echo_helper) + + if config.helpers['http-return-json-headers'].port: + print ("Starting HTTP return request helper on %s" % + config.helpers['http-return-json-headers'].port) + http_return_request_helper = internet.TCPServer( + int(config.helpers['http-return-json-headers'].port), + http_helpers.HTTPReturnJSONHeadersHelper()) + ooniBackendService.addService(http_return_request_helper) + + # this is to ensure same behaviour with an old config file + if config.main.tor_hidden_service and \ + config.main.bouncer_endpoints is None and \ + config.main.collector_endpoints is None: + bouncer_hsdir = os.path.join(config.main.tor_datadir, 'bouncer') + collector_hsdir = os.path.join(config.main.tor_datadir, 'collector') + config.main.bouncer_endpoints = [ {'type': 'onion', 'hsdir': bouncer_hsdir} ] + config.main.collector_endpoints = [ {'type': 'onion', 'hsdir': collector_hsdir} ] + + for endpoint_config in config.main.get('bouncer_endpoints', []): + if config.main.bouncer_file: + print "Starting bouncer with config %s" % endpoint_config + endpoint = getEndpoint(endpoint_config) + bouncer_service = createService(endpoint, 'bouncer', + endpoint_config) + ooniBackendService.addService(bouncer_service) + else: + print "No bouncer configured" + + for endpoint_config in config.main.get('collector_endpoints', []): + print "Starting collector with config %s" % endpoint_config + endpoint = getEndpoint(endpoint_config) + collector_service = createService(endpoint, 'collector', + endpoint_config) + ooniBackendService.addService(collector_service) + + for endpoint_config in config.helpers.web_connectivity.get('endpoints', []): + print "Starting web_connectivity helper with config %s" % endpoint_config + endpoint = getEndpoint(endpoint_config) + web_connectivity_service = createService(endpoint, + 'web_connectivity', + endpoint_config) + ooniBackendService.addService(web_connectivity_service) + + + return ooniBackendService + +class OONIBackendTwistdConfig(twistd.ServerOptions): + subCommands = [("StartOONIBackend", None, usage.Options, "node")] + +def start(): + twistd_args = [] + + flags = [ + 'nodaemon', + 'no_save' + ] + options = [ + 'pidfile', + 'logfile', + 'rundir', + 'euid', + 'gid', + 'uid', + 'umask' + ] + for option in options: + if config.main.get(option, None) is not None: + twistd_args.append('--%s' % option) + twistd_args.append(config.main.get(option)) + for flag in flags: + if config.main.get(flag, None) is True: + twistd_args.append('--%s'% flag) + + twistd_args.append('StartOONIBackend') # Point to our backend plugin + twistd_config = OONIBackendTwistdConfig() + try: + twistd_config.parseOptions(twistd_args) + except usage.error, ue: + print "Usage error from twistd" + sys.exit(7) + + twistd_config.loadedPlugins = {'StartOONIBackend': StartOONIBackendPlugin()} + twistd.runApp(twistd_config) + return 0 diff --git a/requirements.txt b/requirements.txt index b8c18a8..91a711a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ Twisted>=13.2.0 cyclone>=1.1 ipaddr>=2.1.10 pygeoip>=0.2.6 -txtorcon>=0.7 +txtorcon>=0.11.0 pyOpenSSL>=0.13 zope.component>=4.0.0 zope.event>=4.0.0 diff --git a/setup.py b/setup.py index 2113d21..39cb1f9 100644 --- a/setup.py +++ b/setup.py @@ -67,9 +67,9 @@ data_files = [ (data_dir, ['oonib.conf.example']), (os.path.join(data_dir, 'decks'), ['data/decks/README']), (os.path.join(data_dir, 'inputs'), ['data/inputs/Makefile']), - (os.path.join(spool_dir, 'reports'), ['data/reports/empty.txt']), - (os.path.join(spool_dir, 'archive'), ['data/archive/empty.txt']), - (os.path.join(var_dir, 'tor'), ['data/tor/empty.txt']), + (os.path.join(spool_dir, 'reports'), ['data/reports/.gitignore']), + (os.path.join(spool_dir, 'archive'), ['data/archive/.gitignore']), + (os.path.join(var_dir, 'tor'), ['data/tor/.gitignore']), (var_dir, ['data/bouncer.yaml', 'data/policy.yaml']) ]