rack-detect-tor 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +51 -0
  4. data/lib/rack-detect-tor.rb +85 -0
  5. metadata +74 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7963c9ae710b9b5f9a6b47ea251aa6bddc644aac
4
+ data.tar.gz: 45b6a0b4c6c9d3a2c6ed6a57b6c088b7b4bd6fa6
5
+ SHA512:
6
+ metadata.gz: 35a6e8440ae33e266e6f7d70259f3aab97185fc6251b66b6d724740ea7cbc843be81442f5924883fcd3b27e66cd8ecbaa903994b8ef38445b5ec5932559b3d81
7
+ data.tar.gz: 9edc60fbfb0c4698b061a81dbd0ec01b282caf37502113cb330cb0886cde470852fb7ba8f381a93e5ec3d52cb2cd700bb46687565473976196a196a7f46ec441
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (C) 2015 Warren Guy <warren@guy.net.au>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # Rack::DetectTor
2
+
3
+ Rack middleware for detecting Tor exits.
4
+
5
+ Rack::DetectTor determines whether a user is connecting via a Tor exit
6
+ relay. It adds an environment variable `tor_exit_user` to the
7
+ `request.env` object with a value of `true` or `false`.
8
+
9
+ ## Usage
10
+
11
+ Add the gem to your Gemfile:
12
+
13
+ ```ruby
14
+ gem 'rack-detect-tor'
15
+ ```
16
+
17
+ and add it to your middleware stack. In `config.ru`:
18
+
19
+ ```ruby
20
+ require 'rack-detect-tor'
21
+
22
+ use Rack::DetectTor, 'external_ip' => [ip],
23
+ 'external_port' => [port],
24
+ 'update_frequency' => 3600
25
+ ```
26
+
27
+ It is *recommended* to provide `external_ip` and `external_port` (see
28
+ below). `update_frequency` is how often Rack::DetectTor will update its
29
+ list of Tor exits. It defaults to one hour (3600 seconds).
30
+
31
+ ### Note on `external_ip` and `external_port`
32
+
33
+ You are not *required* to provide these. However:
34
+
35
+ It's important to provide the `external_ip` and `external_port` values,
36
+ corresponding with the external IP and port of your web server. Many Tor
37
+ relays are configured not to allow connections on port 80/443/etc. If you
38
+ don't provide or are unable to provide the external IP of your web server,
39
+ the value added to `request.env['tor_exit_user']` will tell you only that
40
+ the IP corresponds with **A** Tor exit, not necessarily one that is
41
+ configured to relay connections to your website.
42
+
43
+ ## License
44
+
45
+ MIT license. See [LICENSE](https://github.com/warrenguy/sinatra-rate-limiter/blob/master/LICENSE).
46
+
47
+ ## Author
48
+
49
+ Warren Guy <warren@guy.net.au>
50
+
51
+ https://warrenguy.me
@@ -0,0 +1,85 @@
1
+ require 'open-uri'
2
+ require 'eventmachine'
3
+
4
+ module Rack
5
+ class DetectTor
6
+
7
+ def initialize(app, options={})
8
+ @app = app
9
+
10
+ @options = {
11
+ 'external_ip' => nil,
12
+ 'external_port' => nil,
13
+ 'update_frequency' => 60*60
14
+ }.merge(options)
15
+
16
+ @identifier = Hash[@options.select{|k,v| k =~ /^external_/}.
17
+ sort_by{|k,v| k}].values.map{|v| v.to_s == '' ? '*' : v}.join('/')
18
+
19
+ log_message 'Fetching initial list of tor exits...'
20
+ @tor_exits = fetch_tor_exits || {}
21
+
22
+ unless @options['update_frequency'].to_i == 0
23
+ log_message "Starting update timer... (updating every #{@options['update_frequency']} seconds)"
24
+ run_update_timer
25
+ end
26
+ end
27
+
28
+ def call(env)
29
+ env['tor_exit_user'] = @tor_exits.include? env['REMOTE_ADDR']
30
+ @app.call(env)
31
+ end
32
+
33
+ private
34
+
35
+ def fetch_tor_exits
36
+ if @options.select{|k,v| k =~ /^external_/}.values.map{|v| v.to_s}.include? ''
37
+ log_message "WARNING: external_ip/external_port not specified. Results will NOT be accurate"
38
+
39
+ begin
40
+ tor_exit_list = open('https://check.torproject.org/exit-addresses').read
41
+ rescue OpenURI::HTTPError => e
42
+ log_error "Error fetching list of tor exits: #{e}"
43
+ end
44
+
45
+ tor_exits = tor_exit_list.split("\n").select{|i| i =~ /^ExitAddress/}.
46
+ map{|j| j.split(' ')[1]}
47
+ else
48
+ check_url = "https://check.torproject.org/cgi-bin/TorBulkExitList.py?" +
49
+ "ip=#{@options['external_ip']}" +
50
+ (@options['external_port'].nil? ? '' : "&port=#{@options['external_port']}")
51
+
52
+ begin
53
+ tor_exit_list = open(check_url).read
54
+ rescue OpenURI::HTTPError => e
55
+ log_error "Error fetching list of tor exits: #{e}"
56
+ end
57
+
58
+ tor_exits = tor_exit_list.split("\n").select{|i| !(i =~ /^\#/)}
59
+ end
60
+
61
+ log_message "Found #{tor_exits.count} exits."
62
+ return tor_exits
63
+ end
64
+
65
+ def run_update_timer
66
+ Thread.new do
67
+ EventMachine.run do
68
+ @update_timer = EventMachine::PeriodicTimer.new(@options['update_frequency']) do
69
+ log_message 'Updating list of tor exits...'
70
+ @tor_exits = fetch_tor_exits || @tor_exits
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ def log_message(message)
77
+ $stdout.puts "Rack::DetectTor [#{@identifier}]: #{message}"
78
+ end
79
+
80
+ def log_error(message)
81
+ $stderr.puts "Rack::DetectTor [#{@identifier}]: ERROR: #{message}"
82
+ end
83
+
84
+ end
85
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-detect-tor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Warren Guy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: eventmachine
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Rack middleware for detecting Tor exits
42
+ email: warren@guy.net.au
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - LICENSE
48
+ - README.md
49
+ - lib/rack-detect-tor.rb
50
+ homepage: https://github.com/warrenguy/rack-detect-tor
51
+ licenses:
52
+ - MIT
53
+ metadata: {}
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubyforge_project:
70
+ rubygems_version: 2.2.2
71
+ signing_key:
72
+ specification_version: 4
73
+ summary: Rack middleware for detecting Tor exits
74
+ test_files: []