You are here

AltaOS 8 Configuration

Submitted by Alan Mels on Thu, 07/02/2020 - 21:39

To enable Cockpit UI run:

  1. systemctl enable --now cockpit.socket

0) Configuring automatic security updates

dnf -y install dnf-automatic
sed -ie 's/apply_updates = no/apply_updates = yes/' /etc/dnf/automatic.conf
sed -ie 's/emit_via = stdio/emit_via = email,stdio/' /etc/dnf/automatic.conf
sed -ie 's/email_from = [email protected]/email_from = root/' /etc/dnf/automatic.conf
systemctl enable --now dnf-automatic.timer

1) Creating an 'altagrade' admin user

if ! id "altagrade" >/dev/null 2>&1; then
  echo "=================================================================================="
  echo "Creating altagrade user .."
  # Disabling root password
  dnf -y install "perl(IO::Pty)"
  passwd -d root
  useradd -G wheel altagrade
  openssl rand -base64 12 | passwd altagrade --stdin
  echo "Setting %wheel group members passwordless sudoers .."
  sed -ie 's/%wheel/#%wheel/' /etc/sudoers && sed -ie 's/# #%wheel/%wheel/' /etc/sudoers
  mkdir /home/altagrade/.ssh
  echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC753VZbicoElj5moS0XZ70ERwse483Cuqc6Jf3YXJvn4+ZGzdjUsUI4+0GHK0aufeFh4YNZQ9QoQnM/3HUKZIGm3/2lYvzY1Z2YtyWz57LSX6o+oskq01Pe+3g+sxbt1yOW/KhClVhTSNzFPtMV5h4//JLxdO1Z6pctXSgq2COZ9fnEAm/AzmYFpuNvg0JmNdWuFkvnSKZrkt9hmw72TTjTE+p9DviTmoq4GCr6l2Pg4y6oTlyQ595yi6wDZe0JK7cdkKMsA4U6kAyHqci7zXOu7HjLdYcKZCohCp/iddHZbERmlZuS1eGbiARYtBZb9FNdUmnUB3nggb4DU3FPeDl
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGfQcSb8ATF0+1LZTEFEXvTz9tl67VDr+Zklu5YJhWajezq6hom4RZ3wWZd01P6qIsqy+wbcY+9NGo/sjU5dRg70lRMYzOU0fX5qz8mz/I3EiXBjSu2Pv2gAKj6ajX0ifMXwNcZkxNX2BLIbHgjSsw9ci5L610gFGjR65q66jjwAIDZP+Ohih7oerfK1LWRcNIsrkUTVSbVWJQytiiyH9Up9Q5wzIceq7H2Kc4GUS0FYKM52oNhpGSD9hPR449w528/hEBeHr1rAT294qZYR59jrZYTtlwOcXU/JlOef0n+G4++dd75zQZ+/NZCh8S+kuYY+Lzip2W6EzMpUvmPVih nurlan' >> /home/altagrade/.ssh/authorized_keys
  restorecon -R -v /home/altagrade/.ssh
  sed -i "s/#Port 22/Port ${PORT}/g" /etc/ssh/sshd_config
  sed -i "s/#PermitRootLogin yes/PermitRootLogin no/g" /etc/ssh/sshd_config
  sed -i "s/PasswordAuthentication yes/PasswordAuthentication no/g" /etc/ssh/sshd_config
fi

2) Configuring MariaDB settings

# Setting the database root password
dnf -y install expect
 
MYSQL_ROOT_PASSWORD=`date +%s | sha256sum | base64 | head -c 16 ; echo`
 
SECURE_MYSQL=$(expect -c "
 
set timeout 3
spawn mysql_secure_installation
 
expect \"Enter current password for root (enter for none):\"
send \"$CURRENT_MYSQL_PASSWORD\r\"
 
expect \"Set root password?\"
send \"y\r\"
 
expect \"New password:\"
send \"$MYSQL_ROOT_PASSWORD\r\"
 
expect \"Re-enter new password:\"
send \"$MYSQL_ROOT_PASSWORD\r\"
 
expect \"Remove anonymous users?\"
send \"y\r\"
 
expect \"Disallow root login remotely?\"
send \"y\r\"
 
expect \"Remove test database and access to it?\"
send \"y\r\"
 
expect \"Reload privilege tables now?\"
send \"y\r\"
expect eof
")
 
echo "$SECURE_MYSQL"
 
dnf -y remove expect
 
if grep -q pass= /etc/webmin/mysql/config; then
  sed -i "/pass=/c\pass=$MYSQL_ROOT_PASSWORD" /etc/webmin/mysql/config
else
  echo pass=$MYSQL_ROOT_PASSWORD >> /etc/webmin/mysql/config
fi
 
# Done setting the database root password
 
if ! grep -Fq "default-character-set = utf8mb4" /etc/my.cnf
then
  rm -f  /etc/my.cnf
cat > /etc/my.cnf << 'EOF'
[client]
default-character-set = utf8mb4
 
[mysql]
default-character-set = utf8mb4
 
[mysqld]
innodb_file_per_table=true
innodb_flush_log_at_trx_commit = 0
innodb_log_buffer_size  = 8M
innodb_buffer_pool_size = 1G
innodb_thread_concurrency = 16
innodb_lock_wait_timeout = 120
innodb_data_file_path   = ibdata1:10M:autoextend
innodb_max_dirty_pages_pct = 90
 
slow_query_log = 1
slow_query_log_file = /var/log/mariadb/slow.log
 
query_cache_size = 128M
query_cache_limit = 16M
 
 
thread_cache_size = 8
myisam_sort_buffer_size = 64M
read_rnd_buffer_size = 8M
read_buffer_size = 2M
sort_buffer_size = 2M
table_cache = 512
max_allowed_packet=1024M
key_buffer_size = 384M
wait_timeout=600
max_connections = 600
tmp_table_size = 256M
max_heap_table_size = 256M
 
 
#
# This group is read both both by the client and the server
# use it for options that affect everything
#
[client-server]
 
#
# include all files from the config directory
#
!includedir /etc/my.cnf.d
EOF
fi
 
# Per https://bugzilla.redhat.com/show_bug.cgi?id=1468028
sed -i s/^plugin-load-add=auth_gssapi.so/#plugin-load-add=auth_gssapi.so/g /etc/my.cnf.d/auth_gssapi.cnf
 
 
# Should go to elsewhere
# Per https://coderwall.com/p/fukoew/speed-up-ssh-logon-by-disabling-gssapiauthentication
sed -i '/GSSAPIAuthentication yes/c\GSSAPIAuthentication no' /etc/ssh/sshd_config

3) Creating backup and sandbox directories

if [ ! -d /home/backup ]; then
  echo "Creating /home/backup directory .."
  mkdir /home/backup
  echo "Creating a symlink /backup to /home/backup .."
  ln -s /home/backup /backup
fi
 
if [ ! -d /sandbox ]; then
  echo "Creating /sandbox directory .."
  mkdir /sandbox
fi

4) Configuring CLI banner and MOTD

(42, 161, 152);">if ! grep -Fq "Welcome" /etc/motd
then
  echo "Creating /etc/motd .."
cat <<EOT >> /etc/motd
*****************************************************************************
*             Welcome to AltaGrade Optimized Operating System!              *
*                                                                           *
* For any issues please browse through the AltaGrade platform documentation *
* on https://www.altagrade.com/help. If you can't find a suitable solution, *
* then submit a support request on https://my.altagrade.com.                *
*                                                                           *
*****************************************************************************
EOT
fi
 
(42, 161, 152);">if grep -Fq "#Banner none" /etc/ssh/sshd_config
then
  sed -ie '/#Banner none/c\Banner /etc/banner' /etc/ssh/sshd_config
(42, 161, 152);">else
  echo 'Banner /etc/banner' >> /etc/ssh/sshd_config
fi
 
(42, 161, 152);">if ! grep -Fq "" /etc/banner
then
  echo "Creating /etc/banner .."
cat <<EOT >> /etc/banner
 
 
     **      **   **               ********                        **        
    ****    /**  /**              **//////**                      /**        
   **//**   /** ******  ******   **      //  ******  ******       /**  ***** 
  **  //**  /**///**/  //////** /**         //**//* //////**   ****** **///**
 ********** /**  /**    ******* /**    ***** /** /   *******  **///**/*******
/**//////** /**  /**   **////** //**  ////** /**    **////** /**  /**/**//// 
/**     /** ***  //** //******** //******** /***   //********//******//******
//      // ///    //   ////////   ////////  ///     ////////  //////  //////                                                                               
 
 
EOT
fi

5) Setting some useful aliases for root user

if ! grep -Fq "update-webmin" /root/.bashrc; then
  echo "Creating root aliases .."
  cat >> /root/.bashrc << 'EOF'
alias update-webmin='yes | /usr/libexec/webmin/update-from-repo.sh'
alias update-theme='yes | /usr/libexec/webmin/authentic-theme/theme-update.sh'
alias webminpass='/usr/libexec/webmin/changepass.pl /etc/webmin root'
alias ps10='ps -auxf | sort -nr -k 4 | head -10'
alias cpu10='ps -eo pcpu,pid,user,args | sort -k 1 -r | head -10'
alias qchwr='drush pml --no-core --type=module --status=enabled --pipe | xargs drush -y dis'
alias repo='sed -n -e "/^\[/h; /priority *=/{ G; s/\n/ /; s/ity=/ity = /; p }" /etc/yum.repos.d/*.repo | sort -k3n'
alias psx="ps -eo pcpu,pid -o comm= | sort -k1 -n -r | head -12"
alias psg="ps fuxa |grep $1"
alias psm="ps -eo pmem,pcpu,rss,vsize,args | sort -k 1 -r | less"
alias eba='nano /etc/profile.d/globaliases.sh'
alias lba='source /etc/profile.d/globaliases.sh'
 
alias net1='rm -rf /etc/udev/rules.d/70-persistent-net.rules'
alias net2='nano /etc/resolv.conf'
alias net3='nano /etc/sysconfig/network-scripts/ifcfg*'
 
snd () {
rsync --rsh -av -e 'ssh -p 19759' --progress --partial ${1} root@IP:/
}
 
# sync two directories
# rsync -azP -e 'ssh -p 19759' local_dir root@IP:/remote_dir
 
EOF
fi

6) Reducing the number of stored kernels down to 2 in order to save storage space

if grep -Fq 'installonly_limit=3' /etc/yum.conf
then
  echo "Setting amount of installed kernels to 2 .."
  sed -ie 's/installonly_limit=3/installonly_limit=2/' /etc/yum.conf
fi

7) Configuring e-mail notifications on SSH logins

if [ -f /etc/ag/scripts/login-notify.sh ]; then
  chmod 755 /etc/ag/scripts/login-notify.sh
  echo 'session optional pam_exec.so seteuid /etc/ag/scripts/login-notify.sh' >> /etc/pam.d/sshd
fi

8) Configuring hourly AltaGrade cron tasks
Excluded for now as we need to redesign the script with Composer

cat > /etc/cron.hourly/altagrade << 'EOF'
#!/bin/bash
sh /etc/ag/scripts/update-drupal 1 > /dev/null
if [ -e /etc/ag/updates/update.sh.old ]; then
  if ! cmp --silent /etc/ag/updates/update.sh /etc/ag/updates/update.sh.old
    then
      chmod 755 /etc/ag/updates/update.sh
      sh /etc/ag/updates/update.sh
      mv /etc/ag/updates/update.sh /etc/ag/updates/update.sh.old
  fi
fi
exit
EOF
chmod 755 /etc/cron.hourly/altagrade

9) Configuring daily AltaGrade cron tasks

cat > /etc/cron.daily/altagrade << 'EOF'
#!/bin/bash
sed -ie 's/CentOS/AltaOS/' /etc/webmin/config >/dev/null 2>&1
sh /etc/ag/cp/new-lang.sh >/dev/null 2>&1
sed -ie 's/slider_enabled=true/slider_enabled=false/' /etc/webmin/authentic-theme/settings.js >/dev/null 2>&1
/usr/libexec/webmin/update-from-repo.sh -y >/dev/null 2>&1
/usr/libexec/webmin/authentic-theme/theme-update.sh -y >/dev/null 2>&1
exit
EOF
chmod 755 /etc/cron.daily/altagrade
/etc/cron.daily/altagrade

10) Configuring miscellaneous settings

echo '*               soft    nofile            65535' >> /etc/security/limits.conf
echo '*               hard    nofile            65535' >> /etc/security/limits.conf
 
if ! grep -q 127.0.0.1 "/etc/resolv.conf"; then
  echo "nameserver 127.0.0.1" >> /etc/resolv.conf
fi

11) Cleaning up the Webmin config files

grep -rl 65.49.80.99 /etc | xargs sed -i "s/65.49.80.99/$IP/g"
grep -rl fe80::216:3eff:feca:7117 /etc | xargs sed -i "s/fe80::216:3eff:feca:7117/$IP6/g"
grep -rl host.altagrade.org /etc | xargs sed -i "s/host.altagrade.org/$HOSTNAME/g"
grep -rl eth0 /etc | xargs sed -i "s/eth0/$IFACE/g"
# Per https://www.virtualmin.com/node/43097
rm -rf /var/webmin/module.infos.cache
/sbin/virtualmin check-config

12) Removing unnecessary services

# Removing cockpit
systemctl stop cockpit && systemctl disable cockpit
dnf -y remove cockpit
firewall-cmd --permanent --remove-service=cockpit
 
# Disabling Usermin
/usr/lib/systemd/systemd-sysv-install disable usermin
 
rm -rf /etc/httpd/conf.d/welcome.conf 
chown -R root:bin /etc/webmin
 
systemctl stop chronyd && yum -y remove chrony
systemctl stop wpa_supplicant && yum -y remove wpa_supplicant
# systemctl stop fail2ban && yum -y remove fail2ban* && rm -rf /var/log/fail2ban.log
systemctl stop proftpd && yum -y remove proftpd && rm -rf /var/log/proftpd
if [ $PORT == 19759 ]; then
  systemctl stop sound.target && systemctl disable sound.target
fi

13) Configuring Apache

sed -ie '/SSLProtocol/c\SSLProtocol All -SSLv2 -SSLv3' /etc/httpd/conf/httpd.conf
sed -ie '/SSLCipherSuite/c\SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"' /etc/httpd/conf/httpd.conf
sed -ie '/SSLCipherSuite/i\SSLHonorCipherOrder on' /etc/httpd/conf/httpd.conf
 
# per https://support.plesk.com/hc/en-us/articles/213399589-Websites-are-slow-and-a-warning-appears-in-logs-mod-fcgid-ap-pass-brigade-failed
echo 'FcgidMaxRequestsPerProcess 500' >> /etc/httpd/conf.d/fcgid.conf
echo 'FcgidOutputBufferSize 0' >> /etc/httpd/conf.d/fcgid.conf
sed -ie 's|LoadModule|#LoadModule|' /etc/httpd/conf.modules.d/00-dav.conf
 
# Maybe we can turn the below ones off.
sed -ie 's/LoadModule proxy/#LoadModule proxy/' /etc/httpd/conf.modules.d/00-proxy.conf
sed -ie 's@#LoadModule proxy_module@LoadModule proxy_module@g' /etc/httpd/conf.modules.d/00-proxy.conf
sed -ie 's@#LoadModule proxy_fcgi_module@LoadModule proxy_fcgi_module@g' /etc/httpd/conf.modules.d/00-proxy.conf
sed -ie 's@LoadModule lbmethod_heartbeat@#LoadModule lbmethod_heartbeat@g' /etc/httpd/conf.modules.d/00-proxy.conf

14) file=/etc/ag/scripts/update-drupal

cat > /etc/ag/scripts/update-drupal << 'EOT'
#!/bin/sh
 
export PATH="/usr/local/bin:$PATH"
 
if [ -f /opt/remi/php74/enable ]; then
  source /opt/remi/php74/enable
elif [ -f /opt/remi/php73/enable ]; then
  source /opt/remi/php73/enable
elif [ -f /opt/remi/php72/enable ]; then
  source /opt/remi/php72/enable
fi
 
doms=`virtualmin list-domains --name-only`
for dom in $doms; do
 
# Check if domain is disabled
partial="$(echo $dom | cut -c1-30)"
disabled="$(virtualmin list-domains --domain $dom --disabled | grep $partial)"
# Leave disabled domains out of process
if [ -z "$disabled" ]; then
 
  path=`virtualmin list-domains --domain $dom --home-only`
  echo "***********************************************************************************************"
  echo " Working in $path..."
  # Let's check if domain is set to Yes and skip otherwise
  drupal_auto_update="$(virtualmin list-custom --domain $dom | grep Autoupdate)"
  if [[ $drupal_auto_update == *"Yes"* ]]; then
    drupal=''
    if [ -d $path/public_html ]; then
      cd $path/public_html
      version=$(drush status | grep 'Drupal version')
      if [[ $version = *8.* ]]; then
        drupal='8'
      elif [[ $version = *7.* ]]; then
        drupal='7'
      elif [[ $version = *6.* ]]; then
        drupal='6'
      fi
      if [ -z "$drupal" ]; then
        echo "***********************************************************************************************"
        echo "It is not bootstrapping, so probably this is not a Drupal site. Skipping..."
      else
        user=`virtualmin list-domains --domain $dom --user-only`
        drush cc all >> /dev/null 2>&1
        drush cr >> /dev/null 2>&1
        status=$(drush ups drupal 2> /dev/null | grep 'Update available\|SECURITY UPDATE available')
        if [ -z "$status" ]; then
          echo "The latest version for $dom is already installed."
          echo "***********************************************************************************************"
        else
 #         exec 3>&1 1>>/tmp/log.txt 2>&1
          echo "*** This is an automatically generated email, please do not reply ***" >> /tmp/log.txt
          echo " " >> /tmp/log.txt
          echo "The $dom has been updated to the latest secure Drupal core." >> /tmp/log.txt
          echo " " >> /tmp/log.txt
          echo "Here is the log:" >> /tmp/log.txt
          echo " " >> /tmp/log.txt
          echo "***********************************************************************************************" >> /tmp/log.txt
          echo "Working in $path/public_html ..." >> /tmp/log.txt
          echo "Drupal "$drupal" is detected." >> /tmp/log.txt
          echo "Update is available for $dom. Backing up the website's files and database ..." >> /tmp/log.txt
          drush -q sql-query "DELETE FROM cache_form"
          systemctl restart mariadb
          drush ard default --tar-options="--exclude=.git"
          echo "Securing the .htaccess and robots.txt files ..." >> /tmp/log.txt
          mkdir -p ../keep
          mv .htaccess robots.txt -t ../keep
          echo "Upgrading the website ..." >> /tmp/log.txt
          drush -y en update 2>&1 >> /tmp/log.txt
          drush -y -q up drupal --no-backup
          find . -type f -name .htaccess -exec sed -i "s/FollowSymLinks/SymLinksIfOwnerMatch/g" {} \; && find . -type f -name file.inc -exec sed -i "s/FollowSymLinks/SymLinksIfOwnerMatch/g" {} \;
          mv -f ../keep/.htaccess .
          mv -f ../keep/robots.txt .
          rm -rf ../keep
          chown -R $user:$user ../public_html
          drush -y updb 2>&1 >> /tmp/log.txt
          echo "$dom has been updated to the latest Drupal core." >> /tmp/log.txt
          echo "***********************************************************************************************" >> /tmp/log.txt
          echo " " >> /tmp/log.txt
          echo "*** This is an automatically generated email, please do not reply ***" >> /tmp/log.txt
          # Now let's find parent domain until https://www.virtualmin.com/node/53104 is resolved
          parent=${dom#*.}
          virtualmin notify-domains --domain $parent --body-file /tmp/log.txt --subject "Your website $dom has been updated" --from noreply@altagrade.com
          rm -f /tmp/log.txt
        fi
      fi
    fi
  else
    echo "Autoupdate for $dom is set to No, so skipping..."
    echo "***********************************************************************************************"
  fi
else
  echo "$dom is disabled, so skipping"
  echo "***********************************************************************************************"
fi
done
echo "***********************************************************************************************"
echo "Drupal core updates are complete."
echo "***********************************************************************************************"
exit
EOT