Skip to content

Commit

Permalink
Add j2 template for enable pam_limit and limit SSH session (#10298)
Browse files Browse the repository at this point in the history
#### Why I did it
    When too many user login concurrently and run commands, SONiC may kernel panic on some device which has very limited memory.

#### How I did it
    Add j2 template for setup pam_limit plugin for limit SSH session per-user.

#### How to verify it
    Manually validate the j2 template can generate correct config file.

#### Which release branch to backport (provide reason below if selected)

- [x] 201811
- [ ] 201911
- [ ] 202006
- [x] 202012
- [x] 202106
- [x] 202111

#### Description for the changelog
    Add j2 template for setup pam_limit plugin for limit SSH session per-user.

#### A picture of a cute animal (not mandatory but encouraged)
  • Loading branch information
liuh-80 authored Mar 23, 2022
1 parent beea989 commit bb65791
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 0 deletions.
65 changes: 65 additions & 0 deletions files/image_config/hostcfgd/hostcfgd
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ PAM_AUTH_CONF_TEMPLATE = "/usr/share/sonic/templates/common-auth-sonic.j2"
NSS_TACPLUS_CONF = "/etc/tacplus_nss.conf"
NSS_TACPLUS_CONF_TEMPLATE = "/usr/share/sonic/templates/tacplus_nss.conf.j2"
NSS_CONF = "/etc/nsswitch.conf"
PAM_LIMITS_CONF_TEMPLATE = "/usr/share/sonic/templates/pam_limits.j2"
LIMITS_CONF_TEMPLATE = "/usr/share/sonic/templates/limits.conf.j2"
PAM_LIMITS_CONF = "/etc/pam.d/pam-limits-conf"
LIMITS_CONF = "/etc/security/limits.conf"

# TACACS+
TACPLUS_SERVER_PASSKEY_DEFAULT = ""
Expand Down Expand Up @@ -232,6 +236,63 @@ class AaaCfg(object):
syslog.syslog(syslog.LOG_INFO, 'pam.d files updated auth={} global={}'.
format(auth, tacplus_global))

class PamLimitsCfg(object):
"""
PamLimit Config Daemon
1) The pam_limits PAM module sets limits on the system resources that can be obtained in a user-session.
2) Purpose of this daemon is to render pam_limits config file.
"""
def __init__(self, config_db):
self.config_db = config_db
self.hwsku = ""
self.type = ""

# Load config from ConfigDb and render config file/
def update_config_file(self):
device_metadata = self.config_db.get_table('DEVICE_METADATA')
if "localhost" not in device_metadata:
return

self.read_localhost_config(device_metadata["localhost"])
self.render_conf_file()

# Read localhost config
def read_localhost_config(self, localhost):
if "hwsku" in localhost:
self.hwsku = localhost["hwsku"]
else:
self.hwsku = ""

if "type" in localhost:
self.type = localhost["type"]
else:
self.type = ""

# Render pam_limits config files
def render_conf_file(self):
env = jinja2.Environment(loader=jinja2.FileSystemLoader('/'), trim_blocks=True)
env.filters['sub'] = sub

try:
template_file = os.path.abspath(PAM_LIMITS_CONF_TEMPLATE)
template = env.get_template(template_file)
pam_limits_conf = template.render(
hwsku=self.hwsku,
type=self.type)
with open(PAM_LIMITS_CONF, 'w') as f:
f.write(pam_limits_conf)

template_file = os.path.abspath(LIMITS_CONF_TEMPLATE)
template = env.get_template(template_file)
limits_conf = template.render(
hwsku=self.hwsku,
type=self.type)
with open(LIMITS_CONF, 'w') as f:
f.write(limits_conf)
except Exception as e:
syslog.syslog(syslog.LOG_ERR,
"modify pam_limits config file failed with exception: {}"
.format(e))

class HostConfigDaemon:
def __init__(self):
Expand All @@ -242,6 +303,10 @@ class HostConfigDaemon:
self.aaacfg = AaaCfg(self.config_db)
self.iptables = Iptables()

# Initialize PamLimitsCfg
self.pamLimitsCfg = PamLimitsCfg(self.config_db)
self.pamLimitsCfg.update_config_file()


def timer_load(self):
global global_lock
Expand Down
69 changes: 69 additions & 0 deletions files/image_config/hostcfgd/limits.conf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# /etc/security/limits.conf
#
# This file generate by j2 template file: src/sonic-host-services-data/templates/limits.conf.j2
#
# Each line describes a limit for a user in the form:
#
# <domain> <type> <item> <value>
#
# Where:
# <domain> can be:
# - a user name
# - a group name, with @group syntax
# - the wildcard *, for default entry
# - the wildcard %, can be also used with %group syntax,
# for maxlogin limit
# - NOTE: group and wildcard limits are not applied to root.
# To apply a limit to the root user, <domain> must be
# the literal username root.
#
# <type> can have the two values:
# - "soft" for enforcing the soft limits
# - "hard" for enforcing hard limits
#
# <item> can be one of the following:
# - core - limits the core file size (KB)
# - data - max data size (KB)
# - fsize - maximum filesize (KB)
# - memlock - max locked-in-memory address space (KB)
# - nofile - max number of open file descriptors
# - rss - max resident set size (KB)
# - stack - max stack size (KB)
# - cpu - max CPU time (MIN)
# - nproc - max number of processes
# - as - address space limit (KB)
# - maxlogins - max number of logins for this user
# - maxsyslogins - max number of logins on the system
# - priority - the priority to run user process with
# - locks - max number of file locks the user can hold
# - sigpending - max number of pending signals
# - msgqueue - max memory used by POSIX message queues (bytes)
# - nice - max nice priority allowed to raise to values: [-20, 19]
# - rtprio - max realtime priority
# - chroot - change root to directory (Debian-specific)
#
#
# <value> is related with <item>:
# All items support the values -1, unlimited or infinity indicating
# no limit, except for priority and nice.
#
# If a hard limit or soft limit of a resource is set to a valid value,
# but outside of the supported range of the local system, the system
# may reject the new limit or unexpected behavior may occur. If the
# control value required is used, the module will reject the login if
# a limit could not be set.
#
# <domain> <type> <item> <value>
#

# * soft core 0
# root hard core 100000
# * hard rss 10000
# @student hard nproc 20
# @faculty soft nproc 20
# @faculty hard nproc 50
# ftp hard nproc 0
# ftp - chroot /ftp
# @student - maxlogins 4

# End of file
12 changes: 12 additions & 0 deletions files/image_config/hostcfgd/pam_limits.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#THIS IS AN AUTO-GENERATED FILE
#
# This file generate by j2 template file: src/sonic-host-services-data/templates/pam_limits.j2
#
# /etc/pam.d/pam-limits settings common to all services
# This file is included from other service-specific PAM config files,
# and should contain a list of the authentication modules that define
# the central authentication scheme for use on the system
# (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the
# traditional Unix authentication mechanisms.
#
# here are the per-package modules (the "Primary" block)

0 comments on commit bb65791

Please sign in to comment.