Merge remote-tracking branch 'shared/master'
authormh <mh@immerda.ch>
Tue, 13 Feb 2018 00:22:57 +0000 (01:22 +0100)
committermh <mh@immerda.ch>
Tue, 13 Feb 2018 00:22:57 +0000 (01:22 +0100)
21 files changed:
1  2 
.gitlab-ci.yml
Gemfile
README.md
Rakefile
manifests/base.pp
manifests/compact.pp
manifests/daemon/control.pp
manifests/daemon/directory.pp
manifests/daemon/dns.pp
manifests/daemon/hidden_service.pp
manifests/daemon/onion_service.pp
manifests/daemon/params.pp
manifests/daemon/relay.pp
manifests/daemon/socks.pp
manifests/daemon/transparent.pp
manifests/munin.pp
manifests/onionbalance.pp
manifests/repo.pp
metadata.json
templates/torrc.global.erb
templates/torrc.onion_service.erb

diff --cc .gitlab-ci.yml
index 0000000,21907f7..268210d
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,20 +1,21 @@@
+ image: ruby:2.3
+ # Test job template
+ .test_template: &test_definition
+   stage: test
+   script:
+     - bundle install --jobs $(nproc) --without docs --path vendor
+     - bundle exec rake tests
++    - bundle exec rake spec
+ # Test with version present on Debian stable
+ test:puppet48:
+   variables:
+     PUPPET_VERSION: "~> 4.8.2"
+     FACTER_VERSION: '~> 2.4.6'
+     HIERA_VERSION: '~> 3.2.0'
+   <<: *test_definition
+ # Test with latest Puppet release
+ test:puppetlatest:
+   <<: *test_definition
diff --cc Gemfile
+++ b/Gemfile
@@@ -1,49 -1,12 +1,18 @@@
- source ENV['GEM_SOURCE'] || 'https://rubygems.org'
- def location_for(place, fake_version = nil)
-   if place =~ /^(git[:@][^#]*)#(.*)/
-     [fake_version, { :git => $1, :branch => $2, :require => false }].compact
-   elsif place =~ /^file:\/\/(.*)/
-     ['>= 0', { :path => File.expand_path($1), :require => false }]
-   else
-     [place, { :require => false }]
-   end
- end
- group :development, :unit_tests do
-   # rspec must be v2 for ruby 1.8.7
-   if RUBY_VERSION >= '1.8.7' and RUBY_VERSION < '1.9'
-     gem 'rspec', '~> 2.0'
-   else
-     gem 'rspec', '~> 3.1.0',     :require => false
-   end
-   gem 'rake', '~> 10.1.0',       :require => false
-   gem 'rspec-puppet', '~> 2.2',  :require => false
-   gem 'mocha',                   :require => false
-   # keep for its rake task for now
-   gem 'puppetlabs_spec_helper',  :require => false
-   gem 'puppet-lint',             :require => false
-   gem 'librarian-puppet',        :require => false
-   gem 'metadata-json-lint',      :require => false
-   gem 'pry',                     :require => false
-   gem 'simplecov',               :require => false
- end
- facterversion = ENV['GEM_FACTER_VERSION'] || ENV['FACTER_GEM_VERSION']
- if facterversion
-   gem 'facter', *location_for(facterversion)
- else
-   gem 'facter', :require => false
- end
++# vim:ft=ruby
+ source 'https://rubygems.org'
  
- puppetversion = ENV['GEM_PUPPET_VERSION'] || ENV['PUPPET_GEM_VERSION']
- if puppetversion
-   gem 'puppet', *location_for(puppetversion)
- else
-   gem 'puppet', :require => false
- end
+ gem 'rake'
 -gem 'puppet', ENV['PUPPET_VERSION']
++# 5.3.4 is currently broken
++# https://github.com/rodjek/rspec-puppet/issues/647
++gem 'puppet', ENV['PUPPET_VERSION'] || '< 5.3.4'
 +
 +gem 'base32'
  
- # vim:ft=ruby
+ group :tests do
+   gem 'facter', ENV['FACTER_VERSION']
+   gem 'hiera', ENV['HIERA_VERSION']
+   gem 'puppetlabs_spec_helper'
++  gem 'librarian-puppet'
+   gem 'metadata-json-lint'
+   gem 'semantic_puppet'
+ end
diff --cc README.md
index 0000000,2cf89df..97213c4
mode 000000,100644..100644
--- /dev/null
+++ b/README.md
@@@ -1,0 -1,245 +1,262 @@@
 -  * [Configuring hidden services](#configuring-hidden-services)
+ # tor
+ #### Table of Contents
+ * [Overview](#overview)
+   * [Upgrade Notice](#upgrade-notice)
+ * [Dependencies](#dependencies)
+ * [Usage](#usage)
+   * [Installing tor](#installing-tor)
+   * [Configuring SOCKS](#configuring-socks)
+   * [Installing torsocks](#installing-torsocks)
+   * [Configuring relays](#configuring-relays)
+   * [Configuring the control](#configuring-control)
 -munin graphs if desired and allows for configuration of relays, hidden services,
++  * [Configuring onion services](#configuring-onion-services)
+   * [Configuring directories](#configuring-directories)
+   * [Configuring exit policies](#configuring-exit-policies)
+   * [Configuring transport plugins](#configuring-transport-plugins)
++* [Functions](#functions)
+ * [Polipo](#polipo)
+ * [Munin](#munin)
+ # Overview<a name="overview"></a>
+ This module tries to manage tor, making sure it is installed, running, has
 -## Configuring hidden services<a name="configuring-hidden-services"></a>
++munin graphs if desired and allows for configuration of relays, onion services,
+ exit policies, etc.
+ ## Upgrade Notice<a name="upgrade-notice"></a>
+  * All of the `listen_address` variables have been deprecated, since they have
+    been deprecated in tor since 0.2.3.x-alpha. Please read the new tor man page
+    if you were using those variables.
+  * Previously, if you did not set the `$outbound_bindaddress` variable, it was
+    being automatically set to the `$listen_address variable`. Now this is not
+    being done and instead you will need to set the `$outbound_bindaddress`
+    explicitly for it to be set.
+  * The `tor::relay{}` variables `$bandwidth_rate` and `$bandwidth_burst` were
+    previously used for the tor configuration variables `RelayBandwidthRate` and
+    `RelayBandwidthBurst`, these have been renamed to `$relay_bandwidth_rate`
+    and `$relay_bandwidth_burst`. If you were using these, please rename your
+    variables in your configuration.
+  * The variables `$bandwidth_rate` and `$bandwidth_burst` are now used for the
+    tor configuration variables `BandwidthRate` and `BandwidthBurst`. If you
+    used `$bandwidth_rate` or `$bandwidth_burst` please be aware that these
+    values have changed and adjust your configuration as necessary.
+  * The `$tor_ensure_version` was converted to a parameter for the tor and
+    `tor::daemon` classes.
+  * The `$torsocks_ensure_version` was converted to a parameter for the
+    `tor::torsocks` class.
+  * The options that used to be settable with the `tor::daemon::global_opts`
+    define now are parameters for the `tor::daemon class`, and
+    `tor::daemon::global_opts` was removed accordingly.
+ # Dependencies<a name="dependencies"></a>
+ This module needs:
+  * the [concat module](https://github.com/puppetlabs/puppetlabs-concat.git)
+ # Usage<a name="usage"></a>
+ ## Installing tor<a name="installing-tor"></a>
+ To install tor, simply include the 'tor' class in your manifests:
+     class { 'tor': }
+ You can specify the `$ensure_version` class parameter to get a specific
+ version installed.
+ However, if you want to make configuration changes to your tor daemon, you will
+ want to instead include the `tor::daemon` class in your manifests, which will
+ inherit the `tor` class from above:
+     class { '::tor::daemon': }
+ You have the following class parameters that you can specify:
+     data_dir    (default: '/var/lib/tor')
+     config_file (default: '/etc/tor/torrc')
+     use_bridges (default: 0)
+     automap_hosts_on_resolve (default: 0)
+     log_rules   (default: ['notice file /var/log/tor/notices.log'])
+ The `data_dir` will be used for the tor user's `$HOME`, and the tor
+ `DataDirectory` value.
+ The `config_file` will be managed and the daemon restarted when it changed.
+ `use_bridges` and `automap_hosts_on_resolve` are used to set the `UseBridges`
+ and `AutomapHostsOnResolve` torrc settings.
+ The `log_rules` can be an array of different Log lines, each will be added to
+ the config, for example the following will use syslog:
+     class { '::tor::daemon':
+         log_rules => [ 'notice syslog' ],
+     }
+ If you want to set specific options for the tor class, you may pass them
+ directly to the tor::daemon in your manifests, e.g.:
+     class { '::tor::daemon':
+       use_munin                 => true,
+       automap_hosts_on_resolve  => 1,
+     }
+ ## Configuring SOCKS<a name="configuring-socks"></a>
+ To configure tor socks support, you can do the following:
+     tor::daemon::socks { "listen_locally":
+       port     => 0,
+       policies => 'your super policy';
+     }
+ ## Installing torsocks<a name="installing-torsocks"></a>
+ To install torsocks, simply include the `torsocks` class in your manifests:
+     class { 'tor::torsocks': }
+ You can specify the `$ensure_version` class parameter to get a specific
+ version installed.
+ # Configuring relays<a name="configuring-relays"></a>
+ An example relay configuration:
+     tor::daemon::relay { "foobar":
+       port             => '9001',
+       address          => '192.168.0.1',
+       bandwidth_rate   => '256',
+       bandwidth_burst  => '256',
+       contact_info     => "Foo <collective at example dot com>",
+       my_family        => '<long family string here>';
+     }
+ You have the following options that can be passed to a relay, with the defaults
+ shown:
+  
+     $port                    = 0,
+     $portforwarding          = 0,     # PortForwarding 0|1, set for opening ports at the router via UPnP.
+                                       # Requires 'tor-fw-helper' binary present.
+     $bandwidth_rate          = '',    # KB/s, defaulting to using tor's default: 5120KB/s
+     $bandwidth_burst         = '',    # KB/s, defaulting to using tor's default: 10240KB/s
+     $relay_bandwidth_rate    = 0,     # KB/s, 0 for no limit.
+     $relay_bandwidth_burst   = 0,     # KB/s, 0 for no limit.
+     $accounting_max          = 0,     # GB, 0 for no limit.
+     $accounting_start        = [],
+     $contact_info            = '',
+     $my_family               = '', # TODO: autofill with other relays
+     $address                 = "tor.${domain}",
+     $bridge_relay            = 0,
+     $ensure                  = present
+     $nickname                = $name
+ ## Configuring the control<a name="configuring-control"></a>
+ To pass parameters to configure the `ControlPort` and the
+ `HashedControlPassword`, you would do something like this:
+     tor::daemon::control { "foo-control": 
+       port                    => '80',
+       hashed_control_password => '<somehash>',
+       ensure                  => present;
+     }
+ Note: you must pass a hashed password to the control port, if you are going to
+ use it.
 -To configure a tor hidden service you can do something like the following:
++## Configuring onion services<a name="configuring-onion-services"></a>
 -    tor::daemon::hidden_service { "hidden_ssh":
++To configure a tor onion service you can do something like the following:
 -If you wish to enable v3-style hidden services to correspond with the v2-style
 -hidden services (the same configuration will be applied to both), you can pass
++    tor::daemon::onion_service { "onion_ssh":
+       ports => 22;
+     }
+ The `HiddenServiceDir` is set to the `${data_dir}/${name}`, but you can override
+ it with the parameter `datadir`.
++If you wish to enable v3-style onion services to correspond with the v2-style
++onion services (the same configuration will be applied to both), you can pass
+ the parameter `v3 => true`. The default is `false`.
+ If you wish to enable single-hop onion addresses, you can enable them by
+ passing `single_hop => true`. The default is `false`.
++Onion services used to be called hidden services, so an old interface
++`tor::daemon::hidden_service` is still available, with the feature
++set of that time.
++
+ ## Configuring directories<a name="configuring-directories"></a>
+ An example directory configuration:
+     tor::daemon::directory { 'ssh_directory':
+       port             => '80',
+       port_front_page  => '/etc/tor/tor.html';
+     }
+   
+ ## Configuring exit policies<a name="configuring-exit-policies"></a>
+ To configure exit policies, you can do the following:
+  
+     tor::daemon::exit_policy { "ssh_exit_policy":
+       accept => "192.168.0.1:22",
+       reject => "*:*";
+     }
+ ## Configuring transport plugins<a name="configuring-transport-plugins"></a>
+ To configure transport plugins, you can do the following:
+     tor::daemon::transport_plugins { "obfs4":
+       ext_port                => '80',
+       servertransport_plugin  => 'obfs4 exec /usr/bin/obfs4proxy',
+     }
+ If you wish to use `obfs4proxy`, you will also need to install the required
+ Debian package, as the puppet module will not do it for you.
+ Other options for transport plugins are also available but not defined by
+ default:
+     $servertransport_listenaddr  #Set a different address for the transport plugin mechanism
+     $servertransport_options     #Pass a k=v parameters to the transport proxy
++# Functions<a name="functions"></a>
++
++This module comes with 2 functions specific to tor support. They require the base32 gem to be installed on the master or wherever they are executed.
++
++## onion_address
++
++This function takes a 1024bit RSA private key as an argument and returns the onion address for an onion service for that key.
++
++## generate_onion_key
++
++This function takes a path (on the puppetmaster!) and an identifier for a key and returns an array containing the matching onion address and the private key. The private key either exists under the supplied `path/key_identifier` or is being generated on the fly and stored under that path for the next execution.
++
+ # Polipo<a name="polipo"></a>
+ Polipo support can be enabled by doing:
+     include tor::polipo
+ This will inherit the `tor` class by default, remove `privoxy` if it's
+ installed, and install `polipo`, making sure it is running.
+   
+ # Munin<a name="munin"></a>
+ If you are using `munin`, and have the puppet munin module installed, you can
+ set the `use_munin` parameter to `true` when defining the `tor::daemon` class
+ to have graphs setup for you.
diff --cc Rakefile
+++ b/Rakefile
@@@ -1,17 -1,10 +1,23 @@@
- require 'puppet-lint/tasks/puppet-lint'
- PuppetLint.configuration.send('disable_80chars')
- PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp"]
 +require 'rubygems'
 +# keep for compatibility for now
 +require 'puppetlabs_spec_helper/rake_tasks'
 -  require 'puppetlabs_spec_helper/rake_tasks'
 -
+ task :tests do
+   # run syntax checks on manifests, templates and hiera data
+   # also runs :metadata_lint
+   Rake::Task[:validate].invoke
+   # runs puppet-lint
+   Rake::Task[:lint].invoke
+ end
 +
 +# use librarian-puppet to manage fixtures instead of .fixtures.yml
 +# offers more possibilities like explicit version management, forge downloads,...
 +task :librarian_spec_prep do
 +  sh "librarian-puppet install --path=spec/fixtures/modules/"
 +  pwd = `pwd`.strip
 +  unless File.directory?("#{pwd}/spec/fixtures/modules/tor")
 +    sh "ln -s #{pwd} #{pwd}/spec/fixtures/modules/tor"
 +  end
 +end
++
 +task :spec_prep => :librarian_spec_prep
@@@ -1,15 -1,7 +1,13 @@@
  # basic management of resources for tor
  class tor::base {
 -  package { [ 'tor', 'tor-geoipdb' ]:
 -    ensure => $tor::ensure_version,
 +  package {'tor':
 +    ensure => $tor::version,
 +  }
-   case $osfamily {
-     'Debian': {
-       package {'tor-geoipdb':
-         ensure => $tor::version,
-         before => Service['tor'],
-       }
++  if $facts['osfamily'] == 'Debian' {
++    package {'tor-geoipdb':
++      ensure => $tor::version,
++      before => Service['tor'],
 +    }
    }
  
    service { 'tor':
@@@ -2,8 -2,6 +2,8 @@@
  # installation with all the basics
  class tor::compact {
    include ::tor
 -  include tor::polipo
    include tor::torsocks
-   if $osfamily == 'Debian' {
++  if $facts['osfamily'] == 'Debian' {
 +    include tor::polipo
 +  }
  }
@@@ -13,14 -13,14 +13,14 @@@ define tor::daemon::control
        fail('You need to define the tor control password')
      }
  
-     if $cookie_authentication == 0 and ($cookie_auth_file != '' or $cookie_auth_file_group_readable != '') {
-       notice('You set a tor cookie authentication option, but do not have cookie_authentication on')
 -  if $cookie_authentication == 0
 -    and ($cookie_auth_file != '' or $cookie_auth_file_group_readable != '') {
++    if $cookie_authentication == 0 and ($cookie_auth_file != '' or $cookie_auth_file_group_readable != '') { # lint:ignore:80chars 
+       notice('You set a tor cookie authentication option, but do not have cookie_authentication on') # lint:ignore:80chars
      }
  
 -  concat::fragment { '04.control':
 -    content => template('tor/torrc.control.erb'),
 -    order   => 04,
 -    target  => $tor::daemon::config_file,
 +    concat::fragment { '04.control':
 +      content => template('tor/torrc.control.erb'),
 +      order   => '04',
 +      target  => $tor::daemon::config_file,
 +    }
    }
  }
@@@ -1,19 -1,15 +1,18 @@@
  # directory advertising
  define tor::daemon::directory (
 +  $ensure           = 'present',
    $port             = 0,
-   $listen_addresses = [],
    $port_front_page  = '/etc/tor/tor-exit-notice.html',
 -  $ensure           = present ) {
 -
 -  concat::fragment { '06.directory':
 -    content => template('tor/torrc.directory.erb'),
 -    order   => 06,
 -    target  => $tor::daemon::config_file,
 +) {
 +  if $ensure == 'present' {
 +    concat::fragment { '06.directory':
 +      content => template('tor/torrc.directory.erb'),
 +      order   => '06',
 +      target  => $tor::daemon::config_file,
 +    }
    }
  
 +  include ::tor::daemon::params
    file { '/etc/tor/tor-exit-notice.html':
      ensure  => $ensure,
      source  => 'puppet:///modules/tor/tor-exit-notice.html',
@@@ -23,4 -19,4 +22,3 @@@
      mode    => '0644',
    }
  }
--
@@@ -1,15 -1,11 +1,14 @@@
  # DNS definition
  define tor::daemon::dns(
 -  $port             = 0 ) {
 -
 -  concat::fragment { "08.dns.${name}":
 -    content => template('tor/torrc.dns.erb'),
 -    order   => '08',
 -    target  => $tor::daemon::config_file,
 +  $ensure           = 'present',
 +  $port             = 0,
-   $listen_addresses = [],
 +){
 +  if $ensure == 'present' {
 +    concat::fragment { "08.dns.${name}":
 +      content => template('tor/torrc.dns.erb'),
 +      order   => '08',
 +      target  => $tor::daemon::config_file,
 +    }
    }
  }
  
index 0000000,9e053cc..8a062c5
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,21 +1,16 @@@
 -  $data_dir      = $tor::daemon::data_dir ) {
 -
 -
 -
 -  if $single_hop {
 -    file { "${$data_dir}/${$name}/onion_service_non_anonymous":
 -      ensure => 'present',
 -    }
 -  }
 -
 -  concat::fragment { "05.hidden_service.${name}":
 -    content => template('tor/torrc.hidden_service.erb'),
 -    order   => 05,
 -    target  => $tor::daemon::config_file,
+ # hidden services definition
+ define tor::daemon::hidden_service(
+   $ports         = [],
+   $single_hop    = false,
+   $v3            = false,
++  $data_dir      = $tor::daemon::data_dir,
++) {
++  info("Using tor::daemon::hidden_service is deprecated, please use tor::daemon::onion_service for ${name}")
++  tor::daemon::onion_service{
++    $name:
++      ports      => $ports,
++      single_hop => $single_hop,
++      v3         => $v3,
++      data_dir   => $data_dir,
+   }
+ }
index 9d12a3a,0000000..cb55d06
mode 100644,000000..100644
--- /dev/null
@@@ -1,57 -1,0 +1,65 @@@
 +# onion services definition
 +define tor::daemon::onion_service(
 +  $ensure                 = 'present',
 +  $ports                  = [],
 +  $data_dir               = $tor::daemon::data_dir,
++  $v3                     = false,
++  $single_hop             = false,
 +  $private_key            = undef,
 +  $private_key_name       = $name,
 +  $private_key_store_path = undef,
 +) {
 +
 +  $data_dir_path = "${data_dir}/${name}"
 +  if $ensure == 'present' {
 +    include ::tor::daemon::params
 +    concat::fragment { "05.onion_service.${name}":
 +      content => template('tor/torrc.onion_service.erb'),
 +      order   => '05',
 +      target  => $tor::daemon::config_file,
 +    }
++    if $single_hop {
++      file { "${$data_dir_path}/onion_service_non_anonymous":
++        ensure => 'present',
++        notify => Service['tor'];
++      }
++    }
 +  }
 +  if $private_key or ($private_key_name and $private_key_store_path) {
 +    if $private_key and ($private_key_name and $private_key_store_path) {
 +      fail('Either private_key OR (private_key_name AND private_key_store_path) must be set, but not all three of them')
 +    }
 +    if $private_key_store_path and $private_key_name {
 +      $tmp = generate_onion_key($private_key_store_path,$private_key_name)
 +      $os_hostname = $tmp[0]
 +      $real_private_key = $tmp[1]
 +    } else {
 +      $os_hostname = onion_address($private_key)
 +      $real_private_key = $private_key
 +    }
 +    file{
 +      $data_dir_path:
 +        ensure  => directory,
 +        purge   => true,
 +        force   => true,
 +        recurse => true,
 +        owner   => $tor::daemon::params::user,
 +        group   => $tor::daemon::params::group,
 +        mode    => '0600',
 +        require => Package['tor'];
 +      "${data_dir_path}/private_key":
 +        content => $real_private_key,
 +        owner   => $tor::daemon::params::user,
 +        group   => $tor::daemon::params::group,
 +        mode    => '0600',
 +        notify  => Service['tor'];
 +      "${data_dir_path}/hostname":
 +        content => "${os_hostname}.onion\n",
 +        owner   => $tor::daemon::params::user,
 +        group   => $tor::daemon::params::group,
 +        mode    => '0600',
 +        notify  => Service['tor'];
 +    }
 +  }
 +}
 +
index 0c35cd6,0000000..39126ee
mode 100644,000000..100644
--- /dev/null
@@@ -1,20 -1,0 +1,19 @@@
-   case $osfamily {
 +# setup variables for different distributions
 +class tor::daemon::params {
-     default: { fail("No support for osfamily ${osfamily}") }
++  case $facts['osfamily'] {
 +    'RedHat': {
 +      $user          = 'toranon'
 +      $group         = 'toranon'
 +      $manage_user   = false
 +      $data_dir_mode = '0750'
 +    }
 +    'Debian': {
 +      $user          = 'debian-tor'
 +      $group         = 'debian-tor'
 +      $manage_user   = true
 +      $data_dir_mode = '0700'
 +    }
++    default: { fail("No support for osfamily ${facts['osfamily']}") }
 +  }
 +
 +}
@@@ -1,8 -1,6 +1,7 @@@
  # relay definition
  define tor::daemon::relay(
 +  $ensure                  = 'present',
    $port                    = 0,
-   $listen_addresses        = [],
    $outbound_bindaddresses  = [],
    $portforwarding          = 0,
    # KB/s, defaulting to using tor's default: 5120KB/s
@@@ -1,12 -1,11 +1,11 @@@
  # socks definition
  define tor::daemon::socks(
    $port = 0,
-   $listen_addresses = [],
 -  $policies = [] ) {
 -
 +  $policies = [],
 +) {
    concat::fragment { '02.socks':
      content => template('tor/torrc.socks.erb'),
 -    order   => 02,
 +    order   => '02',
      target  => $tor::daemon::config_file,
    }
  }
@@@ -1,16 -1,11 +1,14 @@@
  # Transparent proxy definition
  define tor::daemon::transparent(
 -  $port             = 0 ) {
 +  $ensure           = 'present',
-   $port             = 0,
-   $listen_addresses = [],
- ) {
++  $port             = 0) {
  
 -  concat::fragment { "09.transparent.${name}":
 -    content => template('tor/torrc.transparent.erb'),
 -    order   => '09',
 -    target  => $tor::daemon::config_file,
 +  if $ensure == 'present' {
 +    concat::fragment { "09.transparent.${name}":
 +      content => template('tor/torrc.transparent.erb'),
 +      order   => '09',
 +      target  => $tor::daemon::config_file,
 +    }
    }
  }
  
@@@ -7,14 -7,12 +7,14 @@@ class tor::munin 
        cookie_auth_file      => '/var/run/tor/control.authcookie',
    }
  
 +  include ::tor::daemon::params
    Munin::Plugin::Deploy {
-     config => "user ${tor::daemon::params::user}\n env.cookiefile /var/run/tor/control.authcookie\n env.port 9001"
 -    config  => "user debian-tor\n env.cookiefile /var/run/tor/control.authcookie\n env.port 19051" # lint:ignore:80chars
++    config => "user ${tor::daemon::params::user}\n env.cookiefile /var/run/tor/control.authcookie\n env.port 9001" # lint:ignore:80chars 
    }
    munin::plugin::deploy {
 -    'tor_connections':
 -      source => 'tor/munin/tor_connections';
 +    'tor_openfds':
 +      config => 'user root',
 +      source => 'tor/munin/tor_openfds';
      'tor_routers':
        source => 'tor/munin/tor_routers';
      'tor_traffic':
index 6a6b476,0000000..1921754
mode 100644,000000..100644
--- /dev/null
@@@ -1,82 -1,0 +1,82 @@@
-   case $osfamily {
 +# manages an onionbalance installation
 +#
 +# Parameters:
 +#
 +#  services: a hash of onionbalance service instances
 +#    services => {
 +#      keyname_of_service1 => {
 +#        name1        => onionservice_addr_3,
 +#        name2        => onionservice_addr_2,
 +#        _key_content => content_of_key_of_onionbalanced_service1,
 +#      },
 +#    }
 +#
 +class tor::onionbalance(
 +  $services,
 +) {
 +
 +  include ::tor
 +
-       fail("OSFamily ${osfamily} not (yet) supported for onionbalance")
++  case $facts['osfamily'] {
 +    'Debian': {
 +      $pkg_name = 'onionbalance'
 +      $instance_file = '/etc/tor/instances/onionbalance/torrc'
 +      $instance_user = '_tor-onionbalance'
 +      exec{'/usr/sbin/tor-instance-create onionbalance':
 +        creates => '/etc/tor/instances/onionbalance',
 +        require => Package['tor'],
 +        before  => File[$instance_file],
 +      } -> augeas{"manage_onionbalance_in_group_${instance_user}":
 +        context => '/files/etc/group',
 +        changes => [ "set ${instance_user}/user[last()+1] onionbalance" ],
 +        onlyif  => "match ${instance_user}/*[../user='onionbalance'] size == 0",
 +        require => Package['onionbalance'],
 +      }
 +    }
 +    'RedHat': {
 +      $instance_file = '/etc/tor/onionbalance.torrc'
 +      $instance_user = 'toranon'
 +      $pkg_name      = 'python2-onionbalance'
 +    }
 +    default: {
-       content => template("tor/onionbalance/${osfamily}.torrc.erb"),
++      fail("OSFamily ${facts['osfamily']} not (yet) supported for onionbalance")
 +    }
 +  }
 +
 +  package{$pkg_name:
 +    ensure => 'installed',
 +    tag    => 'onionbalance',
 +  } -> file{
 +    '/etc/onionbalance/config.yaml':
 +      content => template('tor/onionbalance/config.yaml.erb'),
 +      owner   => root,
 +      group   => $instance_user,
 +      mode    => '0640',
 +      notify  => Service['onionbalance'];
 +    $instance_file:
++      content => template("tor/onionbalance/${facts['osfamily']}.torrc.erb"),
 +      owner   => root,
 +      group   => 0,
 +      mode    => '0644',
 +      require => Package['tor'],
 +      notify  => Service['tor@onionbalance'],
 +  }
 +
 +  $keys = keys($services)
 +  tor::onionbalance::keys{
 +    $keys:
 +      values => $services,
 +      group  => $instance_user,
 +  }
 +
 +  service{
 +    'tor@onionbalance':
 +      ensure => running,
 +      enable => true;
 +    'onionbalance':
 +      ensure    => running,
 +      enable    => true,
 +      subscribe => Service['tor@onionbalance'];
 +  }
 +
 +}
@@@ -10,11 -10,8 +10,11 @@@ class tor::repo 
        $location = 'https://deb.torproject.org/torproject.org/'
        class { 'tor::repo::debian': }
      }
 +    'RedHat': {
 +      # no need as EPEL is the relevant reference
 +    }
      default: {
-       fail("Unsupported managed repository for osfamily: ${::osfamily}, operatingsystem: ${::operatingsystem}, module ${module_name} currently only supports managing repos for osfamily Debian and Ubuntu")
+       fail("Unsupported managed repository for osfamily: ${::osfamily}, operatingsystem: ${::operatingsystem}, module ${module_name} currently only supports managing repos for osfamily Debian and Ubuntu") # lint:ignore:80chars
      }
    }
  }
diff --cc metadata.json
@@@ -1,71 -1,29 +1,47 @@@
  {
-   "name": "duritong-tor",
-   "version": "0.0.1",
-   "author": "duritong and others",
-   "summary": "Manage tor and its components",
-   "description": "Manage tor and its components",
-   "license": "GPLv3",
-   "source": "https://github.com/duritong/puppet-tor",
-   "project_page": "https://github.com/duritong/puppet-tor",
-   "issues_url": "https://github.com/duritong/puppet-tor/issues",
+   "name": "smash-tor",
+   "version": "1.0.1",
+   "author": "SMASH",
+   "summary": "This project tracks the tor puppet module that manages the tor onion routing system.",
+   "license": "GPL-3.0",
+   "source": "https://gitlab.com/shared-puppet-modules-group/tor",
+   "project_page": "https://gitlab.com/shared-puppet-modules-group/tor",
+   "issues_url": "https://gitlab.com/shared-puppet-modules-group/tor/issues",
+   "dependencies": [
+     { "name":"puppetlabs/concat" }
+   ],
    "operatingsystem_support": [
      {
-       "operatingsystem": "RedHat",
+       "operatingsystem": "Debian",
        "operatingsystemrelease": [
-         "7"
+         "8",
+         "9"
        ]
-         "7"
-       ]
-     },
-     {
-       "operatingsystem": "OracleLinux",
-       "operatingsystemrelease": [
-         "7"
-       ]
-     },
-     {
-       "operatingsystem": "Scientific",
-       "operatingsystemrelease": [
-         "7"
-       ]
-     },
-     {
-       "operatingsystem": "Debian",
-       "operatingsystemrelease": [
-         "6",
 +    },
 +    {
 +      "operatingsystem": "CentOS",
 +      "operatingsystemrelease": [
-         "8"
-       ]
-     },
-     {
-       "operatingsystem": "Ubuntu",
-       "operatingsystemrelease": [
-         "10.04",
-         "12.04",
-         "14.04",
-         "16.04"
 +        "7",
++        "6"
 +      ]
      }
    ],
    "requirements": [
      {
        "name": "puppet",
-       "version_requirement": ">=2.7.20 <5.0.0"
 -      "version_requirement": "4.X"
++      "version_requirement": ">=4.0.0"
 +    }
 +  ],
 +  "dependencies": [
 +    {
 +      "name": "puppetlabs-stdlib"
 +    },
 +    {
 +      "name": "puppetlabs-concat"
 +    },
 +    {
 +      "name": "puppetlabs-apt"
      }
-   ]
+   ],
+   "description": "This module tries to manage tor, making sure it is installed, running, has  munin graphs if desired and allows for configuration of relays, hidden services, exit policies, etc."
  }
@@@ -5,20 -5,20 +5,20 @@@ DataDirectory <%= v %
  <% end -%>
  
  # log
 -<% if (rules=scope.lookupvar('tor::daemon::log_rules')).empty? -%>
 +<% if (rules=scope['tor::daemon::log_rules']).empty? -%>
  Log notice syslog
  <%  else -%>
- <%   rules.each do |log_rule| -%>
+ <%   Array(rules).each do |log_rule| -%>
  Log <%= log_rule %>
 -<%    end -%>
 -<%  end -%>
 -<%- if (v=scope.lookupvar('tor::daemon::safe_logging')) != '1' then -%>
 +<% end
 +end -%>
 +<% if (v=scope['tor::daemon::safe_logging']) != 1 -%>
  SafeLogging <%= v %>
 -<%-   end -%>
 +<% end -%>
  
 -<%  if (v=scope.lookupvar('tor::daemon::automap_hosts_on_resolve')) != '0' -%>
 +<% if (v=scope['tor::daemon::automap_hosts_on_resolve']) != 0 -%>
  AutomapHostsOnResolve <%= v %>
 -<%  end -%>
 -<%  if (v=scope.lookupvar('tor::daemon::use_bridges')) != '0' -%>
 +<% end -%>
 +<% if (v=scope['tor::daemon::use_bridges']) != 0 -%>
  UseBridges <%= v %>
 -<%- end -%>
 +<% end -%>
@@@ -1,6 -1,20 +1,20 @@@
+ <% if @single_hop != false %>
+ HiddenServiceSingleHopMode 1
+ HiddenServiceNonAnonymousMode 1
+ SOCKSPort 0
+ <% end %>
  # hidden service <%= @name %>
 -HiddenServiceDir <%= @data_dir %>/<%= @name %>
 +HiddenServiceDir <%= @data_dir_path %>
  <% Array(@ports).each do |port| -%>
 -HiddenServicePort <%= port %>
 +HiddenServicePort <%= port =~ /^\d+$/ ? "#{port} 127.0.0.1:#{port}" : port %>
  <% end -%>
  
 -HiddenServiceDir <%= @data_dir %>/<%= @name -%>3
+ <% if @v3 != false %>
+ # hidden service v3 static
++HiddenServiceDir <%= @data_dir_path %>3
+ HiddenServiceVersion 3
+ <% Array(@ports).each do |port| -%>
+ HiddenServicePort <%= port %>
+ <% end -%>
+ <% end -%>