Skip to content

Commit

Permalink
Merge pull request #1065 from chef/er-454/crypto2
Browse files Browse the repository at this point in the history
[ER-459] Add crypto2 to the Erlang load path in FIPS mode
  • Loading branch information
tyler-ball authored Feb 3, 2017
2 parents ae0f9bb + 950e768 commit e5b2c91
Show file tree
Hide file tree
Showing 22 changed files with 197 additions and 41 deletions.
33 changes: 33 additions & 0 deletions doc/HOW_THINGS_WORK.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,36 @@ object types and organizations.
5. Erchef responds to the API request either (in the case of a normal
search) with the full document or (in the case of a partial search
via a POST) with a reduced version of the document.

## FIPS Integration

This assumes you understand what the FIPS 140-2 validation is. Putting the
Chef Server into *FIPS mode* means:

1. It sets `OPENSSL_FIPS=1` in the environment, so shelling out to `openssl`
will activate the FIPS module.
2. Using the erlang-crypto2 app it activates the FIPS module for any native
calls.
3. Also using the erlang-crypto2 app it overwrites certain crypto calls that are
unsupported (IE, MD5) in the OpenSSL FIPS module with direct Erlang code.

The server can be switched into and out of FIPS mode at runtime. Edit the
`chef-server.rb` config by adding `fips true` or `fips false` to force FIPS
mode as necessary. On systems where FIPS is enabled at the kernel level this
config is defaulted to true. On all other systems it is defaulted to false. FIPS
mode is currently only supported on RHEL systems.

### FIPS Implementation Details

The erlang-crypto2 app provides `crypto` module implementation. To support
switching to this crypto module at runtime we perform the following:

* Build the erlang-crypto2 app as a separate omnibus definition using the same
Erlang libraries used to build all other Erlang apps. Copy the `ebin` and `priv`
folders from the build into a custom location inside the omnibus package.
* If `fips true` is set and the server is reconfigured, we update the `vm.args`
to put the erlang-crypto2 `ebin` folder at the front of the load path.
* We also export the path to the `priv` folder as an environment variable. When
the erlang-crypto2 app is loaded it uses an `on_load` function to load the
crypto NIFs. We could not figure out how to specify the correct `priv` folder
except by hardcoding it into this environment variable.
1 change: 1 addition & 0 deletions omnibus/config/projects/chef-server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
dependency "runit"
dependency "chef_backup-gem" # chef-server-ctl backup
dependency "veil-gem" # chef-server-ctl rotate-credentials
dependency "erlang-crypto2"

# the backend
dependency "postgresql92"
Expand Down
4 changes: 1 addition & 3 deletions omnibus/config/software/bookshelf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,11 @@

build do
env = with_standard_compiler_flags(with_embedded_path)
profile_name = fips_mode? ? "fips" : "default"

env['REL_VERSION'] = "#{project.build_version}"
env['REBAR_PROFILE'] = profile_name

make "omnibus", env: env

sync "#{project_dir}/_build/#{profile_name}/rel/bookshelf/", "#{install_dir}/embedded/service/bookshelf/"
sync "#{project_dir}/_build/default/rel/bookshelf/", "#{install_dir}/embedded/service/bookshelf/"
delete "#{install_dir}/embedded/service/bookshelf/log"
end
43 changes: 43 additions & 0 deletions omnibus/config/software/erlang-crypto2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#
# Copyright 2012-2017 Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

name "erlang-crypto2"
default_version "master"

source git: "https://github.com/chef/erlang-crypto2.git"

license "BSD-3-Clause"
license_file "LICENSE"
# https://github.com/chef/license_scout/issues/61
skip_transitive_dependency_licensing true

dependency "erlang"

build do
env = with_standard_compiler_flags(with_embedded_path)

# All of the apps include a rebar3 executable. Just use one of them to build
# this application. We do not want to include rebar in the final package
# so don't use a software dependency
rebar3_path = "#{project.files_path}/../../src/bookshelf/rebar3"

command "#{rebar3_path} compile", env: env

crypto2_dir = "#{install_dir}/embedded/lib/erlang-crypto2"
mkdir crypto2_dir
copy "#{project_dir}/_build/default/lib/fips_crypto/ebin", "#{crypto2_dir}/ebin"
copy "#{project_dir}/priv", "#{crypto2_dir}/priv"
end
4 changes: 1 addition & 3 deletions omnibus/config/software/oc_bifrost.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,12 @@

build do
env = with_standard_compiler_flags(with_embedded_path)
profile_name = fips_mode? ? "fips" : "default"

env['REL_VERSION'] = "#{project.build_version}"
env['REBAR_PROFILE'] = profile_name

make "omnibus", env: env

sync "#{project_dir}/_build/#{profile_name}/rel/oc_bifrost/", "#{install_dir}/embedded/service/oc_bifrost/"
sync "#{project_dir}/_build/default/rel/oc_bifrost/", "#{install_dir}/embedded/service/oc_bifrost/"
sync "#{project_dir}/schema", "#{install_dir}/embedded/service/oc_bifrost/db/"
delete "#{install_dir}/embedded/service/oc_bifrost/log"
end
4 changes: 1 addition & 3 deletions omnibus/config/software/oc_erchef.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,12 @@

build do
env = with_standard_compiler_flags(with_embedded_path)
profile_name = fips_mode? ? "fips" : "default"

env['USE_SYSTEM_GECODE'] = "1"
env['REL_VERSION'] = "#{project.build_version}"
env['REBAR_PROFILE'] = profile_name

make "omnibus", env: env

sync "#{project_dir}/_build/#{profile_name}/rel/oc_erchef/", "#{install_dir}/embedded/service/opscode-erchef/", exclude: ['**/.git', '**/.gitignore']
sync "#{project_dir}/_build/default/rel/oc_erchef/", "#{install_dir}/embedded/service/opscode-erchef/", exclude: ['**/.git', '**/.gitignore']
delete "#{install_dir}/embedded/service/opscode-erchef/log"
end
4 changes: 1 addition & 3 deletions omnibus/config/software/opscode-chef-mover.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@

build do
env = with_standard_compiler_flags(with_embedded_path)
profile_name = fips_mode? ? "fips" : "default"

env['USE_SYSTEM_GECODE'] = "1"
env['REL_VERSION'] = "#{project.build_version}"
env['REBAR_PROFILE'] = profile_name

make "omnibus", env: env

sync "#{project_dir}/_build/#{profile_name}/rel/mover/", "#{install_dir}/embedded/service/opscode-chef-mover/"
sync "#{project_dir}/_build/default/rel/mover/", "#{install_dir}/embedded/service/opscode-chef-mover/"
delete "#{install_dir}/embedded/service/opscode-chef-mover/log"

mkdir "#{install_dir}/embedded/service/opscode-chef-mover/scripts"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,18 @@
to bookshelf_config
end

vmargs_config = File.join(bookshelf_dir, "vm.args")

template vmargs_config do
source "bookshelf.vm.args.erb"
owner OmnibusHelper.new(node).ownership['owner']
group OmnibusHelper.new(node).ownership['group']
mode "644"
notifies :restart, 'runit_service[bookshelf]' if is_data_master?
end

link "/opt/opscode/embedded/service/bookshelf/vm.args" do
to vmargs_config
end

component_runit_service "bookshelf"
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,18 @@
to oc_bifrost_config
end

vmargs_config = File.join(oc_bifrost_dir, "vm.args")

template vmargs_config do
source "oc_bifrost.vm.args.erb"
owner OmnibusHelper.new(node).ownership['owner']
group OmnibusHelper.new(node).ownership['group']
mode "644"
notifies :restart, 'runit_service[oc_bifrost]' unless backend_secondary?
end

link "/opt/opscode/embedded/service/oc_bifrost/vm.args" do
to vmargs_config
end

component_runit_service "oc_bifrost"
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@
to mover_config
end

vmargs_config = File.join(opscode_chef_mover_dir, "vm.args")

template vmargs_config do
source "opscode-chef-mover.vm.args.erb"
owner OmnibusHelper.new(node).ownership['owner']
group OmnibusHelper.new(node).ownership['group']
mode "644"
end

link "/opt/opscode/embedded/service/opscode-chef-mover/vm.args" do
to vmargs_config
end

# We want the service defined, but dead
component_runit_service "opscode-chef-mover" do
action :down
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,18 @@
to erchef_config
end

vmargs_config = File.join(opscode_erchef_dir, "vm.args")

template vmargs_config do
source "oc_erchef.vm.args.erb"
owner OmnibusHelper.new(node).ownership['owner']
group OmnibusHelper.new(node).ownership['group']
mode "644"
notifies :restart, 'runit_service[opscode-erchef]' unless backend_secondary?
end

link "/opt/opscode/embedded/service/opscode-erchef/vm.args" do
to vmargs_config
end

component_runit_service "opscode-erchef"
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,11 @@
## Async workers prevents IO from blocking the
## schedulers and increases performance of IO-heavy
## apps, like bookshelf.
+A 10
+A 10

<%- if node['private_chef']['fips_enabled'] -%>
## Runtime switches to enable loading custom crypto module
## that supports OpenSSL-FIPS
-env ERLANG_CRYPTO2_PATH <%= File.join(node['private_chef']['install_path'], "/embedded/lib/erlang-crypto2/priv") =%>
-pa <%= File.join(node['private_chef']['install_path'], "/embedded/lib/erlang-crypto2/ebin") =%>
<%- end -%>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## Name of the node
-name [email protected]

## Cookie for distributed erlang
-setcookie oc_bifrost

## Heartbeat management; auto-restarts VM if it dies or becomes unresponsive
## (Disabled by default..use with caution!)
##-heart

## Enable kernel poll and a few async threads
+K true
+A 10

+P 262144

## Increase number of concurrent ports/sockets
-env ERL_MAX_PORTS 65536

## Tweak GC to run more often
-env ERL_FULLSWEEP_AFTER 10

## Increase logfile size to 10M
-env RUN_ERL_LOG_MAXSIZE 10000000

<%- if node['private_chef']['fips_enabled'] -%>
## Runtime switches to enable loading custom crypto module
## that supports OpenSSL-FIPS
-env ERLANG_CRYPTO2_PATH <%= File.join(node['private_chef']['install_path'], "/embedded/lib/erlang-crypto2/priv") =%>
-pa <%= File.join(node['private_chef']['install_path'], "/embedded/lib/erlang-crypto2/ebin") =%>
<%- end -%>
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,12 @@
{password, <<"<%= @node['private_chef']['rabbitmq']['management_password'] %>">>},
% rabbitmq management http connection pool
{rabbitmq_management_service, [
<% if node['private_chef']['fips_enabled'] -%>
%% See note about Bookshelf
{root_url, "http://<%= @actions_vip %>:<%= @node['private_chef']['rabbitmq']['management_port'] %>/api"},
<% else -%>
{root_url, "https://<%= @actions_vip %>:<%= @node['private_chef']['rabbitmq']['management_port'] %>/api"},
<% end %>
{timeout, <%= @node['private_chef']['rabbitmq']['rabbit_mgmt_timeout'] %>},
{init_count, <%= @node['private_chef']['rabbitmq']['rabbit_mgmt_http_init_count'] %>},
{max_count, <%= @node['private_chef']['rabbitmq']['rabbit_mgmt_http_max_count'] %>},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,9 @@
## Increase logfile size to 10M
-env RUN_ERL_LOG_MAXSIZE 10000000

<%- if node['private_chef']['fips_enabled'] -%>
## Runtime switches to enable loading custom crypto module
## that supports OpenSSL-FIPS
-env ERLANG_CRYPTO2_PATH <%= File.join(node['private_chef']['install_path'], "/embedded/lib/erlang-crypto2/priv") =%>
-pa <%= File.join(node['private_chef']['install_path'], "/embedded/lib/erlang-crypto2/ebin") =%>
<%- end -%>
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@
## Increase logfile size to 10M
-env RUN_ERL_LOG_MAXSIZE 10000000

<%- if node['private_chef']['fips_enabled'] -%>
## Runtime switches to enable loading custom crypto module
## that supports OpenSSL-FIPS
-env ERLANG_CRYPTO2_PATH <%= File.join(node['private_chef']['install_path'], "/embedded/lib/erlang-crypto2/priv") =%>
-pa <%= File.join(node['private_chef']['install_path'], "/embedded/lib/erlang-crypto2/ebin") =%>
<%- end -%>
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@
[{listener, [
{ip, "<%= node['private_chef']['rabbitmq']['node_ip_address'] %>"},
{port, <%= node['private_chef']['rabbitmq']['management_port'] %> },
{ssl, true}
{ssl, <%= node['private_chef']['fips_enabled'] ? false : true %> }
% The Rabbit Management Plugin will use the global Rabbit SSL Config
]}
]}
].

5 changes: 3 additions & 2 deletions omnibus/omnibus.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@

fatal_transitive_dependency_licensing_warnings true

# PROJECT_NAME should be set by jenkins during the build
fips_mode ((ENV["PROJECT_NAME"] || "").downcase == "chef-server-fips")
# Build in FIPS compatability mode
# ------------------------------
fips_mode (ENV['OMNIBUS_FIPS_MODE'] || '').downcase == "true"
8 changes: 1 addition & 7 deletions src/bookshelf/rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,6 @@
{include_src, true}
]}
]},
{fips, [
{deps, [
{crypto, {git,"git://github.com/jaym/erlang-crypto2", {branch, "master"}}}
]}
]},
{test, [
{deps, [
{cth_readable,
Expand Down Expand Up @@ -135,8 +130,7 @@

{include_src, false},
{extended_start_script,true},
{overlay,[{template,"config/vm.args","vm.args"},
{template,"config/app.config","sys.config"},
{overlay,[{template,"config/app.config","sys.config"},
{copy,"schema","."}
]}
]}.
6 changes: 0 additions & 6 deletions src/chef-mover/rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@
{git, "https://github.com/ferd/cth_readable.git", {branch, "master"}}}
]}
]},
{fips, [
{deps, [
{crypto, {git,"git://github.com/jaym/erlang-crypto2", {branch, "master"}}}
]}
]},
{dev, [
{relx, [{dev_mode, true},
{include_src, true}
Expand Down Expand Up @@ -142,7 +137,6 @@
{mkdir,"log/sasl"},
{mkdir,"etc/keys"},
{copy,"scripts", "scripts"},
{template,"config/vm.args","vm.args"},
{template,"config/sys.config","sys.config"}
]}
]}.
5 changes: 0 additions & 5 deletions src/oc_bifrost/rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,6 @@
{include_src, true}
]}
]},
{fips, [
{deps, [
{crypto, {git,"git://github.com/jaym/erlang-crypto2", {branch, "master"}}}
]}
]},
{test, [
{deps, [
{cth_readable,
Expand Down
Loading

0 comments on commit e5b2c91

Please sign in to comment.