Created
December 2, 2014 08:38
Revisions
-
Michael Dec created this gist
Dec 2, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,289 @@ #!/bin/bash # Before running this script RUNLEVELS="235" HAVE_PASS=0 FEEDED_KEY="" ROLE="" JOB_PID=$$ NAN=1 NUMREGEX='^[0-9]+$' DEPS="" DEBUG=0 # Before you begin, you have to set these variables: NS1_INET="0" SOLUS_MANAGER="0" # If there are any commented out lines, that means they are for MySQL 5.1 # The script has been refactored to work with MariaDB 5.5, which is a non-Oracle implementation of MySQL 5.5 if [ "$NS1_INET" == "0" ] || [ "$SOLUS_MANAGER" == "0" ]; then echo "Before you begin to set up your host, you must edit the following variables:" echo "NS1_INET located at line 14" echo "SOLUS_MANAGER located at line 15" echo "They need to be IPv4 addresses of your nameserver 1 and your VM manager" exit fi if [ "$#" -gt "0" ]; then if [ "$#" -eq "1" ] || [ "$#" -eq "2" ]; then if [[ $1 =~ ^([mM][aA][sS][tT][eE][rR])$ ]]; then ROLE="Master" elif [[ $1 =~ ^([sS][lL][aA][vV][eE])$ ]]; then ROLE="Slave" else echo "First argument is either slave or master." exit fi fi if [ "$#" -eq "2" ]; then FEEDED_KEY="$2" HAVE_PASS=1 fi if [ "$#" -gt "3" ]; then echo "This program accepts only 2 argument" exit fi else echo "Usage: setup_pdns.sh role (pass)" echo "role is either master or slave" echo "pass is optional" exit fi CONFLICT=`netstat -lnpu | tail -n+3 | awk '{print $4}' | sed 's/.*://' | grep ^53$ | wc -l` if [ "$CONFLICT" -eq "1" ]; then COLUMNS=`netstat -lnpu | tail -n+3 | awk 'BEGIN {FS=" "} ; END{print NF}'` CONFLICT_NAME=`netstat -lnpu | tail -n+3 | awk '{print $"$COLUMNS"}'` echo "$CONFLICT_NAME is hogging port 53. Kill it." exit elif [ "$CONFLICT" -gt "1" ]; then echo "There are programs fighting for port 53! Kill them before continuing." exit fi mkdir -p /var/lib/mysql HAVE_EPEL=`rpm -qa epel-release | wc -l` if [ "$HAVE_EPEL" -eq "0" ]; then rpm -U http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm 2>/dev/null fi if [ ! -f "/etc/yum.repos.d/mariadb.repo" ] || [ `md5sum /etc/yum.repos.d/mariadb.repo 2>/dev/null | awk '{print $1}'` != "02fdd192719bcc8bf621db927a1c3de4" ]; then printf "Adding MariaDB repo... " echo "[mariadb]" > /etc/yum.repos.d/mariadb.repo echo "name = MariaDB" >> /etc/yum.repos.d/mariadb.repo echo "baseurl = http://yum.mariadb.org/5.5/centos6-amd64" >> /etc/yum.repos.d/mariadb.repo echo "gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB" >> /etc/yum.repos.d/mariadb.repo echo "gpgcheck=1" >> /etc/yum.repos.d/mariadb.repo rpm --import https://yum.mariadb.org/RPM-GPG-KEY-MariaDB echo "done!" fi printf "Installing MariaDB and PDNS... " if [ "`rpm -qa pdns pdns-backend-mysql MariaDB-server | wc -l`" -lt "3" ]; then HAVE_PDNS=`rpm -qa pdns | wc -l` HAVE_BACKEND=`rpm -qa pdns-backend-mysql | wc -l` HAVE_MARIA=`rpm -qa MariaDB-server | wc -l` if [ "$HAVE_PDNS" -eq "0" ]; then DEPS="$DEPS pdns" fi if [ "$HAVE_BACKEND" -eq "0" ]; then DEPS="$DEPS pdns-backend-mysql" fi if [ "$HAVE_MARIA" -eq "0" ]; then DEPS="$DEPS MariaDB-server" fi yum install $DEPS --enablerepo=epel,mariadb -y -q 2>/dev/null 1>/dev/null echo "done!" else echo "it wasn't necessary" fi printf "Adding MySQLd and PDNS to runlevels: $RUNLEVELS... " chkconfig --levels $RUNLEVELS mysql on chkconfig --levels $RUNLEVELS pdns on echo "done!" service mysql start INTERJECT=`cat -n /etc/my.cnf.d/server.cnf | grep "\[mysqld\]" | awk '{print $1}'` if [ "$HAVE_PASS" -eq "1" ]; then mysqladmin -u root password $FEEDED_KEY else read -r -s -p "What should be the root MySQL pass? " FEEDED_KEY echo "" HAVE_PASS=1 mysqladmin -u root password $FEEDED_KEY fi printf "Fetching PDNS SQL database... " curl http://files.soluslabs.com/solusvm/pdns/pdns.sql 2>/dev/null > pdns.sql.$JOB_PID sed 's/type=InnoDB;/ENGINE\ =\ InnoDB;/' pdns.sql.$JOB_PID > pdns.sql rm -f pdns.sql.$JOB_PID echo "done!" printf "Merging PDNS database into our MySQL... " mysql -u root --password=$FEEDED_KEY < pdns.sql rm -f pdns.sql echo "done!" printf "Altering PDNS config... " sed 's/^launch=bind$/launch=gmysql/' /etc/pdns/pdns.conf > pdns.conf.$JOB_PID mv pdns.conf.$JOB_PID /etc/pdns/pdns.conf echo "gmysql-host=127.0.0.1" >> /etc/pdns/pdns.conf echo "gmysql-user=root" >> /etc/pdns/pdns.conf echo "gmysql-password=$FEEDED_KEY" >> /etc/pdns/pdns.conf echo "gmysql-dbname=powerdns" >> /etc/pdns/pdns.conf echo "done!" service pdns start printf "Altering iptables rules... " IPT_RULE_NO=`iptables -L INPUT --line-number | tail -n+3 | tail -n-1 | awk '{print $1}'` for ((IPT_COUNTER=IPT_RULE_NO; IPT_COUNTER > 0; IPT_COUNTER--)); do IPT_RULE=`iptables -L INPUT | tail -n+3 | head -n$IPT_RULE_NO | tail -n1` echo $IPT_RULE > ipt.$JOB_PID IPT_RULE=`cat ipt.$JOB_PID` rm -f ipt.$JOB_PID if [ "$IPT_RULE" == "REJECT all -- anywhere anywhere reject-with icmp-host-prohibited" ]; then iptables -D INPUT $IPT_COUNTER fi done SSH_DUPES=`iptables -L INPUT | grep -E '22|ssh' | grep -v SSH | wc -l` if [ "$SSH_DUPES" -ne "0" ]; then for ((SSH_COUNTER=1; SSH_COUNTER <= $SSH_DUPES; SSH_COUNTER++)); do iptables -D INPUT `iptables -L INPUT --line-number | grep -E '22|ssh' | grep -v SSH | head -n$SSH_COUNTER | tail -n1 | awk '{print $1}'` done fi if ! iptables -L INPUT | grep -qE '53|domain'; then iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT fi if [ `iptables -L INPUT --line-number | grep SSH | wc -l` -eq "0" ]; then iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name SSH --rsource iptables -A INPUT -p tcp -m tcp --dport 22 -m recent --rcheck --seconds 30 --hitcount 4 --rttl --name SSH --rsource -j REJECT --reject-with tcp-reset iptables -A INPUT -p tcp -m tcp --dport 22 -m recent --rcheck --seconds 30 --hitcount 3 --rttl --name SSH --rsource -j LOG --log-prefix "SSH brute force " iptables -A INPUT -p tcp -m tcp --dport 22 -m recent --update --seconds 30 --hitcount 3 --rttl --name SSH --rsource -j REJECT --reject-with tcp-reset fi iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT if [ "$ROLE" == "Master" ]; then if ! iptables -L INPUT | grep -qE '3306|mysql'; then iptables -A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT fi iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited echo "done!" printf "Granting permission to users to connect to master... " echo "GRANT ALL ON powerdns.* TO 'root'@'$NS1_INET' IDENTIFIED BY '$FEEDED_KEY';" > mysql.cmd.$JOB_PID printf "grant all privileges on *.* to 'root'@'$SOLUS_MANAGER' identified by '$FEEDED_KEY';" >> mysql.cmd.$JOB_PID mysql -u root --password=$FEEDED_KEY < mysql.cmd.$JOB_PID rm -f mysql.cmd.$JOB_PID echo "done!" printf "Editing /etc/my.cnf.d/server.cnf... " head -n$INTERJECT /etc/my.cnf.d/server.cnf > server.cnf.$JOB_PID echo "server-id=1" >> server.cnf.$JOB_PID echo "log-bin=mariadb-bin" >> server.cnf.$JOB_PID echo "log-bin-index=mariadb-bin.index" >> server.cnf.$JOB_PID echo "expire-logs-days=10" >> server.cnf.$JOB_PID echo "max-binlog-size=100M" >> server.cnf.$JOB_PID echo "binlog-do-db=powerdns" >> server.cnf.$JOB_PID tail -n+`expr $INTERJECT + 1` /etc/my.cnf.d/server.cnf >> server.cnf.$JOB_PID mv server.cnf.$JOB_PID /etc/my.cnf.d/server.cnf echo "done!" read -r -s -p "Enter slave password: " USER_PASS echo "" printf "Preparing MySQL master setup command... " echo "create user pdnsslave;" > mysql.cmd.$JOB_PID echo "create user 'pdnsslave'@'*';" >> mysql.cmd.$JOB_PID echo "grant replication slave on *.* to pdnsslave identified by '$USER_PASS';" >> mysql.cmd.$JOB_PID printf "flush privileges;" >> mysql.cmd.$JOB_PID echo "done!" printf "Executing said command... " mysql -u root --password=$FEEDED_KEY < mysql.cmd.$JOB_PID echo "done!" service pdns stop service mysql stop service mysql start service pdns start printf "Altering iptables rules... " IPT_RULE_NO=`iptables -L INPUT --line-number | tail -n+3 | tail -n-1 | awk '{print $1}'` for ((IPT_COUNTER=$IPT_RULE_NO; IPT_COUNTER > 0; IPT_COUNTER--)); do IPT_RULE=`iptables -L INPUT | tail -n+3 | head -n$IPT_RULE_NO | tail -n1` echo $IPT_RULE > ipt.$JOB_PID IPT_RULE=`cat ipt.$JOB_PID` rm -f ipt.$JOB_PID if [ "$IPT_RULE" == "REJECT all -- anywhere anywhere reject-with icmp-host-prohibited" ]; then iptables -D INPUT $IPT_COUNTER fi done SSH_DUPES=`iptables -L INPUT | grep -E '22|ssh' | grep -v SSH | wc -l` if [ "$SSH_DUPES" -ne "0" ]; then for ((SSH_COUNTER=1; SSH_COUNTER <= $SSH_DUPES; SSH_COUNTER++)); do iptables -D INPUT `iptables -L INPUT --line-number | grep -E '22|ssh' | grep -v SSH | head -n$SSH_COUNTER | tail -n1 | awk '{print $1}'` done fi if ! iptables -L INPUT | grep -qE '3306|mysql'; then iptables -A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT fi if ! iptables -L INPUT | grep -qE '53|domain'; then iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT fi if [ `iptables -L INPUT --line-number | grep SSH | wc -l` -eq "0" ]; then iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name SSH --rsource iptables -A INPUT -p tcp -m tcp --dport 22 -m recent --rcheck --seconds 30 --hitcount 4 --rttl --name SSH --rsource -j REJECT --reject-with tcp-reset iptables -A INPUT -p tcp -m tcp --dport 22 -m recent --rcheck --seconds 30 --hitcount 3 --rttl --name SSH --rsource -j LOG --log-prefix "SSH brute force " iptables -A INPUT -p tcp -m tcp --dport 22 -m recent --update --seconds 30 --hitcount 3 --rttl --name SSH --rsource -j REJECT --reject-with tcp-reset fi iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited echo "done!" service iptables save mysql -u root --password=$FEEDED_KEY -e "show master status \G" elif [ "$ROLE" == "Slave" ]; then iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited echo "done!" while [ "$NAN" -eq "1" ]; do read -r -p "What server ID should this host have? [2 or greater] " SLAVE_ID if [[ $SLAVE_ID =~ $NUMREGEX ]] && [ $SLAVE_ID -gt 1 ]; then NAN=0 printf "Thanks! Now, configuring my.cnf for slave... " else echo "This is not a valid number greater than 2" fi done head -n$INTERJECT /etc/my.cnf.d/server.cnf > server.cnf.$JOB_PID echo "server-id=$SLAVE_ID" >> server.cnf.$JOB_PID echo "relay-log=slave-relay-bin" >> server.cnf.$JOB_PID echo "relay-log-index=slave-relay-bin.index" >> server.cnf.$JOB_PID echo "replicate-do-db=powerdns" >> server.cnf.$JOB_PID tail -n+`expr $INTERJECT + 1` /etc/my.cnf.d/server.cnf >> server.cnf.$JOB_PID mv server.cnf.$JOB_PID /etc/my.cnf.d/server.cnf echo "done!" service mysql restart echo "Continue only if you have configured your master PDNS correctly!" read -r -p "What was the file number? mariadb-bin." INDEX read -r -p "And what was the position? " POSITION read -r -s -p "Enter slave password: " USER_PASS echo "" echo "change master to master_host='$NS1_INET', master_user='pdnsslave', master_password='$USER_PASS', master_log_file='mariadb-bin.$INDEX', master_log_pos=$POSITION, master_connect_retry=60;" > mysql.cmd.$JOB_PID printf "Preparing SQL command... " echo "change master to master_host='$NS1_INET', master_user='pdnsslave', master_password='$USER_PASS', master_log_file='mariadb-bin.$INDEX', master_log_pos=$POSITION, master_connect_retry=60;" > mysql.cmd.$JOB_PID printf "start slave;" >> mysql.cmd.$JOB_PID echo "done!" mysql -u root --password=$FEEDED_KEY < mysql.cmd.$JOB_PID mysql -u root --password=$FEEDED_KEY -e "show slave status \G" rm -f mysql.cmd.$JOB_PID else echo "Congratulations. You somehow tricked bash." fi