tarbit 1.0.5 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8741b27a87810bc7ee88265453e62e8db227db785a12d81fc5afd16fd4b941cf
4
- data.tar.gz: d15135c2485f6f140138e46b02736d39b64ea1f0b401629c9f02f72bf0f41a8a
3
+ metadata.gz: '02867e5eb3be82482021f0ed4189d11e1601f2f2dc9679d5cff119e84518f438'
4
+ data.tar.gz: 05edc27632929089d62fa713f2d39dec3af2650b4309cc961c65725bf807317f
5
5
  SHA512:
6
- metadata.gz: 0ef11ee91cfb362d3298288b6d60c4a0f50a056b3d2fac747b89cd2f02490804102cda155579e921e7caf41c0f4fbdc99f9e43702ceeacb2f4bc9cae17f52caf
7
- data.tar.gz: 2a3e0400ce6f519d28f10e66c89c79825ac56aacaf82c80c06134f7475b704cdb81706b9a7f5673c8807380ff0b244767ebcb5b1f94ffafa0870e228fccd4164
6
+ metadata.gz: 0e4aad70c5122b3d5a297721c77ecce80b68220a07573d1d15a0f87df3bd38e0bbb9fe9a70eb8eedfa0605a2e589b55bc0d17c07ebb1c7a195de40d3041d40bb
7
+ data.tar.gz: 7e1e7f6fe4270be0b2e05189fc54dbf058f0da1aa335a3d550080113073b480c410c4de3d331231110b7ad8674cc647c3b31f73ccdcd8f43688ec671587bd904
data/Gemfile.lock CHANGED
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tarbit (1.0.1)
4
+ tarbit (1.0.5)
5
5
  async-io
6
6
  commander
7
7
  gruff
8
+ os
8
9
 
9
10
  GEM
10
11
  remote: https://rubygems.org/
@@ -22,6 +23,7 @@ GEM
22
23
  rmagick (~> 2.13, >= 2.13.4)
23
24
  highline (2.0.3)
24
25
  nio4r (2.5.2)
26
+ os (1.0.1)
25
27
  rmagick (2.16.0)
26
28
  timers (4.3.0)
27
29
 
data/bin/tarbit CHANGED
@@ -7,25 +7,49 @@ require 'fileutils'
7
7
  # :name is optional, otherwise uses the basename of this executable
8
8
  program :name, 'Tarbit - SSH Tarpit using Ruby'
9
9
  program :version, Tarbit::VERSION
10
- program :description, 'Stupid command that prints foo or bar.'
10
+ program :description, 'Catch em all!'
11
+
12
+ FileUtils.mkdir_p Tarbit::STATS_PATH
13
+ FileUtils.mkdir_p Tarbit::SNAPSHOT_PATH
11
14
 
12
15
  command :serve do |c|
13
- c.syntax = 'apollo serve [options]'
14
- c.description = 'Runs the apollo server'
15
- c.option '--debug', nil, 'Runs the apollo server in debug mode'
16
- c.option '--suffix STRING', String, 'Adds a suffix to bar'
16
+ c.syntax = 'tarbit serve [options]'
17
+ c.description = 'Runs the tarbit honeypot'
18
+
19
+ c.option '--interval NUMBER', Integer, 'Defines an interval in seconds, falls back to 600'
20
+ c.option '--port NUMBER', Integer, 'Defines a port, falls back to 22'
21
+
17
22
  c.action do |args, options|
18
23
 
19
- FileUtils.mkdir_p File.expand_path ('~/.tarbit/stats/')
20
- puts "Starting tarbit ssh tarpit"
21
24
 
22
- server = Tarbit::Server.new
23
- statistic = Tarbit::Statistic.new(server, 600)
25
+ server = Tarbit::Server.new(options.port.to_i)
26
+ statistic = Tarbit::StatisticWatcher.new(server, options.interval.to_i)
24
27
 
25
28
  Async do |task|
29
+ Async.logger.info "============================================================"
30
+ Async.logger.info "Starting tarbit on port #{options.port || 22} creating time points every #{options.interval || 600} seconds"
31
+ Async.logger.info "============================================================"
26
32
  statistic.watch
27
33
  server.run
28
34
  end
29
35
 
30
36
  end
37
+
38
+ end
39
+
40
+ command :snapshot do |c|
41
+ c.syntax = 'apollo snapshot [options]'
42
+ c.description = 'Creates a statistic snapshot of the current gathered data'
43
+ c.option '--debug', nil, 'Runs the apollo server in debug mode'
44
+ c.option '--suffix STRING', String, 'Adds a suffix to bar'
45
+ c.action do |args, options|
46
+
47
+ statistic = Tarbit::StatisticSnapshot.new
48
+
49
+ Async do |task|
50
+ statistic.snapshot
51
+ end
52
+
53
+ end
54
+
31
55
  end
data/lib/tarbit/server.rb CHANGED
@@ -11,12 +11,13 @@ module Tarbit
11
11
  class Server
12
12
  attr_reader :connections
13
13
 
14
- def initialize
14
+ def initialize(port = 22)
15
15
  @connections = []
16
+ @port = port
16
17
  end
17
18
 
18
19
  def run
19
- endpoint = Async::IO::Endpoint.parse("tcp://0.0.0.0:22")
20
+ endpoint = Async::IO::Endpoint.parse("tcp://0.0.0.0:#{@port}")
20
21
 
21
22
  Async do |task|
22
23
  while true
@@ -38,13 +39,13 @@ module Tarbit
38
39
  }
39
40
 
40
41
  while true do
41
- task.sleep 1
42
- if stream.eof? or stream.closed?
42
+ task.sleep 60
43
+ if stream.eof? || stream.closed? || stream.io.closed?
43
44
  raise Async::TimeoutError.new
44
45
  end
45
46
  stream.write "#{rand(10)}\r\n"
46
47
  end
47
- rescue Async::TimeoutError => e
48
+ rescue StandardError => e
48
49
  @connections = @connections.reject { |stats| stats.fetch(:id) == id }
49
50
  Async.logger.info "Connection closed: #{stream}"
50
51
  end
@@ -0,0 +1,41 @@
1
+ require 'gruff'
2
+ require 'async'
3
+ require 'json'
4
+
5
+ module Tarbit
6
+ class StatisticSnapshot
7
+
8
+ def initialize
9
+
10
+ end
11
+
12
+ def snapshot
13
+ Async do
14
+ write_line_chart
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def write_line_chart
21
+ files = Dir.glob(File.join(Tarbit::STATS_PATH, '*.json'))
22
+
23
+ files = files.map { |filename| JSON.parse(File.read(filename)) }
24
+
25
+ g = Gruff::Line.new
26
+ g.title = 'History of connections over time'
27
+
28
+ labels = {}
29
+ files.each_with_index{ |item, index| labels[index] = item.fetch("created_at") }
30
+ g.labels = labels
31
+
32
+ g.data :Bots, files.map {|point_in_time| point_in_time.fetch("connections").size }
33
+
34
+ filename = "#{Time.now.to_i}.png"
35
+ g.write(File.join(Tarbit::SNAPSHOT_PATH, filename))
36
+
37
+ Async.logger.info "Snapshot saved in: #{Tarbit::SNAPSHOT_PATH}/#{filename}"
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,37 @@
1
+ require 'gruff'
2
+ require 'async'
3
+ require 'json'
4
+
5
+ module Tarbit
6
+ class StatisticWatcher
7
+
8
+ def initialize(server, interval = 600)
9
+ @server = server
10
+ @interval = interval
11
+ @history = []
12
+ end
13
+
14
+ def watch
15
+ Async do |task|
16
+ while true
17
+ task.sleep @interval
18
+ create_point_in_time
19
+ end
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def create_point_in_time
26
+ # Add point in time
27
+ statistic_point = {
28
+ created_at: Time.now.to_i,
29
+ connections: @server.connections.clone
30
+ }
31
+
32
+ File.write("#{Tarbit::STATS_PATH}/#{statistic_point.fetch(:created_at)}.json", JSON.generate(statistic_point))
33
+
34
+ end
35
+
36
+ end
37
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tarbit
4
- VERSION = "1.0.5"
4
+ VERSION = "1.0.6"
5
5
  end
data/lib/tarbit.rb CHANGED
@@ -2,12 +2,37 @@
2
2
  #
3
3
 
4
4
  require 'async/reactor'
5
+ require 'os'
6
+
5
7
  require_relative 'tarbit/server'
6
- require_relative 'tarbit/statistic'
8
+ require_relative 'tarbit/statistic_watcher'
9
+ require_relative 'tarbit/statistic_snapshot'
7
10
  require_relative 'tarbit/version'
8
11
 
9
12
  Signal.trap "SIGINT" do
10
13
  exit(0)
11
14
  end
12
15
 
13
- module Tarbit; end
16
+ module Tarbit
17
+
18
+ if OS.posix?
19
+ if $stdout.isatty # If we are interactive, we can guess there is a home directory
20
+ STATS_PATH = File.expand_path("~/.tarbit/statistics").to_s
21
+ SNAPSHOT_PATH = File.expand_path("~/.tarbit/snapshots").to_s
22
+ else
23
+ STATS_PATH = "/etc/tarbit/statistics"
24
+ SNAPSHOT_PATH = "/etc/tarbit/snapshots"
25
+ end
26
+ end
27
+
28
+ if OS.windows?
29
+ if $stdout.isatty # If we are interactive, we can guess there is a home directory
30
+ STATS_PATH = File.expand_path("~/.tarbit/statistics").to_s
31
+ SNAPSHOT_PATH = File.expand_path("~/.tarbit/snapshots").to_s
32
+ else
33
+ STATS_PATH = "/etc/tarbit/statistics"
34
+ SNAPSHOT_PATH = "/etc/tarbit/snapshots"
35
+ end
36
+ end
37
+
38
+ end
data/tarbit.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
  s.add_dependency 'async-io'
25
25
  s.add_dependency 'commander'
26
26
  s.add_dependency 'gruff'
27
+ s.add_dependency 'os'
27
28
 
28
29
  # Development Dependencies
29
30
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tarbit
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Niklas Hanft
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: os
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  description: Description
56
70
  email: hello@niklashanft.com
57
71
  executables:
@@ -65,7 +79,8 @@ files:
65
79
  - bin/tarbit
66
80
  - lib/tarbit.rb
67
81
  - lib/tarbit/server.rb
68
- - lib/tarbit/statistic.rb
82
+ - lib/tarbit/statistic_snapshot.rb
83
+ - lib/tarbit/statistic_watcher.rb
69
84
  - lib/tarbit/version.rb
70
85
  - tarbit.gemspec
71
86
  homepage: https://github.com/nhh/apollo
@@ -1,46 +0,0 @@
1
- require 'gruff'
2
- require 'async'
3
-
4
- module Tarbit
5
- class Statistic
6
-
7
- def initialize(server, interval)
8
- @server = server
9
- @interval = interval
10
- @history = []
11
- end
12
-
13
- def watch
14
- Async do |task|
15
- while true
16
- task.sleep @interval
17
- write_line_chart
18
- end
19
- end
20
- end
21
-
22
- private
23
-
24
- def write_line_chart
25
- return if @server.connections.size == 0 and @history.size == 0
26
-
27
- # Add point in time
28
- @history << {
29
- created_at: Date.new.strftime("%B %d, %Y"),
30
- connections: @server.connections.clone # Cloning instead of referencing
31
- }
32
-
33
- g = Gruff::Line.new
34
- g.title = 'History of connections over time'
35
-
36
- labels = {}
37
- @history.each_with_index{ |item, index| labels[index] = item.fetch(:created_at) }
38
- g.labels = labels
39
-
40
- g.data :Bots, @history.map {|point_in_time| point_in_time.fetch(:connections).size }
41
-
42
- g.write(File.expand_path ('~/.tarbit/stats/line_chart.png'))
43
- end
44
-
45
- end
46
- end