#!/bin/bash ####################################################################### #Script Name: da_setup_bsd.sh #Version: 1.6 #Description: Wrapper for installing Da server #Last Modify Date: 03102021 #Author:Brent Dacus #Email:brent[at]thedacus[dot]net ####################################################################### # Banner # ####################################################################### export COLUMNS=100 dsksetup_banner() { cat <<"eot" ad88888a d8" "8b ,d DdadPPYba, Y8, 88 HH 8b ,adPPYba, `Y8aaaaa, ,adPPYba, MM88MMM 88 88 8b,dPPYba, a8 44 a8P_____88 `"""""8b, a8P_____88 88 88 88 88P' "8a 8b 55 8PP""""""" `8b 8PP""""""" 88 88 88 88 d8 D8 aa "8b, ,aa Y8a a8P "8b, ,aa 88, "8a, ,a88 88b, ,a8" TTTYbbd8"' `"Ybbd8"' "Y88888P" `"Ybbd8"' "Y888 `"YbbdP'Y8 88`YbbdP"' 88 88 eot cat <<"eot" Author: Brent Dacus eot } ####################################################################### # Variables # ####################################################################### cur_hostname="$(hostname)" serverip="$(ifconfig | grep -E 'inet.[0-9]' | grep -v '127.0.0.1' | awk 'NR==1{ print $2}')" serverip6="$(ifconfig | grep -E 'inet6.[0-9]' | grep -v '127.0.0.1' | awk 'NR==1{ print $2}')" servername="$(hostname -s)" svrdomainname="$(hostname -d)" admuser=bdacus01 os=$(uname) vn=$(freebsd-version -u | tr -s '0-9.' | cut -d \. -f1) pvn=$(freebsd-version -u | cut -d - -f3) prvn=$(freebsd-version -u | cut -d - -f1) logfile=/root/install.log builddir=~/dsktpsetup/ usrdir=/usr/local/ usetcdir=/usr/local/etc/ rcconf=/etc/rc.conf ldrconf=/boot/loader.conf random_pass=$(pwgen -nys 10 1) ####################################################################### # Main Util Functions # ####################################################################### mkdir -p ~/dsktpsetup/ trap '' 2 # ignore ctrl+c ##set PS3 prompt## PS3="Number selection? " linebreak() { printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - } do_install() { printf "Installing %s into %s.\n" "${1}" "${dir}" cd "${dir}" || exit if [ -f "${1}" ]; then rm -f "${1}.bak" cp -f "${1}" "${1}.bak" chmod 600 "${1}.bak" fi wget --no-check-certificate -q -O "${1}" "${2}" chmod 644 "${1}" chown diradmin:diradmin "${1}" } do_setting() { printf "Installing value %s into %s.\n" "${1}" "${2}" printf 'Backing up original file %s.\n' "${2}" if [ -f "${2}" ]; then rm -f "${2}.bak" cp -f "${2}" "${2}.bak" chmod 600 "${2}.bak" fi printf 'Adding values in to %s.\n' "${2}" if ! grep -q '#added by DH.' "${2}"; then echo '#added by DH.' >>"${2}" fi if grep -q "${1}" "${2}"; then printf '%s exists.\n Skipping.\n' "${1}" else printf '%s does not exist\n' "$1" echo "$1" >>"${2}" fi } doreboot() { printf "Need to reboot? (y/n)? " read -r yn yn=${yn:-n} case $yn in [Yy]*) reboot ;; [Nn]*) ;; esac } ####################################################################### # Add Admin User # ####################################################################### addadminuser() { printf "Installing Standard packages.\n" printf "Please Wait.\n" pkg install -y doas python38 beadm curl nano bash x86info devcpu-data pwgen wget >/dev/null printf "Add an admin user? Enter username [bdacus01]:" read -r admuser admuser=${admuser:-bdacus01} grep -E "^$admuser\b" /etc/passwd >/dev/null if [ $? -eq 0 ]; then printf "User found: %s\n" "$admuser" else echo "$random_pass" | pw user add "$admuser" -m -s /bin/tcsh -G wheel -h 0 echo "Created admin user" "$admuser" "with" "$(random_pass)" "." echo "$random_pass" >/home/"$admuser"/pass.txt fi printf "Done.\n" grep -q "#User Config" /home/"$admuser"/.cshrc # if not then create it if [ $? -ne 0 ]; then printf 'C shell profile not setup for %s. adding...\n' "$admuser" sed -i -e 's/.*EDITOR.*/setenv EDITOR nano/g' /home/"$admuser"/.cshrc cat <<"eol" >>/home/"$admuser"/.cshrc #User Config alias rm rm -i alias cp cp -i alias mv mv -i alias df df -achT alias usrdir cd /usr/local/ alias uetc cd /usr/local/etc/ alias etc cd /etc/ set rcf = /etc/rc.conf set ldrf = /boot/loader.conf alias la ls -abFG alias lc ls -bCG alias ll ls -abhlG alias lr ls -bRG alias lh 'history |grep ' alias search 'find / -name ' alias doansible cd /home/bdacus01/ansible/ eol printf "Print Profile File.\n" cat /home/"$admuser"/.cshrc printf "Done." else printf "Profile already setup for %s.\n" "$admuser" fi printf 'Shell profile not set up. adding Editor...\n' printf "EDITOR=nano\nexport EDITOR\n" | tee -a /home/"$admuser"/.profile grep -q "#Root Config" /root/.cshrc # if not then create it if [ $? -ne 0 ]; then printf 'C shell profile not setup for Root. adding...\n' sed -i -e 's/.*EDITOR.*/setenv EDITOR nano/g' /root/.cshrc cat <<"eol" >>/root/.cshrc #Root Config alias rm rm -i alias cp cp -i alias mv mv -i alias df df -achT alias usrdir cd /usr/local/ alias uetc cd /usr/local/etc/ alias etc cd /etc/ set rcf = /etc/rc.conf set ldrf = /boot/loader.conf alias la ls -abFG alias lc ls -bCG alias ll ls -abhlG alias lr ls -bRG alias lh 'history |grep ' alias search 'find / -name ' alias top top -P alias dodesk 'curl -o dsktp_setup_bsd.sh -L https://files.delaintech.com/dsktp_setup_bsd.sh && bash dsktp_setup_bsd.sh' eol printf "Print Profile File.\n" cat /root/.cshrc printf "Done.\n" else printf "Profile already setup for Root.\n" fi printf 'Shell profile not set up. adding Editor...\n' printf "EDITOR=nano\nexport EDITOR\n" | tee -a /root/.profile } ####################################################################### # Set Timezone # ####################################################################### settimezone() { printf "What TimeZone are you in? [America/Chicago]: " read -r tmzone tmzone=${tmzone:-America/Chicago} if grep -E "^$tmzone" /var/db/zoneinfo >/dev/null; then printf "%s found\n" "$tmzone" else tzsetup "$tmzone" fi printf "We set timezone as: " cat /var/db/zoneinfo printf "Done.\n" } ####################################################################### # Add Hosts file # ####################################################################### creathostfile() { # does the Host already exist? if ! grep -q "${svrdomainname}" /etc/hosts; then printf 'Hostfile not found. adding...\n' cat <<"eol" >>/etc/hosts 209.126.81.64 apollo.delainhosting.com apollo 209.145.52.110 athena.delainhosting.com athena 144.91.108.77 thor.delainhosting.com thor 154.12.224.183 saturn.delainhosting.com saturn eol printf "Print Host File.\n" cat /etc/hosts printf "Done.\n" else printf "Hostfile exsits.\nSee Below.\n" cat /etc/hosts fi } ####################################################################### # Set Server Hostname # ####################################################################### creathostname() { # does the Host alreadry exist? unset new_hostname printf "Please enter a Hostname to add: " read -r new_hostname if ! grep -q "$new_hostname" /etc/rc.conf >/dev/null; then printf 'Hostname not found. adding...\n' printf "Changing hostname %s from to %s...\n" "$cur_hostname" "$new_hostname" sysrc hostname="$new_hostname" servername="${new_hostname}" | cut -d "." -f1 echo "${servername}" echo "${serverip} ${new_hostname} ${servername}" >>/etc/hosts echo "${serverip6} ${new_hostname} ${servername}" >>/etc/hosts printf "Print Host File.\n" cat /etc/hosts printf "Done.\n" else printf "Hostname exsits.\nAll good.\n" fi } ####################################################################### # Add External Hosts # ####################################################################### creathostentry() { # does the Host already exist? unset serverip add_hostname servername printf "Enter Hostname to add:[ IP FDQN Hostname ]: " read -r serverip add_hostname servername if ! grep -q "$add_hostname" /etc/hosts; then printf 'Hostname not found. adding...\n' echo "${serverip} ${add_hostname} ${servername}" >>/etc/hosts echo "${serverip6} ${add_hostname} ${servername}" >>/etc/hosts printf "Print Host File.\n" cat /etc/hosts printf "Done.\n" else printf "Hostname exsits.\nAll good.\n" fi while true; do printf "Continue adding? (y/n)?" read -r yn yn=${yn:-n} case $yn in [Yy]*) creathostentry break ;; [Nn]*) break ;; esac done } ####################################################################### # Remove Hostnames # ####################################################################### removehosts() { printf "Here is the Host file.\n" cat /etc/hosts printf "What is the server name or ip to remove?" read -r removehosts sed -i.bkp '/'$removehosts'/d ' /etc/hosts printf "Print Host.\n" cat /etc/hosts printf "Done.\n" while true; do printf "Continue removing? (y/n)?" read -r yn yn=${yn:-n} case $yn in [Yy]*) removehosts break ;; [Nn]*) break ;; esac done } ####################################################################### # Add Swapfile # ####################################################################### creatswapfile() { printf 'Enter Swapfile size in GB: ' read -r swapsize swapsize=${swapsize:-2} printf "You choose %s GB for swap.\n" "$swapsize" # does the swap file already exist? cp /etc/fstab /etc/fstab.bak # if not then create it if ! grep -q "swap" /etc/fstab; then printf 'Swap file not found.\nCreating Swap file.\n' truncate -s "${swapsize}"G /swapfile chmod 0600 /swapfile swapon -aq printf "md99 none swap sw,file=/swapfile,late 0 0" | tee -a /etc/fstab swapon -aqL swapinfo -g printf "Done Swap should be active.\nIf not reboot.\n" else printf 'Swap file found.\nNo changes made.\n' fi } ####################################################################### # Update OS on Server # ####################################################################### serverupdate() { printf "Do we need to do a release update? (y/n)? " read -r yn yn=${yn:-n} case $yn in [Yy]*) printf "Release to move to? 13.0-RELEASE: " read -r bsdrelease freebsd-update upgrade -r "$bsdrelease" printf "Updating FreeBSD.\nHold Please.\n" freebsd-update install doreboot ;; [Nn]*) ;; esac printf "Post reboot run update install? (y/n)? " read -r yn yn=${yn:-n} case $yn in [Yy]*) printf "Updating FreeBSD.\nHold Please.\n" freebsd-update install pkg bootstrap -f ;; [Nn]*) ;; esac printf "FreeBSD Cleaning and Updating.\n" pkg autoremove ${pkgargs} >/dev/null pkg clean -a ${pkgargs} >/dev/null printf "Done.\n" printf "Updating FreeBSD.\nHold Please.\n" freebsd-update fetch install doreboot printf "Updating All Packages.\n" mkdir -p /usr/local/etc/pkg/repos cp /etc/pkg/FreeBSD.conf /usr/local/etc/pkg/repos/FreeBSD.conf sed -i -e 's/quarterly/latest/g' /usr/local/etc/pkg/repos/FreeBSD.conf pkg update -f && pkg upgrade ${pkgargs} >/dev/null printf "Done.\n" } ####################################################################### # Harden Server # ####################################################################### hardenserver() { printf "Do we need to Secure sshd? (y/n)? " read -r yn yn=${yn:-n} case $yn in [Yy]*) cursshport="$(grep -m1 -E "Port .*" /etc/ssh/sshd_config)" printf "Enter SSH port to change to:" read -r sshport sshport=${sshport:-14} printf "Set to Port: %s\n" "$sshport" printf "Securing the server, please wait...\n" sed -i -e "s/$cursshport/Port ${sshport}/g" /etc/ssh/sshd_config sed -i -e 's/.*UseDNS .*/UseDNS no/g' /etc/ssh/sshd_config sed -i -e 's/.*AddressFamily any/AddressFamily inet/g' /etc/ssh/sshd_config sed -i -e 's/.*LoginGraceTime .*/LoginGraceTime 2m/g' /etc/ssh/sshd_config sed -i -e 's/.*MaxAuthTries .*/MaxAuthTries 3/g' /etc/ssh/sshd_config sed -i -e 's/.*MaxStartups .*/MaxStartups 10:30:100/g' /etc/ssh/sshd_config sed -i -e 's/.*PermitRootLogin yes/PermitRootLogin prohibit-password/g' /etc/ssh/sshd_config sed -i -e 's/.*PasswordAuthentication .*/PasswordAuthentication no/g' /etc/ssh/sshd_config sed -i -e 's/.*ClientAliveInterval .*/ClientAliveInterval 120/g' /etc/ssh/sshd_config sed -i -e 's/.*ClientAliveCountMax .*/ClientAliveCountMax 4/g' /etc/ssh/sshd_config sed -i -e 's/.*UseBlacklist no/UseBlacklist yes/g' /etc/ssh/sshd_config sed -i -e 's/.*AllowTcpForwarding .*/AllowTcpForwarding no/g' /etc/ssh/sshd_config sed -i -e 's/.*Compression .*/Compression no/g' /etc/ssh/sshd_config sed -i -e 's/.*AllowAgentForwarding yes/AllowAgentForwarding no/g' /etc/ssh/sshd_config sed -i -e 's/.*X11Forwarding yes/X11Forwarding no/g' /etc/ssh/sshd_config # remove or disable services sysrc rpcbind_enable="NO" service rpcbind onestop service rpcbind onedisable service sshd restart ;; [Nn]*) ;; esac printf "Do we need to Secure TMP? (y/n)? " read -r yn yn=${yn:-n} case $yn in [Yy]*) if ! grep -q 'zfs_enable="YES"' /etc/rc.conf; then printf 'Filesystem UFS.\n' filesys="ufs" else printf 'Filesystem ZFS.\n' filesys="zfs" fi case $filesys in "zfs") if ! grep -q "tmpfs" /etc/fstab; then printf 'tmpfs file not found.\nCreating tmp file.\n' sysrc tmpfs_load="YES" umount -f zroot/tmp zfs set mountpoint=none zroot/tmp umount -f zroot/var/tmp zfs set mountpoint=none zroot/var/tmp rm -rf /tmp mkdir /tmp rm -rf /var/tmp mkdir /var/tmp mount -t tmpfs -o rw,nosuid,noexec,mode=01777 tmpfs /tmp mount -t tmpfs -o rw,nosuid,noexec,mode=01777 tmpfs /var/tmp echo "tmpfs /tmp tmpfs rw,nosuid,noexec,mode=01777 0 0" | tee -a /etc/fstab echo "tmpfs /var/tmp tmpfs rw,nosuid,noexec,mode=01777 0 0" | tee -a /etc/fstab zfs destroy zroot/tmp zfs destroy zroot/var/tmp printf "Done tmp and /var/tmp should be active and secure. ZFS filesystem removed.\nIf not reboot.\n" else printf 'tmp file found.\nNo changes made.\n' fi ;; "ufs") if ! grep -q "tmpfs" /etc/fstab; then printf 'tmpfs file not found.\nCreating tmp file.\n' sysrc tmpfs_load="YES" umount -f /tmp umount -f /var/tmp rm -rf /tmp mkdir /tmp rm -rf /var/tmp mkdir /var/tmp mount -t tmpfs -o rw,nosuid,noexec,mode=01777 tmpfs /tmp mount -t tmpfs -o rw,nosuid,noexec,mode=01777 tmpfs /var/tmp echo "tmpfs /tmp tmpfs rw,nosuid,noexec,mode=01777 0 0" | tee -a /etc/fstab echo "tmpfs /var/tmp tmpfs rw,nosuid,noexec,mode=01777 0 0" | tee -a /etc/fstab printf "Done tmp and /var.tmp should be active and secure. UFS filesystem removed.\nIf not reboot.\n" else printf 'tmp file found.\nNo changes made.\n' fi ;; *) printf 'Not sure of filesystem.\nNo changes made.\n' ;; esac ;; [Nn]*) ;; esac } ####################################################################### # Install Firewall # ####################################################################### installfirewall() { pkg install ${pkgargs} pftop touch /usr/local/etc/whitelist_ips echo "99.34.232.208" >/usr/local/etc/whitelist_ips echo "127.0.0.1" >>/usr/local/etc/whitelist_ips echo "$serverip" >>/usr/local/etc/whitelist_ips touch /usr/local/etc/blocked_ips printf "Securing the server, please wait...\n" wget -rnH --cut-dirs=2 http://files.delaintech.com/bsd/pf/pf.conf -P /etc/ >>${logfile} wget -rnH --cut-dirs=2 http://files.delaintech.com/bsd/pf/pfloadtable.sh -P /usr/local/bin/ >>${logfile} chmod 755 /usr/local/bin/pfloadtable.sh wget -rnH --cut-dirs=2 http://files.delaintech.com/bsd/pf/pfloadabipdb.sh -P /usr/local/bin/ >>${logfile} chmod 755 /usr/local/bin/pfloadabipdb.sh wget -rnH --cut-dirs=2 http://files.delaintech.com/bsd/pf/pfloadcountry.sh -P /usr/local/bin/ >>${logfile} chmod 755 /usr/local/bin/pfloadcountry.sh cronline0="#pf jobs" ( crontab -l 2>/dev/null echo "$cronline0" ) | sort - | uniq - | crontab - cronline1="@reboot /usr/local/bin/pfloadtable.sh" cronline2="@reboot /usr/local/bin/pfloadabipdb.sh" cronline3="@reboot /usr/local/bin/pfloadcountry.sh" cronline4="0 0 * * * /sbin/pfctl -t bruteforce -T expire 432000" cronline5="0 1 * * * /usr/local/bin/pfloadabipdb.sh" cronline6="0 1 * * * /usr/local/bin/pfloadcountry.sh" crontab -l | sed -e '/^#pf jobs/a\ '"$cronline1" | sort - | uniq - | crontab - crontab -l | sed -e '/^#pf jobs/a\ '"$cronline2" | sort - | uniq - | crontab - crontab -l | sed -e '/^#pf jobs/a\ '"$cronline3" | sort - | uniq - | crontab - crontab -l | sed -e '/^#pf jobs/a\ '"$cronline4" | sort - | uniq - | crontab - crontab -l | sed -e '/^#pf jobs/a\ '"$cronline5" | sort - | uniq - | crontab - crontab -l | sed -e '/^#pf jobs/a\ '"$cronline6" | sort - | uniq - | crontab - service cron restart wget -rnH --cut-dirs=2 http://files.delaintech.com/bsd/pf/blacklistd.conf -P /etc/ >>${logfile} sysrc firewall_enable="NO" sysrc blacklistd_enable="YES" sysrc pf_enable="YES" sysrc pf_rules="/etc/pf.conf" sysrc pflog_enable="YES" sysrc pflog_logfile="/var/log/pflog" sysrc sendmail_enable="NO" sysrc sendmail_submit_enable="NO" sysrc sendmail_outbound_enable="NO" sysrc sendmail_msp_queue_enable="NO" pfctl -nf /etc/pf.conf kldload -n pf kldstat -h service ipfw onestop doreboot } ####################################################################### # Install Standard Packages # ####################################################################### installpreq() { printf 'Setting up DOAS file.\n' if ! grep -q "#DH doas file setup" /usr/local/etc/doas.conf; then cp /usr/local/etc/doas.conf.sample /usr/local/etc/doas.conf do_setting "permit nopass :wheel as root" "/usr/local/etc/doas.conf" do_setting "permit nopass $admuser as root" "/usr/local/etc/doas.conf" printf 'Done.\n' fi printf 'Setting admin groups.\n' pw groupmod wheel -m "$admuser" pw groupmod operator -m "$admuser" pw groupmod network -m "$admuser" do_setting 'autoboot_delay="3"' "$ldrconf" do_setting 'boot_mute="YES"' "$ldrconf" do_setting 'kern.vty=vt' "$ldrconf" do_setting 'kern.vt.fb.default_mode="1280x720"' "$ldrconf" do_setting 'kern.ipc.shmseg=1024' "$ldrconf" do_setting 'kern.ipc.shmmni=1024' "$ldrconf" do_setting 'kern.maxproc=100000' "$ldrconf" do_setting 'hw.ata.atapi_dma="1"' "$ldrconf" do_setting 'aio_load="YES"' "$ldrconf" do_setting 'ahci_load="YES"' "$ldrconf" do_setting 'atapicam_load="YES"' "$ldrconf" do_setting 'tmpfs_load="YES"' "$ldrconf" do_setting 'coretemp_load="YES"' "$ldrconf" do_setting 'cpu_microcode_load="YES"' "$ldrconf" do_setting 'cpu_microcode_name="/boot/firmware/intel-ucode.bin"' "$ldrconf" printf 'Creating boot env.\n Please wait.\n' if beadm list | grep -q factory"$prvn"; then printf 'Exists. Skipping.\n' else printf 'Does not exist\n' beadm create factory"$prvn" printf 'Added. factory%s.\n' "$prvn" fi if beadm list | grep -q "desktop"$prvn" NR"; then printf 'Desktop BE is already Active.\n Skipping.\n' else printf 'Activating BE.\n' beadm activate factory"$prvn" printf 'Added. factory%s.\nYou might need to reboot.\n' "$prvn" doreboot fi } ####################################################################### # Install Desktop # ####################################################################### installdesktop() { printf 'Creating boot env.\n Please wait.\n' if beadm list | grep -q desktop"$prvn"; then printf 'Exists. Skipping.\n' else printf 'Does not exist\n' beadm create desktop"$prvn" printf 'Added. desktop%s.\n' "$prvn" fi if beadm list | grep -q "desktop"$prvn" NR"; then printf 'Desktop BE is already Active.\n Skipping.\n' else printf 'Activating BE.\n' beadm activate desktop"$prvn" printf 'Activated desktop%s.\nYou might need to reboot.\n' "$prvn" doreboot fi printf "Installing Desktop packages.\n" printf "Please Wait.\n" pkg install -y xorg kde5 plasma5-plasma sddm drm-kmod plasma5-sddm-kcm cups screen rsync filezilla vscode remmina cdrtools dvd+rw-tools \ fusefs-ntfs printf "Done.\n" printf "Install Ansible? (yn)" read -r yn yn=${yn:-n} case $yn in [Yy]*) printf 'Installing Ansible.\n' pkg install -y py38-ansible virtualbox-ose virtualbox-ose-additions vagrant do_setting 'vboxdrv_enable="YES"' "$ldrconf" pw groupmod vboxusers -m "$admuser" pw groupmod operator -m "$admuser" sysrc vboxnet_enable="YES" sysrc vboxguest_enable="YES" sysrc vboxservice_enable="YES" mkdir -p /usr/local/etc/ansible cp /usr/local/etc/ansible/hosts /usr/local/etc/ansible/hosts.bak cp /usr/local/etc/ansible/ansible.cfg /usr/local/etc/ansible/ansible.cfg.bak cp /usr/local/share/examples/py38-ansible-core/hosts /usr/local/etc/ansible cp /usr/local/share/examples/py38-ansible-core/ansible.cfg /usr/local/etc/ansible mkdir -p /home/"${admuser}"/ansible/{bsd/dns,deb/{da,vrtm},adhoc/{bsd,deb}} chown -R "${admuser}":"${admuser}" /home/"${admuser}"/ansible ;; [Nn]*) ;; esac } ####################################################################### # Main Configure Section # ####################################################################### ####################################################################### # Configure Desktop # ####################################################################### confdesktop() { sysrc dbus_enable="YES" && service dbus start sysrc sddm_enable="YES" && service sddm start sysrc kld_list="amdgpu coretemp fusefs" pw groupmod video -m "$admuser" } ####################################################################### # Configure DNS # ####################################################################### confresolver() { printf "Setup Resolver configuration.\n" if ! grep -q "192.168.59.1" /etc/resolv.conf; then cat >/etc/resolv.conf <&1 if [ "$os" = "FreeBSD" ] && [ "$vn" -gt 12 ]; then printf "System runs on %s version %s patch level %s. Great! Continuing on....\n" "$os" "$prvn" "$pvn" else printf "System runs on unsupported os. Exiting...\n" exit fi #Menus Starts here linebreak cat <&2 ;; esac done done if [ -d "$builddir" ]; then rm -rf $builddir fi mkdir $builddir if [ "$run" ]; then ${run} exit fi printf "Cleaning up build files, please wait...\n" cd ~ || return rm -rf $builddir