Skip to content

Commit 8d88455

Browse files
serhepopovychlguohan
authored andcommitted
[baseimage]: Improve password hashing for default user account (#1748)
* [slave.mk]: Fix displaying username and password in build summary We display contents of DEFAULT_USERNAME and DEFAULT_PASSWORD, while image can be build with USERNAME and/or PASSWORD given on make(1) command line. For example: $ make USERNAME=adm PASSWORD=mypass target/sonic-broadcom.bin Fix by displaying USERNAME and PASSWORD variables in build summary. Signed-off-by: Sergey Popovich <[email protected]> * [baseimage]: Improve default user account handling There are couple of issues with current implementation of default user account management in baseimage: 1) It uses DES to encrypt accounts password. Furthermore this effectively limits password length to 8 symbols, even if more provided with PASSWORD or DEFAULT_PASSWORD from rules/config. 2) Salt value for password is same on all builds even with different password increasing attack surface. 3) During the build process password passed as command line parameter either as plain text (if given to make(1) as "make PASSWORD=...") or DES encrypted (if given to build_debian.sh) can be seen by non-build users using /proc/<pid>/cmdline file that has group and world readable permissions. Both 1) and 2) come from: perl -e 'print crypt("$(PASSWORD)", "salt"),"\n"')" that by defalt uses DES if salt does not have format $<id>$<salt>$, where <id> is hashing function id. See crypt(3) for more details on valid <id> values. To address issues above we propose following changes: 1) Do not create password by hands (e.g. using perl snippet above): put this job to chpasswd(8) which is aware about system wide password hashing policy specified in /etc/login.defs with ENCRYPT_METHOD (by default it is SHA512 for Debian 8). 2) Now chpasswd(8) will take care about proper salt value. 3) This has two steps: 3.1) For compatibility reasons accept USERNAME and PASSWORD as make(1) parameters, but warn user that this is unsafe. 3.2) Use process environment to pass USERNAME and PASSWORD variables from Makefile to build_debian.sh as more secure alternative to passing via command line parameters: /proc/<pid>/environ readable only by user running process or privileged users like root. Before change: -------------- hash1 ----- # u='admin' # p="$(LANG=C perl -e 'print crypt("YourPaSs", "salt"),"\n"')" ^^^^^^^^ 8 symbols # echo "$u:$p" | chpasswd -e # getent shadow admin admin:sazQDkwgZPfSk:17680:0:99999:7::: ^^^^^^^^^^^^^ Note the hash (DES encrypted password) hash2 ----- # u='admin' # p="$(LANG=C perl -e 'print crypt("YourPaSsWoRd", "salt"),"\n"')" ^^^^^^^^^^^^ 12 symbols # echo "$u:$p" | chpasswd -e # getent shadow admin admin:sazQDkwgZPfSk:17680:0:99999:7::: ^^^^^^^^^^^^^ Hash is the same as for "YourPaSs" After change: ------------- hash1 ----- # echo "admin:YourPaSs" | chpasswd # getent shadow admin admin:$6$1Nho1jHC$T8YwK58FYToXMFuetQta7/XouAAN2q1IzWC3bdIg86woAs6WuTg\ ^^^^^^^^ Note salt here ksLO3oyQInax/wNVq.N4de6dyWZDsCAvsZ1:17681:0:99999:7::: hash2 ----- # echo "admin:YourPaSs" | chpasswd # getent shadow admin admin:$6$yKU5g7BO$kdT02Z1wHXhr1VCniKkZbLaMPZXK0WSSVGhSLGrNhsrsVxCJ.D9\ ^^^^^^^^ Here salt completely different from case above plFpd8ksGNpw/Vb92hvgYyCL2i5cfI8QEY/:17681:0:99999:7::: Since salt is different hashes for same password different too. hash1 ----- # LANG=C perl -e 'print crypt("YourPaSs", "\$6\$salt\$"),"\n"' ^^^^^ We want SHA512 hash $6$salt$qkwPvXqUeGpexO1vatnIQFAreOTXs6rnDX.OI.Sz2rcy51JrO8dFc9aGv82bB\ yd2ELrIMJ.FQLNjgSD0nNha7/ hash2 ----- # LANG=C perl -e 'print crypt("YourPaSsWoRd", "\$6\$salt\$"),"\n"' $6$salt$1JVndGzyy/dj7PaXo6hNcttlQoZe23ob8GWYWxVGEiGOlh6sofbaIvwl6Ho7N\ kYDI8zwRumRwga/A29nHm4mZ1 Now with same "salt" and $<id>$, and same 8 symbol prefix in password, but different password length we have different hashes. Signed-off-by: Sergey Popovich <[email protected]>
1 parent d2b1a0b commit 8d88455

File tree

2 files changed

+23
-17
lines changed

2 files changed

+23
-17
lines changed

build_debian.sh

+9-13
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,22 @@
33
## an ONIE installer image.
44
##
55
## USAGE:
6-
## ./build_debian USERNAME PASSWORD_ENCRYPTED
7-
## PARAMETERS:
6+
## USERNAME=username PASSWORD=password ./build_debian
7+
## ENVIRONMENT:
88
## USERNAME
99
## The name of the default admin user
10-
## PASSWORD_ENCRYPTED
11-
## The encrypted password, expected by chpasswd command
10+
## PASSWORD
11+
## The password, expected by chpasswd command
1212

1313
## Default user
14-
USERNAME=$1
1514
[ -n "$USERNAME" ] || {
16-
echo "Error: no or empty USERNAME argument"
15+
echo "Error: no or empty USERNAME"
1716
exit 1
1817
}
1918

20-
## Password for the default user, customizable by environment variable
21-
## By default it is an empty password
22-
## You may get a crypted password by: perl -e 'print crypt("YourPaSsWoRd", "salt"),"\n"'
23-
PASSWORD_ENCRYPTED=$2
24-
[ -n "$PASSWORD_ENCRYPTED" ] || {
25-
echo "Error: no or empty PASSWORD_ENCRYPTED argument"
19+
## Password for the default user
20+
[ -n "$PASSWORD" ] || {
21+
echo "Error: no or empty PASSWORD"
2622
exit 1
2723
}
2824

@@ -178,7 +174,7 @@ sudo cp files/docker/docker.service.conf $_
178174
## Note: user should be in the group with the same name, and also in sudo/docker group
179175
sudo LANG=C chroot $FILESYSTEM_ROOT useradd -G sudo,docker $USERNAME -c "$DEFAULT_USERINFO" -m -s /bin/bash
180176
## Create password for the default user
181-
echo $USERNAME:$PASSWORD_ENCRYPTED | sudo LANG=C chroot $FILESYSTEM_ROOT chpasswd -e
177+
echo "$USERNAME:$PASSWORD" | sudo LANG=C chroot $FILESYSTEM_ROOT chpasswd
182178

183179
## Pre-install hardware drivers
184180
sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install \

slave.mk

+14-4
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,14 @@ endif
7676

7777
ifeq ($(USERNAME),)
7878
override USERNAME := $(DEFAULT_USERNAME)
79+
else
80+
$(warning USERNAME given on command line: could be visible to other users)
7981
endif
8082

8183
ifeq ($(PASSWORD),)
8284
override PASSWORD := $(DEFAULT_PASSWORD)
85+
else
86+
$(warning PASSWORD given on command line: could be visible to other users)
8387
endif
8488

8589
ifeq ($(SONIC_BUILD_JOBS),)
@@ -100,8 +104,8 @@ $(info "CONFIGURED_PLATFORM" : "$(if $(PLATFORM),$(PLATFORM),$(CONFI
100104
$(info "SONIC_CONFIG_PRINT_DEPENDENCIES" : "$(SONIC_CONFIG_PRINT_DEPENDENCIES)")
101105
$(info "SONIC_BUILD_JOBS" : "$(SONIC_BUILD_JOBS)")
102106
$(info "SONIC_CONFIG_MAKE_JOBS" : "$(SONIC_CONFIG_MAKE_JOBS)")
103-
$(info "DEFAULT_USERNAME" : "$(DEFAULT_USERNAME)")
104-
$(info "DEFAULT_PASSWORD" : "$(DEFAULT_PASSWORD)")
107+
$(info "USERNAME" : "$(USERNAME)")
108+
$(info "PASSWORD" : "$(PASSWORD)")
105109
$(info "ENABLE_DHCP_GRAPH_SERVICE" : "$(ENABLE_DHCP_GRAPH_SERVICE)")
106110
$(info "SHUTDOWN_BGP_ON_START" : "$(SHUTDOWN_BGP_ON_START)")
107111
$(info "ENABLE_PFCWD_ON_START" : "$(ENABLE_PFCWD_ON_START)")
@@ -484,8 +488,14 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \
484488

485489
DIRTY_SUFFIX="$(shell date +%Y%m%d\.%H%M%S)"
486490
export DIRTY_SUFFIX
487-
./build_debian.sh "$(USERNAME)" "$(shell perl -e 'print crypt("$(PASSWORD)", "salt"),"\n"')" $(LOG)
488-
TARGET_MACHINE=$($*_MACHINE) IMAGE_TYPE=$($*_IMAGE_TYPE) ./build_image.sh $(LOG)
491+
492+
USERNAME="$(USERNAME)" \
493+
PASSWORD="$(PASSWORD)" \
494+
./build_debian.sh $(LOG)
495+
496+
TARGET_MACHINE=$($*_MACHINE) \
497+
IMAGE_TYPE=$($*_IMAGE_TYPE) \
498+
./build_image.sh $(LOG)
489499

490500
$(foreach docker, $($*_DOCKERS), \
491501
rm -f $($(docker)_CONTAINER_NAME).sh

0 commit comments

Comments
 (0)