uninterruptible 2.2.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ec0c8eaf7fcd4e6be024f10c74ea412c7b2e1c4a
4
- data.tar.gz: 4dc641d56fcbdbf69237db8366ad89e094fd4008
3
+ metadata.gz: 4b2930d6fcae73edfbb4d6f39cd6e5995304d8a5
4
+ data.tar.gz: 6c22d922f5cd20810d5849d322af57bb69a22abe
5
5
  SHA512:
6
- metadata.gz: 445bb79aef41ed50720a674fc9df82461eed9a63231648d53fe4cb567cc9900638f359709f060712c8c332a47596d1be9971e676b63d417d03bf060abc659af2
7
- data.tar.gz: c72b8005bd3a954ad35d98555566e3fcdb67055b2b7d6b1764273515ec4f4864e9bf150b5260b56d95a16588ce692b14538e16687b386678cb9d4938b0b13a17
6
+ metadata.gz: 32742c8851a675116a8489b3f62b666eb0e1ede1ba54f9682d0c47287ead8d1ba6c4abe50bd9755f8bd1d579b35d20e880f3aa2b3328569cf45413104a322343
7
+ data.tar.gz: 740993f1d8a5d940acd874ba3f990846dfde887dd26124fd0944f59ef7d542104890ed879b4cb7bc369a8248318ec2fb98932433ac7e556ef3efc97f0aa73de7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Changelog
2
2
 
3
+ # 2.3.0
4
+ * Incoming connections can be restricted to certain networks by setting `allowed_networks` in the configuration.
5
+
3
6
  # 2.2.1
4
7
  * Allow multiple certificates to be used in one build file
5
8
 
data/README.md CHANGED
@@ -69,6 +69,7 @@ echo_server.configure do |config|
69
69
  config.tls_certificate = nil # Certificate to use for TLS, reads file from ENV['TLS_CERTIFICATE'] if set
70
70
  config.verify_client_tls_certificate = false # Should client TLS certificates be required and verifiyed? Falls back to ENV['VERIFY_CLIENT_TLS_CERTIFICATE']
71
71
  config.client_tls_certificate_ca = nil # Path to a trusted CA for client certificates. Implies `config.verify_client_tls_certificate = true`. Falls back to ENV['CLIENT_TLS_CERTIFICATE_CA']
72
+ config.allowed_networks = ['127.0.0.1/8', '2001:db8::/32'] # A list of networks that clients are allowed to connect from. If blank, all networks are allowed. Falls back to a comma-separated list from ENV['ALLOWED_NETWORKS']
72
73
  end
73
74
  ```
74
75
 
@@ -96,8 +97,8 @@ By default, Uninterruptible operates on a very simple one thread per connection
96
97
  something more advanced such as a threadpool or an event driven pattern you can define this in your server class.
97
98
 
98
99
  By overriding `accept_client_connection` you can change how connections are accepted and handled. It is recommended
99
- that you call `process_request` from this method and still implement `handle_request` to do the bulk of the work since
100
- `process_request` tracks the number of active connections to the server.
100
+ that you call `process_request` from this method and implement `handle_request` to do the bulk of the work since
101
+ `process_request` tracks the number of active connections to the server and handles network restrictions.
101
102
 
102
103
  `accept_client_connection` is called whenever a connection is waiting to be accepted on the socket server.
103
104
 
@@ -6,7 +6,7 @@ module Uninterruptible
6
6
  AVAILABLE_SSL_VERSIONS = %w[TLSv1_1 TLSv1_2].freeze
7
7
 
8
8
  attr_writer :bind, :bind_port, :bind_address, :pidfile_path, :start_command, :log_path, :log_level, :tls_version,
9
- :tls_key, :tls_certificate, :verify_client_tls_certificate, :client_tls_certificate_ca
9
+ :tls_key, :tls_certificate, :verify_client_tls_certificate, :client_tls_certificate_ca, :allowed_networks
10
10
 
11
11
  # Available TCP Port for the server to bind to (required). Falls back to environment variable PORT if set.
12
12
  #
@@ -94,5 +94,17 @@ module Uninterruptible
94
94
  def client_tls_certificate_ca
95
95
  @client_tls_certificate_ca || ENV['CLIENT_TLS_CERTIFICATE_CA']
96
96
  end
97
+
98
+ # Specifiy allowed networks to reject all connections except those originating from allowed networks. Set to an
99
+ # array of networks in CIDR format. If environment variable ALLOWED_NETWORKS is set, a comma separated list will be
100
+ # read from that. Setting this enables #block_connections?
101
+ def allowed_networks
102
+ @allowed_networks || (ENV['ALLOWED_NETWORKS'] && ENV['ALLOWED_NETWORKS'].split(',')) || []
103
+ end
104
+
105
+ # True when allowed_networks is set
106
+ def block_connections?
107
+ !allowed_networks.empty?
108
+ end
97
109
  end
98
110
  end
@@ -0,0 +1,39 @@
1
+ module Uninterruptible
2
+ class NetworkRestrictions
3
+ attr_reader :configuration
4
+
5
+ # @param [Uninterruptible::Configuration] configuration Object with allowed_networks configuration
6
+ def initialize(configuration)
7
+ @configuration = configuration
8
+ check_configuration!
9
+ end
10
+
11
+ # Should the incoming connection be allowed to connect?
12
+ #
13
+ # @param [TCPSocket] client_socket Incoming socket from the client connection
14
+ def connection_allowed_from?(client_address)
15
+ return true unless configuration.block_connections?
16
+ allowed_networks.any? { |allowed_network| allowed_network.include?(client_address) }
17
+ end
18
+
19
+ private
20
+
21
+ # Parse the list of allowed networks from the configuration and turn them into IPAddr objects
22
+ #
23
+ # @return [Array<IPAddr>] Parsed list of IP networks
24
+ def allowed_networks
25
+ @allowed_networks ||= configuration.allowed_networks.map do |network|
26
+ IPAddr.new(network)
27
+ end
28
+ end
29
+
30
+ # Check the configuration parameters for network restrictions
31
+ #
32
+ # @raise [Uninterruptible::ConfigurationError] Correct options are not set for network restrictions
33
+ def check_configuration!
34
+ unless configuration.bind.start_with?('tcp://')
35
+ raise ConfigurationError, "Network restrictions can only be used on TCP servers"
36
+ end
37
+ end
38
+ end
39
+ end
@@ -89,7 +89,6 @@ module Uninterruptible
89
89
  # concurrency model.
90
90
  def accept_client_connection
91
91
  Thread.start(socket_server.accept_nonblock) do |client_socket|
92
- logger.debug "Accepted connection from #{client_socket.peeraddr.last}"
93
92
  process_request(client_socket)
94
93
  end
95
94
  end
@@ -101,7 +100,13 @@ module Uninterruptible
101
100
  def process_request(client_socket)
102
101
  mutex.synchronize { @active_connections += 1 }
103
102
  begin
104
- handle_request(client_socket)
103
+ client_address = client_socket.peeraddr.last
104
+ if network_restrictions.connection_allowed_from?(client_address)
105
+ logger.debug "Accepting connection from #{client_address}"
106
+ handle_request(client_socket)
107
+ else
108
+ logger.debug "Rejecting connection from #{client_address}"
109
+ end
105
110
  ensure
106
111
  client_socket.close
107
112
  mutex.synchronize { @active_connections -= 1 }
@@ -196,6 +201,10 @@ module Uninterruptible
196
201
  end
197
202
  end
198
203
 
204
+ def network_restrictions
205
+ @network_restrictions ||= Uninterruptible::NetworkRestrictions.new(server_configuration)
206
+ end
207
+
199
208
  # The current configuration of this server
200
209
  #
201
210
  # @return [Uninterruptible::Configuration] Current or new configuration if unset.
@@ -1,3 +1,3 @@
1
1
  module Uninterruptible
2
- VERSION = "2.2.1".freeze
2
+ VERSION = "2.3.0".freeze
3
3
  end
@@ -1,8 +1,11 @@
1
1
  require 'openssl'
2
+ require 'ipaddr'
3
+
2
4
  require "uninterruptible/version"
3
5
  require 'uninterruptible/ssl_extensions'
4
6
  require 'uninterruptible/configuration'
5
7
  require 'uninterruptible/binder'
8
+ require 'uninterruptible/network_restrictions'
6
9
  require 'uninterruptible/tls_server_factory'
7
10
  require 'uninterruptible/server'
8
11
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uninterruptible
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Wentworth
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-10-06 00:00:00.000000000 Z
11
+ date: 2018-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -75,6 +75,7 @@ files:
75
75
  - lib/uninterruptible.rb
76
76
  - lib/uninterruptible/binder.rb
77
77
  - lib/uninterruptible/configuration.rb
78
+ - lib/uninterruptible/network_restrictions.rb
78
79
  - lib/uninterruptible/server.rb
79
80
  - lib/uninterruptible/ssl_extensions.rb
80
81
  - lib/uninterruptible/tls_server_factory.rb
@@ -100,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
100
101
  version: '0'
101
102
  requirements: []
102
103
  rubyforge_project:
103
- rubygems_version: 2.5.1
104
+ rubygems_version: 2.5.2.1
104
105
  signing_key:
105
106
  specification_version: 4
106
107
  summary: Zero-downtime restarts for your trivial socket servers