Skip to content

Instantly share code, notes, and snippets.

@fire1ce
Last active September 26, 2024 13:55
Show Gist options
  • Save fire1ce/65d3e370120750a5deb283abe1d74491 to your computer and use it in GitHub Desktop.
Save fire1ce/65d3e370120750a5deb283abe1d74491 to your computer and use it in GitHub Desktop.
Install oh-my-zsh on openwrt/lede-project

Install oh-my-zsh on OpenWrt

Install Requirements Packages

opkg update && opkg install ca-certificates zsh curl git-http

Install oh-my-zsh

sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

Set zsh as default (thanks to @mlouielu)

which zsh && sed -i -- 's:/bin/ash:'`which zsh`':g' /etc/passwd

Prevent User Lockout

To prevent lock-outs after accidentially removing zsh(as explained in the wiki) you can add a check for zsh and fallback to ash in /etc/rc.local (thanks to @fox34):

# Revert root shell to ash if zsh is not available
if grep -q '^root:.*:/usr/bin/zsh$' /etc/passwd && [ ! -x /usr/bin/zsh ]; then
    # zsh is root shell, but zsh was not found or not executable: revert to default ash
    [ -x /usr/bin/logger ] && /usr/bin/logger -s "Reverting root shell to ash, as zsh was not found on the system"
    sed -i -- 's:/usr/bin/zsh:/bin/ash:g' /etc/passwd
fi
@mlouielu
Copy link

Hi @fire1ce, this line should change to use this:

sed -i -- 's/ash/zsh/g' /etc/passwd

to

sed -i -- 's:/bin/ash:/usr/bin/zsh:g' /etc/passwd

Otherwise it will reject user to login from ssh

@fire1ce
Copy link
Author

fire1ce commented Mar 26, 2018

@mlouielu thanks. change been applied to the gist.

@moorer2k
Copy link

moorer2k commented Sep 12, 2018

Great script, I had to modify the sed command to work for my Pineapple Tetra, which runs off OpenWRT also.

Changed:

sed -i -- 's:/bin/ash:/usr/bin/zsh:g' /etc/passwd

to

sed -i -- 's:/bin/ash:/bin/zsh:g' /etc/passwd

Adding the /usr/ segment would prevent logging in at all.

But, thanks for the provided script! Saved so much time!

@mlouielu
Copy link

maybe it should use which zsh to determine the path, like this:

$ which zsh && sed -i -- 's:/bin/ash:'`which zsh`':g' /etc/passwd

@TommyMacMoo
Copy link

TommyMacMoo commented May 10, 2019

Cool, works also under OpenWrt 18.06.2
this worked for me:
->
opkg update && opkg install ca-certificates zsh curl git-http
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
sed -i -- 's:/bin/ash:/usr/bin/zsh:g' /etc/passwd

logged out, and in again, and Oh-My-ZSH was working ------------------>Thanks

@reancool
Copy link

Cool, works also under OpenWrt 18.06.2
this worked for me:
->
opkg update && opkg install ca-certificates zsh curl git-http
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
sed -i -- 's:/bin/ash:/usr/bin/zsh:g' /etc/passwd

logged out, and in again, and Oh-My-ZSH was working ------------------>Thanks

which zsh
/usr/bin/zsh
i edit /etc/passwd. change ash's path to zsh's path.
i cannot ssh login anymore.
"Permission denied, please try again."
i can web login.

@dpvpro
Copy link

dpvpro commented May 28, 2020

Thanks. Works on OpenWrt 19.07.3.

@RyanHakurei
Copy link

@reancool. Delete /etc/passwd and /etc/shadow then reboot the router. It will recreate those files from scratch and you will be able to ssh again.

@teq0
Copy link

teq0 commented Jan 24, 2021

@reancool. Delete /etc/passwd and /etc/shadow then reboot the router. It will recreate those files from scratch and you will be able to ssh again.

How do you delete these files if you can't connect with ssh?

@RyanHakurei
Copy link

@reancool. Delete /etc/passwd and /etc/shadow then reboot the router. It will recreate those files from scratch and you will be able to ssh again.

How do you delete these files if you can't connect with ssh?

I used Telnet

@teq0
Copy link

teq0 commented Jan 24, 2021

I just get connection refused if I try telnet. I ended up taking a backup, editing /etc/passwd to put ash back as shell, then restored from that.
I don't quite understand how changing the shell in /etc/passwd, then deleting /etc/passwd, gets it to use zsh. The only place the choice of zsh is stored is in /etc/passwd. Or does the OS make a backup of it?

@ms1995
Copy link

ms1995 commented Oct 22, 2021

Just in case you are locked out by the wrong ZSH path and need a way to execute commands: try Network > Firewall > Custom Rules. These commands get executed right away.

@fox34
Copy link

fox34 commented Oct 26, 2021

To make oh-my-zsh persistent after system upgrades, there are several options. I suggest to remove unneeded plugins and themes, since they will increase config (backup) size by a few MB.

Option A: Adding /root to backup file list

Go to LuCI -> System -> Backup/Flash Firmware -> Tab "Configuration" -> Add /root

Option B: Install oh-my-zsh to /etc/zsh and keep user files there

Step 1: Install or move oh-my-zsh to /etc/zsh

Install oh-my-zsh into /etc/zsh upon initial setup (see instructions). If you already installed oh-my-zsh into /root/, move it from there:

mkdir /etc/zsh
mv /root/.oh-my-zsh /etc/zsh/oh-my-zsh
sed -i -- 's:/root/.oh-my-zsh:/etc/zsh/oh-my-zsh:g' /root/.zshrc

Step 2: Add /etc/zsh to backup files

Go to LuCI -> System -> Backup/Flash Firmware -> Tab "Configuration" -> Add /etc/zsh

Step 3: Move and symlink zsh-related user files to /etc/zsh to keep them after sysupgrades

# Temporarily disable history file modification
HISTFILE=/dev/null

# Symlinking every file is necessary, since zsh on OpenWrt does not read files in /etc/zsh by default
for f in zshenv zprofile zshrc zlogin zlogout zsh_history; do
    [ -f /root/.$f ] && [ ! -f /etc/zsh/$f ] && mv /root/.$f /etc/zsh/$f
    [ -f /etc/zsh/$f ] && ln -s /etc/zsh/$f /root/.$f
done

# check result: root directory should not contain any zsh-related files (except for zcompdump), only symlinks
ls -la /root

Login in a separate shell (for security reasons) to check functionality.

Step 4: Check and restore symlinks on reboot

Append the following commands in /etc/rc.local (before exit 0) to restore the symlinks after every reboot, if they are missing:

if [ -d /etc/zsh ]; then
    
    # Restore oh-my-zsh functionality after sysupgrades
    [ -x /usr/bin/logger ] && /usr/bin/logger -s "Checking and restoring oh-my-zsh"
    
    # Always symlink history file, even if it did not exist
    [ ! -f /etc/zsh/zsh_history ] && touch /etc/zsh/zsh_history
    for f in zshenv zprofile zshrc zlogin zlogout zsh_history; do
        [ -r /etc/zsh/$f ] && [ ! -r /root/.$f ] && ln -s /etc/zsh/$f /root/.$f
    done
fi

Prevent lock outs due to a missing zsh installation

To prevent lock-outs after accidentially removing zsh (as explained in the wiki), you can add a check for zsh and fallback to ash in /etc/rc.local:

# Revert root shell to ash if zsh is not available
if grep -q '^root:.*:/usr/bin/zsh$' /etc/passwd && [ ! -x /usr/bin/zsh ]; then
    # zsh is root shell, but zsh was not found or not executable: revert to default ash
    [ -x /usr/bin/logger ] && /usr/bin/logger -s "Reverting root shell to ash, as zsh was not found on the system"
    sed -i -- 's:/usr/bin/zsh:/bin/ash:g' /etc/passwd
fi

@fire1ce
Copy link
Author

fire1ce commented Nov 3, 2021

Sorry i've neglected this gist.
i've updated the gist and added the lock outs prevention from @fox34 post. thanks!

@VergilGao
Copy link

Cool, works also under OpenWrt 18.06.2
this worked for me:
->
opkg update && opkg install ca-certificates zsh curl git-http
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
sed -i -- 's:/bin/ash:/usr/bin/zsh:g' /etc/passwd
logged out, and in again, and Oh-My-ZSH was working ------------------>Thanks

which zsh /usr/bin/zsh i edit /etc/passwd. change ash's path to zsh's path. i cannot ssh login anymore. "Permission denied, please try again." i can web login.

just add
/usr/bin/zsh
to /etc/shells

your /etc/shells would be like:

$ cat /etc/shells
/bin/ash
/bin/bash
/bin/rbash
/usr/bin/zsh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment