Skip to content

Commit

Permalink
Support to config fips state
Browse files Browse the repository at this point in the history
  • Loading branch information
xumia committed Jun 27, 2023
1 parent eab4a9e commit 030dd9a
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 4 deletions.
52 changes: 50 additions & 2 deletions scripts/hostcfgd
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ RADIUS_SERVER_TIMEOUT_DEFAULT = "5"
RADIUS_SERVER_AUTH_TYPE_DEFAULT = "pap"
RADIUS_PAM_AUTH_CONF_DIR = "/etc/pam_radius_auth.d/"

# FIPS
FIPS_MODE_ENFORCE = 'enforce'

# MISC Constants
CFG_DB = "CONFIG_DB"
STATE_DB = "STATE_DB"
Expand Down Expand Up @@ -1660,7 +1663,6 @@ class RSyslogCfg(object):
self.cache['config'] = rsyslog_config
self.cache['servers'] = rsyslog_servers


class DnsCfg:

def load(self, *args, **kwargs):
Expand All @@ -1669,6 +1671,41 @@ class DnsCfg:
def dns_update(self, *args, **kwargs):
run_cmd(['systemctl', 'restart', 'resolv-config'], True, False)

class FipsCfg(object):
"""
FipsCfg Config Daemon
Handles the changes in FIPS table.
"""

def __init__(self):
self.enabled = '0'
self.enforced = '0'

def load(self, data={}):
common_config = data.get('global', {})
if not common_config:
syslog.syslog(syslog.LOG_INFO, f'FipsCfg: skipped the FIPS config, the FIPS setting is empty.')
return
mode = common_config.get('mode', '').lower()
self.enabled = '0'
self.enforced = '0'
if mode == 'enforce':
self.enabled = '1'
self.enforced = '1'
elif mode == 'noneenforce':
self.enabled = '1'
self.update()

def fips_handler():
data = self.config_db.get_table('FIPS')
self.load(data)

def update(self):
syslog.syslog(syslog.LOG_DEBUG, f'FipsCfg: update fips option enabled: {self.enabled}, enforced: {self.enforced}')
try:
run_cmd(['sudo', 'update-fips-config', self.enforced, self.enabled])
except subprocess.CalledProcessError as e:
syslog.syslog(syslog.LOG_ERR, f'FipsCfg: Failed to set new fips option enabled: {self.enabled}')

class HostConfigDaemon:
def __init__(self):
Expand Down Expand Up @@ -1726,6 +1763,9 @@ class HostConfigDaemon:
# Initialize DnsCfg
self.dnscfg = DnsCfg()

# Initialize FipsCfg
self.fipscfg = FipsCfg()

def load(self, init_data):
features = init_data['FEATURE']
aaa = init_data['AAA']
Expand All @@ -1744,6 +1784,7 @@ class HostConfigDaemon:
syslog_cfg = init_data.get(swsscommon.CFG_SYSLOG_CONFIG_TABLE_NAME, {})
syslog_srv = init_data.get(swsscommon.CFG_SYSLOG_SERVER_TABLE_NAME, {})
dns = init_data.get('DNS_NAMESERVER', {})
fips_cfg = init_data.get('FIPS', {})

self.feature_handler.sync_state_field(features)
self.aaacfg.load(aaa, tacacs_global, tacacs_server, radius_global, radius_server)
Expand All @@ -1756,6 +1797,7 @@ class HostConfigDaemon:

self.rsyslogcfg.load(syslog_cfg, syslog_srv)
self.dnscfg.load(dns)
self.fipscfg.load(fips_cfg)

# Update AAA with the hostname
self.aaacfg.hostname_update(self.devmetacfg.hostname)
Expand Down Expand Up @@ -1875,6 +1917,10 @@ class HostConfigDaemon:
syslog.syslog(syslog.LOG_INFO, 'DNS nameserver handler...')
self.dnscfg.dns_update(key, data)

def fips_config_handler(self, key, op, data):
syslog.syslog(syslog.LOG_INFO, 'FIPS table handler...')
self.fipscfg.fips_handler()

def wait_till_system_init_done(self):
# No need to print the output in the log file so using the "--quiet"
# flag
Expand Down Expand Up @@ -1930,6 +1976,9 @@ class HostConfigDaemon:

self.config_db.subscribe('DNS_NAMESERVER', make_callback(self.dns_nameserver_handler))

# Handle FIPS changes
self.config_db.subscribe('FIPS', make_callback(self.fips_config_handler))

syslog.syslog(syslog.LOG_INFO,
"Waiting for systemctl to finish initialization")
self.wait_till_system_init_done()
Expand All @@ -1939,7 +1988,6 @@ class HostConfigDaemon:
def start(self):
self.config_db.listen(init_data_handler=self.load)


def main():
signal.signal(signal.SIGTERM, signal_handler)
signal.signal(signal.SIGINT, signal_handler)
Expand Down
28 changes: 27 additions & 1 deletion scripts/procdockerstatsd
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ from datetime import datetime

from sonic_py_common import daemon_base
from swsscommon import swsscommon
from sonic_py_common.general import getstatusoutput_noshell_pipe
from sonic_py_common.general import getstatusoutput_noshell_pipe, getstatusoutput_noshell

VERSION = '1.0'

Expand Down Expand Up @@ -168,6 +168,30 @@ class ProcDockerStats(daemon_base.DaemonBase):
cmd = row.get('CMD')
self.update_state_db(value, 'CMD', cmd)

def update_procfipsstats_command(self):
fips_enable_flag = '0'
current_enforce_state = '0'
next_enforce_state = '0'
if os.path.isfile('/etc/fips/fips_enable.flag'):
with open('/etc/fips/fips_enable.flag') as f:
fips_enable_flag = f.read().trip()
with open('/proc/cmdline') as f:
cmdline = f.read().trip()
if 'fips=1' in cmdline:
current_enforce_state = '1'
cmd = ['sonic-installer', 'get-fips']
exitcode, data = getstatusoutput_noshell(cmd)
if any(exitcode):
self.log_error("Error running command '{}'".format(cmd))
data = None
if 'enabled' in data:
next_enforce_state = '1'
fips_db_key = 'FIPS_STATS|state'
self.state_db.delete_all_by_pattern('STATE_DB', "FIPS_STATS|*")
self.update_state_db(fips_db_key, 'enabled', fips_enable_flag)
self.update_state_db(fips_db_key, 'enforced', current_enforce_state)
self.update_state_db(fips_db_key, 'enforced_next', next_enforce_state)

def update_state_db(self, key1, key2, value2):
self.state_db.set('STATE_DB', key1, key2, value2)

Expand All @@ -186,6 +210,8 @@ class ProcDockerStats(daemon_base.DaemonBase):
self.update_state_db('DOCKER_STATS|LastUpdateTime', 'lastupdate', str(datetimeobj))
self.update_processstats_command()
self.update_state_db('PROCESS_STATS|LastUpdateTime', 'lastupdate', str(datetimeobj))
self.update_fipsstats_command()
self.update_state_db('FIPS_STATS|LastUpdateTime', 'lastupdate', str(datetimeobj))

# Data need to be updated every 2 mins. hence adding delay of 120 seconds
time.sleep(120)
Expand Down
77 changes: 77 additions & 0 deletions scripts/update-fips-config
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/bin/bash

# Update the FIPS configuration

set -e

FIPS_ENFORCE=$1
FIPS_ENABLE=$2
[ -z "$FIPS_ENFORCE" ] && FIPS_ENFORCE=0
[ -z "$FIPS_ENABLE" ] && FIPS_ENABLE=0
RESTART_REQUIRED_IMAGES="docker-sonic-telemetry docker-sonic-restapi"
RESTART_REQUIRED_SERVICES="sshd"

if [ -f /etc/sonic/fips.conf ]; then
. /etc/sonic/fips.conf
fi

# Configure the FIPS runtime option, restart the docker containers
# and the system services to enable or disable the FIPS
update_runtime_config()
{
mkdir -p /etc/fips
if [ "$FIPS_ENABLE" == "1" ]; then
if grep -qE "fips=1|sonic_fips=1" /proc/cmdline; then
echo "FIPS enabled in the kernel command line, skipped the configuration."
exit 0
fi
fi

echo $FIPS_ENABLE > /etc/fips/fips_enable
if [ -f /etc/fips/fips_enable.flag ] && [ "$(cat /etc/fips/fips_enable.flag)" == "$FIPS_ENABLE" ]; then
echo "The FIPS option $FIPS_ENABLE not changed, skipped."
exit 0
fi

# Restart the running docker contianers by image name
running_dockers=$(docker ps --format '{{.Image}},{{.Names}}')
for image in $RESTART_REQUIRED_IMAGES; do
[ -z "$image" ] && continue
while read -r line; do
contaner_name=$(echo $line | cut -d, -f2)
echo "Restarting the docker container $contaner_name"
docker restart $contaner_name > /dev/null
done < <(echo "$running_dockers" | grep "^${image}:")
done

# Restart the services
for service in "$RESTART_REQUIRED_SERVICES"; do
[ -z "$service" ] && continue
echo "Restarting the service $service"
systemctl restart $service
done

# Set the flag in a file to indicate the config complete successfully
echo $FIPS_ENABLE > /etc/fips/fips_enable.flag
}

# Update the FIPS enforcement config option in Linux kernel cmdline
update_enforcement_config()
{
local fips_enforce_state=$(sonic-installer get-fips | grep -q enabled && echo 1)
if [ "$fips_enforced_state" == "$FIPS_ENFORCE" ]; then
echo "FIPS enforcement state $fips_enforced_state not change, skipped the configuration."
exit 0
fi

fips_option = '--disable-fips'
if [ "$FIPS_ENFORCE" == "1" ]; then
fips_option = '--enable-fips'
fi

echo "Set FIPS with option $fips_option"
sonic-installer set-fips "$fips_option"
}

update_runtime_config
update_enforcement_config
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
'scripts/procdockerstatsd',
'scripts/determine-reboot-cause',
'scripts/process-reboot-cause',
'scripts/sonic-host-server'
'scripts/sonic-host-server',
'scripts/update-fips-config'
],
install_requires = [
'dbus-python',
Expand Down

0 comments on commit 030dd9a

Please sign in to comment.