Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Security related fixes #70

Merged
merged 4 commits into from
Oct 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ruby:2.7.5-alpine AS ruby-builder
FROM ruby:3.1.2-alpine AS ruby-builder

RUN apk add --update build-base

Expand All @@ -19,7 +19,7 @@ RUN yarn run build
# Re-install only production for final layer
RUN rm -rf node_modules && yarn install --production

FROM nginx:1.19.6-alpine AS final-stage
FROM nginx:1.22.0-alpine AS final-stage
ARG TARGETPLATFORM

# Delete sym links from nginx image, install logrotate
Expand Down Expand Up @@ -50,7 +50,7 @@ RUN export ARCH=$(echo $TARGETPLATFORM | cut -d'/' -f2 | sed 's/arm64/aarch64/')
rm /etc/nginx/conf.d/default.conf && \
apk add --update \
# From original image
python2 ruby=2.7.5-r0 iproute2 apache2-utils logrotate openssl \
python3 ruby=3.1.2-r0 iproute2 apache2-utils logrotate openssl \
# For Typescript app
nodejs \
&& \
Expand Down
2 changes: 1 addition & 1 deletion fs_overlay/opt/certs_manager/certs_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def reconfig
ident = filename.include?('ssl') ? filename.delete_suffix('.ssl.conf') : filename.delete_suffix('.conf')
unless names.include? ident
puts "Deleting old #{filename} configuration..."
system "rm /etc/nginx/conf.d/#{filename}"
system "/bin/rm /etc/nginx/conf.d/#{filename}"
end
end
ensure_signed(domains)
Expand Down
2 changes: 1 addition & 1 deletion fs_overlay/opt/certs_manager/lib/acme.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def self.le_sign(domain)
puts "Signing certificates from #{domain.ca} ..."

command = <<-EOC
acme_tiny \
/bin/acme_tiny \
--account-key #{NAConfig.portal_base_dir}/account.key \
--csr #{domain.csr_path} \
--acme-dir /var/www/default/challenges/ \
Expand Down
6 changes: 3 additions & 3 deletions fs_overlay/opt/certs_manager/lib/commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ module Commands

def chain_certs(domain)
# Keeping it for backward compatibility
system "test ! -e #{domain.chained_cert_path} && ln -s #{domain.signed_cert_path} #{domain.chained_cert_path}"
system "/usr/bin/test ! -e #{domain.chained_cert_path} && ln -s #{domain.signed_cert_path} #{domain.chained_cert_path}"
end

def mkdir(domain)
system "mkdir -p #{domain.dir}"
system "/bin/mkdir -p #{domain.dir}"
end

def add_dockerhost_to_hosts
Expand All @@ -23,7 +23,7 @@ def add_dockerhost_to_hosts
def generate_ht_access(domains)
domains.each do |domain|
if domain.basic_auth_enabled?
system "htpasswd -bc #{domain.htaccess_path} #{domain.basic_auth_username} #{domain.basic_auth_password}"
system "/usr/bin/htpasswd -bc #{domain.htaccess_path} #{domain.basic_auth_username} #{domain.basic_auth_password}"
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion fs_overlay/opt/certs_manager/lib/erb_binding.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def get
end
end

def initialize(template_path, **binding_hash)
def initialize(template_path, binding_hash)
@template = File.read(template_path)
@binding_hash = binding_hash
end
Expand Down
8 changes: 4 additions & 4 deletions fs_overlay/opt/certs_manager/lib/nginx.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Nginx
def self.setup
compiled_basic_config = ERBBinding.new('/var/lib/nginx-conf/nginx.conf.erb').compile
compiled_basic_config = ERBBinding.new('/var/lib/nginx-conf/nginx.conf.erb', {}).compile

File.open('/etc/nginx/nginx.conf', 'w') do |f|
f.write compiled_basic_config
Expand All @@ -24,15 +24,15 @@ def self.config_ssl(domain)
end

def self.start
system 'nginx -q'
system '/usr/sbin/nginx -q'
end

def self.reload
system 'nginx -s reload'
system '/usr/sbin/nginx -s reload'
end

def self.stop
system 'nginx -s stop'
system '/usr/sbin/nginx -s stop'
end

private
Expand Down
28 changes: 14 additions & 14 deletions fs_overlay/opt/certs_manager/lib/open_ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,30 @@ module OpenSSL
def self.ensure_account_key
path = "#{NAConfig.portal_base_dir}/account.key"
unless File.exist?(path) && system("openssl rsa --in #{path} --noout --check")
system "openssl genrsa 4096 > #{path}"
system "/usr/bin/openssl genrsa 4096 > #{path}"
end
end

def self.ensure_domain_key(domain)
unless File.exist?(domain.key_path) && system("openssl rsa --in #{domain.key_path} --noout --check")
system "openssl genrsa #{NAConfig.key_length} > #{domain.key_path}"
system "/usr/bin/openssl genrsa #{NAConfig.key_length} > #{domain.key_path}"
end
end

def self.create_csr(domain)
if domain.stage == 'dappnode-api'
system "openssl req -new -sha256 -key #{domain.key_path} -subj '/CN=#{domain.global}' -addext 'subjectAltName = DNS:*.#{domain.global}' > #{domain.csr_path}"
system "/usr/bin/openssl req -new -sha256 -key #{domain.key_path} -subj '/CN=#{domain.global}' -addext 'subjectAltName = DNS:*.#{domain.global}' > #{domain.csr_path}"
else
system "openssl req -new -sha256 -key #{domain.key_path} -subj '/CN=#{domain.name}' > #{domain.csr_path}"
system "/usr/bin/openssl req -new -sha256 -key #{domain.key_path} -subj '/CN=#{domain.name}' > #{domain.csr_path}"
end
end

def self.need_to_sign_or_renew?(domain)
return true if NAConfig.force_renew?

if File.exist?(domain.key_path) && File.exist?(domain.signed_cert_path)
cert_pubkey = `openssl x509 -pubkey -noout -in #{domain.signed_cert_path}`
priv_pubkey = `openssl rsa -in #{domain.key_path} -pubout`
cert_pubkey = `/usr/bin/openssl x509 -pubkey -noout -in #{domain.signed_cert_path}`
priv_pubkey = `/usr/bin/openssl rsa -in #{domain.key_path} -pubout`
else
return true
end
Expand All @@ -47,7 +47,7 @@ def self.expires_in_days(pem)

def self.ensure_dhparam
unless dhparam_valid?(NAConfig.dhparam_path)
system "mkdir -p #{File.dirname(NAConfig.dhparam_path)} && openssl dhparam -out #{NAConfig.dhparam_path} 2048"
system "/bin/mkdir -p #{File.dirname(NAConfig.dhparam_path)} && /usr/bin/openssl dhparam -out #{NAConfig.dhparam_path} 2048"
end
end

Expand All @@ -57,7 +57,7 @@ def self.self_sign(domain)
ensure_domain_key(domain)

command = <<-EOC
openssl x509 -req -days 90 \
/usr/bin/openssl x509 -req -days 90 \
-in #{domain.csr_path} \
-signkey #{domain.key_path} \
-out #{domain.signed_cert_path}
Expand Down Expand Up @@ -87,7 +87,7 @@ def self.send_api_request(domain, certapi_url, signature, address, timestamp, fo
end
raise "An error occured during API call to the signing service: #{response.to_str}" unless response.code == 200
File.write(domain.signed_cert_path, response.to_str)
system "test ! -e #{domain.chained_cert_path} && ln -s #{domain.signed_cert_path} #{domain.chained_cert_path}"
system "/usr/bin/test ! -e #{domain.chained_cert_path} && ln -s #{domain.signed_cert_path} #{domain.chained_cert_path}"
end

def self.api_sign(domain)
Expand All @@ -96,8 +96,8 @@ def self.api_sign(domain)
certapi_url = ENV['CERTAPI_URL']
force = ENV['FORCE'] || 0
send_api_request(domain, certapi_url, signature, address, timestamp, force)
cert_pubkey = `openssl x509 -pubkey -noout -in #{domain.signed_cert_path}`
priv_pubkey = `openssl rsa -in #{domain.key_path} -pubout`
cert_pubkey = `/usr/bin/openssl x509 -pubkey -noout -in #{domain.signed_cert_path}`
priv_pubkey = `/usr/bin/openssl rsa -in #{domain.key_path} -pubout`
unless cert_pubkey == priv_pubkey
puts 'Keys do not match, trying forcing certification service'
send_api_request(domain, certapi_url, signature, address, timestamp, 1)
Expand All @@ -112,7 +112,7 @@ def self.generate_dummy_certificate(dir, out_path, keyout_path)

command = <<-EOC
mkdir -p #{dir} && \
openssl req -x509 -newkey \
/usr/bin/openssl req -x509 -newkey \
rsa:#{NAConfig.key_length} -nodes \
-out #{out_path} \
-keyout #{keyout_path} \
Expand All @@ -127,11 +127,11 @@ def self.generate_dummy_certificate(dir, out_path, keyout_path)
private

def self.expires_at(pem)
date_str = `openssl x509 -enddate -noout -in #{pem}`.sub('notAfter=', '')
date_str = `/usr/bin/openssl x509 -enddate -noout -in #{pem}`.sub('notAfter=', '')
Date.parse date_str
end

def self.dhparam_valid?(path)
File.exist?(path) && system("openssl dhparam -check < #{path}")
File.exist?(path) && system("/usr/bin/openssl dhparam -check < #{path}")
end
end