]> gitweb.fluxo.info Git - puppet-shorewall.git/commitdiff
Add support for Tor-ified traffic.
authorintrigeri <intrigeri@boum.org>
Fri, 17 Dec 2010 18:39:44 +0000 (19:39 +0100)
committerintrigeri <intrigeri@boum.org>
Fri, 17 Dec 2010 18:39:44 +0000 (19:39 +0100)
README
manifests/init.pp
manifests/rules/torify.pp [new file with mode: 0644]
manifests/rules/torify/allow_tor_transparent_proxy.pp [new file with mode: 0644]
manifests/rules/torify/allow_tor_user.pp [new file with mode: 0644]
manifests/rules/torify/redirect_tcp_to_tor.pp [new file with mode: 0644]
manifests/rules/torify/reject_non_tor.pp [new file with mode: 0644]
manifests/rules/torify/user.pp [new file with mode: 0644]

diff --git a/README b/README
index a80fd5d448db9617ee14abadcb0e8605212e8410..648eaf7744a02955683d635f54c459c540e6679a 100644 (file)
--- a/README
+++ b/README
@@ -39,7 +39,76 @@ Documentation
 -------------
 
 see also: http://reductivelabs.com/trac/puppet/wiki/Recipes/AqueosShorewall
+
+Torify
+------
+
+The shorewall::rules::torify define can be used to force some outgoing
+TCP traffic through the Tor transparent proxy. The corresponding
+non-TCP traffic is rejected accordingly.
+
+Beware! This define only is part of a torified setup. DNS requests and
+IPv6, amongst others, might leak network activity you would prefer not
+to. You really need to read proper documentation about these matters
+before using this feature e.g.:
+
+  https://www.torproject.org/download/download.html.en#warning
+
+The Tor transparent proxy location defaults to 127.0.0.1:9040 and can
+be configured by setting the $tor_transparent_proxy_host and
+$tor_transparent_proxy_port variables before including the main
+shorewall class.
+
+Example usage follows.
+
+Torify any outgoing TCP traffic originating from user bob or alice and
+aimed at 6.6.6.6 or 7.7.7.7:
+
+  shorewall::rules::torify {
+    'torify-some-bits':
+      users        => [ 'bob', 'alice' ],
+      destinations => [ '6.6.6.6', '7.7.7.7' ];
+  }
+
+Torify any outgoing TCP traffic to 8.8.8.8:
+
+  shorewall::rules::torify {
+    'torify-to-this-host':
+      destinations  => [ '8.8.8.8' ];
+  }
+
+When no destination nor user is provided any outgoing TCP traffic (see
+restrictions bellow) is torified. In that case the user running the
+Tor client ($tor_user) is whitelisted; this variable defaults to
+"debian-tor" on Debian systems and to "tor" on others. if this does
+not suit your configuration you need to set the $tor_user variable
+before including the main shorewall class.
+
+When no destination is provided traffic directed to RFC1918 addresses
+is by default allowed and (obviously) not torified. This behaviour can
+be changed by setting the allow_rfc1918 parameter to false.
+
+Torify any outgoing TCP traffic but connections to RFC1918 addresses:
+
+  shorewall::rules::torify {
+    'torify-everything-but-lan':
+  }
+
+Torify any outgoing TCP traffic:
+
+  shorewall::rules::torify {
+    'torify-everything:
+      allow_rfc1918 => false;
+  }
+
+In some cases (e.g. when providing no specific destination nor user
+and denying access to RFC1918 addresses) UDP DNS requests may be
+rejected. This is intentional: it does not make sense leaking -via DNS
+requests- network activity that would otherwise be torified. In that
+case you probably want to read proper documentation about such
+matters, enable the Tor DNS resolver and redirect DNS requests through
+it.
+
 Example
 -------
 
index 3e759db801ad61f2ddcee2cb87be8f937597bb9b..f69a6f26c12f2478c489bdb5ea4c5fce2fdf6cc4 100644 (file)
@@ -5,7 +5,10 @@ class shorewall {
 
   case $operatingsystem {
     gentoo: { include shorewall::gentoo }
-    debian: { include shorewall::debian }
+    debian: {
+      include shorewall::debian
+      $dist_tor_user = 'debian-tor'
+    }
     centos: { include shorewall::base }
     ubuntu: {
     case $lsbdistcodename {
@@ -19,6 +22,19 @@ class shorewall {
     }
   }
 
+  case $tor_transparent_proxy_host {
+    '': { $tor_transparent_proxy_host = '127.0.0.1' }
+  }
+  case $tor_transparent_proxy_port {
+    '': { $tor_transparent_proxy_port = '9040' }
+  }
+  if $tor_user == '' {
+    $tor_user = $dist_tor_user ? {
+      ''      => 'tor',
+      default => $dist_tor_user,
+    }
+  }
+
   file {"/var/lib/puppet/modules/shorewall":
     ensure => directory,
     force => true,
diff --git a/manifests/rules/torify.pp b/manifests/rules/torify.pp
new file mode 100644 (file)
index 0000000..f6e62d8
--- /dev/null
@@ -0,0 +1,29 @@
+# shorewall::rules::torify
+#
+# Note: shorewall::rules::torify cannot be used several times with the
+# same user listed in the $users array. This restriction applies to
+# using this define multiple times without providing a $users
+# parameter.
+#
+# Parameters:
+#
+# - users: every element of this array must be valid in shorewall
+#   rules user/group column.
+# - destinations: every element of this array must be valid in
+#   shorewall rules original destination column.
+
+define shorewall::rules::torify(
+  $users        = ['-'],
+  $destinations = ['-'],
+  $allow_rfc1918 = true
+){
+
+  $originaldest = join($destinations,',')
+
+  shorewall::rules::torify::user {
+    $users:
+      originaldest  => $originaldest,
+      allow_rfc1918 => $allow_rfc1918;
+  }
+
+}
diff --git a/manifests/rules/torify/allow_tor_transparent_proxy.pp b/manifests/rules/torify/allow_tor_transparent_proxy.pp
new file mode 100644 (file)
index 0000000..3c18db6
--- /dev/null
@@ -0,0 +1,21 @@
+class shorewall::rules::torify::allow_tor_transparent_proxy {
+
+  $rule = "allow-tor-transparent-proxy"
+
+  if !defined(Shorewall::Rule["$rule"]) {
+    # A weirdness in shorewall forces us to explicitly allow traffic to
+    # net:$tor_transparent_proxy_host:$tor_transparent_proxy_port even
+    # if $FW->$FW traffic is allowed. This anyway avoids us special-casing
+    # the remote Tor transparent proxy situation.
+    shorewall::rule {
+      "$rule":
+        source          => '$FW',
+        destination     => "net:${shorewall::tor_transparent_proxy_host}",
+        proto           => 'tcp',
+        destinationport => $shorewall::tor_transparent_proxy_port,
+        order           => 100,
+        action          => 'ACCEPT';
+    }
+  }
+
+}
diff --git a/manifests/rules/torify/allow_tor_user.pp b/manifests/rules/torify/allow_tor_user.pp
new file mode 100644 (file)
index 0000000..f44c1f0
--- /dev/null
@@ -0,0 +1,15 @@
+class shorewall::rules::torify::allow_tor_user {
+
+  $whitelist_rule = "allow-from-tor-user"
+  if !defined(Shorewall::Rule["$whitelist_rule"]) {
+    shorewall::rule {
+      "$whitelist_rule":
+        source      => '$FW',
+        destination => 'all',
+        user        => $shorewall::tor_user,
+        order       => 101,
+        action      => 'ACCEPT';
+    }
+  }
+
+}
diff --git a/manifests/rules/torify/redirect_tcp_to_tor.pp b/manifests/rules/torify/redirect_tcp_to_tor.pp
new file mode 100644 (file)
index 0000000..2bee658
--- /dev/null
@@ -0,0 +1,40 @@
+define shorewall::rules::torify::redirect_tcp_to_tor(
+  $user = '-',
+  $originaldest = '-'
+){
+
+  # hash the destination as it may contain slashes
+  $originaldest_sha1 = sha1($originaldest)
+  $rule = "redirect-to-tor-user=${user}-to=${originaldest_sha1}"
+
+  if !defined(Shorewall::Rule["$rule"]) {
+
+    $originaldest_real = $originaldest ? {
+      '-'     => '!127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16',
+      default => $originaldest,
+    }
+
+    $user_real = $user ? {
+      '-'     => "!${shorewall::tor_user}",
+      default => $user,
+    }
+
+    $destzone = $shorewall::tor_transparent_proxy_host ? {
+      '127.0.0.1' => '$FW',
+      default     => 'net'
+    }
+    
+    shorewall::rule {
+      "$rule":
+        source       => '$FW',
+        destination  => "${destzone}:${shorewall::tor_transparent_proxy_host}:${shorewall::tor_transparent_proxy_port}",
+        proto        => 'tcp:syn',
+        originaldest => $originaldest_real,
+        user         => $user_real,
+        order        => 110,
+        action       => 'DNAT';
+    }
+
+  }
+
+}
diff --git a/manifests/rules/torify/reject_non_tor.pp b/manifests/rules/torify/reject_non_tor.pp
new file mode 100644 (file)
index 0000000..80240ec
--- /dev/null
@@ -0,0 +1,32 @@
+define shorewall::rules::torify::reject_non_tor(
+  $user = '-',
+  $originaldest = '-',
+  $allow_rfc1918 = true
+){
+
+  # hash the destination as it may contain slashes
+  $originaldest_sha1 = sha1($originaldest)
+  $rule = "reject-non-tor-from-${user}-to=${originaldest_sha1}"
+
+  if $originaldest == '-' {
+    $originaldest_real = $allow_rfc1918 ? {
+      false   => '!127.0.0.1',
+      default => '!127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16',
+    }
+  } else {
+    $originaldest_real = $originaldest
+  }
+
+  if !defined(Shorewall::Rule["$rule"]) {
+    shorewall::rule {
+      "$rule":
+        source          => '$FW',
+        destination     => 'all',
+        originaldest    => $originaldest_real,
+        user            => $user,
+        order           => 120,
+        action          => 'REJECT';
+    }
+  }
+
+}
diff --git a/manifests/rules/torify/user.pp b/manifests/rules/torify/user.pp
new file mode 100644 (file)
index 0000000..5caccfd
--- /dev/null
@@ -0,0 +1,27 @@
+define shorewall::rules::torify::user(
+  $originaldest = '-',
+  $allow_rfc1918 = true
+){
+
+  $user = $name
+
+  include shorewall::rules::torify::allow_tor_transparent_proxy
+
+  if $originaldest == '-' and $user == '-' {
+    include shorewall::rules::torify::allow_tor_user
+  }
+
+  shorewall::rules::torify::redirect_tcp_to_tor {
+    "redirect-to-tor-user=${user}-to=${originaldest}":
+      user         => $user,
+      originaldest => $originaldest
+  }
+
+  shorewall::rules::torify::reject_non_tor {
+    "reject-non-tor-user=${user}-to=${originaldest}":
+      user          => "$user",
+      originaldest  => $originaldest,
+      allow_rfc1918 => $allow_rfc1918;
+  }
+
+}