Skip to content
Closed
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
2 changes: 1 addition & 1 deletion .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ Lint/Void:

# Offense count: 60
Metrics/AbcSize:
Max: 84
Max: 88

# Offense count: 15
# Configuration parameters: CountComments, ExcludedMethods.
Expand Down
23 changes: 23 additions & 0 deletions docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,29 @@ input:
secure: false
```

## Password Masking in Debug Logs

By default Oxidized will no longer log cleartext passwords in debug logs. This is designed to prevent Oxidized debug logs from containing all of your node authentication information. This makes submitting [GitHub issues for oxidized](https://github.com/ytti/oxidized/issues) and sharing debug logs easier and safer for everyone.

NOTE - This only applies to the configuration of Oxidized itself - NOT any fetched device configurations. Model-specific code is used for model-specific configuration sanitization (see Removing secrets below).

The value for `password` will instead be logged as `********`.

These settings can be controlled by the global section in the Oxidized configuration file.

```yaml
..(other global configuration)...
mask_value: "<Redacted by Security Directive 1234>"
```

If you need to log authentication information in your debug logs you can make the following adjustments:

```yaml
..(other global configuration)...
mask_sensitive: false
```


## Privileged mode

To start privileged mode before pulling the configuration, Oxidized needs to send the enable command. You can globally enable this, by adding the following snippet to the global section of the configuration file.
Expand Down
5 changes: 4 additions & 1 deletion lib/oxidized/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ def self.load(cmd_opts={})
asetus.default.retries = 3
asetus.default.prompt = /^([\w.@-]+[#>]\s?)$/
asetus.default.rest = '127.0.0.1:8888' # or false to disable
asetus.default.next_adds_job = false # if true, /next adds job, so device is fetched immmeiately
asetus.default.next_adds_job = false # if true, /next adds job, so device is fetched immediately
asetus.default.mask_sensitive= true # True to mask sensitive configuration fields from log output/display
asetus.default.mask_fields = /^(password)$/i # Our default regexp of configuration fields to mask
asetus.default.mask_value = '*' * 8 # What we mask the sensitive configuration fields with
asetus.default.vars = {} # could be 'enable'=>'enablePW'
asetus.default.groups = {} # group level configuration
asetus.default.models = {} # model level configuration
Expand Down
28 changes: 23 additions & 5 deletions lib/oxidized/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -201,19 +201,37 @@ def resolve_key key, opt, global=nil
key_sym = key.to_sym
key_str = key.to_s
value = global
Oxidized.logger.debug "node.rb: resolving node key '#{key}', with passed global value of '#{value}' and node value '#{opt[key_sym]}'"

# Implement basic configuration field masking
# The goal is to prevent logging of sensitive information unless the user positively activates logging of sensitive information
# This helps to keep authentication credentials out of logs, pastebins, GitHub issues, etc.
# Authentication failures to devices are typically easy to spot in other ways.
# NOTE - This does NOT control any masking for device configurations - that is covered in model-specific code
# Controllable with the configuration file via the following parameters:
# mask_sensitive: true || false (default is true)
# mask_fields: A regular expression of what is masked. Defaults to /^(password)$/i
# mask_value: A String value of what to log/display instead. Defaults to '*' * 8
is_key_masked = false
if Oxidized.config.mask_sensitive
if key_str =~ Oxidized.config.mask_fields
is_key_masked = true
masked_value = Oxidized.config.mask_value
end
end

Oxidized.logger.debug "node.rb: resolving node key '#{key}', with passed global value of '" + (is_key_masked ? masked_value.to_s : value.to_s) + "' and node value '" + (is_key_masked ? masked_value.to_s : opt[key_sym].to_s) + "'"

#global
if not value and Oxidized.config.has_key?(key_str)
value = Oxidized.config[key_str]
Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from global"
Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '" + (is_key_masked ? masked_value.to_s : value.to_s) + "' from global"
end

#group
if Oxidized.config.groups.has_key?(@group)
if Oxidized.config.groups[@group].has_key?(key_str)
value = Oxidized.config.groups[@group][key_str]
Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from group"
Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '" + (is_key_masked ? masked_value.to_s : value.to_s) + "' from group"
end
end

Expand All @@ -222,13 +240,13 @@ def resolve_key key, opt, global=nil
if Oxidized.config.models.has_key?(@model.class.name.to_s.downcase)
if Oxidized.config.models[@model.class.name.to_s.downcase].has_key?(key_str)
value = Oxidized.config.models[@model.class.name.to_s.downcase][key_str]
Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from model"
Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '" + (is_key_masked ? masked_value.to_s : value.to_s) + "' from model"
end
end

#node
value = opt[key_sym] || value
Oxidized.logger.debug "node.rb: returning node key '#{key}' with value '#{value}'"
Oxidized.logger.debug "node.rb: returning node key '#{key}' with value '" + (is_key_masked ? masked_value.to_s : value.to_s) + "'"
value
end

Expand Down