#!/usr/bin/bash ####################################################################### #Script Name: pdns_master_bsd.sh #Version: 1.6 #Description: Install for PowerDNS on FreeBSD #Last Modify Date: 09242021 #Author:Brent Dacus #Email:brent[at]thedacus[dot]net ####################################################################### # Banner # ####################################################################### export COLUMNS=100 nssetupdeb_banner() { cat <<"eot" ad8888ba d8" "8b ,aiiiiia, ,d nnd8888bn Y8, 6' " 88 ns 'we `Y8aaaaa, `8aaaa, ,adPPYba, MM88MMM 88 88 8b,dPPYba, ns we `"""""8b, `"8b, a8P_____88 88 88 88 88P' "8a ns we `8b `8b 8PP""""""" 88 88 88 88 d8 ns we '8a a8P Y8a a8P "8b, ,aa 88, "8a, ,a88 88b, ,a8" ns we "Y88888P" `"YbbdP' `"Ybbd8"' "Y888 `"YbbdP'Y8 88`YbbdP"' 88 88 eot cat <<"eot" MASTER DNS SERVER 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}')" servername="$(hostname -s)" os=$(uname) vn=$(freebsd-version -u | tr -s '0-9.' | cut -d \. -f1) pvn=$(freebsd-version -u | tr -s '0-9.' | cut -d - -f3) prvn=$(freebsd-version -u | tr -s '0-9.' | cut -d - -f1) # -----------------------------------# # Declare vars. # # -----------------------------------# ilog=/root/install.log pkgargs="-y" builddir=~/nssetupdebbuild/ # -----------------------------------# # User Vars Set these to your values # # -----------------------------------# swapsize=2 sshport=22 tmzone="America/Chicago" svrdomainname="delainhosting.com" db_root_user=root db_root_pass="G@ndalf69" db_user=pdns_usr db_usr_pass="w5pPuAuB8TS" rcconf=/etc/rc.conf ldrconf=/boot/loader.conf ####################################################################### # Main # ####################################################################### trap '' 2 # ignore ctrl+c ##set PS3 prompt## PS3="Number selection? " linebreak() { printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - } random_pass() { rpc=${1:-$(perl -le 'print int rand(7) + 10')} tr -cd 'a-za-z0-9' /dev/null | head -c${rpc} # perl generates a random integer between 10 and 16 } doreboot() { printf "Need to reboot? (y/n)? " read -r yn yn=${yn:-n} case $yn in [Yy]*) reboot ;; [Nn]*) ;; esac } # ------------------------------------------------------------------------------# # Install Functions # # ------------------------------------------------------------------------------# addadminuser() { printf "Installing Standard packages.\n" printf "Please Wait.\n" pkg install -y doas python38 beadm curl nano bash x86info devcpu-data >/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 printf "Done.\n" fi grep -E "#User Config" /home/"$admuser"/.cshrc >/dev/null # if not then create it if [ $? -ne 0 ]; then printf 'C shell profile not set up. adding...\n' #-----------------------------------------------------------------------------# # Set your hostfile info inside the eol # #---------------------------------------------------------------------------- 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 lh 'history |grep ' alias la ls -abFG alias lc ls -bCG alias ll ls -abhlG alias lr ls -bRG alias doserver 'curl -o pdns_master_bsd.sh -L https://files.delaintech.com/dns/pdns_master_bsd.sh && bash pdns_master_bsd.sh' eol printf "Profile File for %s. See Below.\n" "$admuser" linebreak cat /home/"$admuser"/.cshrc else printf "Profile already setup for %s. See Below.\n" "$admuser" linebreak cat /home/"$admuser"/.cshrc fi grep -q "#User Root Config" /root/.cshrc # if not then create it if [ $? -ne 0 ]; then printf 'Root C shell profile not set up. adding...\n' #-----------------------------------------------------------------------------# # Set your hostfile info inside the eol # #---------------------------------------------------------------------------- sed -i -e 's/.*EDITOR.*/setenv EDITOR nano/g' /root/.cshrc cat <<"eol" >>/root/.cshrc #User Root Config alias rm rm -i alias cp cp -i alias mv mv -i alias df df -achT alias lh 'history |grep ' alias la ls -abFG alias lc ls -bCG alias ll ls -abhlG alias lr ls -bRG alias doserver 'curl -o pdns_master_bsd.sh -L https://files.delaintech.com/pdns_master_bsd.sh && bash pdns_master_bsd.sh' eol printf "Profile File for Root.\n" linebreak cat /root/.cshrc else printf "Profile already setup for Root. See Below.\n" linebreak cat /root/.cshrc printf "\n" fi printf "Set shell as sh for Root. See Below.\n" pw user mod root -s /bin/csh linebreak pw user show root } settimezone() { printf "What TimeZone are you in? [America/Chicago]: " read -r tmzone tmzone=${tmzone:-America/Chicago} grep -E "^$tmzone" /var/db/zoneinfo >/dev/null if [ $? -eq 0 ]; then printf "%s found\n" "$tmzone" else tzsetup "$tmzone" fi printf "We set timezone as: " cat /var/db/zoneinfo printf "Done.\n" } creathostfile() { # does the Host already exist? grep -q ${svrdomainname} /etc/hosts # if not then create it if [ $? -ne 0 ]; then printf 'Hostfile not found. adding...\n' #-----------------------------------------------------------------------------# # Set your hostfile info inside the eol # #---------------------------------------------------------------------------- cat <<"eol" >>/etc/hosts 209.126.81.64 apollo.delainhosting.com apollo 209.145.52.110 athena.delainhosting.com athena 207.244.97.182 thor.delainhosting.com thor 116.202.102.0 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 hostname for Server fdqn.server.net # #-----------------------------------------------------------------------------# creathostname() { # does the Host alreadry exist? unset new_hostname printf "Please enter a Hostname to add: " read -r new_hostname grep -q "$new_hostname" /etc/rc.conf >/dev/null if [ $? -ne 0 ]; then printf 'Hostname not found. adding...\n' printf "Changing hostname %s from to %s...\n" "$cur_hostname" "$new_hostname" sysrc hostname="$new_hostname" serverip="$(ifconfig | grep -E 'inet.[0-9]' | grep -v '127.0.0.1' | awk 'NR==1{ print $2}')" servername="${new_hostname}" | cut -d "." -f1 echo "${servername}" echo "${serverip} ${new_hostname} ${servername}" >>/etc/hosts printf "Print Host File.\n" cat /etc/hosts printf "Done.\n" else printf "Hostname exsits.\nAll good.\n" fi } #-----------------------------------------------------------------------------# # create extra host enties for other servers fdqn.server.net # #-----------------------------------------------------------------------------# 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 grep -q "$add_hostname" /etc/hosts # if not then create it if [ $? -ne 0 ]; then printf 'Hostname not found. adding...\n' echo "${serverip} ${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 } 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 } #-----------------------------------------------------------------------------# # Create Swap file # #-----------------------------------------------------------------------------# 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 grep -q "swap" /etc/fstab if [ $? -ne 0 ]; 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 } 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? 12.2-RELEASE: " read -r bsdrelease freebsd-update upgrade -r $bsdrelease printf "Updating FreeBSD.\nHold Please.\n" freebsd-update install doreboot ;; [Nn]*) ;; esac printf "FreeBSD Cleaning and Updating.\n" pkg autoremove -y >/dev/null pkg clean -a -y >/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 -y >/dev/null printf "Done.\n" } #-----------------------------------------------------------------------------# # Start configuring and hardening here # #-----------------------------------------------------------------------------# 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 2m/LoginGraceTime 2m/g' /etc/ssh/sshd_config sed -i -e 's/#MaxAuthTries 6/MaxAuthTries 5/g' /etc/ssh/sshd_config sed -i -e 's/#MaxStartups 10:30:100/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/.*PubkeyAuthentication .*/PubkeyAuthentication yes/g' /etc/ssh/sshd_config sed -i -e 's/#ClientAliveInterval .*/ClientAliveInterval 120/g' /etc/ssh/sshd_config sed -i -e 's/#ClientAliveCountMax .*/ClientAliveCountMax 15/g' /etc/ssh/sshd_config sed -i -e 's/.*UseBlacklist no/UseBlacklist yes/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]*) grep -q 'zfs_enable="YES"' /etc/rc.conf if [ $? -ne 0 ]; then printf 'Filesystem UFS.\n' filesys="ufs" else printf 'Filesystem ZFS.\n' filesys="zfs" fi case $filesys in "zfs") grep -q "tmpfs" /etc/fstab if [ $? -ne 0 ]; 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") grep -q "tmpfs" /etc/fstab if [ $? -ne 0 ]; 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 printf "Do we need to intall Maldetect? (y/n)? " read -r yn yn=${yn:-n} case $yn in [Yy]*) installmaldetect ;; [Nn]*) ;; esac } installfirewall() { pkg install -y 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 touch /usr/local/etc/blocked_ips printf "Securing the server, please wait...\n" wget -rnH --cut-dirs=3 http://files.delaintech.com/bsd/pf/dns/pf.conf -P /etc/ wget -rnH --cut-dirs=2 http://files.delaintech.com/bsd/pf/pfloadtable.sh -P /usr/local/bin/ chmod 755 /usr/local/bin/pfloadtable.sh wget -rnH --cut-dirs=2 http://files.delaintech.com/bsd/pf/pfloadabipdb.sh -P /usr/local/bin/ chmod 755 /usr/local/bin/pfloadabipdb.sh wget -rnH --cut-dirs=2 http://files.delaintech.com/bsd/pf/pfloadcountry.sh -P /usr/local/bin/ 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 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 pf reload printf "Setup Resolver configuration.\n" grep -q "9.9.9.9" /etc/resolv.conf if [ $? -ne 0 ]; then cat >/etc/resolv.conf </dev/null printf 'Setting up DOAS file.\n' grep -q "#DH doas file setup" /usr/local/etc/doas.conf if [ $? -ne 0 ]; then cp /usr/local/etc/doas.conf.sample /usr/local/etc/doas.conf cat >/usr/local/etc/doas.conf <>${ldrconf} printf '%s\n' "$ldrval" >>${ldrconf} fi done printf 'Setting up Boot Environments.\n' if beadm list | grep -q factory"$prvn"; then printf 'Factory BE Exists. Skipping.\n' else printf 'Factory BE Does not exist\n' beadm create factory"$prvn" printf 'Added. factory%s.\n' "$prvn" fi if beadm list | grep -q "powerdns"$prvn" NR"; then printf 'PowerDNS BE is already Active.\n Skipping.\n' else printf 'Activating BE.\n' beadm activate powerdns"$prvn" printf 'Added. PowerDNS%s.\nYou might need to reboot.\n' "$prvn" doreboot fi } installmaldetect() { cd $builddir || return wget https://www.rfxn.com/downloads/maldetect-current.tar.gz tar -xzf maldetect-*.tar.gz rm -rf maldetect-*.tar.gz cd maldetect* || return sh install.sh #------------------------------------------------------------------------------# # Pull in your conf.maldet here. Change the links. #------------------------------------------------------------------------------# wget https://files.delaintech.com/conf.maldet -O conf.maldet \cp -f conf.maldet /usr/local/maldetect/ maldet -u } installwebmin() { echo "Installing Webmin." if [ -f /var/webmin ]; then echo "Webmin is installed Skipping." else pkg install ${pkgargs} webmin p5-DBD-mysql /usr/local/lib/webmin/setup.sh service webmin enable service webmin start fi } installmariadb() { echo "Installing Mysql 8.0 server." if [ -f /usr/local/etc/mysql/my.cnf ]; then echo "Mysql is installed Skipping." else pkg install ${pkgargs} mysql80-server service mysql-server enable service mysql-server start mysql_secure_installation cp /root/.mysql_secret /root/.mysql_secret.bkp echo "Done." fi echo "Downloading and importing PDNS Database schema..." wget https://files.delaintech.com/mysql_pdns.sql -O mysql_pdns.sql >>${ilog} mysql -u$db_root_user -p >${ilog} echo "Done." service mysql-server restart printf "Please create Admin user: " read -r admuser printf "Please give Admin User a password: " read -rs admpass echo "" mysql -u$db_root_user -p <>${ilog} pkg install ${pkgargs} powerdns service pdns enable service pdns start echo "Done." fi echo "Configuring PDNS." #no quotes in pdns.conf cp /usr/local/etc/pdns/pdns.conf /usr/local/etc/pdns/pdns.conf.bak grep -q "gmysql-dbname=pdns_db" /usr/local/etc/pdns/pdns.conf if [ $? -ne 0 ]; then echo 'PDNS config not found. Creating.' cat >/usr/local/etc/pdns/pdns.conf <>${ilog} } serverstatus() { echo "Checking Webmin." service webmin status echo "Checking MariaDB." service mysql-server status echo "Checking PowerDNS." service pdns status echo "done" } #-----------------------------------------------------------------------------# # Main PowerDNS Setup - Above here. # #-----------------------------------------------------------------------------# clear linebreak echo "" nssetupdeb_banner echo "" linebreak #Check that user is root. if [ "$(id -u)" = "0" ]; then printf "We are root. Continuing on....\n" else printf "This script must be run as root. Exiting.\n" exit 1 fi #What OS level are you on? printf "This installer is for FreeBSD 12+.\n" 2>&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 echo "Cleaning up build files, please wait..." cd ~ rm -rf $builddir echo "Good work see you later."