ssl_gate 0.0.1
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 +7 -0
- data/bin/ssl_gate +4 -0
- data/lib/ssl_gate/base_gate.rb +47 -0
- data/lib/ssl_gate/base_ssl_gate.rb +28 -0
- data/lib/ssl_gate/client_cert.rb +12 -0
- data/lib/ssl_gate/headers_mod.rb +27 -0
- data/lib/ssl_gate/raw_gate.rb +56 -0
- data/lib/ssl_gate/raw_ssl.rb +21 -0
- data/lib/ssl_gate/runner.rb +29 -0
- data/lib/ssl_gate.rb +35 -0
- metadata +109 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6249ae8b79002d80de3d5710270887c8894834db
|
4
|
+
data.tar.gz: f3c9e97ddc513d3ebc72306f8c1ab5cca7c32ec6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 469ccb88950f8402c3d01576e19a02ab7ba720a47177e15c4337a97239c0d8001f407103bce7d8c6c4a819fd03237e2418219659dde972c2e1db514baab7ba8a
|
7
|
+
data.tar.gz: 9d6feea10dc30a8985f36293e314e7a44de9a147cc4c33774c17b1beace980bc36e65186d13c26efe5e68d196d3c2826067d972f62199560da49c1319859906f
|
data/bin/ssl_gate
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'thin'
|
2
|
+
require 'em-http'
|
3
|
+
|
4
|
+
module SSLGate
|
5
|
+
|
6
|
+
class HTTPServer
|
7
|
+
class << self; attr_accessor :add_ons end
|
8
|
+
@add_ons = []
|
9
|
+
|
10
|
+
attr_reader :config
|
11
|
+
def initialize(config)
|
12
|
+
@config = { signals: false,
|
13
|
+
# target: 'http://localhost:9000'
|
14
|
+
}.merge config
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(env)
|
18
|
+
r_method = env['REQUEST_METHOD'].downcase.to_sym
|
19
|
+
r_query = env['QUERY_STRING']
|
20
|
+
r_path = env['REQUEST_PATH']
|
21
|
+
# input = env['rack.input'] #StringIO
|
22
|
+
env[:target_request_options] ||= { connect_timeout: 20, inactivity_timeout: 20 }
|
23
|
+
|
24
|
+
puts "head: #{env[:target_get_options][:head] rescue ''}"
|
25
|
+
request = EM::HttpRequest.new @config[:target], env[:target_request_options]
|
26
|
+
http = request.send r_method, (env[:target_get_options] || {}).merge( path: r_path, query: r_query) # body: input
|
27
|
+
puts "#{r_method}: #{r_path} #{r_query}"
|
28
|
+
|
29
|
+
ready = lambda {
|
30
|
+
headers = http.response_header.map{ |key, val| [key.tr('_', '-'), val] }.to_h
|
31
|
+
headers.delete 'TRANSFER-ENCODING'
|
32
|
+
headers.delete 'CONTENT-ENCODING'
|
33
|
+
headers.delete 'CONTENT-LENGTH'
|
34
|
+
puts "OK: #{headers}"
|
35
|
+
env['async.callback'].call [http.response_header.status, headers, [http.response]]
|
36
|
+
}
|
37
|
+
http.callback { ready.call }
|
38
|
+
http.errback { ready.call }
|
39
|
+
throw :async
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.start(config)
|
43
|
+
server = new(config)
|
44
|
+
Thin::Server.start (config[:bind_interface] || '0.0.0.0'), config[:bind_port], server.config, server
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'thin'
|
3
|
+
|
4
|
+
OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:options] |= OpenSSL::SSL::OP_NO_COMPRESSION
|
5
|
+
OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:options] |= OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
6
|
+
OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ciphers] = 'TLSv1.2:!aNULL:!eNULL'
|
7
|
+
OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ssl_version] = 'TLSv1_2'
|
8
|
+
|
9
|
+
module SSLGate
|
10
|
+
|
11
|
+
class SSLBackend < ::Thin::Backends::TcpServer
|
12
|
+
def initialize(host, port, options)
|
13
|
+
super(host, port)
|
14
|
+
@ssl = true
|
15
|
+
@ssl_options = options
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module SSLBackendAddOn
|
20
|
+
def initialize(config)
|
21
|
+
super config.merge backend: SSLBackend
|
22
|
+
# private_key_file: File.dirname(__FILE__) + "/server.key",
|
23
|
+
# cert_chain_file: File.dirname(__FILE__) + "/server.crt",
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
HTTPServer.add_ons << SSLBackendAddOn
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module SSLGate
|
2
|
+
|
3
|
+
module HeadersModAddOn
|
4
|
+
|
5
|
+
def call(env)
|
6
|
+
prev = env['async.callback']
|
7
|
+
env['async.callback'] = lambda { |*args|
|
8
|
+
# puts 'I see you'
|
9
|
+
prev.call(*args)
|
10
|
+
}
|
11
|
+
headers = env.select { |k, _v| k.start_with? 'HTTP_' }
|
12
|
+
.collect { |key, val| [key.sub(/^HTTP_/, '').gsub('_', '-'), val] }
|
13
|
+
.to_h
|
14
|
+
headers.delete 'HOST'
|
15
|
+
headers.delete 'USER-AGENT'
|
16
|
+
headers['REFERER'].sub! %r{^https?://[^/]+(:\d+)?}, @config[:target] if headers['REFERER']
|
17
|
+
super env
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(config)
|
21
|
+
super
|
22
|
+
# subst_host: 'name'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
HTTPServer.add_ons << HeadersModAddOn
|
27
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
|
3
|
+
module SSLGate
|
4
|
+
|
5
|
+
class RawClient < EM::Connection
|
6
|
+
attr_reader :queue
|
7
|
+
|
8
|
+
def initialize(q, parent)
|
9
|
+
set_sock_opt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) # Nagle off
|
10
|
+
|
11
|
+
@parent = parent
|
12
|
+
@queue = q
|
13
|
+
|
14
|
+
cb = proc do |msg|
|
15
|
+
msg ? send_data(msg) : close_connection
|
16
|
+
q.pop(&cb)
|
17
|
+
end
|
18
|
+
q.pop(&cb)
|
19
|
+
end
|
20
|
+
|
21
|
+
def receive_data(data)
|
22
|
+
@parent.send_data data
|
23
|
+
end
|
24
|
+
|
25
|
+
def unbind
|
26
|
+
@parent.close_connection
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class RawServer < EM::Connection
|
31
|
+
class << self; attr_accessor :add_ons end
|
32
|
+
@add_ons = []
|
33
|
+
|
34
|
+
def self.start(config)
|
35
|
+
EventMachine.start_server (config[:bind_interface] || '0.0.0.0'), config[:bind_port], self, config
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize(config)
|
39
|
+
@config = config
|
40
|
+
end
|
41
|
+
|
42
|
+
def post_init
|
43
|
+
@queue = EM::Queue.new
|
44
|
+
uri = URI.parse @config[:target]
|
45
|
+
EM.connect uri.host, uri.port, RawClient, @queue, self
|
46
|
+
end
|
47
|
+
|
48
|
+
def receive_data(data)
|
49
|
+
@queue.push data
|
50
|
+
end
|
51
|
+
|
52
|
+
def unbind
|
53
|
+
@queue.push nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SSLGate
|
2
|
+
module SSLRawAddOn
|
3
|
+
def post_init
|
4
|
+
super
|
5
|
+
start_tls private_key_file: @config[:private_key_file],
|
6
|
+
cert_chain_file: @config[:cert_chain_file]
|
7
|
+
# verify_peer: true,
|
8
|
+
# fail_if_no_peer_cert: true
|
9
|
+
end
|
10
|
+
|
11
|
+
# def ssl_verify_peer(cert)
|
12
|
+
# true
|
13
|
+
# end
|
14
|
+
|
15
|
+
def ssl_handshake_completed
|
16
|
+
$server_handshake_completed = true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
RawServer.add_ons << SSLRawAddOn
|
21
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module SSLGate
|
4
|
+
# CLI runner.
|
5
|
+
class Runner
|
6
|
+
|
7
|
+
def self.symbolize_keys(hash)
|
8
|
+
hash.each_with_object({}) do |(key, value), result|
|
9
|
+
new_key = key.is_a?(String) ? key.to_sym : key
|
10
|
+
new_value = value.is_a?(Hash) ? symbolize_keys(value) : value
|
11
|
+
result[new_key] = new_value
|
12
|
+
result
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.start
|
17
|
+
config = symbolize_keys YAML.load_file('SSLGate')
|
18
|
+
|
19
|
+
EventMachine.run do
|
20
|
+
Signal.trap('INT') { EM.stop if EM.reactor_running? }
|
21
|
+
Signal.trap('TERM') { EM.stop if EM.reactor_running? }
|
22
|
+
|
23
|
+
SSLGate.factory config
|
24
|
+
end
|
25
|
+
rescue => e
|
26
|
+
STDERR.puts e.message
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/ssl_gate.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative 'ssl_gate/raw_gate'
|
2
|
+
require_relative 'ssl_gate/raw_ssl'
|
3
|
+
|
4
|
+
require_relative 'ssl_gate/base_gate'
|
5
|
+
require_relative 'ssl_gate/base_ssl_gate'
|
6
|
+
require_relative 'ssl_gate/headers_mod'
|
7
|
+
#require_relative 'ssl_gate/client_cert'
|
8
|
+
require_relative 'ssl_gate/runner'
|
9
|
+
|
10
|
+
module SSLGate
|
11
|
+
class RawServerAll < RawServer
|
12
|
+
RawServer.add_ons.each { |add_on|
|
13
|
+
puts "Include server add-on: #{add_on}"
|
14
|
+
prepend add_on
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
class HTTPServerAll < HTTPServer
|
19
|
+
HTTPServer.add_ons.each { |add_on|
|
20
|
+
puts "Include server add-on: #{add_on}"
|
21
|
+
prepend add_on
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.factory(config)
|
26
|
+
config.each do |key, conf|
|
27
|
+
case key.to_s
|
28
|
+
when 'http' then HTTPServerAll.start conf
|
29
|
+
when 'tcp' then RawServerAll.start conf
|
30
|
+
else STDERR.puts "Unknown gate type: #{key}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ssl_gate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Artyom B
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-03-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: em-http-request
|
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
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: thin
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: ''
|
70
|
+
email: author@email.address
|
71
|
+
executables:
|
72
|
+
- ssl_gate
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- bin/ssl_gate
|
77
|
+
- lib/ssl_gate.rb
|
78
|
+
- lib/ssl_gate/base_gate.rb
|
79
|
+
- lib/ssl_gate/base_ssl_gate.rb
|
80
|
+
- lib/ssl_gate/client_cert.rb
|
81
|
+
- lib/ssl_gate/headers_mod.rb
|
82
|
+
- lib/ssl_gate/raw_gate.rb
|
83
|
+
- lib/ssl_gate/raw_ssl.rb
|
84
|
+
- lib/ssl_gate/runner.rb
|
85
|
+
homepage: http://rubygems.org/gems/ssl_gate
|
86
|
+
licenses:
|
87
|
+
- Nonstandard
|
88
|
+
metadata: {}
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
requirements: []
|
104
|
+
rubyforge_project:
|
105
|
+
rubygems_version: 2.6.14
|
106
|
+
signing_key:
|
107
|
+
specification_version: 4
|
108
|
+
summary: SSL Proxy
|
109
|
+
test_files: []
|