ssh_tunnels 0.1.1 → 0.2.1

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: ba405495fb6506f5a69ac1fb1e222ff0b471a6276914f82c46b6960c4fa3796c
4
- data.tar.gz: fe87c9476685c2d87d7843f098260875561399967c0f504081f92e844a58e4e4
3
+ metadata.gz: b02037bed34da5ad832e27db6175c5cfb9dc22ed945aea8b06132d11b3b1cf40
4
+ data.tar.gz: afdc8849d8297603f943056c32bfbd75a20f02ab6ac420f99411193570b1ac52
5
5
  SHA512:
6
- metadata.gz: ded2e91fc8fce982c29a31a7da1e37e0ea3b009407c215dc6bfd4f0a6c451a22e639630a2acbf1f5776de3d8b20337857658e44ddb86554b61c67b86632b27e0
7
- data.tar.gz: 7827c2125fb9ea315d0e70629c01fde527bba7b027fa8c81b899caab12cb83c465fdaa937351272ded5e0a8b71c423deb3c8f455fda4aeff8c41eeaf44c0ae11
6
+ metadata.gz: 448766cc0443b44c59798e1f1efc71a5e6f3e955f778df03ce1682a7d7467ab42e0c390aaff4524697f7cba8fc10e936dd16e93570efcafcf2604023146065af
7
+ data.tar.gz: c54e62eb16ad72a4ef0698be1a5b1a2b9b8e07b09d4d574df444194a3f83b755ef18477af1e04f7ce8b9a7fd8d6117657d39d3c93741af0a7c22d83e47dc83bc
data/Gemfile.lock CHANGED
@@ -1,42 +1,48 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ssh_tunnels (0.1.1)
4
+ ssh_tunnels (0.2.1)
5
+ bcrypt_pbkdf (~> 1.1)
5
6
  curses (~> 1.3)
7
+ ed25519 (~> 1.3)
6
8
  net-ssh-gateway (~> 2.0)
7
9
 
8
10
  GEM
9
11
  remote: https://rubygems.org/
10
12
  specs:
11
- ast (2.4.1)
12
- concurrent-ruby (1.1.6)
13
- curses (1.3.2)
14
- diff-lcs (1.4.2)
15
- i18n (1.8.3)
13
+ ast (2.4.2)
14
+ bcrypt_pbkdf (1.1.0)
15
+ concurrent-ruby (1.2.3)
16
+ curses (1.4.4)
17
+ diff-lcs (1.5.1)
18
+ ed25519 (1.3.0)
19
+ i18n (1.14.4)
16
20
  concurrent-ruby (~> 1.0)
17
- net-ssh (6.1.0)
21
+ net-ssh (7.2.3)
18
22
  net-ssh-gateway (2.0.0)
19
23
  net-ssh (>= 4.0.0)
20
- paint (2.2.0)
21
- parallel (1.19.2)
22
- parser (2.7.1.4)
24
+ paint (2.3.0)
25
+ parallel (1.24.0)
26
+ parser (3.3.0.5)
23
27
  ast (~> 2.4.1)
24
- rainbow (3.0.0)
25
- regexp_parser (1.7.1)
26
- rexml (3.2.4)
27
- rspec (3.9.0)
28
- rspec-core (~> 3.9.0)
29
- rspec-expectations (~> 3.9.0)
30
- rspec-mocks (~> 3.9.0)
31
- rspec-core (3.9.2)
32
- rspec-support (~> 3.9.3)
33
- rspec-expectations (3.9.2)
28
+ racc
29
+ racc (1.7.3)
30
+ rainbow (3.1.1)
31
+ regexp_parser (2.9.0)
32
+ rexml (3.2.6)
33
+ rspec (3.13.0)
34
+ rspec-core (~> 3.13.0)
35
+ rspec-expectations (~> 3.13.0)
36
+ rspec-mocks (~> 3.13.0)
37
+ rspec-core (3.13.0)
38
+ rspec-support (~> 3.13.0)
39
+ rspec-expectations (3.13.0)
34
40
  diff-lcs (>= 1.2.0, < 2.0)
35
- rspec-support (~> 3.9.0)
36
- rspec-mocks (3.9.1)
41
+ rspec-support (~> 3.13.0)
42
+ rspec-mocks (3.13.0)
37
43
  diff-lcs (>= 1.2.0, < 2.0)
38
- rspec-support (~> 3.9.0)
39
- rspec-support (3.9.3)
44
+ rspec-support (~> 3.13.0)
45
+ rspec-support (3.13.1)
40
46
  rubocop (0.86.0)
41
47
  parallel (~> 1.10)
42
48
  parser (>= 2.7.0.1)
@@ -46,13 +52,13 @@ GEM
46
52
  rubocop-ast (>= 0.0.3, < 1.0)
47
53
  ruby-progressbar (~> 1.7)
48
54
  unicode-display_width (>= 1.4.0, < 2.0)
49
- rubocop-ast (0.0.3)
50
- parser (>= 2.7.0.1)
51
- ruby-progressbar (1.10.1)
52
- strong_versions (0.4.4)
53
- i18n (>= 0.5.0)
55
+ rubocop-ast (0.8.0)
56
+ parser (>= 2.7.1.5)
57
+ ruby-progressbar (1.13.0)
58
+ strong_versions (0.4.5)
59
+ i18n (>= 0.5)
54
60
  paint (~> 2.0)
55
- unicode-display_width (1.7.0)
61
+ unicode-display_width (1.8.0)
56
62
 
57
63
  PLATFORMS
58
64
  ruby
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # SshTunnels
2
2
 
3
- Interactive _SSH_ tunnel management.
3
+ Interactive _SSH_ tunnel management. Console UI powered by [ncurses](https://invisible-island.net/ncurses/).
4
+
5
+ ![example](doc/demo.png)
4
6
 
5
7
  ## Installation
6
8
 
@@ -14,14 +16,64 @@ gem install ssh_tunnels
14
16
  ssh_tunnels -c config.yml
15
17
  ```
16
18
 
19
+ Alternatively, default to using `~/.ssh_tunnels.yml` for configuration:
20
+
21
+ ```bash
22
+ ssh_tunnels
23
+ ```
24
+
17
25
  ## Configuration
18
26
 
27
+ ### Gateways
28
+
29
+ There are two ways to configure an SSH gateway. Both can be used together, but at least one must be defined:
30
+
31
+ 1. Define a `default_gateway` section in your configuration file.
32
+ 1. Define a `gateways` section in your conifguration file.
33
+
34
+ The `default_gateway` is a map containing these keys:
35
+
36
+ * `host`: hostname or IP address of gateway (required).
37
+ * `port`: SSH port on gateway (default: `22`).
38
+ * `user`: Username on gateway to connect with (default: `$USER`).
39
+
40
+ The `gateways` section is also a map, but each key represents a named gateway, and each gateway is configured using the same parameters as `default_gateway`.
41
+
42
+ Each named gateway can be referred to in the `gateway` field for each tunnel.
43
+
19
44
  ```yaml
20
45
  # config.yml
21
46
 
22
- gateway:
47
+ default_gateway:
23
48
  host: gateway.example.com
24
- port: 22
49
+
50
+ gateways:
51
+ aws:
52
+ host: 111.111.111.111
53
+ user: ubuntu
54
+ azure:
55
+ host: 222.222.222.222
56
+ user: william
57
+ ```
58
+
59
+ ### Tunnels
60
+
61
+ The `tunnels` section is a map where each key represents a named tunnel. Each tunnel can be configured using the following parameters:
62
+
63
+ * `host`: The remote host to connect to from the gateway.
64
+ * `remote`: The remote port to use for forwarding.
65
+ * `local`: The local port to bind to (defaults to the `remote` port).
66
+
67
+ ```yaml
68
+ # config.yml
69
+
70
+ default_gateway:
71
+ host: gateway.example.com
72
+
73
+ gateways:
74
+ aws:
75
+ host: 111.111.111.111
76
+ user: ubuntu
25
77
 
26
78
  tunnels:
27
79
  my_host:
@@ -29,6 +81,7 @@ tunnels:
29
81
  host: my.host.example.com
30
82
  remote: 4567
31
83
  other_host:
84
+ gateway: aws
32
85
  local: 1111
33
86
  host: other.host.example.com
34
87
  remote: 5555
data/bin/ssh_tunnels CHANGED
@@ -20,24 +20,40 @@ OptionParser.new do |opts|
20
20
  end
21
21
  end.parse!
22
22
 
23
- unless options[:config_path]
24
- warn('Must provide configuration path. See --help')
25
- exit 1
26
- end
23
+ config_path = options.fetch(:config_path, File.expand_path('~/.ssh_tunnels.yml'))
27
24
 
28
- unless File.exist?(options[:config_path])
29
- warn("Unable to locate configuration file: #{options[:config_path]}")
25
+ unless File.exist?(config_path)
26
+ warn("Unable to locate configuration file: #{config_path}")
30
27
  exit 1
31
28
  end
32
29
 
33
- config = YAML.safe_load(File.read(options[:config_path]))
30
+ config = YAML.safe_load(File.read(config_path))
34
31
 
35
32
  begin
36
- gateway = config.fetch('gateway')
33
+ default_gateway = config.fetch('default_gateway', nil)
34
+ if !config.key?('tunnels')
35
+ warn('Configuration file must provide `tunnels` section. Exiting.')
36
+ exit 1
37
+ end
38
+
39
+ gateways = config.fetch('gateways', {})
40
+
37
41
  tunnels = config.fetch('tunnels')
38
- rescue KeyError
39
- warn('Configuration file must provide `gateway` and `tunnels` sections.')
40
- exit 1
42
+ error = false
43
+ tunnels.each do |key, tunnel|
44
+ if tunnel.key?('gateway') && !gateways.key?(tunnel.fetch('gateway'))
45
+ error = true
46
+ warn("Tunnel `#{key}` references unknown gateway `#{tunnel.fetch('gateway')}`")
47
+ elsif !tunnel.key?('gateway') && default_gateway.nil?
48
+ error = true
49
+ warn("Tunnel `#{key}` must provide `gateway` key or define a top-level `default_gateway` configuration.")
50
+ end
51
+ end
52
+
53
+ if error
54
+ warn("Configuration errors detected. Exiting.")
55
+ exit 1
56
+ end
41
57
  end
42
58
 
43
59
  user = ENV.fetch('USER')
@@ -47,6 +63,11 @@ puts
47
63
 
48
64
  begin
49
65
  tunnels = tunnels.map do |name, tunnel_config|
66
+ gateway = if tunnel_config.key?('gateway')
67
+ gateways.fetch(tunnel_config.fetch('gateway'))
68
+ else
69
+ default_gateway
70
+ end
50
71
  SshTunnels::Tunnel.new(name, user, tunnel_config, gateway, passphrase)
51
72
  end
52
73
  ui = SshTunnels::UI.new(tunnels)
data/doc/demo.png ADDED
Binary file
@@ -27,11 +27,11 @@ module SshTunnels
27
27
  end
28
28
 
29
29
  def open
30
- @connection = Net::SSH::Gateway.new(@gateway.fetch('host'), @user, options)
30
+ @connection = Net::SSH::Gateway.new(@gateway.fetch('host'), @gateway.fetch('user', @user), options)
31
31
  @connection.open(remote_host, remote_port, local_port)
32
- rescue Errno::EADDRINUSE => e
33
- @error = e.to_s
32
+ rescue StandardError => e
34
33
  shutdown
34
+ raise
35
35
  end
36
36
 
37
37
  def active?
@@ -41,7 +41,7 @@ module SshTunnels
41
41
  end
42
42
 
43
43
  def shutdown
44
- @connection.shutdown!
44
+ @connection&.shutdown!
45
45
  end
46
46
 
47
47
  private
@@ -55,14 +55,14 @@ module SshTunnels
55
55
  end
56
56
 
57
57
  def local_port
58
- @config.fetch('local_port')
58
+ @config.fetch('local_port', remote_port)
59
59
  end
60
60
 
61
61
  def options
62
62
  {
63
63
  keepalive: true,
64
64
  keepalive_interval: 5,
65
- port: @gateway.fetch('port'),
65
+ port: @gateway.fetch('port', 22),
66
66
  passphrase: @passphrase
67
67
  }
68
68
  end
@@ -96,7 +96,11 @@ module SshTunnels
96
96
  else
97
97
  status("Connecting: #{tunnel}")
98
98
  end
99
- tunnel.toggle
99
+ begin
100
+ tunnel.toggle
101
+ rescue StandardError => e
102
+ status("Error: #{e}")
103
+ end
100
104
  end
101
105
 
102
106
  def tunnel_color(tunnel)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SshTunnels
4
- VERSION = '0.1.1'
4
+ VERSION = '0.2.1'
5
5
  end
data/ssh_tunnels.gemspec CHANGED
@@ -27,6 +27,8 @@ Gem::Specification.new do |spec|
27
27
 
28
28
  spec.add_runtime_dependency 'curses', '~> 1.3'
29
29
  spec.add_runtime_dependency 'net-ssh-gateway', '~> 2.0'
30
+ spec.add_runtime_dependency 'ed25519', '~> 1.3'
31
+ spec.add_runtime_dependency 'bcrypt_pbkdf', '~> 1.1'
30
32
 
31
33
  spec.add_development_dependency 'rspec', '~> 3.9'
32
34
  spec.add_development_dependency 'rubocop', '~> 0.86.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ssh_tunnels
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bob Farrell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-08 00:00:00.000000000 Z
11
+ date: 2024-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: curses
@@ -38,6 +38,34 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: ed25519
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bcrypt_pbkdf
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.1'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: rspec
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -100,6 +128,7 @@ files:
100
128
  - bin/console
101
129
  - bin/setup
102
130
  - bin/ssh_tunnels
131
+ - doc/demo.png
103
132
  - lib/ssh_tunnels.rb
104
133
  - lib/ssh_tunnels/tunnel.rb
105
134
  - lib/ssh_tunnels/ui.rb