How can I get a secure system-wide oh-my-zsh configuration? - linux

I'd like to have a system-wide oh-my-zsh setup, but I'm not sure what would be the "best" approach for this. It is not my intention to ask about personal preferences or the like, I'm just unsure whether the solutions below are:
ln my local user configuration somewhere doesn't seem right, because adding an exploit to my local cfg and therefore gain root permissions would be very easy.
Installing oh-my-zsh to /etc would be maybe also a security hole because I simply haven't written it by myself.
Simply writing my own personal .zshrc would be the last approach I would like to try out because it’s very time-consuming.
Any recommendations?

Unless I'm misunderstanding the marked answer from Caleb is just the normal per-user installation steps with adding a .zshrc file to the skel dir and changing the default new-user shell, but it doesn't actually work or really answer the question because each user still requires the oh-my-zsh dir/would still require each user to clone the oh-my-zsh dir into their own folder meaning it's not really installed system wide, it just automatically gives them a zshrc file and changes the default shell to zsh, but without oh-my-zsh in each user folder it will error out.
From what I understand of the question it's asking how to install oh-my-zsh system-wide aka have it installed in ONE place and not require manually messing around on each new user/having a git clone of oh-my-zsh on each user dir. Assuming that's the case, here's what I did based off Arch Linux's AUR Package I normally use but was looking for the same on a centos server, however this can be done on any distro. Credit goes to MarcinWieczorek and the other maintainers, I just adapted the below so can do the same on non-arch distros.
If you already have oh-my-zsh installed on root just skip to Step 3. This isn't distro specific just uses the AUR Patch File for zshrc
Step #1
Install zsh of course
Step #2
Install oh-my-zsh as root as normal (shows wget method, see Calebs answer for alternative)
sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"
Step #3
Move the install to /usr/share so is system-wide
#Copy zsh files to /usr/share for all uer access
mv /root/.oh-my-zsh /usr/share/oh-my-zsh
# Move into the dir and copy the zshrc template to zshrc (which will be the default for users)
cd /usr/share/oh-my-zsh/
cp templates/zshrc.zsh-template zshrc
# Nab the patch file from MarcinWieczorek's AUR Package and apply to the zshrc file
wget https://aur.archlinux.org/cgit/aur.git/plain/0001-zshrc.patch\?h\=oh-my-zsh-git -O zshrc.patch && patch -p1 < zshrc.patch
Now oh-my-zsh is installed globally and the user just needs that zshrc file. so NOW is where Caleb's answer comes in though just do the below as /etc/adduser.conf is only on debian whereas the below should be distro independent.
Step #4
Set it up to be the default on new users
# Create hard link to the zshrc file so it creates an actual independent copy on new users
sudo ln /usr/share/oh-my-zsh/zshrc /etc/skel/.zshrc
# Set default shell to zsh
sudo adduser -D -s /bin/zsh
Now that's a true installation of oh-my-zsh with all new users automatically having it applied with the /usr/share/oh-my-zsh/zshrc settings and no other steps needed.
Misc Notes
For any pre-existing users with oh-my-zsh:
cp /usr/share/oh-my-zsh/zshrc ~/.zshrc
You can set new user OMZ defaults in /usr/share/oh-my-zsh/zshrc
Auto Updates are disabled since new users do not have permissions to update the /usr/share/oh-my-zsh files
To update oh-my-zsh just cd to /usr/share/oh-my-zsh/ and run 'sudo git pull'
The oh-my-zsh cache will be handled per-user within each user dir under ~/.oh-my-zsh-cache/ (automatically created)

Fair Warning: this assumes a Debian style linux, but this should work on other forms as well. This also assumes you are starting from scratch.
Part 1, the install:
You will need to install zsh system wide, and not just for one user. (you may have already done this but I'll include it just to be comprehensive)
make sure you have installed zsh, simply: sudo apt-get install zsh
Follow the oh-my-zsh install guide or you can either:
use curl
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
use wget
sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"
Part 2, Setting up zsh when new users are added:
You will need to make it so that new users default to zsh. In your /etc/adduser.conf file edit the line that says:
DSHELL=/bin/sh
to:
DSHELL=/bin/zsh
You should also change it for the /etc/default/useradd file, change the line:
SHELL=/bin/sh
to:
SHELL=/bin/zsh
Part 3, set your custom theme.
I have a custom theme file (here) that I wanted all users on the system to have. First, you should add the file to your .oh-my-zsh/themes folder:
cp your_custom_style.zsh-theme ~/.oh-my-zsh/themes
Next, edit your .zshrc file in your home directory, change the ZSH_THEME="default" to ZSH_THEME="your_custom_style"
Then, reload your .zshrc file with: . ~/.zshrc
Part 4, setting up new user's home directories.
We need to to place whatever files we want the new users to have in the /etc/skel directory, because this is what the system copies when it is creating new user's home directory. See this sys admin guide for details.
Copy your user's files (you may need to sudo):
cp -r .oh-my-zsh /etc/skel/
cp .zshrc /etc/skel
Now you will be able to add new users and they will have oh-my-zsh by
default with whatever custom theme you want them to have.
If you want to change all other existing user's shell to zsh, I would recommend reading this serverfault question.

If you want a system-wide install of Oh-My-Zsh, a convenient approach that overwrites the least number files is:
sudo git clone https://github.com/robbyrussell/oh-my-zsh.git /etc/oh-my-zsh
sudo cp /etc/oh-my-zsh/templates/zshrc.zsh-template /etc/skel/.zshrc
sudo mkdir -p /etc/skel/.oh-my-zsh/cache
Edit /etc/skel/.zshrc:
Edit the line export ZSH=$HOME/.oh-my-zsh (currently line 5)
Change the line to be:
export ZSH=/etc/oh-my-zsh
export ZSH_CACHE_DIR=~/.oh-my-zsh/cache
Then edit /etc/default/useradd and change the line SHELL=... to SHELL=/bin/zsh.
That's basically all (of course, git and zsh must be installed already).
To update a pre-existing user: login as them and cp /etc/skel/.zshrc ~/.zshrc
Update: Please do not edit this. I just rolled back an edit which completely botched it up!

Login as ROOT
Step 1: Install ZSH
# Download and extract ZSH
wget https://github.com/zsh-users/zsh/archive/zsh-5.8.tar.gz -P /tmp/demo/zsh
cd /tmp/demo/zsh
tar -xvzf zsh-*
cd zsh-zsh-5.8
# configure and make
sudo ./Util/preconfig
sudo ./configure
sudo make && sudo make install
# Add ZSH to the list of shells
echo /usr/local/bin/zsh | sudo tee -a /etc/shells
Step 2: Install oh-my-zsh
# If you're running the Oh My Zsh install script as part of an automated install,
# you can pass the flag --unattended to the install.sh script.
# This will have the effect of not trying to change the default shell, and also won't
# run zsh when the installation has finished.
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
# Add oh-my-zsh to /usr/share
mv /root/.oh-my-zsh /usr/share
mv /usr/share/.oh-my-zsh /usr/share/oh-my-zsh
mv /root/.zshrc /usr/share/oh-my-zsh
mv /usr/share/oh-my-zsh/.zshrc /usr/share/oh-my-zsh/zshrc
# Modify zshrc to point to /usr/share/oh-my-zsh
sed -i 's|export ZSH="'"$HOME"'/.oh-my-zsh"|export ZSH="\/usr\/share\/oh-my-zsh"|g' /usr/share/oh-my-zsh/zshrc
Step 3: Add Extra (Optional - Look at the bottom for extra features)
Step 4: Create Symbolic link
# Create Symbolic Links to /etc/skel
sudo ln /usr/share/oh-my-zsh/zshrc /etc/skel/.zshrc
Step 5: Add oh-my-zsh for root
# Change shell to ZSH for root
echo "$USER" | chsh -s /usr/local/bin/zsh
Step 6: Add oh-my-zsh for user
# Change user
su - username
# Copy zshrc to $HOME for user
cp /usr/share/oh-my-zsh/zshrc ~/.zshrc
# Change shell to ZSH for user
echo "$USER" | chsh -s /usr/local/bin/zsh
OR
sudo -i -u username bash << EOF
cp /usr/share/oh-my-zsh/zshrc ~/.zshrc
echo username | chsh -s /usr/local/bin/zsh
EOF
EXTRA:
Change theme to powerlevel10k
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-/usr/share/oh-my-zsh/custom}/themes/powerlevel10k
sed -i 's/ZSH_THEME="robbyrussell"/ZSH_THEME="powerlevel10k\/powerlevel10k"/g' /usr/share/oh-my-zsh/zshrc
Enable Auto correction
sed -i 's/# ENABLE_CORRECTION="true"/ENABLE_CORRECTION="true"/g' /usr/share/oh-my-zsh/zshrc
Enable Auto suggestions and Syntax highlighting
git clone --depth=1 https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-/usr/share/oh-my-zsh/custom}/plugins/zsh-autosuggestions
git clone --depth=1 https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-/usr/share/oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
sed -i 's/plugins=(git)/plugins=(\n git\n zsh-autosuggestions\n zsh-syntax-highlighting\n)/' /usr/share/oh-my-zsh/zshrc
sed -i 's/plugins=(git)/plugins=(git)\nZSH_DISABLE_COMPFIX=true/' /usr/share/oh-my-zsh/zshrc
Add nord dircolors
git clone --depth=1 https://github.com/arcticicestudio/nord-dircolors.git /tmp/demo/dircolors
mv /tmp/demo/dircolors/src/dir_colors /usr/share/
cd /usr/share/
mv /usr/share/dir_colors /usr/share/.dir_colors
tee -a /usr/share/oh-my-zsh/zshrc >/dev/null <<'EOF'
test -r "/usr/share/.dir_colors" && eval $(dircolors /usr/share/.dir_colors)
EOF

I combined cFINNY's answer, reading and understanding the oh-my-zsh install script, the AUR patch in his answer, and fixing the broken adduser command to do this install in a FROM ubuntu:bionic (Ubuntu 18.04) Dockerfile :
RUN git clone \
-c core.eol=lf \
-c core.autocrlf=false \
-c fsck.zeroPaddedFilemode=ignore \
-c fetch.fsck.zeroPaddedFilemode=ignore \
-c receive.fsck.zeroPaddedFilemode=ignore \
--depth=1 \
--branch master \
https://github.com/ohmyzsh/ohmyzsh.git \
/usr/share/oh-my-zsh \
# Adapt zshrc template
&& cd /usr/share/oh-my-zsh/ \
&& cp templates/zshrc.zsh-template zshrc \
&& sed -i 's/export ZSH=$HOME\/.oh-my-zsh/export ZSH=\/usr\/share\/oh-my-zsh/g' zshrc \
&& sed -i 's/# DISABLE_AUTO_UPDATE="true"/DISABLE_AUTO_UPDATE="true"/g' zshrc \
&& sed -i 's/source $ZSH\/oh-my-zsh.sh//g' zshrc \
&& sed -i 's/ZSH_THEME="robbyrussell"/ZSH_THEME="bira"/g' zshrc \
&& echo '\n \
\n \
ZSH_CACHE_DIR=$HOME/.cache/oh-my-zsh \n \
if [[ ! -d $ZSH_CACHE_DIR ]]; then \n \
mkdir -p $ZSH_CACHE_DIR \n \
fi \n \
\n \
source $ZSH/oh-my-zsh.sh \n \
' >> zshrc \
# Copy zshrc template to $HOME on user creation
&& ln /usr/share/oh-my-zsh/zshrc /etc/skel/.zshrc \
# Setting the default shell for new users has no effect since:
# 1. The default shell is specified when creating new users in entrypoint
# 2. The `ade enter` command will execute `bash` anyways
&& sed -i 's/DSHELL=\/bin\/bash/DSHELL=\/bin\/zsh/g' /etc/adduser.conf

There's also a simple way to do this as well:
Login as the root user and install zsh
sudo su
apt-get install zsh
Then login as another user of the system:
su username
export ZSH=/home/username/.oh-my-zsh
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
Follow same procedures for all users who want oh-my-zsh

Related

Change directory in a startup script debian

I am running a debian VM Instance using GCP Compute Engine and I have added a automation script to be executed on startup.
There are few tools which will be downloaded on startup. Only issue is, everything is getting downloaded in / directory.
I need to download everything in $HOME directory.
Different ways I have tried
#!/bin/bash
set -x
cd $HOME
mkdir $HOME/test
cd $HOME/test
apt install wget -y
wget https://download.java.net/openjdk/jdk11/ri/openjdk-11+28_linux-x64_bin.tar.gz
#!/bin/bash
set -x
source $HOME
mkdir $HOME/something
#!/bin/bash
set -x
cd $HOME
mkdir $HOME/something
exec bash
Still it is downloaded in / directory. What else can be done here?
You are trying to make 2 things : install wget package and download another one.
Why don't you tried to install wget manually ?
apt-get install wget
You have then to store the full path for your script, and download the package needed it it. Try this :
#!/bin/bash
homePath=$HOME
mkdir $HOME/test
wget https://download.java.net/openjdk/jdk11/ri/openjdk-11+28_linux-x64_bin.tar.gz -P $homePath/test/

Not working „source ~/.profile“ inside bash script

To permanently update ~/.profile with source, only working on manual input. Also reboot of the whole system won‘t update ~/.profile and i need to update it manual.
Is there a special code style to use it as working code inside a bash/shell script or is this special code not intended to be used in automated scripts?
Need it to automate installation of golang.
In the following code the line "source ~/.profile" won't work, and without any error messages, the rest is working fine:
#!/bin/bash
sudo apt update
sudo apt -y upgrade
cd ~
curl -O https://dl.google.com/go/go1.12.5.linux-amd64.tar.gz
tar xvf go1.12.5.linux-amd64.tar.gz
sudo chown -R root:root ./go
sudo mv go /usr/local
cd ~
sudo rm go1.12.5.linux-amd64.tar.gz
sudo echo "export GOPATH=\$HOME/work" >> ~/.profile
sudo echo "export PATH=\$PATH:/usr/local/go/bin:\$GOPATH/bin" >> ~/.profile
source ~/.profile
Preferred:
Source the script itself rather than running it - then the commands in the script are run in the current shell, including the source ~/.profile.
Alternative (since this replaces the running shell, history, variable values, and other state will be lost. So there should be a very good reason to use this method):
Use exec bash or something similar instead of source ~/.profile - this replaces the currently running Bash with another instance which will itself load the new .profile.
Here is a refactoring which defers the decision to the user and cleans up the script somewhat.
#!/bin/bash
# Put this in a variable so there is only one place to update
tarball='go1.12.5.linux-amd64.tar.gz'
sudo apt update
sudo apt -y upgrade
# cd || why would you?
curl -O "https://dl.google.com/go/$tarball"
tar xvf "$tarball"
sudo chown -R root:root ./go
sudo mv go /usr/local
rm "$tarball"
printf '%s\n' "export GOPATH=\$HOME/work" \
"export PATH=\$PATH:/usr/local/go/bin:\$GOPATH/bin" >> ~/.profile
echo "$0: done. source ~/.profile or exec bash to activate new settings." >&2

Remove ".bash_aliases" with bash script

In my .bashrc I'm using .sh script for easily configuring newly installed Debian. But while trying to
rm -f ~/.bash_aliases
wget https://raw.githubusercontent.com/.../.bash_aliases
rm -f ~/.bashrc
wget https://raw.githubusercontent.com/.../.bashrc
it's just omitting those line?
File is with permission chmod +x ./script.sh and run by sudo ./script.sh
What could possibly be wrong?
(In final code there is full link, files are being downloaded as .bashrc.1 and .bash_aliases.1)
Don't use sudo unless you have a good reason.
When you run sudo ./script.sh it runs as root, so ~ refers to root's home directory /root instead of your user's home directory.
Just run ./script.sh instead, so that it runs as you and modifies your own home directory.

Ubuntu Script run a series of script one line by one line automatically

I am a new Ubuntu user.
Recently, I try to set up a server on Ubuntu.
I am wondering how to write a automatically script to run a series of script one by one.
For example, I need to install squid first, after that I need to make a copy of config file then modify the file. The following are the steps that I write in the command console. I wonder how to make a script to run that automatically.
sudo apt-get install squid -y;
cd /etc/squid3;
sudo cp squid.conf squid.conf.bak;
sudo rm -rf squid.conf;
sudo nano squid.conf
Just add a shebang, place everything in a ".sh" file, make the file executable, and run it...
Save this as test.sh
#!/bin/bash
sudo apt-get install squid -y;
cd /etc/squid3;
sudo cp squid.conf squid.conf.bak;
sudo rm -rf squid.conf;
sudo nano squid.conf
Make it executable chmod +x test.sh
Run it... ./test.sh
To edit the file from a terminal
Get a terminal on the box where you want the script to live. Probably you will SSH into it.
Then just cd to the path you want the script to live and do the following...
nano test.sh This opens the nano terminal text editor.
Copy the above test.sh commands, make sure to get the shebang (#!/bin/bash).
Paste the script into the nano editor, you'll need to use ctrl+v or cmd+v.
Hit the key combination of ctrl + o, hit the enter key.
Hit the key combination of ctrl + w. This exits nano. Proceed with the abov instructions.
I suggest you read up on nano so you can get more familiar with its abilities as it can save a lot of time!
I have wrote some script for my VPS and this is a example for Squid3
#!/bin/bash
function add_user () {
while true; do
echo -e "\nInsert a name for the Squid3 user (0=exit): \c"
read utente
case "$utente" in
0)
echo -e "\nGoodbye $USER!\n"
exit 0
;;
*\ *)
echo -e "\nYou can't use spaces in the name!"
sleep 2
continue
;;
*)
break
;;
esac
done
if [ ! -e '/etc/squid3/.passwd' ]; then
sudo htpasswd -c /etc/squid3/.passwd $utente
else
sudo htpasswd /etc/squid3/.passwd $utente
fi
}
function installer () {
sudo apt-get install squid3 apache2-utils -y
sudo bash -c "echo 'here
you
must
paste
your
configuration
file' > /etc/squid3/squid.conf"
sudo service squid3 restart
}
if ! [ "$(sudo which squid3)" ]; then
installer
add_user
else
add_user
fi
First run it install squid3 and apache2-utils (for htpasswd) and after make a new user.
If you run it again you can add more users.

some error with the 'ln' scripts

anybody is familiar with the etcd project? Or we'd better forget the project when talk about this issue. The issue is
$ build
ln: `gopath/src/github.com/coreos/etcd': cannot overwrite directory
when exec the build shell
and the content is:
#!/bin/sh -e
if [ ! -h gopath/src/github.com/coreos/etcd ]; then
mkdir -p gopath/src/github.com/coreos/
ln -s ../../../.. gopath/src/github.com/coreos/etcd
fi
export GOBIN=${PWD}/bin
export GOPATH=${PWD}/gopath
export GOFMTPATH="./bench ./config ./discovery ./etcd ./error ./http ./log main.go ./metrics ./mod ./server ./store ./tests"
# Don't surprise user by formatting their codes by stealth
if [ "--fmt" = "$1" ]; then
gofmt -s -w -l $GOFMTPATH
fi
go install github.com/coreos/etcd
go install github.com/coreos/etcd/bench
Some addition:
My system is windows 7
I run the shell on git bash.
issue reproduce:
step1: open the git bash
step2: git clone git#github.com:coreos/etcd.git
step3: cd etcd
step4: build
As mentioned in "Git Bash Shell fails to create symbolic links" (since you are using the script in a git bash on Windows 7)
the ln that shipped with msysGit simply tries to copy its arguments, rather than fiddle with links. This is because links only work (sort of) on NTFS filesystems, and the MSYS team didn't want to reimplement ln.
A workaround is to run mklink from Bash.
This also allows you to create either a Symlink or a Junction.
So 'ln' wouldn't work as expected by default, in the old shell that ships with Git for Windows.
Here's solution. Tbh it is a workaround, but since you're on Windows, I don't see another way.
Start a command line, and enter there to the directory with the script. There should be a path gopath/src/github.com/coreos/ (if no such a path, you must create it). Next issue a command
mklink /D "gopath/src/github.com/coreos/etcd" "../../../../"
Next you should edit the build script to delete a lines with creation symlink and a directory. E.g.
#!/bin/sh -e
export GOBIN=${PWD}/bin
export GOPATH=${PWD}/gopath
export GOFMTPATH="./bench ./config ./discovery ./etcd ./error ./http ./log main.go ./metrics ./mod ./server ./store ./tests"
# Don't surprise user by formatting their codes by stealth
if [ "--fmt" = "$1" ]; then
gofmt -s -w -l $GOFMTPATH
fi
go install github.com/coreos/etcd
go install github.com/coreos/etcd/bench
Note, that I am just removed 4 lines of code. Next you run the script, and this should work.
You shouldn't be using git clone and the build sh script. Use the go get command. For example, on Windows 7,
Microsoft Windows [Version 6.1.7601]
C:\>set gopath
GOPATH=C:\gopath
C:\>go version
go version go1.3 windows/amd64
C:\>go get -v -u github.com/coreos/etcd
github.com/coreos/etcd (download)
github.com/coreos/etcd/third_party/bitbucket.org/kardianos/osext
github.com/coreos/etcd/pkg/strings
github.com/coreos/etcd/error
github.com/coreos/etcd/third_party/github.com/coreos/go-etcd/etcd
github.com/coreos/etcd/http
github.com/coreos/etcd/third_party/github.com/coreos/go-log/log
github.com/coreos/etcd/third_party/github.com/rcrowley/go-metrics
github.com/coreos/etcd/mod/dashboard/resources
github.com/coreos/etcd/log
github.com/coreos/etcd/third_party/github.com/gorilla/context
github.com/coreos/etcd/third_party/github.com/gorilla/mux
github.com/coreos/etcd/mod/dashboard
github.com/coreos/etcd/discovery
github.com/coreos/etcd/pkg/btrfs
github.com/coreos/etcd/pkg/http
github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto
github.com/coreos/etcd/mod/leader/v2
github.com/coreos/etcd/mod/lock/v2
github.com/coreos/etcd/metrics
github.com/coreos/etcd/third_party/github.com/mreiferson/go-httpclient
github.com/coreos/etcd/mod
github.com/coreos/etcd/third_party/github.com/BurntSushi/toml
github.com/coreos/etcd/third_party/github.com/goraft/raft/protobuf
github.com/coreos/etcd/third_party/github.com/goraft/raft
github.com/coreos/etcd/store
github.com/coreos/etcd/server/v1
github.com/coreos/etcd/server/v2
github.com/coreos/etcd/store/v2
github.com/coreos/etcd/server
github.com/coreos/etcd/config
github.com/coreos/etcd/etcd
github.com/coreos/etcd
C:\>

Resources