Skip to content

Commit df7a458

Browse files
[SONiC] Implement comprehensive local user management system
SONiC currently lacks a comprehensive local user management system that can: - Manage users through CONFIG_DB with role-based access control - Provide secure password hashing and authentication policies - Support SSH key management and PAM integration - Enable/disable users dynamically without system restarts - Integrate with SONiC's configuration management framework This implementation addresses the User Management HLD requirements for centralized user administration in SONiC. **1. YANG Model & Configuration Schema:** - Added sonic-user.yang model defining LOCAL_USER and LOCAL_ROLE_SECURITY_POLICY tables - Integrated user management into CONFIG_DB schema with role-based configuration - Added DEVICE_METADATA.local_user_management feature flag **2. User Management Daemon (userd):** - Implemented C++ daemon using SWSS framework for CONFIG_DB integration - Added comprehensive user lifecycle management (create/update/delete/enable/disable) - Implemented role-based group assignment (administrator, operator roles) - Added SSH key management with proper file permissions - Integrated PAM faillock configuration using Jinja2 templates - Used posix_spawn() for secure command execution without shell interpretation - Added efficient change detection to avoid unnecessary system calls **3. CLI Interface:** - Extended sonic-utilities with 'config user' and 'show user' commands - Added user import functionality to migrate existing system users - Implemented secure password hashing using system's default method (yescrypt/SHA-512) - Added role-based user management with proper validation **4. Build System Integration:** - Added sonic-host-services package with userd daemon and systemd service - Integrated user management into SONiC image build process - Added template-based configuration generation for init_cfg.json - Added build dependencies for JSON processing and password hashing **5. Security & Authentication:** - Implemented secure password storage using system's native hashing - Added PAM faillock integration for login attempt limiting - Proper file permissions for SSH keys and user directories - Role-based access control with predefined group assignments **1. Basic User Management:** ```bash sudo config user add testuser --role administrator --password-prompt show user sudo config user modify --enabled testuser sudo config user modify --disabled testuser sudo config user delete testuser ``` **2. Import Existing Users:** ```bash sudo config user import-existing ``` **3. SSH Key Management:** ```bash sudo config user add-ssh-key testuser "ssh-rsa AAAAB3NzaC1yc2E..." sudo config user remove-ssh-key testuser "ssh-rsa AAAAB3NzaC1yc2E..." ``` **4. Verify Configuration:** ```bash redis-cli -n 4 hgetall "LOCAL_USER|testuser" redis-cli -n 4 hget "DEVICE_METADATA|localhost" local_user_management getent passwd testuser sudo cat /etc/shadow | grep testuser groups testuser ``` **5. Verify Daemon Operation:** ```bash systemctl status userd journalctl -u userd -f cat /etc/security/faillock.conf ``` **6. Test Authentication:** ```bash su - testuser ssh testuser@localhost ``` The implementation provides a complete user management solution integrated with SONiC's configuration framework, supporting both CLI and programmatic management of local users with proper security controls.
1 parent 7f7f726 commit df7a458

File tree

13 files changed

+156
-3
lines changed

13 files changed

+156
-3
lines changed

build_debian.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ fi
320320
## Note: ca-certificates is needed for easy_install
321321
## Note: don't install python-apt by pip, older than Debian repo one
322322
## Note: fdisk and gpg are needed by fwutil
323+
## Note: whois is needed for mkpasswd by sonic-utilities
323324
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \
324325
file \
325326
ifmetric \
@@ -386,7 +387,8 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in
386387
wireless-regdb \
387388
ethtool \
388389
zstd \
389-
nvme-cli
390+
nvme-cli \
391+
whois
390392

391393
sudo cp files/initramfs-tools/pzstd $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/pzstd
392394
sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/pzstd

files/build_templates/init_cfg.json.j2

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
{%- if include_p4rt == "y" %}"synchronous_mode":"enable",{% endif %}
66
"default_bgp_status": {% if shutdown_bgp_on_start == "y" %}"down"{% else %}"up"{% endif %},
77
"default_pfcwd_status": {% if enable_pfcwd_on_start == "y" %}"enable"{% else %}"disable"{% endif %},
8+
"local_user_management": {%- if sonicadmin_user and sonicadmin_password %}"enabled"{% else %}"disabled"{% endif %},
89
"timezone": "UTC"
910
}
1011
},
@@ -203,6 +204,15 @@
203204
"num_dumps": "3"
204205
}
205206
},
207+
{%- if sonicadmin_user and sonicadmin_password %}
208+
"LOCAL_USER": {
209+
"{{ sonicadmin_user }}": {
210+
"role": "administrator",
211+
"password_hash": "{{ sonicadmin_password }}",
212+
"enabled": "true"
213+
}
214+
},
215+
{%- endif %}
206216
"NTP": {
207217
"global": {
208218
"authentication": "disabled",

files/build_templates/sonic_debian_extension.j2

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,8 @@ install_deb_package {{deb}}
346346
# Install sonic-db-cli
347347
install_deb_package $debs_path/sonic-db-cli_*.deb
348348

349+
# Install SONiC host userd package
350+
install_deb_package $debs_path/sonic-host-userd_*.deb
349351

350352
{% if include_system_eventd == "y" and build_reduce_image_size != "y" %}
351353
# Install sonic-rsyslog-plugin
@@ -635,7 +637,7 @@ echo "config-topology.service" | sudo tee -a $GENERATED_SERVICE_FILE
635637
sudo cp $IMAGE_CONFIGS/config-topology/config-topology.sh $FILESYSTEM_ROOT/usr/bin
636638

637639
# Generate initial SONiC configuration file
638-
j2 files/build_templates/init_cfg.json.j2 | sudo tee $FILESYSTEM_ROOT/etc/sonic/init_cfg.json
640+
sonicadmin_password="$(sudo grep ^${sonicadmin_user} $FILESYSTEM_ROOT/etc/shadow | cut -d: -f2)" j2 files/build_templates/init_cfg.json.j2 | sudo tee $FILESYSTEM_ROOT/etc/sonic/init_cfg.json
639641

640642
# Copy config-setup script, conf file and service file
641643
j2 files/build_templates/config-setup.service.j2 | sudo tee $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM/config-setup.service

platform/vs/docker-sonic-vs.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ $(DOCKER_SONIC_VS)_DEPENDS += $(SYNCD_VS) \
1212
$(LIBYANG_PY3) \
1313
$(SONIC_UTILITIES_DATA) \
1414
$(SONIC_HOST_SERVICES_DATA) \
15+
$(SONIC_HOST_USERD) \
1516
$(SYSMGR)
1617

1718
$(DOCKER_SONIC_VS)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) \

platform/vs/docker-sonic-vs/Dockerfile.j2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ RUN apt-get install -y net-tools \
3434
iptables \
3535
jq \
3636
uuid-dev \
37+
# For using mkpasswd by sonic-utilities
38+
whois \
3739
# For installing Python m2crypto package
3840
# (these can be uninstalled after installation)
3941
build-essential \

rules/sonic-host-services.dep

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
SPATH := $($(SONIC_HOST_SERVICES_PY3)_SRC_PATH)
22
DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-host-services.mk rules/sonic-host-services.dep
33
DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
4-
SMDEP_FILES := $(addprefix $(SPATH)/,$(shell git -C $(SPATH) ls-files | grep -v ^data))
4+
SMDEP_FILES := $(addprefix $(SPATH)/,$(shell git -C $(SPATH) ls-files | grep -v ^data | grep -v ^userd))
55

66
$(SONIC_HOST_SERVICES_PY3)_CACHE_MODE := GIT_CONTENT_SHA
77
$(SONIC_HOST_SERVICES_PY3)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)

rules/sonic-host-userd.dep

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
SPATH := $($(SONIC_HOST_USERD)_SRC_PATH)
2+
DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-host-userd.mk rules/sonic-host-userd.dep
3+
DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
4+
DEP_FILES += $(addprefix $(SPATH)/,$(shell git -C $(SPATH) ls-files))
5+
6+
$(SONIC_HOST_USERD)_CACHE_MODE := GIT_CONTENT_SHA
7+
$(SONIC_HOST_USERD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)
8+
$(SONIC_HOST_USERD)_DEP_FILES := $(DEP_FILES)

rules/sonic-host-userd.mk

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SONiC host userd binary package
2+
3+
SONIC_HOST_USERD = sonic-host-userd_1.0-1_$(CONFIGURED_ARCH).deb
4+
$(SONIC_HOST_USERD)_SRC_PATH = $(SRC_PATH)/sonic-host-services/userd
5+
$(SONIC_HOST_USERD)_DEPENDS += $(LIBSWSSCOMMON_DEV)
6+
$(SONIC_HOST_USERD)_RDEPENDS += $(SONIC_HOST_SERVICES_DATA) $(LIBSWSSCOMMON)
7+
SONIC_DPKG_DEBS += $(SONIC_HOST_USERD)

slave.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,6 +1398,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \
13981398
$(SONIC_UTILITIES_DATA) \
13991399
$(SONIC_CTRMGRD_RS) \
14001400
$(SONIC_HOST_SERVICES_DATA) \
1401+
$(SONIC_HOST_USERD) \
14011402
$(BASH) \
14021403
$(BASH_TACPLUS) \
14031404
$(AUDISP_TACPLUS) \

src/sonic-yang-models/setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
'sonic-smart-switch.yang',
148148
'sonic-spanning-tree.yang',
149149
'sonic-srv6.yang',
150+
'sonic-user.yang',
150151
]
151152

152153
class my_build_py(build_py):

0 commit comments

Comments
 (0)