From 26a722db5dd35f89b25ae78bcf2d3ed5de519178 Mon Sep 17 00:00:00 2001 From: zt2 Date: Mon, 10 Feb 2020 11:24:13 +0800 Subject: [PATCH 1/8] strong certificate --- lib/ritm/certs/certificate.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ritm/certs/certificate.rb b/lib/ritm/certs/certificate.rb index 2c2e5d2..93f54d0 100644 --- a/lib/ritm/certs/certificate.rb +++ b/lib/ritm/certs/certificate.rb @@ -20,7 +20,7 @@ def self.create(common_name, serial_number: nil) cert.subject.country = 'AR' cert.not_before = cert.not_before - 3600 * 24 * 30 # Substract 30 days cert.serial_number.number = serial_number || common_name.hash.abs - cert.key_material.generate_key(1024) + cert.key_material.generate_key(2048) yield cert if block_given? new cert end From 70a64e344677f7b00d8190b6f5aa677b0a1b5dc6 Mon Sep 17 00:00:00 2001 From: zt2 Date: Mon, 10 Feb 2020 11:25:52 +0800 Subject: [PATCH 2/8] spoof certificate --- lib/ritm/proxy/cert_signing_https_server.rb | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/ritm/proxy/cert_signing_https_server.rb b/lib/ritm/proxy/cert_signing_https_server.rb index 270203a..e4232b9 100644 --- a/lib/ritm/proxy/cert_signing_https_server.rb +++ b/lib/ritm/proxy/cert_signing_https_server.rb @@ -1,3 +1,4 @@ +require 'net/http' require 'openssl' require 'webrick' require 'webrick/https' @@ -33,7 +34,11 @@ def prepare_sni_callback(ctx, ca) ctx.servername_cb = proc do |sock, servername| mutex.synchronize do unless contexts.include? servername - cert = Ritm::Certificate.create(servername) + begin + cert = fetch_remote_cert(servername) + rescue StandardError + cert = Ritm::Certificate.create(servername) + end ca.sign(cert) contexts[servername] = context_with_cert(sock.context, cert) end @@ -61,6 +66,17 @@ def duplicate_context(original_ctx) end ctx end + + def fetch_remote_cert(servername) + host = servername.gsub( "*.", "www." ) + x509_cert = Net::HTTP.start( + host, + '443', use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE, + &:peer_cert + ) + Ritm::Certificate.new(CertificateAuthority::Certificate.from_openssl(x509_cert)) + end end end end + From 883accb61219e37d5eb8c51aebef6a3e9d22d6f6 Mon Sep 17 00:00:00 2001 From: zt2 Date: Tue, 11 Feb 2020 12:09:14 +0800 Subject: [PATCH 3/8] fix no SAN error --- lib/ritm/certs/ca.rb | 4 ++-- lib/ritm/proxy/cert_signing_https_server.rb | 22 ++++++--------------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/lib/ritm/certs/ca.rb b/lib/ritm/certs/ca.rb index 5067e60..96e564a 100644 --- a/lib/ritm/certs/ca.rb +++ b/lib/ritm/certs/ca.rb @@ -20,9 +20,9 @@ def self.load(crt, private_key) end end - def sign(certificate) + def sign(certificate, extensions = self.class.signing_profile) certificate.cert.parent = @cert - certificate.cert.sign!(self.class.signing_profile) + certificate.cert.sign!(extensions) end def self.signing_profile diff --git a/lib/ritm/proxy/cert_signing_https_server.rb b/lib/ritm/proxy/cert_signing_https_server.rb index e4232b9..ae63a6e 100644 --- a/lib/ritm/proxy/cert_signing_https_server.rb +++ b/lib/ritm/proxy/cert_signing_https_server.rb @@ -34,12 +34,12 @@ def prepare_sni_callback(ctx, ca) ctx.servername_cb = proc do |sock, servername| mutex.synchronize do unless contexts.include? servername - begin - cert = fetch_remote_cert(servername) - rescue StandardError - cert = Ritm::Certificate.create(servername) - end - ca.sign(cert) + cert = Ritm::Certificate.create(servername) + extensions = Ritm::CA.signing_profile + extensions['extensions']['subjectAltName'] = { + 'dns_names' => [servername] + } + ca.sign(cert, extensions) contexts[servername] = context_with_cert(sock.context, cert) end end @@ -66,16 +66,6 @@ def duplicate_context(original_ctx) end ctx end - - def fetch_remote_cert(servername) - host = servername.gsub( "*.", "www." ) - x509_cert = Net::HTTP.start( - host, - '443', use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE, - &:peer_cert - ) - Ritm::Certificate.new(CertificateAuthority::Certificate.from_openssl(x509_cert)) - end end end end From 69878a8cb080d97bdb919eb551f0f10403a55e2b Mon Sep 17 00:00:00 2001 From: zt2 Date: Tue, 11 Feb 2020 12:12:36 +0800 Subject: [PATCH 4/8] remove net/http --- lib/ritm/proxy/cert_signing_https_server.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/ritm/proxy/cert_signing_https_server.rb b/lib/ritm/proxy/cert_signing_https_server.rb index ae63a6e..7dbaaf2 100644 --- a/lib/ritm/proxy/cert_signing_https_server.rb +++ b/lib/ritm/proxy/cert_signing_https_server.rb @@ -1,4 +1,3 @@ -require 'net/http' require 'openssl' require 'webrick' require 'webrick/https' From e790605c6c876191c164185e614fbff377974812 Mon Sep 17 00:00:00 2001 From: zt2 Date: Wed, 12 Feb 2020 11:57:23 +0800 Subject: [PATCH 5/8] make ssl reverse proxy can be accessed from remote --- lib/ritm/proxy/launcher.rb | 3 ++- lib/ritm/proxy/ssl_reverse_proxy.rb | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/ritm/proxy/launcher.rb b/lib/ritm/proxy/launcher.rb index ac3ac1c..0f84475 100644 --- a/lib/ritm/proxy/launcher.rb +++ b/lib/ritm/proxy/launcher.rb @@ -53,7 +53,8 @@ def build_proxy end def build_reverse_proxy - @https = Ritm::Proxy::SSLReverseProxy.new(@conf.ssl_reverse_proxy.bind_port, + @https = Ritm::Proxy::SSLReverseProxy.new(@conf.ssl_reverse_proxy.bind_address, + @conf.ssl_reverse_proxy.bind_port, @certificate, @forwarder) end diff --git a/lib/ritm/proxy/ssl_reverse_proxy.rb b/lib/ritm/proxy/ssl_reverse_proxy.rb index be79732..585b3a8 100644 --- a/lib/ritm/proxy/ssl_reverse_proxy.rb +++ b/lib/ritm/proxy/ssl_reverse_proxy.rb @@ -9,13 +9,15 @@ module Proxy # It does man-in-the-middle with on-the-fly certificate signing using the given CA class SSLReverseProxy # Creates a HTTPS server with the given settings + # @param host [String]: Host to bind the service # @param port [Fixnum]: TCP port to bind the service # @param ca [Ritm::CA]: The certificate authority used to sign fake server certificates # @param forwarder [Ritm::HTTPForwarder]: Forwards http traffic with interception - def initialize(port, ca, forwarder) + def initialize(host, port, ca, forwarder) @ca = ca default_vhost = 'localhost' - @server = CertSigningHTTPSServer.new(Port: port, + @server = CertSigningHTTPSServer.new(BindAddress: host, + Port: port, AccessLog: [], Logger: WEBrick::Log.new(File.open(File::NULL, 'w')), ca: ca, From 1743ebfce122300a569cb56da3e8e28e1f1adf08 Mon Sep 17 00:00:00 2001 From: zt2 Date: Thu, 13 Feb 2020 17:17:36 +0800 Subject: [PATCH 6/8] fix: param typo --- lib/ritm/proxy/cert_signing_https_server.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/ritm/proxy/cert_signing_https_server.rb b/lib/ritm/proxy/cert_signing_https_server.rb index 7dbaaf2..c9814b0 100644 --- a/lib/ritm/proxy/cert_signing_https_server.rb +++ b/lib/ritm/proxy/cert_signing_https_server.rb @@ -36,9 +36,11 @@ def prepare_sni_callback(ctx, ca) cert = Ritm::Certificate.create(servername) extensions = Ritm::CA.signing_profile extensions['extensions']['subjectAltName'] = { - 'dns_names' => [servername] + 'dns_names' => [servername], + 'uris' => [servername] } ca.sign(cert, extensions) + contexts[servername] = context_with_cert(sock.context, cert) end end From e9afa0f9e2ab7bde02672e4da092bd6c56a16bce Mon Sep 17 00:00:00 2001 From: zt2 Date: Thu, 13 Feb 2020 17:18:10 +0800 Subject: [PATCH 7/8] fix: weak cert error --- lib/ritm/certs/ca.rb | 3 ++- lib/ritm/certs/certificate.rb | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/ritm/certs/ca.rb b/lib/ritm/certs/ca.rb index 96e564a..945830e 100644 --- a/lib/ritm/certs/ca.rb +++ b/lib/ritm/certs/ca.rb @@ -30,7 +30,8 @@ def self.signing_profile 'extensions' => { 'keyUsage' => { 'usage' => %w[keyEncipherment digitalSignature] }, 'extendedKeyUsage' => { 'usage' => %w[serverAuth clientAuth] } - } + }, + 'digest' => 'SHA512' } end diff --git a/lib/ritm/certs/certificate.rb b/lib/ritm/certs/certificate.rb index 93f54d0..21d352a 100644 --- a/lib/ritm/certs/certificate.rb +++ b/lib/ritm/certs/certificate.rb @@ -20,7 +20,7 @@ def self.create(common_name, serial_number: nil) cert.subject.country = 'AR' cert.not_before = cert.not_before - 3600 * 24 * 30 # Substract 30 days cert.serial_number.number = serial_number || common_name.hash.abs - cert.key_material.generate_key(2048) + cert.key_material.generate_key(4096) yield cert if block_given? new cert end From f480b06d2844aebece2462d918e23c764257e022 Mon Sep 17 00:00:00 2001 From: zt2 Date: Mon, 13 Dec 2021 04:01:58 -0500 Subject: [PATCH 8/8] enable basic auth --- lib/ritm/configuration.rb | 7 ++++++- lib/ritm/proxy/launcher.rb | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/ritm/configuration.rb b/lib/ritm/configuration.rb index be90cd6..3b45895 100644 --- a/lib/ritm/configuration.rb +++ b/lib/ritm/configuration.rb @@ -7,7 +7,12 @@ def default_settings # rubocop:disable Metrics/MethodLength { proxy: { bind_address: '127.0.0.1', - bind_port: 8080 + bind_port: 8080, + auth_proc: Proc.new do |req, res| + WEBrick::HTTPAuth.proxy_basic_auth(req, res, 'proxy') do |user, pass| + user == "user" && pass == "pass" + end + end }, ssl_reverse_proxy: { diff --git a/lib/ritm/proxy/launcher.rb b/lib/ritm/proxy/launcher.rb index 0f84475..6411968 100644 --- a/lib/ritm/proxy/launcher.rb +++ b/lib/ritm/proxy/launcher.rb @@ -44,6 +44,7 @@ def build_settings(session) def build_proxy @http = Ritm::Proxy::ProxyServer.new(BindAddress: @conf.proxy.bind_address, Port: @conf.proxy.bind_port, + ProxyAuthProc: @conf.proxy.auth_proc, AccessLog: [], Logger: WEBrick::Log.new(File.open(File::NULL, 'w')), https_forward: @https_forward,