#95 Add Tor, configure hidden service for Mastodon

Merged
raucao merged 7 commits from feature/tor_hidden_services into master 1 year ago
  1. +1
    -0
      site-cookbooks/kosmos-ejabberd/metadata.rb
  2. +12
    -0
      site-cookbooks/kosmos-ejabberd/recipes/default.rb
  3. +1
    -0
      site-cookbooks/kosmos-mastodon/metadata.rb
  4. +28
    -5
      site-cookbooks/kosmos-mastodon/recipes/nginx.rb
  5. +2
    -0
      site-cookbooks/kosmos-mastodon/templates/default/env.production.erb
  6. +13
    -80
      site-cookbooks/kosmos-mastodon/templates/default/nginx_conf_mastodon.erb
  7. +79
    -0
      site-cookbooks/kosmos-mastodon/templates/default/nginx_conf_shared.erb
  8. +4
    -0
      site-cookbooks/tor-full/.gitignore
  9. +22
    -0
      site-cookbooks/tor-full/.kitchen.yml
  10. +3
    -0
      site-cookbooks/tor-full/Berksfile
  11. +15
    -0
      site-cookbooks/tor-full/CHANGELOG.md
  12. +20
    -0
      site-cookbooks/tor-full/LICENCE.txt
  13. +162
    -0
      site-cookbooks/tor-full/README.md
  14. +88
    -0
      site-cookbooks/tor-full/attributes/default.rb
  15. +14
    -0
      site-cookbooks/tor-full/metadata.rb
  16. +113
    -0
      site-cookbooks/tor-full/recipes/default.rb
  17. +8
    -0
      site-cookbooks/tor-full/recipes/relay.rb
  18. +124
    -0
      site-cookbooks/tor-full/templates/default/tor-exit-notice.html.erb
  19. +235
    -0
      site-cookbooks/tor-full/templates/default/torrc.erb
  20. +6
    -0
      site-cookbooks/tor-full/test/integration/default/bats/tor_installed.bats

+ 1
- 0
site-cookbooks/kosmos-ejabberd/metadata.rb View File

@@ -23,3 +23,4 @@ depends "kosmos-postgresql"
depends "kosmos-base"
depends "backup"
depends "firewall"
depends "tor-full"

+ 12
- 0
site-cookbooks/kosmos-ejabberd/recipes/default.rb View File

@@ -130,3 +130,15 @@ unless node.chef_environment == "development"
command :allow
end
end

#
# Tor hidden service
#
node.override["tor"]["HiddenServices"]["ejabberd"] = {
"HiddenServicePorts" => [
"5222 127.0.0.1:5222",
"5223 127.0.0.1:5223",
"5269 127.0.0.1:5269"
]
}
include_recipe "tor-full"

+ 1
- 0
site-cookbooks/kosmos-mastodon/metadata.rb View File

@@ -15,3 +15,4 @@ depends "application_javascript"
depends "postgresql"
depends "kosmos-postgresql"
depends "backup"
depends "tor-full"

+ 28
- 5
site-cookbooks/kosmos-mastodon/recipes/nginx.rb View File

@@ -29,19 +29,34 @@ server_name = node["kosmos-mastodon"]["server_name"]

include_recipe "kosmos-nginx"

template "#{node['nginx']['dir']}/sites-available/#{server_name}" do
source 'nginx_conf_mastodon.erb'
directory "#{node['nginx']['dir']}/snippets" do
action :create
owner 'www-data'
mode 0640
end

template "#{node['nginx']['dir']}/snippets/mastodon.conf" do
source 'nginx_conf_shared.erb'
owner 'www-data'
mode 0640
variables streaming_port: node["kosmos-mastodon"]["streaming_port"],
puma_port: node["kosmos-mastodon"]["puma_port"],
server_name: server_name,
ssl_cert: "/etc/letsencrypt/live/#{server_name}/fullchain.pem",
ssl_key: "/etc/letsencrypt/live/#{server_name}/privkey.pem",
mastodon_path: mastodon_path
notifies :reload, 'service[nginx]', :delayed
end

template "#{node['nginx']['dir']}/sites-available/#{server_name}" do
source 'nginx_conf_mastodon.erb'
owner 'www-data'
mode 0640
variables server_name: server_name,
ssl_cert: "/etc/letsencrypt/live/#{server_name}/fullchain.pem",
ssl_key: "/etc/letsencrypt/live/#{server_name}/privkey.pem",
shared_config_path: "#{node['nginx']['dir']}/snippets/mastodon.conf",
onion_address: File.read("/var/lib/tor/mastodon/hostname").strip
notifies :reload, 'service[nginx]', :delayed
end

# Legacy vhost
nginx_site "mastodon" do
action :disable
@@ -52,3 +67,11 @@ nginx_site server_name do
end

nginx_certbot_site server_name

#
# Tor hidden service
#
node.override["tor"]["HiddenServices"]["mastodon"] = {
"HiddenServicePorts" => ["80 127.0.0.1:80"]
}
include_recipe "tor-full"

+ 2
- 0
site-cookbooks/kosmos-mastodon/templates/default/env.production.erb View File

@@ -54,3 +54,5 @@ S3_REGION=<%= @s3_region %>
# Web Push API
VAPID_PRIVATE_KEY=<%= @vapid_private_key %>
VAPID_PUBLIC_KEY=<%= @vapid_public_key %>

ALLOW_ACCESS_TO_HIDDEN_SERVICE=true

+ 13
- 80
site-cookbooks/kosmos-mastodon/templates/default/nginx_conf_mastodon.erb View File

@@ -1,3 +1,15 @@
server {
listen 80;
server_name mastodon.<%= @onion_address %>;
include <%= @shared_config_path %>;
}

server {
listen 80;
server_name <%= @server_name %>;
return 301 https://$server_name$request_uri;
}

map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
@@ -7,9 +19,7 @@ server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name <%= @server_name %>;

access_log "/var/log/nginx/mastodon.access.log";
error_log "/var/log/nginx/mastodon.error.log";
include <%= @shared_config_path %>;

<% if File.exist?(@ssl_cert) &&
File.exist?(@ssl_key) -%>
@@ -17,82 +27,5 @@ server {
ssl_certificate_key <%= @ssl_key %>;
<% end -%>

keepalive_timeout 70;
sendfile on;
client_max_body_size 0;

root <%= @mastodon_path %>/public;

gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

add_header Strict-Transport-Security "max-age=31536000";

location / {
# If the maintenance file is present, show maintenance page
if (-f <%= @mastodon_path %>/public/maintenance.html) {
return 503;
}

try_files $uri @proxy;
}

location /sw.js {
add_header Cache-Control "max-age=0, no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
}

location ~ ^/(emoji|packs|system/accounts/avatars|system/media_attachments/files) {
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri @proxy;
}

location @proxy {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Proxy "";
proxy_pass_header Server;

proxy_pass http://localhost:<%= @puma_port %>;
proxy_buffering off;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

tcp_nodelay on;
}

location /api/v1/streaming {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Proxy "";

proxy_pass http://localhost:<%= @streaming_port %>;
proxy_buffering off;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

tcp_nodelay on;
}

error_page 500 501 502 504 /500.html;
error_page 503 /maintenance.html;

location = /maintenance.html {
root <%= @mastodon_path %>/public;
}

}

+ 79
- 0
site-cookbooks/kosmos-mastodon/templates/default/nginx_conf_shared.erb View File

@@ -0,0 +1,79 @@
access_log "/var/log/nginx/mastodon.access.log";
error_log "/var/log/nginx/mastodon.error.log";

keepalive_timeout 70;

sendfile on;
client_max_body_size 0;

root <%= @mastodon_path %>/public;

gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

location / {
# If the maintenance file is present, show maintenance page
if (-f <%= @mastodon_path %>/public/maintenance.html) {
return 503;
}

try_files $uri @proxy;
}

location /sw.js {
add_header Cache-Control "max-age=0, no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
}

location ~ ^/(emoji|packs|system/accounts/avatars|system/media_attachments/files) {
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri @proxy;
}

location @proxy {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Proxy "";
proxy_pass_header Server;

proxy_pass http://localhost:<%= @puma_port %>;
proxy_buffering off;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

tcp_nodelay on;
}

location /api/v1/streaming {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Proxy "";

proxy_pass http://localhost:<%= @streaming_port %>;
proxy_buffering off;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

tcp_nodelay on;
}

error_page 500 501 502 504 /500.html;
error_page 503 /maintenance.html;

location = /maintenance.html {
root <%= @mastodon_path %>/public;
}

+ 4
- 0
site-cookbooks/tor-full/.gitignore View File

@@ -0,0 +1,4 @@
.kitchen/
.kitchen.local.yml

.DS_Store

+ 22
- 0
site-cookbooks/tor-full/.kitchen.yml View File

@@ -0,0 +1,22 @@
---
driver:
name: vagrant

provisioner:
name: chef_zero

platforms:
- name: centos-6.5
- name: centos-7.0
- name: fedora-20
- name: fedora-21
- name: ubuntu-10.04
- name: ubuntu-12.04
- name: ubuntu-14.04

suites:
- name: default
excludes: []
run_list:
- recipe[tor-full::default]
attributes: {}

+ 3
- 0
site-cookbooks/tor-full/Berksfile View File

@@ -0,0 +1,3 @@
source "https://api.berkshelf.com"

metadata

+ 15
- 0
site-cookbooks/tor-full/CHANGELOG.md View File

@@ -0,0 +1,15 @@
tor-full CHANGELOG
=============

This file is used to list changes made in each version of the tor cookbook.

0.2.0
-----
- Ben Chrobot
* Updated Readme
* Tor now installed from TorProject.org repository
* Added BATS test suite

0.1.0
-----
- Richard Klafter - Initial release of tor-full

+ 20
- 0
site-cookbooks/tor-full/LICENCE.txt View File

@@ -0,0 +1,20 @@
Copyright 2012 Richard Klafter

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 162
- 0
site-cookbooks/tor-full/README.md View File

@@ -0,0 +1,162 @@
Description
===========

Installs Tor and optionally sets up a hidden service or configures as a relay

Requirements
============
## Ohai and Chef:

* Ohai: 6.14.0+

This cookbook makes use of `node['platform_family']` to simplify platform
selection logic. This attribute was introduced in Ohai v0.6.12.

## Platform:

The following platform families are supported:

* Debian
* RHEL
* Fedora

## Cookbooks:

* apt (for Debian installation)
* yum (for RHEL 5 installation)

## Attributes

### General config section
* `node['tor']['DataDirectory']` - The directory for keeping all the keys/etc
* `node['tor']['MinLogLevel']` - The minimum log level to log. Possible values include debug, info, notice, warn, and err.
* `node['tor']['LogDestination']` - Where logs should be written. Valid values include a path to a file or "syslog"
* `node['tor']['SocksPorts']` - List of 'address:port' to open tor socks proxy on. Defaults to disabled

### Hidden Services config section

* `node['tor']['HiddenServices']` - hidden services Tor should expose
```ruby
# Example
default['tor']['hiddenServices'] = {
'HIDDEN_SERVICE_NAME':{
'HiddenServiceDir' => '/var/lib/tor/some_service/', #default is /var/lib/tor/HIDDEN_SERVICE_NAME/
'HiddenServicePorts' => ['80 127.0.0.1:80'] #x y:z says to redirect requests on port x to the address y:z
}
```

### Relay config section

* `node['tor']['relay']['enabled']` - if true tor will act as a relay
* `node['tor']['relay']['ORPort']` - What port to advertise for incoming Tor connections
* `node['tor']['relay']['Address']` - The IP address or full DNS name for incoming connections to your relay
* `node['tor']['relay']['OutboundBindAddress']` - If you have multiple network interfaces, you can specify one for outgoing traffic to use
* `node['tor']['relay']['Nickname']` - A handle for your relay, so people don't have to refer to it by key
* `node['tor']['relay']['RelayBandwidthRate']` - Limit how much relayed traffic you will allow in kilobytes (not bits)
* `node['tor']['relay']['RelayBandwidthBurst']` - Limit how much relayed traffic you will allow for bursts in kilobytes (not bits)
* `node['tor']['relay']['ContactInfo']` - ContactInfo you can be reached at
* Example: `"0xFFFFFFFF Random Person nobody AT example dot com"`
* `node['tor']['relay']['ExitPolicy']` - Sets the exit node policy for tor defaults to no exit
* Exampe: `['accept *:6660-6667','reject *:*'] # allow irc ports but no more`
* `node['tor']['relay']['BridgeRelay']` - Set to 1 to run a bridge relay
* `node['tor']['relay']['PublishServerDescriptor']` - Set to 0 to run a private bridge relay
* `node['tor']['relay']['Directory']` - If true tor relay will server as a directory mirror
* `node['tor']['relay']['DirPort']` - "address:port" from which to mirror directory information
* `node['tor']['relay']['DirPortFrontPage']` - If true a blob of html will be returned on your DirPort explaining Tor.
* To send a custom HTML blob specify its full path, example `"/etc/tor/tor-exit-notice.html"`
* `node['tor']['relay']['MyFamily']` - If you run more than one tor node add keyids for other tor nodes

Recipes
=======

## tor-full::default

Installs Tor and enables Tor service. By default it will not open a socks proxy, offer a hidden service,
or act as a relay.

## tor-full::relay

Installs Tor and configs Tor to be a relay. By default the relay will not be an exit or directory.
Make sure to read through the attributes section for relays above.

Usage
=====

This cookbook primarily installs Tor core packages. It can also be
used to run a Tor relay or a hidden service.

To install tor client (all supported platforms):

include_recipe 'tor'

To install tor relay:

include_recipe "tor::relay"

Examples
-----
### Open local socks port
The example role below opens a Tor socks proxy on port 9050 available to localhost only

```ruby
name "torproxy"
run_list("recipe[tor-full]")
override_attributes(
"tor" => {
"SocksPorts" => ["127.0.0.1:9050"]
}
)
```

### Hidden service on port 80
The example role below serves a website on port 80 as a hidden service.

```ruby
name "torservice"
run_list("recipe[tor-full]")
override_attributes(
"tor" => {
"hiddenServices" => {
"hidden_web_service" => {
"HiddenServicePorts" => ["80 127.0.0.1:8080"]
#requests on port 80 are redirected to localhost port 8080
}
}
}
)
```

Note: The `tor-full` recipe will write the hidden service's hostname to the attribute `node.tor.hiddenServices.HIDDEN_SERVICE_NAME.hostname` after node convergence.

### Tor Relay
The node config below sets up a Tor relay. The relay is a directory and an exit
for IRC (ports 6660 & 6667).

```json
{
"run_list": [
"recipe[tor-full::relay]"
],
"tor": {
"relay": {
"Address":"tor.icyego.com",
"Nickname":"IcyEgo",
"RelayBandwidthRate":"1000",
"RelayBandwidthBurst":"1100",
"ContactInfo":"ContactInfo 0x04FAC2E9CC21424A Richard Klafter <rpklafter@yahoo.com>",
"Directory":true,
"ExitPolicy":["accept *:6660-6667","reject *:*"]
}
}
}

```

Note: you can make `recipe[tor-full]` behave like `recipe[tor-full::relay]` by
setting the attribute `tor.relay.enabled = true`.

License and Author
==================

- Author:: Richard Klafter (<rpklafter@yahoo.com>)
- License:: MIT

+ 88
- 0
site-cookbooks/tor-full/attributes/default.rb View File

@@ -0,0 +1,88 @@
#
# Author:: Richard Klafter (<rpklafter@yahoo.com>)
# Cookbook Name:: tor
# Attributes:: default
#


#######################################
# General config section
#######################################

# The directory for keeping all the keys/etc
default['tor']['DataDirectory'] = "/var/lib/tor"

# The minimum log level to log. Possible values include debug, info, notice, warn, and err.
default['tor']['MinLogLevel'] = "notice"

# Where logs should be written. Valid values include a path to a file or "syslog"
default['tor']['LogDestination'] = "/var/log/tor/log"

# List of 'address:port' to open tor socks proxy on. Defaults to disabled
# Example: ['127.0.0.1:9050'] opens socks proxy on 9050 accessible to only the local machine
default['tor']['SocksPorts'] = ['9050']

#######################################
# Hidden Services config section
#######################################
# Desc: hidden services tor should expose
# Example:
# default['tor']['hiddenServices'] = {
# 'HIDDEN_SERVICE_NAME':{
# 'HiddenServiceDir' => '/var/lib/tor/some_service/', #default is /var/lib/tor/HIDDEN_SERVICE_NAME/
# 'HiddenServicePorts' => ['80 127.0.0.1:80'] #x y:z says to redirect requests on port x to the address y:z
# }
# }
default['tor']['HiddenServices'] = {}

#######################################
# Relay config section
#######################################

# If true tor will act as a relay
default['tor']['relay']['enabled'] = false

# What port to advertise for incoming Tor connections
default['tor']['relay']['ORPort'] = '9001'

# The IP address or full DNS name for incoming connections to your relay.
default['tor']['relay']['Address'] = nil

# If you have multiple network interfaces, you can specify one for outgoing traffic to use
default['tor']['relay']['OutboundBindAddress'] = nil

# A handle for your relay, so people don't have to refer to it by key
default['tor']['relay']['Nickname'] = "IDidntEditTheConfig"

# Limit how much relayed traffic you will allow in kilobytes (not bits)
default['tor']['relay']['RelayBandwidthRate'] = nil

# Limit how much relayed traffic you will allow for bursts in kilobytes (not bits)
default['tor']['relay']['RelayBandwidthBurst'] = nil

# ContactInfo you can be reached at
# Example: "0xFFFFFFFF Random Person nobody AT example dot com"
default['tor']['relay']['ContactInfo'] = nil

# Sets the exit node policy for tor defaults to no exit
# Exampe: ['accept *:6660-6667','reject *:*'] # allow irc ports but no more
default['tor']['relay']['ExitPolicy'] = ['reject *:*']

# Set to 1 to run a bridge relay
default['tor']['relay']['BridgeRelay'] = 0

# Set to 0 to run a private bridge relay
default['tor']['relay']['PublishServerDescriptor'] = 1

# If true tor relay will server as a directory mirror
default['tor']['relay']['Directory'] = false

# "address:port" from which to mirror directory information
default['tor']['relay']['DirPort'] = "9030"

# If true a blob of html will be returned on your DirPort explaining Tor.
# To send a custom HTML blob specify its full path, example "/etc/tor/tor-exit-notice.html"
default['tor']['relay']['DirPortFrontPage'] = nil

# If you run more than one tor node add keyids for other tor nodes
default['tor']['relay']['MyFamily'] = []

+ 14
- 0
site-cookbooks/tor-full/metadata.rb View File

@@ -0,0 +1,14 @@
name 'tor-full'
maintainer 'Richard Klafter'
maintainer_email 'rpklafter@yahoo.com'
license 'MIT'
description 'Installs/Configures tor'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
supports 'ubuntu'
supports 'debian'
supports 'rhel'
supports 'fedora'
version '0.2.0'

depends 'apt'
depends 'yum'

+ 113
- 0
site-cookbooks/tor-full/recipes/default.rb View File

@@ -0,0 +1,113 @@
#
# Author:: Richard Klafter (<rpklafter@yahoo.com>)
# Cookbook Name:: tor
# Recipe:: default
#

case node['platform_family']
# Debian / Ubuntu
when 'debian'
include_recipe 'apt'

case node['lsb']['codename']
when 'sana'
dist = 'jessie'
when 'kali'
dist = 'wheezy'
when 'kali-rolling'
dist = 'stretch'
else
dist = node['lsb']['codename']
end

# Add TorProject.org repository
apt_repository 'tor' do
uri 'http://deb.torproject.org/torproject.org'
distribution dist
components ['main']
key 'https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc'
deb_src true
end

# Install Tor
package 'tor'

# RHEL / Fedora
when 'rhel', 'fedora'
include_recipe 'yum'

# Add TorProject.org repository
platformShort = node['platform_family'] == 'rhel' ? 'el' : 'fc'
intVersion = node['platform_version'].to_i
yum_repository 'tor' do
description "Tor Stable repo"
baseurl "https://deb.torproject.org/torproject.org/rpm/#{platformShort}/#{intVersion}/$basearch/"
gpgkey 'https://deb.torproject.org/torproject.org/rpm/RPM-GPG-KEY-torproject.org.asc'
action :create
end
yum_repository 'tor-source' do
description "Tor Source repo"
baseurl "https://deb.torproject.org/torproject.org/rpm/#{platformShort}/#{intVersion}/SRPMS/"
gpgkey 'https://deb.torproject.org/torproject.org/rpm/RPM-GPG-KEY-torproject.org.asc'
action :create
end

# Exclude platform Tor package
if node['platform_family'] == 'rhel' then
yum_repository 'epel' do
description 'Extra Packages for Enterprise Linux'
mirrorlist 'https://mirrors.fedoraproject.org/mirrorlist?repo=epel-6&arch=$basearch'
gpgkey 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6'
exclude 'tor'
action :create
end
elsif node['platform_family'] == 'fedora' then
yum_repository 'fedora' do
description 'Fedora'
mirrorlist 'https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch'
gpgkey 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch'
exclude 'tor'
action :create
end
end

# Install Tor
package 'tor'

# TODO: support Mac using homebrew
# when 'mac_os_x'
end

# Configure hidden services
ruby_block "read-hostnames" do
retries 2
action :nothing
block do
# Set generated hostname for hidden services
node['tor']['HiddenServices'].each do |name, service|
path = File.join(service['HiddenServiceDir'], "/hostname")
node.normal['tor']['HiddenServices'][name]['hostname'] = File.read(path).strip()
end
end
end

# Build torrc configuration file
template '/etc/tor/torrc' do
source 'torrc.erb'
notifies :restart, 'service[tor]', :immediately
notifies :run, "ruby_block[read-hostnames]"
# Set default HiddenServiceDir
node['tor']['HiddenServices'].each do |name, service|
node.default['tor']['HiddenServices'][name]['HiddenServiceDir'] = File.join("/var/lib/tor/", name, "/")
end
end

# Install exit policy notice
template '/etc/tor/tor-exit-notice.html' do
source 'tor-exit-notice.html.erb'
end

service 'tor' do
supports [:restart, :reload, :status]
action [:enable, :start]
end

+ 8
- 0
site-cookbooks/tor-full/recipes/relay.rb View File

@@ -0,0 +1,8 @@
#
# Author:: Richard Klafter <rpklafter@yahoo.com>
# Cookbook Name:: tor
# Recipe:: relay
#

node.default['tor']['relay']['enabled'] = true
include_recipe "tor-full"

+ 124
- 0
site-cookbooks/tor-full/templates/default/tor-exit-notice.html.erb View File

@@ -0,0 +1,124 @@
<html>
<head>
<title>This is a Tor Exit Router</title>

<!--

This notice is intended to be placed on a virtual host for a domain that
your Tor exit node IP reverse resolves to so that people who may be about
to file an abuse complaint would check it first before bothering you or
your ISP. Ex:
http://tor-exit.yourdomain.org or http://tor-readme.yourdomain.org.

This type of setup has proven very effective at reducing abuse complaints
for exit node operators.

There are a few places in this document that you may want to customize.
They are marked with FIXME.

-->

</head>
<body bgcolor=white text=black>

<center><h1>This is a Tor Exit Router</h1></center>

<p>Most likely you are accessing this website because you had some issue with
the traffic coming from this IP. This router is part of the <a
href="https://www.torproject.org/">Tor Anonymity Network</a>, which is
dedicated to providing people with anonymity who need it most: average
computer users. This router IP should be generating no other traffic, unless
it has been compromised.

<p>

While Tor is not designed for malicious computer users, it is inevitable that
some may use the network for malicious ends. In the mind of this operator,
the social need for easily accessible censorship-resistant anonymous
communication trumps the risk. Tor sees use by many important segments of the
population, including whistle blowers, journalists, Chinese dissidents
skirting the Great Firewall and oppressive censorship, abuse victims,
stalker targets, the US military, and law enforcement, just to name a few.

<p>

<!-- FIXME: you should probably grab your own copy of how_tor_works_thumb.png
and serve it locally -->
<center><a href="https://www.torproject.org/overview.html">
<img src="http://www.torproject.org/images/how_tor_works_thumb.png"></a></center>

<p>

In terms of applicable law, the best way to understand Tor is to consider it a
network of routers operating as common carriers, much like the Internet
backbone. However, unlike the Internet backbone routers, Tor routers
explicitly do not contain identifiable routing information about the source of
a packet.

<p>

As such, there is little the operator of this router can do to help you track
the connection further. This router maintains no logs of any of the Tor
traffic, so there is little that can be done to trace either legitimate or
illegitimate traffic (or to filter one from the other). Attempts to
seize this router will accomplish nothing.
<p>

<!--- FIXME: US-Only section. Remove if you are a non-US operator -->

Furthermore, this machine also serves as a carrier of email, which means that
its contents are further protected under the ECPA. <a
href="http://www4.law.cornell.edu/uscode/html/uscode18/usc_sec_18_00002707----000-.html">18
USC 2707</a> explicitly allows for civil remedies ($1000/account
<i><b><u>plus</u></b></i> legal fees)
in the event of a seizure executed without good faith or probable cause (it
should be clear at this point that traffic with an originating IP address of
<%= node['tor']['relay']['Address'] %> should not constitute probable cause to seize the
machine). Similar considerations exist for 1st amendment content on this
machine.

<p>

<!-- FIXME: May or may not be US-only. Some non-US tor nodes have in
fact reported DMCA harassment... -->

If you are a representative of a company who feels that this router is being
used to violate the DMCA, please be aware that this machine does not host or
contain any illegal content. Also be aware that network infrastructure
maintainers are not liable for the type of content that passes over their
equipment, in accordance with <a
href="http://www4.law.cornell.edu/uscode/html/uscode17/usc_sec_17_00000512----000-.html">DMCA
"safe harbor" provisions</a>. In other words, you will have just as much luck
sending a takedown notice to the Internet backbone providers. Please consult
<a href="https://www.torproject.org/eff/tor-dmca-response.html">EFF's prepared
response</a> for more information on this matter.

<p>For more information, please consult the following documentation:

<ol>
<li><a href="https://www.torproject.org/overview.html">Tor Overview</a></li>
<li><a href="https://www.torproject.org/faq-abuse.html">Tor Abuse FAQ</a></li>
<li><a href="https://www.torproject.org//eff/tor-legal-faq.html">Tor Legal FAQ</a></li>
</ol>
<p>

That being said, if you still have a complaint about the router, you may
email the <a href="mailto:<%= node['tor']['relay']['ContactInfo'] %>">maintainer</a>. If
complaints are related to a particular service that is being abused, I will
consider removing that service from my exit policy, which would prevent my
router from allowing that traffic to exit through it. I can only do this on an
IP+destination port basis, however. Common P2P ports are
already blocked.

<p>You also have the option of blocking this IP address and others on
the Tor network if you so desire. The Tor project provides a <a
href="https://www.torproject.org/cvs/tor/contrib/exitlist">python script</a> to
extract all IP addresses of Tor exit nodes, and an official <a
href="http://exitlist.torproject.org/">DNSRBL</a> is also available to
determine if a given IP address is actually a Tor exit server. Please
be considerate
when using these options. It would be unfortunate to deny all Tor users access
to your site indefinitely simply because of a few bad apples.

</body>
</html>

+ 235
- 0
site-cookbooks/tor-full/templates/default/torrc.erb View File

@@ -0,0 +1,235 @@
###############################################################
#This file was automatically generated and dropped off by Chef!
###############################################################

## Configuration file for a typical Tor user
## Last updated 12 September 2012 for Tor 0.2.4.3-alpha.
## (may or may not work for much older or much newer versions of Tor.)
##
## Lines that begin with "## " try to explain what's going on. Lines
## that begin with just "#" are disabled commands: you can enable them
## by removing the "#" symbol.
##
## See 'man tor', or https://www.torproject.org/docs/tor-manual.html,
## for more options you can use in this file.
##
## Tor will look for this file in various places based on your platform:
## https://www.torproject.org/docs/faq#torrc

## Tor opens a socks proxy on port 9050 by default -- even if you don't
## configure one below. Set "SocksPort 0" if you plan to run Tor only
## as a relay, and not make any local application connections yourself.
#SocksPort 9050 # Default: Bind to localhost:9050 for local connections.
#SocksPort 192.168.0.1:9100 # Bind to this address:port too.
<% if node['tor']['SocksPorts'].length > 0 %>
<% node['tor']['SocksPorts'].each do |socksPort| -%>
SocksPort <%= socksPort %>
<% end -%>
<% else %>
SocksPort 0
<% end %>

## Entry policies to allow/deny SOCKS requests based on IP address.
## First entry that matches wins. If no SocksPolicy is set, we accept
## all (and only) requests that reach a SocksPort. Untrusted users who
## can access your SocksPort may be able to learn about the connections
## you make.
#SocksPolicy accept 192.168.0.0/16
#SocksPolicy reject *

## Logs go to stdout at level "notice" unless redirected by something
## else, like one of the below lines. You can have as many Log lines as
## you want.
##
## We advise using "notice" in most cases, since anything more verbose
## may provide sensitive information to an attacker who obtains the logs.
##
## Send all messages of level 'notice' or higher to /var/log/tor/notices.log
#Log notice file /var/log/tor/notices.log
## Send every possible message to /var/log/tor/debug.log
#Log debug file /var/log/tor/debug.log
## Use the system log instead of Tor's logfiles
#Log notice syslog
## To send all messages to stderr:
#Log debug stderr
Log <%= node['tor']['MinLogLevel'] %> <%= node['tor']['LogDestination']=="syslog" ? "" : "file " %><%= node['tor']['LogDestination'] %>

## Uncomment this to start the process in the background... or use
## --runasdaemon 1 on the command line. This is ignored on Windows;
## see the FAQ entry if you want Tor to run as an NT service.
#RunAsDaemon 1

## The directory for keeping all the keys/etc. By default, we store
## things in $HOME/.tor on Unix, and in Application Data\tor on Windows.
DataDirectory <%= node['tor']['DataDirectory'] %>

## The port on which Tor will listen for local connections from Tor
## controller applications, as documented in control-spec.txt.
#ControlPort 9051
## If you enable the controlport, be sure to enable one of these
## authentication methods, to prevent attackers from accessing it.
#HashedControlPassword 16:872860B76453A77D60CA2BB8C1A7042072093276A3D701AD684053EC4C
#CookieAuthentication 1

############### This section is just for location-hidden services ###

## Once you have configured a hidden service, you can look at the
## contents of the file ".../hidden_service/hostname" for the address
## to tell people.
##
## HiddenServicePort x y:z says to redirect requests on port x to the
## address y:z.

#HiddenServiceDir /var/lib/tor/hidden_service/
#HiddenServicePort 80 127.0.0.1:80

#HiddenServiceDir /var/lib/tor/other_hidden_service/
#HiddenServicePort 80 127.0.0.1:80
#HiddenServicePort 22 127.0.0.1:22
<% node['tor']['HiddenServices'].each do |name, service| -%>

HiddenServiceDir <%= service['HiddenServiceDir'] %>
<% service['HiddenServicePorts'].each do |port| -%>
HiddenServicePort <%= port %>
<% end -%>
<% end -%>

<% if node['tor']['relay']['enabled'] %>
################ This section is just for relays #####################
#
## See https://www.torproject.org/docs/tor-doc-relay for details.

## Required: what port to advertise for incoming Tor connections.
ORPort <%= node['tor']['relay']['ORPort'] %>
## If you want to listen on a port other than the one advertised in
## ORPort (e.g. to advertise 443 but bind to 9090), you can do it as
## follows. You'll need to do ipchains or other port forwarding
## yourself to make this work.
#ORPort 443 NoListen
#ORPort 127.0.0.1:9090 NoAdvertise

## The IP address or full DNS name for incoming connections to your
## relay. Leave commented out and Tor will guess.
<% unless node['tor']['relay']['Address'].nil? %>
Address <%= node['tor']['relay']['Address'] %>
<% end %>

## If you have multiple network interfaces, you can specify one for
## outgoing traffic to use.
<% unless node['tor']['relay']['OutboundBindAddress'].nil? %>
OutboundBindAddress <%= node['tor']['relay']['OutboundBindAddress'] %>
<% end %>

## A handle for your relay, so people don't have to refer to it by key.
Nickname <%= node['tor']['relay']['Nickname'] %>

## Define these to limit how much relayed traffic you will allow. Your
## own traffic is still unthrottled. Note that RelayBandwidthRate must
## be at least 20 KB.
## Note that units for these config options are bytes per second, not bits
## per second, and that prefixes are binary prefixes, i.e. 2^10, 2^20, etc.
<% unless node['tor']['relay']['RelayBandwidthRate'].nil? %>
RelayBandwidthRate <%= node['tor']['relay']['RelayBandwidthRate'] %> KB
<% end %>
<% unless node['tor']['relay']['RelayBandwidthRate'].nil? %>
RelayBandwidthBurst <%= node['tor']['relay']['RelayBandwidthBurst'] %> KB
<% end %>
#RelayBandwidthRate 100 KB # Throttle traffic to 100KB/s (800Kbps)
#RelayBandwidthBurst 200 KB # But allow bursts up to 200KB/s (1600Kbps)

## Use these to restrict the maximum traffic per day, week, or month.
## Note that this threshold applies separately to sent and received bytes,
## not to their sum: setting "4 GB" may allow up to 8 GB total before
## hibernating.
##
## Set a maximum of 4 gigabytes each way per period.
#AccountingMax 4 GB
## Each period starts daily at midnight (AccountingMax is per day)
#AccountingStart day 00:00
## Each period starts on the 3rd of the month at 15:00 (AccountingMax
## is per month)
#AccountingStart month 3 15:00

## Contact info to be published in the directory, so we can contact you
## if your relay is misconfigured or something else goes wrong. Google
## indexes this, so spammers might also collect it.
#ContactInfo Random Person nobody AT example dot com
## You might also include your PGP or GPG fingerprint if you have one:
#ContactInfo 0xFFFFFFFF Random Person nobody AT example dot com
<% unless node['tor']['relay']['ContactInfo'].nil? %>
ContactInfo <%= node['tor']['relay']['ContactInfo'] %>
<% end %>

## Uncomment this to mirror directory information for others. Please do
## if you have enough bandwidth.
#DirPort 9030 # what port to advertise for directory connections
## If you want to listen on a port other than the one advertised in
## DirPort (e.g. to advertise 80 but bind to 9091), you can do it as
## follows. below too. You'll need to do ipchains or other port
## forwarding yourself to make this work.
#DirPort 80 NoListen
#DirPort 127.0.0.1:9091 NoAdvertise
## Uncomment to return an arbitrary blob of html on your DirPort. Now you
## can explain what Tor is if anybody wonders why your IP address is
## contacting them. See contrib/tor-exit-notice.html in Tor's source
## distribution for a sample.
<% if node['tor']['relay']['DirPortFrontPage'].is_a? String %>
DirPortFrontPage <%= node['tor']['relay']['DirPortFrontPage'] %>
<% elsif node['tor']['relay']['DirPortFrontPage'] %>
DirPortFrontPage /etc/tor/tor-exit-notice.html
<% end %>
<% if node['tor']['relay']['Directory'] %>
DirPort <%= node['tor']['relay']['DirPort'] %>
<% end %>

## Uncomment this if you run more than one Tor relay, and add the identity
## key fingerprint of each Tor relay you control, even if they're on
## different networks. You declare it here so Tor clients can avoid
## using more than one of your relays in a single circuit. See
## https://www.torproject.org/docs/faq#MultipleRelays
## However, you should never include a bridge's fingerprint here, as it would
## break its concealability and potentionally reveal its IP/TCP address.
#MyFamily $keyid,$keyid,...
<% if node['tor']['relay']['MyFamily'].length > 0 %>
MyFamily <%= node['tor']['relay']['MyFamily'].join(",") %>
<% end %>

## A comma-separated list of exit policies. They're considered first
## to last, and the first match wins. If you want to _replace_
## the default exit policy, end this with either a reject *:* or an
## accept *:*. Otherwise, you're _augmenting_ (prepending to) the
## default exit policy. Leave commented to just use the default, which is
## described in the man page or at
## https://www.torproject.org/documentation.html
##
## Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses
## for issues you might encounter if you use the default exit policy.
##
## If certain IPs and ports are blocked externally, e.g. by your firewall,
## you should update your exit policy to reflect this -- otherwise Tor
## users will be told that those destinations are down.
##
## For security, by default Tor rejects connections to private (local)
## networks, including to your public IP address. See the man page entry
## for ExitPolicyRejectPrivate if you want to allow "exit enclaving".
##
#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports but no more
#ExitPolicy accept *:119 # accept nntp as well as default exit policy
#ExitPolicy reject *:* # no exits allowed
<% node['tor']['relay']['ExitPolicy'].each do |exitPolicy| -%>
ExitPolicy <%= exitPolicy %>
<% end -%>

## Bridge relays (or "bridges") are Tor relays that aren't listed in the
## main directory. Since there is no complete public list of them, even an
## ISP that filters connections to all the known Tor relays probably
## won't be able to block all the bridges. Also, websites won't treat you
## differently because they won't know you're running Tor. If you can
## be a real relay, please do; but if not, be a bridge!
BridgeRelay <%= node['tor']['relay']['BridgeRelay'] %>
## By default, Tor will advertise your bridge to users through various
## mechanisms like https://bridges.torproject.org/. If you want to run
## a private bridge, for example because you'll give out your bridge
## address manually to your friends, uncomment this line:
PublishServerDescriptor <%= node['tor']['relay']['PublishServerDescriptor'] %>
<% end %>

+ 6
- 0
site-cookbooks/tor-full/test/integration/default/bats/tor_installed.bats View File

@@ -0,0 +1,6 @@
#!/usr/bin/env bats

@test "tor binary is found in PATH" {
run which tor
[ "$status" -eq 0 ]
}

Loading…
Cancel
Save