`chsh -s /bin/zsh` breaks sudo

When a login begins while my shell is bash sudo works.
First move my .*shrc’s out of the question:

me@eb:~> mv -vb .bashr{c,}
renamed '.bashrc' -> '.bashr'
me@eb:~> mv -vb .zshr{c,}
renamed '.zshrc' -> '.zshr'
me@eb:~> chsh -s /bin/bash
Password:

fresh login while shell is bash, from either bash or zsh sudo doesn’t ask for password:

login: me
password:
Have a lot of fun...
You have new mail.
me@eb:~> sudo -s
  #  exit
me@eb:~> zsh
This is the Z Shell configuration function for new users,
...
--- Type one of the keys in parentheses --- q
eb% sudo -s
  #  exit

But when a login begins while my shell is zsh sudo fails.

me@eb:~> chsh -s /bin/zsh
Password:

fresh login while shell is zsh, from either zsh or bash sudo broken:

login: me
password:
This is the Z Shell configuration function for new users,
...
--- Type one of the keys in parentheses --- q
eb% sudo -s
[sudo] password for me: ^C
sudo: a password is required
eb% bash
me@eb:~> sudo -s
[sudo] password for me:

What’s going on?

i don’t see any clues here:
login shell environment when my shell is bash:

me@eb:~> set
AUDIODRIVER=pulseaudio
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:globasciiranges:globskipdots:histappend:interactive_comme
BASH_ALIASES=()
BASH_ARGC=([0]="0")
BASH_ARGV=()
BASH_CMDS=()
BASH_COMPLETION_VERSINFO=([0]="2" [1]="11")
BASH_LINENO=()
BASH_LOADABLES_PATH=/usr/lib64/bash
BASH_SOURCE=()
BASH_VERSINFO=([0]="5" [1]="2" [2]="15" [3]="1" [4]="release" [5]="x86_64-suse-linux")
BASH_VERSION='5.2.15(1)-release'
COLUMNS=170
CONSOLE_MAGIC=
CPU=x86_64
CSHEDIT=emacs
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
DEBUGINFOD_URLS='https://debuginfod.opensuse.org/ '
DEFAULT_WM=default
DIRSTACK=()
EUID=1000
FROM_HEADER=
GPG_TTY=/dev/tty2
GROUPS=()
G_BROKEN_FILENAMES=1
G_FILENAME_ENCODING=@locale,UTF-8,ISO-8859-15,CP1252
HISTCONTROL=ignoreboth
HISTFILE=/home/me/.bash_history
HISTFILESIZE=1000
HISTSIZE=1000
HOME=/home/me
HOST=eb840g3
HOSTNAME=eb840g3
HOSTTYPE=x86_64
IFS=$' \t\n'
INSTALL_DESKTOP_EXTENSIONS=yes
INVOCATION_ID=d1c22411cef246f3a64fe2bb74c59f5b
JAVA_BINDIR=/usr/lib64/jvm/jre-openjdk/bin
JAVA_HOME=/usr/lib64/jvm/jre-openjdk
JAVA_ROOT=/usr/lib64/jvm/jre-openjdk
JRE_HOME=/usr/lib64/jvm/java-11-openjdk-11
LANG=en_US.UTF-8
LESS='-M -I -R'
LESSCLOSE='lessclose.sh %s %s'
LESSKEY=/usr/etc/lesskey.bin
LESSOPEN='lessopen.sh %s'
LESS_ADVANCED_PREPROCESSOR=no
LINES=48
LOGNAME=me
LS_COLORS='no=00:fi=00:di=01;34:ln=00;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=41;33;01:ex=00;32:*.cmd=00;32:*.exe=01;32:*.com=01;32:*.b
LS_OPTIONS='-N --color=tty -T 0'
MACHTYPE=x86_64-suse-linux
MAIL=/var/mail/me
MAILCHECK=60
MANPATH=/usr/local/man:/usr/share/man
MANPATHISSET=yes
MINICOM='-c on'
MORE=-sl
MOTD_SHOWN=pam
OPTERR=1
OPTIND=1
OSTYPE=linux
PAGER=less
PATH=/home/me/bin:/usr/local/bin:/usr/bin:/bin
PIPESTATUS=([0]="0")
PPID=11514
PROFILEREAD=true
PS1='\u@\h:\w> '
PS2='> '
PS4='+ '
PWD=/home/me
PYTHONSTARTUP=/etc/pythonstart
QEMU_AUDIO_DRV=pa
SHELL=/bin/bash
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
SHLVL=1
SYSTEMD_EXEC_PID=11514
TERM=linux
UID=1000
USER=me
VENDOR=suse
WINDOWMANAGER=/usr/bin/startplasma-x11
XDG_CONFIG_DIRS=/etc/xdg:/usr/local/etc/xdg:/usr/etc/xdg
XDG_DATA_DIRS=/home/me/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share/:/usr/share/
XDG_RUNTIME_DIR=/run/user/1000
XDG_SEAT=seat0
XDG_SESSION_CLASS=user
XDG_SESSION_ID=16
XDG_SESSION_TYPE=tty
XDG_VTNR=2
XKEYSYMDB=/usr/X11R6/lib/X11/XKeysymDB
XNLSPATH=/usr/share/X11/nls
X_MOUSE_CURSOR=
_=true
_HOMEBASHRC=true
_backup_glob='@(#*#|*@(~|.@(bak|orig|rej|swp|dpkg*|rpm@(orig|new|save))))'
_xspecs=(...)
japanese_legacy_encoding=EUC-JP
new_dirs=/home/me/.local/share/flatpak/exports/share
noprofile=false
norc=false
restricted=false
tty=/dev/tty2

login shell environment when my shell is zsh:

eb% set
'!'=0
'#'=0
'$'=11770
'*'=(  )
-=59DEJNRSVXZhilms
0=-zsh
'?'=1
@=(  )
ARGC=0
AUDIODRIVER=pulseaudio
CDPATH='' 
COLUMNS=170
CONSOLE_MAGIC=''
CPU=x86_64
CPUTYPE=x86_64
CSHEDIT=emacs
DBUS_SESSION_BUS_ADDRESS='unix:path=/run/user/1000/bus'
DEBUGINFOD_URLS='https://debuginfod.opensuse.org/ '
DEFAULT_WM=default
EGID=1000
EUID=1000
FIGNORE=''
FPATH=/usr/local/share/zsh/site-functions:/usr/share/zsh/site-functions:/usr/share/zsh//functions/Calendar:/usr/share/zsh//functions/Chpwd:/usr/share/zs
FROM_HEADER=''
FUNCNEST=500
GID=1000
GPG_TTY=/dev/tty3
G_BROKEN_FILENAMES=1
G_FILENAME_ENCODING=@locale,UTF-8,ISO-8859-15,CP1252
HISTCHARS='!^#'
HISTCMD=121
HISTFILE=/home/me/.zsh_history
HISTSIZE=1000
HOME=/home/me
HOST=eb840g3
HOSTNAME=eb840g3
HOSTTYPE=x86_64
IFS=$' \t\n\C-@'
INSTALL_DESKTOP_EXTENSIONS=yes
INVOCATION_ID=25c0c5017cbd4cdca3b35f407343dc33
JAVA_BINDIR=/usr/lib64/jvm/jre-openjdk/bin
JAVA_HOME=/usr/lib64/jvm/jre-openjdk
JAVA_ROOT=/usr/lib64/jvm/jre-openjdk
JRE_HOME=/usr/lib64/jvm/java-11-openjdk-11
KEYBOARD_HACK=''
KEYTIMEOUT=40
LANG=en_US.UTF-8
LESS='-M -I -R'
LESSCLOSE='lessclose.sh %s %s'
LESSKEY=/usr/etc/lesskey.bin
LESSOPEN='lessopen.sh %s'
LESS_ADVANCED_PREPROCESSOR=no
LINENO=1
LINES=48
LISTMAX=100
LOGNAME=me
LS_OPTIONS='-N --color=tty -T 0'
MACHTYPE=x86_64
MAIL=/var/mail/me
MAILCHECK=60
MAILPATH=''
MANPATH=/usr/local/man:/usr/share/man
MANPATHISSET=yes
MINICOM='-c on'
MODULE_PATH=/usr/lib64/zsh/5.9
MORE=-sl
MOTD_SHOWN=pam
NULLCMD=cat
OLDPWD=/home/me
OPTARG=''
OPTIND=1
OSTYPE=linux-gnu
PAGER=less
PATH=/home/me/bin:/usr/local/bin:/usr/bin:/bin
PPID=11733
PROFILEREAD=true
PROMPT='%m%# '
PROMPT2='%_> '
PROMPT3='?# '
PROMPT4='+%N:%i> '
PS1='%m%# '
PS2='%_> '
PS3='?# '
PS4='+%N:%i> '
PSVAR=''
PWD=/home/me
PYTHONSTARTUP=/etc/pythonstart
QEMU_AUDIO_DRV=pa
RANDOM=13212
READNULLCMD=more
SAVEHIST=500
SECONDS=33
SHELL=/bin/zsh
SHLVL=1
SPROMPT='zsh: correct ''%R'' to ''%r'' [nyae]? '
SYSTEMD_EXEC_PID=11733
TERM=linux
TIMEFMT='%J  %U user %S system %P cpu %*E total'
TMPPREFIX=/tmp/zsh
TRY_BLOCK_ERROR=-1
TRY_BLOCK_INTERRUPT=-1
TTY=/dev/tty3
TTYIDLE=4
UID=1000
USER=me
USERNAME=me
VENDOR=suse
WATCH
WINDOWMANAGER=/usr/bin/startplasma-x11
WORDCHARS='*?_-.[]~=/&;!#$%^(){}<>'
XDG_CONFIG_DIRS=/etc/xdg:/usr/local/etc/xdg:/usr/etc/xdg
XDG_DATA_DIRS=/home/me/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share/:/usr/share/
XDG_RUNTIME_DIR=/run/user/1000
XDG_SEAT=seat0
XDG_SESSION_CLASS=user
XDG_SESSION_ID=17
XDG_SESSION_TYPE=tty
XDG_VTNR=3
XKEYSYMDB=/usr/X11R6/lib/X11/XKeysymDB
XNLSPATH=/usr/share/X11/nls
X_MOUSE_CURSOR=''
ZSHEDIT=emacs
ZSH_ARGZERO=-zsh
ZSH_EVAL_CONTEXT=toplevel
ZSH_NAME=zsh
ZSH_PATCHLEVEL=zsh-5.9-0-g73d3173
ZSH_SUBSHELL=0
ZSH_VERSION=5.9
_=set
_comp_assocs=( '' )
_comp_dumpfile=/home/me/.zcompdump
_comp_options
_comp_setup
_compautos
_comps
_lastcomp
_patcomps
_postpatcomps
_services
aliases
argv=(  )
builtins
cdpath=(  )
commands
comppostfuncs=(  )
compprefuncs=(  )
dirstack
dis_aliases
dis_builtins
dis_functions
dis_functions_source
dis_galiases
dis_patchars
dis_reswords
dis_saliases
fignore=(  )
fpath=( /usr/local/share/zsh/site-functions /usr/share/zsh/site-functions /usr/share/zsh//functions/Calendar /usr/share/zsh//functions/Chpwd /usr/share/
funcfiletrace
funcsourcetrace
funcstack
functions
functions_source
functrace
galiases
histchars='!^#'
history
historywords
japanese_legacy_encoding=EUC-JP
jobdirs
jobstates
jobtexts
keymaps
mailpath=(  )
manpath=( /usr/local/man /usr/share/man )
module_path=( /usr/lib64/zsh/5.9 )
modules
nameddirs
new_dirs=/home/me/.local/share/flatpak/exports/share
norc=false
options
parameters
patchars
path=( /home/me/bin /usr/local/bin /usr/bin /bin )
pipestatus=( 1 )
prompt='%m%# '
psvar=(  )
restricted=false
reswords
saliases
signals=( EXIT HUP INT QUIT ILL TRAP IOT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH
status=1
termcap
terminfo
tty=/dev/tty3
userdirs
usergroups
watch
widgets
zle_bracketed_paste=( $'\C-[[?2004h' $'\C-[[?2004l' )
zsh_eval_context=( toplevel )
zsh_scheduled_events
  #  inxi -bz
System:                                                                                                                                                
  Kernel: 6.5.4-1-default arch: x86_64 bits: 64 Console: pty pts/5          
    Distro: openSUSE Tumbleweed 20230929                                    
Machine:                                                                                                                                                
  Type: Laptop System: HP product: HP EliteBook 840 G3 v: N/A serial: <filter>                                                                          
  Mobo: HP model: 8079 v: KBC Version 85.78 serial: <filter> UEFI: HP                                                                                   
    v: N75 Ver. 01.39 date: 04/16/2019                                      
Battery:                              
  ID-1: BAT0 charge: 41.5 Wh (98.6%) condition: 42.1/42.1 Wh (100.0%)                                                                                   
CPU:                                                                                                                                                    
  Info: dual core Intel Core i5-6200U [MT MCP] speed (MHz): avg: 400        
    min/max: 400/2800                                                                                                                                   
Graphics:                                                                                                                                               
  Device-1: Intel Skylake GT2 [HD Graphics 520] driver: i915 v: kernel                                                                                  
  Device-2: Cheng Uei Precision Industry (Foxlink) HP HD Camera                                                                                         
    driver: uvcvideo type: USB        
  Display: server: X.Org v: 21.1.8 with: Xwayland v: 23.2.1 driver: X:      
    loaded: modesetting unloaded: fbdev,vesa dri: iris gpu: i915 resolution:                                                                            
    1: 1366x768~60Hz 2: 1920x1080~60Hz 3: 1366x768~60Hz                                                                                                 
  API: OpenGL v: 4.6 Mesa 23.1.8 renderer: Mesa Intel HD Graphics 520 (SKL                                                                              
    GT2)                              
Network:                                                                                                                                                
  Device-1: Intel Ethernet I219-V driver: e1000e                            
  Device-2: Intel Wireless 8260 driver: iwlwifi                                                                                                         
  Device-3: Intel Bluetooth wireless interface driver: btusb type: USB                                                                                  
Drives:                                                                     
  Local Storage: total: 232.89 GiB used: 224.91 GiB (96.6%)                 
Info:                                                                       
  Processes: 196 Uptime: 0h 34m Memory: available: 15.5 GiB
  used: 1.23 GiB (7.9%) Shell: Bash inxi: 3.3.27

solution: change /etc/sudoers.d/ entry from
%admin ALL=(ALL) NOPASSWD: /bin/bash
to
%admin ALL=(ALL) NOPASSWD: ALL

If you’ve recently entered your password, you don’t get asked again for a little while. See man 4 sudoers for information about the timestamp_timeout parameter.

ETA: Oh, yes, I see what you’re saying. Yes, if you want no password to be prompted, the change that you made would do it. I don’t believe the line you changed is the default configuration, however, but it seems you’ve found the solution to what you’re looking to accomplish.

in what way does my solution further elevate hack exposure?

Well, if your non-root login is compromised, your root account will also be compromised - assuming that you’re not configured to use the user password to execute commands via sudo. If you’re using your user password with sudo, then arguably it makes little difference if your user account password is compromised, since that compromised password can be used to execute commands via sudo.

Being able to run sudo /bin/bash without a password arguably also leaves you with that exposure.

1 Like

after further thought changed
%admin ALL=(ALL) NOPASSWD: ALL
to
%admin ALL=(ALL) NOPASSWD: /bin/bash
%admin ALL=(ALL) NOPASSWD: /bin/zsh
fwiw this only allows these 2 shells and only with no further arguments to sudo

The thing about doing that is that once you’re in the shell, you can run anything as root, so functionally, setting it up that way is the same as using the first option.

my last change disallows sudo with more than zero arguments, slightly narrowing the exposure to a hacker getting root

I’m not sure I follow. If they can get a shell with sudo, then they can do anything. By allowing any user in the admin group to launch bash or zsh with sudo as root, they can execute any commands as root once they’ve launched the shell.

They do need to know that they can launch the shell, and a normal user can’t view /etc/sudoers, but you are still leaving an exposure that lets someone do that. Chances are, a seasoned hacker would probably try something like that first just to see if the security was that easily compromised.

I guess a question to ask is this: What is your end goal?

it’s admittedly a pretty small extra advantage. the security settings we choose are always a tradeoff between security and convenience. if convenience were to be totally left out we’d certainly never use NOPASSWD, not even ALL. i choose to limit NOPASSWD to what i want convenient, sudo -s. i dont care/never use sudo with other commands as args, so my last change above disallows them. the admin group has few members who all keep close contact. the most important security considerations are against actors or malware gaining any kind of access at all. we hide ssh inside ikev2, we protect our network with pfsense as well as internal software firewalls, we watch what we click, etc.

I think I see what your goal is now, I think. Unfortunately, I think what you end up doing is increasing your exposure because you’re assuming that a hacker isn’t going to try with no arguments - and as soon as they run sudo -s, they’re going to have full access to your system.

I think you’ll find that they can access with arguments by specifying /bin/bash or /bin/zsh as a parameter to the sudo command. You could put something like /this/doesnt/exist as a parameter, and as long as the path is invalid, they won’t be able to use it, but at that point, you might as well just get rid of the line entirely.

Ultimately, opening up a shell with nopasswd is not a good security practice, because you’re allowing any user who compromises an account with access to it to obtain root access.

Say you have sshd configured to disallow root login (good practice), and you use only public key authentication via SSH to the system (also a good practice). Someone in the group loses their public key and doesn’t realize it. Now not only is their account compromised, but root access is also compromised, you’ve undone the benefit of disallowing root remote SSH access.

Ultimately, it’s your decision to make how you want to handle security on your systems. Just never underestimate the bad guys.

1 Like

For such things there is

/usr/bin/false

That would work as well, sure.

We have both. And you need passwords with any of those keys. And that’s only if and after you penetrate our ikev2 vpn. These are the sorts of things i’m more concerned with, frankly. Your points about gaining root once inside are valid, but that’s up against just how difficult do you want to make your daily activities. Still my last change from ALL to listing the shells, with no parameters, was at least a step toward more secure, not less. And i suppose i may reconsider entering yet another password to gain root. We’ll see. Anyway i do appreciate your eye toward security advocacy.

1 Like