Skip to content

Commit

Permalink
Log when Conjur config permissions are incorrect
Browse files Browse the repository at this point in the history
  • Loading branch information
micahlee committed Feb 7, 2023
1 parent 567fb0d commit 3b8a01d
Show file tree
Hide file tree
Showing 8 changed files with 332 additions and 40 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [1.19.3] - 2023-01-26

### Added
- Conjur now logs when it detects that the Conjur configuration file
(conjur.yml) or directory permissions prevent the Conjur server from
successfully reading it. Conjur also now logs at the DEBUG level when it
detects that either the directory or file do not exist.
[cyberark/conjur#2715](https://github.com/cyberark/conjur/pull/2715)

## [1.19.2] - 2022-01-13

### Fixed
Expand Down
27 changes: 27 additions & 0 deletions app/domain/logs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -794,4 +794,31 @@ module Util
)

end

module Config
ConfigDirectoryDoesNotExist = ::Util::TrackableLogMessageClass.new(
msg: "Conjur config directory doesn't exist or has " \
"insufficient permission to list it: {0-config-directory}",
code: "CONJ00147D"
)

ConfigDirectoryInvalidPermissions = ::Util::TrackableLogMessageClass.new(
msg: "Conjur config directory exists but is missing " \
"search/execute permission required to list the config file: " \
"{0-config-directory}",
code: "CONJ00148W"
)

ConfigFileDoesNotExist = ::Util::TrackableLogMessageClass.new(
msg: "Conjur config file doesn't exist or has insufficient " \
"permission to list it: {0-config-path}",
code: "CONJ00149D"
)

ConfigFileInvalidPermissions = ::Util::TrackableLogMessageClass.new(
msg: "Conjur config file exists but has insufficient permission to " \
"read it: {0-config-path}",
code: "CONJ00150W"
)
end
end
4 changes: 3 additions & 1 deletion bin/conjur-cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,9 @@
Anyway::Settings.default_config_path = "/etc/conjur/config"

begin
conjur_config = Conjur::ConjurConfig.new
conjur_config = Conjur::ConjurConfig.new(
logger: Logger.new($stderr)
)
rescue Conjur::ConfigValidationError => e
$stderr.puts e
exit 1
Expand Down
4 changes: 3 additions & 1 deletion config/initializers/conjur_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@
#
# We create this in application.rb instead of an initializer so that it's
# guaranteed to be available for other initializers to use.
config.conjur_config = Conjur::ConjurConfig.new
config.conjur_config = Conjur::ConjurConfig.new(
logger: Rails.logger
)
end
108 changes: 106 additions & 2 deletions lib/conjur/conjur_config.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Conjur::ConjurConfig is also used in the conjurctl executable, so we cannot
# rely on Rails autoloading to make the `Anyway::Config` constant available.
require 'anyway_config'
require 'logger'

require 'app/domain/logs'

module Conjur
# We are temporarily avoiding hooking into the application error system
Expand Down Expand Up @@ -33,8 +36,21 @@ class ConjurConfig < Anyway::Config
extensions: []
)

def initialize(*args)
super(*args)
def initialize(
*args,
logger: Rails.logger,
**kwargs
)
# The permissions checks emit log messages, so we need to initialize the
# logger before verifying permissions.
@logger = logger

# First verify that we have the permissions necessary to read the config
# file.
verify_config_is_readable

# Initialize Anyway::Config
super(*args, **kwargs)

# If the config file is not a valid YAML document, we want
# to raise a user-friendly ConfigValidationError rather than
Expand Down Expand Up @@ -101,6 +117,94 @@ def extensions=(val)

private

def verify_config_is_readable
return unless verify_config_directory_exists

return unless verify_config_directory_permissions

return unless verify_config_file_exists

return unless verify_config_file_permissions

# If no issues are detected, log where the config file is being read from.
@logger.info("Loading Conjur config file: #{config_path}")
end

def verify_config_directory_exists
return true if File.directory?(config_directory)

# It may be expected that the config directory not exist, so this is
# a log message for debugging the Conjur config, rather than alerting the
# user to an issue.
@logger.debug(
LogMessages::Conjur::Config::ConfigDirectoryDoesNotExist.new(
config_directory: config_directory
)
)
false
end

def verify_config_directory_permissions
return true if File.executable?(config_directory)

# If the config direct does exist, we want to alert the user if the
# permissions will prevent Conjur from reading a config file in that
# directory.
@logger.warn(
LogMessages::Conjur::Config::ConfigDirectoryInvalidPermissions.new(
config_directory: config_directory
)
)

false
end

def verify_config_file_exists
return true if File.file?(config_path)

# Similar to the directory, if the config file doesn't exist, this becomes
# debugging information.
@logger.debug(
LogMessages::Conjur::Config::ConfigFileDoesNotExist.new(
config_path: config_path
)
)

false
end

def verify_config_file_permissions
return true if File.readable?(config_path)

# If the file exists but we can detect it's not readable, let the user
# know. Conjur will also fail to start in this configuration.
@logger.warn(
LogMessages::Conjur::Config::ConfigFileInvalidPermissions.new(
config_path: config_path
)
)

false
end

def config_directory
File.dirname(config_path)
end

# Because we call this before the base class initialized, we need to move the
# implementation here.
#
# Derived from:
# https://github.com/palkan/anyway_config/blob/83d79ccaf5619889c07c8ecdf8d66dcb22c9dc05/lib/anyway/config.rb#L358
#
# :reek:DuplicateMethodCall due to `self.class`
def config_path
@config_path ||= resolve_config_path(
self.class.config_name,
self.class.env_prefix
)
end

def str_to_list(val)
val.is_a?(String) ? val.split(',') : val
end
Expand Down
8 changes: 4 additions & 4 deletions spec/conjurctl/configuration_show_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
"conjurctl configuration show --output invalid"
)

expect(stderr).to eq(
"error: Unknown configuration output format 'invalid'\n"
expect(stderr).to include(
"error: Unknown configuration output format 'invalid'"
)
end

Expand All @@ -43,8 +43,8 @@
"CONJUR_TRUSTED_PROXIES=boop conjurctl configuration show"
)

expect(stderr).to eq(
"Invalid values for configured attributes: trusted_proxies\n"
expect(stderr).to include(
"Invalid values for configured attributes: trusted_proxies"
)

expect(status.exitstatus).to eq(1)
Expand Down
Loading

0 comments on commit 3b8a01d

Please sign in to comment.