@@ -54,9 +54,14 @@ LINUX_DEFAULT_PASS_MAX_DAYS = 99999
5454LINUX_DEFAULT_PASS_WARN_AGE = 7
5555
5656# Ssh min-max values
57- SSH_MIN_VALUES = {"authentication_retries" : 3 , "login_timeout" : 1 , "ports" : 1 }
58- SSH_MAX_VALUES = {"authentication_retries" : 100 , "login_timeout" : 600 , "ports" : 65535 }
59- SSH_CONFIG_NAMES = {"authentication_retries" : "MaxAuthTries" , "login_timeout" : "LoginGraceTime" }
57+ SSH_MIN_VALUES = {"authentication_retries" : 3 , "login_timeout" : 1 , "ports" : 1 ,
58+ "inactivity_timeout" : 0 , "max_sessions" : 0 }
59+ SSH_MAX_VALUES = {"authentication_retries" : 100 , "login_timeout" : 600 ,
60+ "ports" : 65535 , "inactivity_timeout" : 35000 ,
61+ "max_sessions" : 100 }
62+ SSH_CONFIG_NAMES = {"authentication_retries" : "MaxAuthTries" ,
63+ "login_timeout" : "LoginGraceTime" , "ports" : "Port" ,
64+ "inactivity_timeout" : "ClientAliveInterval" }
6065
6166ACCOUNT_NAME = 0 # index of account name
6267AGE_DICT = { 'MAX_DAYS' : {'REGEX_DAYS' : r'^PASS_MAX_DAYS[ \t]*(?P<max_days>-?\d*)' , 'DAYS' : 'max_days' , 'CHAGE_FLAG' : '-M ' },
@@ -1101,9 +1106,15 @@ class SshServer(object):
11011106 syslog .syslog (syslog .LOG_ERR , "Ssh {} {} out of range" .format (key , value ))
11021107 elif key in SSH_CONFIG_NAMES :
11031108 # search replace configuration - if not in config file - append
1109+ if key == "inactivity_timeout" :
1110+ # translate min to sec.
1111+ value = int (value ) * 60
11041112 kv_str = "{} {}" .format (SSH_CONFIG_NAMES [key ], str (value )) # name +' '+ value format
11051113 modify_single_file_inplace (SSH_CONFG_TMP ,['-E' , "/^#?" + SSH_CONFIG_NAMES [key ]+ "/{h;s/.*/" +
11061114 kv_str + "/};${x;/^$/{s//" + kv_str + "/;H};x}" ])
1115+ elif key in ['max_sessions' ]:
1116+ # Ignore, these parameters handled in other modules
1117+ continue
11071118 else :
11081119 syslog .syslog (syslog .LOG_ERR , "Failed to update sshd config file - wrong key {}" .format (key ))
11091120
@@ -1318,16 +1329,31 @@ class PamLimitsCfg(object):
13181329 self .config_db = config_db
13191330 self .hwsku = ""
13201331 self .type = ""
1332+ self .max_sessions = None
13211333
13221334 # Load config from ConfigDb and render config file/
13231335 def update_config_file (self ):
13241336 device_metadata = self .config_db .get_table ('DEVICE_METADATA' )
1325- if "localhost" not in device_metadata :
1337+ ssh_server_policies = {}
1338+ try :
1339+ ssh_server_policies = self .config_db .get_table ('SSH_SERVER' )
1340+ except KeyError :
1341+ """Dont throw except in case we don`t have SSH_SERVER config."""
1342+ pass
1343+
1344+ if "localhost" not in device_metadata and "POLICIES" not in ssh_server_policies :
13261345 return
13271346
13281347 self .read_localhost_config (device_metadata ["localhost" ])
1348+ self .read_max_sessions_config (ssh_server_policies .get ("POLICIES" , None ))
13291349 self .render_conf_file ()
13301350
1351+ # Read max_sessions config
1352+ def read_max_sessions_config (self , ssh_server_policies ):
1353+ if ssh_server_policies is not None :
1354+ max_sess_cfg = ssh_server_policies .get ('max_sessions' , 0 )
1355+ self .max_sessions = max_sess_cfg if max_sess_cfg != 0 else None
1356+
13311357 # Read localhost config
13321358 def read_localhost_config (self , localhost ):
13331359 if "hwsku" in localhost :
@@ -1344,7 +1370,6 @@ class PamLimitsCfg(object):
13441370 def render_conf_file (self ):
13451371 env = jinja2 .Environment (loader = jinja2 .FileSystemLoader ('/' ), trim_blocks = True )
13461372 env .filters ['sub' ] = sub
1347-
13481373 try :
13491374 template_file = os .path .abspath (PAM_LIMITS_CONF_TEMPLATE )
13501375 template = env .get_template (template_file )
@@ -1358,7 +1383,8 @@ class PamLimitsCfg(object):
13581383 template = env .get_template (template_file )
13591384 limits_conf = template .render (
13601385 hwsku = self .hwsku ,
1361- type = self .type )
1386+ type = self .type ,
1387+ max_sessions = self .max_sessions )
13621388 with open (LIMITS_CONF , 'w' ) as f :
13631389 f .write (limits_conf )
13641390 except Exception as e :
@@ -1690,6 +1716,39 @@ class FipsCfg(object):
16901716 syslog .syslog (syslog .LOG_INFO , f'FipsCfg: update the FIPS enforce option { self .enforce } .' )
16911717 loader .set_fips (image , self .enforce )
16921718
1719+
1720+ class SerialConsoleCfg :
1721+
1722+ def __init__ (self ):
1723+ self .cache = {}
1724+
1725+ def load (self , cli_sessions_conf ):
1726+ self .cache = cli_sessions_conf or {}
1727+ syslog .syslog (syslog .LOG_INFO ,
1728+ f'SerialConsoleCfg: Initial config: { self .cache } ' )
1729+
1730+ def update_serial_console_cfg (self , key , data ):
1731+ '''
1732+ Apply config flow:
1733+ inactivity_timeout | set here AND in ssh_config flow | serial-config.service restarted.
1734+ max_sessions | set by PamLimitsCfg | serial-config.service DOESNT restarted.
1735+ sysrq_capabilities | set here | serial-config.service restarted.
1736+ '''
1737+
1738+ if self .cache .get (key , {}) != data :
1739+ ''' Config changed, need to restart the serial-config.service '''
1740+ syslog .syslog (syslog .LOG_INFO , f'Set serial-config parameter { key } value: { data } ' )
1741+ try :
1742+ run_cmd (['sudo' , 'service' , 'serial-config' , 'restart' ],
1743+ True , True )
1744+ except Exception :
1745+ syslog .syslog (syslog .LOG_ERR , f'Failed to update { key } serial-config.service config' )
1746+ return
1747+ self .cache .update ({key : data })
1748+
1749+ return
1750+
1751+
16931752class HostConfigDaemon :
16941753 def __init__ (self ):
16951754 self .state_db_conn = DBConnector (STATE_DB , 0 )
@@ -1741,6 +1800,9 @@ class HostConfigDaemon:
17411800 # Initialize FipsCfg
17421801 self .fipscfg = FipsCfg (self .state_db_conn )
17431802
1803+ # Initialize SerialConsoleCfg
1804+ self .serialconscfg = SerialConsoleCfg ()
1805+
17441806 def load (self , init_data ):
17451807 aaa = init_data ['AAA' ]
17461808 tacacs_global = init_data ['TACPLUS' ]
@@ -1763,6 +1825,7 @@ class HostConfigDaemon:
17631825 ntp_global = init_data .get (swsscommon .CFG_NTP_GLOBAL_TABLE_NAME )
17641826 ntp_servers = init_data .get (swsscommon .CFG_NTP_SERVER_TABLE_NAME )
17651827 ntp_keys = init_data .get (swsscommon .CFG_NTP_KEY_TABLE_NAME )
1828+ serial_console = init_data .get ('SERIAL_CONSOLE' , {})
17661829
17671830 self .aaacfg .load (aaa , tacacs_global , tacacs_server , radius_global , radius_server , ldap_global , ldap_server )
17681831 self .iptables .load (lpbk_table )
@@ -1771,11 +1834,12 @@ class HostConfigDaemon:
17711834 self .sshscfg .load (ssh_server )
17721835 self .devmetacfg .load (dev_meta )
17731836 self .mgmtifacecfg .load (mgmt_ifc , mgmt_vrf )
1774-
17751837 self .rsyslogcfg .load (syslog_cfg , syslog_srv )
17761838 self .dnscfg .load (dns )
17771839 self .fipscfg .load (fips_cfg )
17781840 self .ntpcfg .load (ntp_global , ntp_servers , ntp_keys )
1841+ self .serialconscfg .load (serial_console )
1842+ self .pamLimitsCfg .update_config_file ()
17791843
17801844 # Update AAA with the hostname
17811845 self .aaacfg .hostname_update (self .devmetacfg .hostname )
@@ -1797,6 +1861,8 @@ class HostConfigDaemon:
17971861
17981862 def ssh_handler (self , key , op , data ):
17991863 self .sshscfg .policies_update (key , data )
1864+ self .pamLimitsCfg .update_config_file ()
1865+
18001866 syslog .syslog (syslog .LOG_INFO , 'SSH Update: key: {}, op: {}, data: {}' .format (key , op , data ))
18011867
18021868 def tacacs_server_handler (self , key , op , data ):
@@ -1922,6 +1988,10 @@ class HostConfigDaemon:
19221988 data = self .config_db .get_table ("FIPS" )
19231989 self .fipscfg .fips_handler (data )
19241990
1991+ def serial_console_config_handler (self , key , op , data ):
1992+ syslog .syslog (syslog .LOG_INFO , 'SERIAL_CONSOLE table handler...' )
1993+ self .serialconscfg .update_serial_console_cfg (key , data )
1994+
19251995 def wait_till_system_init_done (self ):
19261996 # No need to print the output in the log file so using the "--quiet"
19271997 # flag
@@ -1951,6 +2021,8 @@ class HostConfigDaemon:
19512021 self .config_db .subscribe ('LDAP_SERVER' , make_callback (self .ldap_server_handler ))
19522022 self .config_db .subscribe ('PASSW_HARDENING' , make_callback (self .passwh_handler ))
19532023 self .config_db .subscribe ('SSH_SERVER' , make_callback (self .ssh_handler ))
2024+ # Handle SERIAL_CONSOLE
2025+ self .config_db .subscribe ('SERIAL_CONSOLE' , make_callback (self .serial_console_config_handler ))
19542026 # Handle IPTables configuration
19552027 self .config_db .subscribe ('LOOPBACK_INTERFACE' , make_callback (self .lpbk_handler ))
19562028 # Handle updates to src intf changes in radius
0 commit comments