Skip to content

Instantly share code, notes, and snippets.

@dnviti
Created December 22, 2021 18:50
Show Gist options
  • Save dnviti/f18b59f20d8735e4de1bacc784692d23 to your computer and use it in GitHub Desktop.
Save dnviti/f18b59f20d8735e4de1bacc784692d23 to your computer and use it in GitHub Desktop.
Almalinux Post Install
#!/bin/bash
#set -o xtrace
if [[ $USER != "root" ]]
then
echo "Script must be run as root"
exit 1
fi
sed -i "s/#Port/Port/g" /etc/ssh/sshd_config
S=$(grep "Port " /etc/ssh/sshd_config)
OLD_SSH_PORT=${S:5:99}
NEW_SSH_PORT=$(( $RANDOM % 999 + 22000 ))
SSH_GW_IP=$(ip route | grep default | awk '{print $3}')
## Use the first sudoer user available post-install
SCRIPT_USER=$(id -nu 1000)
## by default script will not install kubernetes
KUBE_INSTALL="n"
KUBE_MASTER="n"
NETINTERFACE="ens0"
MACHINE_IP=""
DOCKER_DIRECTORY="/docker"
DHCP_FORCE="n"
SSH_CHANGE_PORT="n"
# if no arguments are provided, return usage function
# maybe no need
# if [ $# -eq 0 ]; then
# usage # run usage function
# exit 1
# fi
usage () {
echo "RHEL Docker + Kubernetes Post-Install usage"
echo "----"
echo " Kubernetes Installer:"
echo " -kn | --kube-node -> Install Kubernetes Node"
echo " -km | --kube-master -> Install Kubernetes Master"
echo " -do | --docker-only -> Install Docker Only"
echo "----"
echo " Optional Parameters:"
echo ""
echo " -u -> Specify non-root user to run the script"
echo " -a -> Specify a network gateway address to be used for firewalling purposes"
echo "----"
echo "Version: 0.9.3"
echo "Release Date: 08/12/2021"
echo "Author: dnviti@gmail.com"
}
firewall_rules() {
echo "Selinux setting..."
echo "SSH Port"
semanage port -a -t ssh_port_t -p tcp $NEW_SSH_PORT
firewall-cmd --remove-service=ssh --zone=public --permanent
firewall-cmd --remove-service=cockpit --zone=public --permanent
firewall-cmd --remove-service=dhcpv6-client --zone=public --permanent
firewall-cmd --permanent --zone=work --add-port=$NEW_SSH_PORT/tcp
firewall-cmd --permanent --zone=work --add-source=$NETWORK_IP/24
if [[ $KUBE_INSTALL == "y" || $KUBE_INSTALL == "Y" ]]
then
semanage port -a -t http_port_t -p tcp 8080
semanage port -a -t kubehc1_port_t -p tcp 6443
semanage port -a -t kubehc2_port_t -p tcp 10250
firewall-cmd --add-port=8080/tcp --permanent --zone=work
firewall-cmd --add-port=6443/tcp --permanent --zone=work
firewall-cmd --add-port=10248/tcp --permanent --zone=work
firewall-cmd --add-port=10250/tcp --permanent --zone=work
fi
}
while [ "$1" != "" ]; do
case $1 in
-kn | --kube-node)
shift
KUBE_INSTALL="y"
KUBE_MASTER="n"
if [[ $KUBE_MASTER == "y" || $KUBE_MASTER == "Y" ]]
then
echo "Kubernetes cannot be Master and Node at the same time!"
exit 1
fi
KUBE_MASTER_HOST=$1
echo "Checking Kubernetes Master at $KUBE_MASTER_HOST..."
ping -c 5 $KUBE_MASTER_HOST &> /dev/null
PING_ERR=$?
echo "Ping Error: $PING_ERR"
if [[ $PING_ERR == 0 ]]
then
echo "Host Succesfully Found at $KUBE_MASTER_HOST"
echo "Kubernetes Node installation configuration successfull"
else
echo "Error! Cannot enstablish a stable connection to the Kubernetes Master at $KUBE_MASTER_HOST"
echo "Exiting Script with error $PING_ERR"
KUBE_INSTALL="n"
exit 1
fi
rm -f kubecheck.log
echo "Checking Kubernetes Master Health Check..."
curl -k https://$KUBE_MASTER_HOST:6443/livez?verbose -o kubecheck.log
KUBECHECK_RESULT=$(tail -n 1 kubecheck.log)
if [[ KUBECHECK_RESULT == "healthz check passed" ]]
then
echo "Kubernetes Master Health-Check passed..."
echo "Resuming Installation..."
rm -r kubecheck.log
else
echo "Kubernetes Master Health-Check error, see below or kubecheck.log"
echo $(cat kubecheck.log)
echo "Quitting Installation..."
KUBE_INSTALL="n"
exit 1
fi
### To be tested after master installation
;;
-km | --kube-master)
shift
KUBE_INSTALL="y"
KUBE_MASTER="y"
if [[ $KUBE_NODE == "y" || $KUBE_NODE == "Y" ]]
then
echo "Kubernetes cannot be Master and Node at the same time!"
KUBE_INSTALL="n"
KUBE_MASTER="n"
exit 1
fi
;;
-do | --docker-only)
shift
KUBE_INSTALL="n"
KUBE_MASTER="n"
;;
-dd | --docker-directory)
shift
DOCKER_DIRECTORY=$1
;;
-hs | --hostname-change)
shift
HOSTNAME=$1
echo "$HOSTNAME" > /etc/hostname
;;
-u | --user)
shift
## Specify a manual Script user
SCRIPT_USER=$1
## Script User Check
if [[ $SCRIPT_USER == "" ]]
then
echo "No user defined"
exit 1
fi
if id "$SCRIPT_USER" &>/dev/null; then
USER_EXISTS="y"
else
USER_EXISTS="n"
fi
;;
-a | --gateway-address)
shift
## Specify a manual SSH Gateway IP
SSH_GW_IP=$1
;;
-ni | --network-interface)
shift
NETINTERFACE=$1
;;
-fwd | --enable-firewall)
shift
ENABLE_FIREWALL="y"
;;
-dhcp | --force-dhcp-renew)
shift
DHCP_FORCE="y"
;;
-sp | --change-ssh-port)
shift
SSH_CHANGE_PORT="y"
;;
-h | --help)
usage # run usage function
;;
*)
usage
exit 1
;;
esac
shift # remove the current value for '$1' and use the next
done
### START SCRIPT
## For Kubernetes the following link was references (adapted to Red Hat from Debian/Ubuntu)
## https://www.dgline.it/digitalroots/guida-per-la-costruzione-di-un-cluster-kubernetes-con-ubuntu/
## Check if ip and net interface are correct
if [[ $(ip addr | grep $NETINTERFACE) == "" ]]
then
echo "Error: Network interface [$NETINTERFACE] not found."
exit 1
fi
MACHINE_IP=$(ip -4 addr show $NETINTERFACE | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
if [[ $MACHINE_IP == "" ]]
then
echo "IPv4 address not found for interface [$NETINTERFACE]"
exit 1
fi
HOSTNAME=$(cat /etc/hostname)
echo "Hostname is set to: $HOSTNAME"
if [[ $SSH_GW_IP == "" ]]
then
echo "You must enter the Gateway IP to allow connections"
exit 1
fi
## Find network address from gateway
NETWORK_IP=$(awk -F"." '{print $1"."$2"."$3".2"}'<<<$SSH_GW_IP)
if [[ $SCRIPT_USER == "" ]]
then
echo "You must enter a non root user as parameter"
exit 1
fi
if id "$SCRIPT_USER" &>/dev/null; then
USER_EXISTS="y"
else
USER_EXISTS="n"
fi
## Replace current HOME variable with new one for script user selected
HOME="/home/$SCRIPT_USER"
## Adding the new user if not exists
if [[ $USER_EXISTS == "n" ]]
then
read -p "The User specified [$SCRIPT_USER] does not exists, should i create it? (N/y)" CREATE_USER_CHOICE
if [[ $CREATE_USER_CHOICE = "" || $CREATE_USER_CHOICE == "n" || $CREATE_USER_CHOICE == "N" ]]
then
echo "Error: User [$SCRIPT_USER] does not exists and you do not automatically want to create it. Aborting"
exit 1
fi
echo "User $SCRIPT_USER does not exists, adding..."
adduser $SCRIPT_USER
## Create a new home and set permissions
mkdir "$HOME"
chown $SCRIPT_USER:$SCRIPT_USER "$HOME" -R
chmod u+rwx "$HOME" -R
fi
## System Utilities Install
dnf install -y nano ca-certificates curl epel-release policycoreutils-python-utils dhclient
dnf install -y fail2ban fail2ban-firewalld
## Security Prep
## SSH Config
if [[ $SSH_CHANGE_PORT = "y" ]]
then
sed -i "s/Port $OLD_SSH_PORT/Port $NEW_SSH_PORT/g" /etc/ssh/sshd_config
sed -i "s/PermitRootLogin yes/PermitRootLogin no/g" /etc/ssh/sshd_config
else
NEW_SSH_PORT="$OLD_SSH_PORT"
fi
systemctl enable --now firewalld
if [[ $ENABLE_FIREWALL == "y" ]]
then
firewall_rules
systemctl enable --now firewalld
else
echo "Warning! Firewall has been opened to public!"
firewall-cmd --permanent --zone=public --add-port=$NEW_SSH_PORT/tcp
firewall-cmd --permanent --zone=public --set-target=ACCEPT
fi
systemctl enable --now fail2ban
tee -a /etc/fail2ban/jail.conf > /dev/null <<EOT
[ssh]
enabled = true
port = $NEW_SSH_PORT
filter = sshd
logpath = /var/log/auth.log
EOT
## Forza DHCP
if [[ $DHCP_FORCE == "y" ]]
then
dhclient -v
fi
## Docker Install
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
dnf remove podman buildah
dnf install -y docker-ce docker-ce-cli containerd.io
usermod -aG docker $SCRIPT_USER
curl -L "https://github.com/docker/compose/releases/download/v2.1.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
## Install Docker 2 Retro-Compatibility Command (Compose Switch)
curl -fL https://raw.githubusercontent.com/docker/compose-cli/main/scripts/install/install_linux.sh | sh
## Docker Post-Install
groupadd docker
usermod -aG docker $SCRIPT_USER
install -d -m 0755 -o $SCRIPT_USER -g docker "$DOCKER_DIRECTORY"
sed '/ExecStart=\/usr\/bin\/dockerd -H fd:\/\/ --containerd=\/run\/containerd\/containerd.sock/ s/$/ --exec-opt native.cgroupdriver=systemd/' /lib/systemd/system/docker.service
systemctl enable --now docker.service
## Install Kubernetes
if [[ $KUBE_INSTALL == "y" || $KUBE_INSTALL == "Y" ]]
then
## Prepare repository
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
## Prepare docker configuration
mkdir /etc/docker
cat <<EOF | sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
## Installing Kubernetes Tools
dnf install -y kubeadm kubectl kubelet
## start and enable kubelet service
systemctl enable kubelet.service
systemctl start kubelet.service
## Disable SWAP
sudo swapoff -a
## also disable permanently
SWAP_LINE=$(tail -n 1 /etc/fstab)
sed "s/$SWAP_LINE/#$SWAP_LINE/" /etc/fstab
if [[ $KUBE_MASTER == "y" || $KUBE_MASTER == "Y" ]]
then
kubeadm reset -f
kubeadm init
echo "Kubernetes Master initialized, see kubemaster.log for additional information"
cp /etc/kubernetes/admin.conf $HOME/
chown $(id -u):$(id -g) $HOME/admin.conf
export KUBECONFIG=$HOME/admin.conf
echo "export KUBECONFIG=$HOME/admin.conf" | tee -a ~/.bashrc
## First POD Installation
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/k8s-manifests/kube-flannel-rbac.yml
kubectl get pods -all-namespaces
## Master can join itself
# kubectl taint nodes –all node-role.kubernetes.io/master-
fi
fi
NEW_SCRIPT_USER_PASSWORD=$(tr -cd "[:alnum:]" < /dev/urandom | fold -w32 | head -n 1)
NEW_ROOT_PASSWORD=$(tr -cd "[:alnum:]" < /dev/urandom | fold -w32 | head -n 1)
echo "Setting secure password for user $SCRIPT_USER"
echo "$SCRIPT_USER:$NEW_SCRIPT_USER_PASSWORD"|chpasswd
echo "Setting secure password for user root"
echo "root:$NEW_ROOT_PASSWORD"|chpasswd
echo "Script end - User Information"
## User Output
echo "New $SCRIPT_USER password is: $NEW_SCRIPT_USER_PASSWORD"
echo "New root password is: $NEW_ROOT_PASSWORD"
echo "Connect via SSH: ssh $SCRIPT_USER@$MACHINE_IP -p $NEW_SSH_PORT"
echo "Warning! System will be restarted, please save all the info before"
read -p "Press [Enter] to reboot system"
reboot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment