#!/bin/bash # # # NAME: compile_kernel.sh # # COPY: Copyright 2012 d2@tdhack.com # # LEGAL NOTICE: This software is for internal use ONLY. Copying, modifying # or distributing it without knowledge and/or permission of # its author is strictly forbidden! # # Author of this script can not be held responsible for any # damage or problems this software may cause (especially # version modified by third parties). # # Any changes should be discussed with author of this script # or sent to him as diff-patch to let him quickly verify or # introduce changes made by others. # # Remember: You are using this software at your own risk and # by using it you agree with all above terms of use. # # # # chpax -ps /usr/sbin/grub-probe # paxctl -ps /usr/sbin/grub-probe export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH DEBUG=0 HOMEDIR=/home/kernel MAILRCPT="d2@tdhack.com" INSTALLLOG=/tmp/installlog.txt LOCALDATA=${HOMEDIR}/localdata CURGR=${LOCALDATA}/gr.txt KRFILE=/tmp/kernel.txt GRFILE=/tmp/grsec.txt VSFILE=/tmp/vserver.txt YESALL=1 if [[ ${DEBUG} == 1 ]]; then ECHO="echo " fi trap sk_handle ERR function sk_handle() { LINE=${1} echo -e "${FERR} *** Fatal Error. Read more recent log from console ***${NC}" echo -en "${FERR} Continue anyway? (y/n)${NC} " if [[ ${YESALL} == 1 ]]; then echo -e "${GREEN}Aborting.${NC}" exit 1 else if [[ $(sk_yesno) == 1 ]]; then echo -e "${GREEN}Aborting.${NC}" exit 1 else echo -e "${LRED}Continuing regardless previous errors.${NC}" fi fi } function sk_checkstatus(){ if [[ $? != 0 ]]; then sk_mailadmin "An error occured during build, please fix it manually!" echo -e "Aborting operation." exit 1 fi } function sk_setcolors(){ LRED="\033[1;31m" RED="\033[0;31m" FERR="\033[37;41m" LGREEN="\033[1;32m" GREEN="\033[0;32m" LYELLOW="\033[1;33m" YELLOW="\033[0;33m" LCYAN="\033[1;36m" CYAN="\033[0;36m" LGRAY="\033[0;37m" GRAY="\033[1;30m" WHITE="\033[1;37m" NC="\033[0m" } function sk_probe_kernel(){ NEWKERNEL_LINK=`wget -q http://kernel.org -O ${KRFILE};cat ${KRFILE}|sed -n "/

/,/<\/h3>/p"|grep href|cut -d\" -f2` NEWKERNEL_NAME=`basename ${NEWKERNEL_LINK} 2>/dev/null` NEWKERNEL_VERS=`echo ${NEWKERNEL_NAME}|sed -r "s,(linux-)|(.tar.bz2),,g"` #NEWGRSEC_NAME=`wget -q http://grsecurity.net/test.php -O ${GRFILE};cat ${GRFILE}|grep "${NEWKERNEL_VERS}"|grep ".patch"|grep -v pax|sed -r 's,(<[^>]*>)|(\[sig\])|([0-9]{2}(:?/| ))|([0-9]{2}:[0-9]{2}), ,g'|awk '{print $2}'` NEWGRSEC_NAME=`wget -q http://grsecurity.net/test.php -O ${GRFILE};cat ${GRFILE}|grep "\-${NEWKERNEL_VERS}"|grep ".patch"|grep -v pax|sed -r 's,<[^>]*>|\[sig\]|../../.. ..:.., ,g'|tr " " "\n"|grep "\-${NEWKERNEL_VERS}"|grep ".patch"` NEWGRSEC_LINK="http://grsecurity.net/test/${NEWGRSEC_NAME}" #NEWVSERVER=`wget http://linux-vserver.org/Welcome_to_Linux-VServer.org -O /tmp/vserver.txt;cat /tmp/vserver.txt|grep 2.6.31.6|grep diff|grep grsec|awk '{print $6}'|cut -d\" -f2` echo -e "[+] new kernel link: ${NEWKERNEL_LINK}" echo -e "[+] new kernel: ${NEWKERNEL_NAME}" echo -e "[+] new kernel version: ${NEWKERNEL_VERS}" echo -e "[+] new grsec name: ${NEWGRSEC_NAME}" echo -e "[+] newgrsec link: ${NEWGRSEC_LINK}" if [[ ${NEWGRSEC_NAME} ]]; then echo -e "[+] Matching grsec patch for kernel ${NEWKERNEL_VERS} has been found" | tee -a ${INSTALLLOG} if [[ -e ${CURGR} ]]; then OLDGR=`cat ${CURGR}` if [[ "${OLDGR}" != "${NEWGRSEC_NAME}" ]]; then echo -e "[+] build new kernel" | tee -a ${INSTALLLOG} sk_mailadmin "Matching grsec patch for kernel ${NEWKERNEL_VERS} has been found" cd ${HOMEDIR}/update | tee -a ${INSTALLLOG} echo -e "[+] fetching new kernel sources ... this will take a while, be patient!" | tee -a ${INSTALLLOG} ${ECHO} wget -q ${NEWKERNEL_LINK} -O ${HOMEDIR}/update/${NEWKERNEL_NAME} | tee -a ${INSTALLLOG} echo -e "[+] fetching new grsec patch" | tee -a ${INSTALLLOG} ${ECHO} wget -q ${NEWGRSEC_LINK} -O ${HOMEDIR}/update/${NEWGRSEC_NAME} | tee -a ${INSTALLLOG} echo "${NEWGRSEC_NAME}" > ${CURGR} sk_buildkernel else echo -e "[-] Last compiled kernel is most recent one." | tee -a ${INSTALLLOG} sk_mailadmin "Last compiled kernel is most recent one." exit 1 fi else echo ${NEWGRSEC_NAME} > ${CURGR} echo -e "[+] No previous verion found. Build new kernel" | tee -a ${INSTALLLOG} sk_mailadmin "No previous verion found. Build new kernel" ${ECHO} wget -q ${NEWKERNEL_LINK} -O ${HOMEDIR}/update/${NEWKERNEL_NAME} | tee -a ${INSTALLLOG} ${ECHO} wget -q ${NEWGRSEC_LINK} -O ${HOMEDIR}/update/${NEWGRSEC_NAME} | tee -a ${INSTALLLOG} sk_buildkernel fi else echo -e "[-] No matching grsec patch for kernel ${NEWKERNEL_VERS} has been found" | tee -a ${INSTALLLOG} sk_mailadmin "No matching grsec patch for kernel ${NEWKERNEL_VERS} has been found" fi } function sk_buildkernel(){ if [[ `ls ${HOMEDIR}/update` != '' ]]; then ${ECHO} cd ${HOMEDIR}/update NEWKERNEL=`ls linux-*.tar.bz2|sed -e 's,.tar.bz2,,g'` NEWGRSEC=`ls *.patch` if [[ ${NEWKERNEL} == '' ]]; then echo -e "${RED}[-] No new kernel available. Abort.${NC}" | tee -a ${INSTALLLOG} exit 1 else echo -e "${GREEN}[+] Found new kernel:${NC} ${LCYAN} ${NEWKERNEL}${NC}" | tee -a ${INSTALLLOG} fi if [[ ${NEWGRSEC} == '' ]]; then echo -e "${RED}[-] No new grsecs available. Abort.${NC}" | tee -a ${INSTALLLOG} exit 1 elif [[ ${NEWGRSEC} =~ `echo ${NEWKERNEL}|sed -e 's,linux-,,g'` ]]; then echo -e "${GREEN}[+] Found new grsec:${NC} ${LCYAN} ${NEWGRSEC}${NC}" | tee -a ${INSTALLLOG} else echo -e "${RED}[-] grsec patch is not for this kernel.${NC}" | tee -a ${INSTALLLOG} exit 1 fi if [[ -e ../linux/.config ]]; then ${ECHO} cp -pr ../linux/.config . | tee -a ${INSTALLLOG} elif [[ -e /boot/config-`uname -r` ]]; then echo -e "[+] using /boot/config-`uname -r` as a config file." | tee -a ${INSTALLLOG} ${ECHO} cp -pr /boot/config-`uname -r` .config DOBRK=1 else echo -e "[-] config file not found, using default one" | tee -a ${INSTALLLOG} fi ${ECHO} tar -jxf *.tar.bz2 | tee -a ${INSTALLLOG} #NEWKERNEL=`ls -d linux-|grep -v *.tar.bz2` WORKINGGRSEC=`ls ${NEWKERNEL}/|grep grsecurity` if [[ (`ls -d ${HOMEDIR}/linux-*|grep ${NEWKERNEL}` != '') && (${WORKINGGRSEC} == ${NEWGRSEC}) ]]; then echo -e "${RED}[-] Sources${NC} ${LCYAN}${NEWKERNEL}${NC} ${GREEN}exists and is using the same grsec patch Upgrade aborted.${NC}" | tee -a ${INSTALLLOG} exit 1 fi if [[ -e ../${NEWKERNEL} ]]; then HOWMANY=`ls ../|grep ${NEWKERNEL}|wc -l|awk '{print $1}'` if [[ ${HOWMANY} == '' ]] then HOWMANY="0" fi ${ECHO} mv ../${NEWKERNEL} ../${NEWKERNEL}-bak_${HOWMANY} fi ${ECHO} mv ${NEWKERNEL} ../ sk_checkstatus cd ../ ${ECHO} sk_delete linux | tee -a ${INSTALLLOG} ${ECHO} ln -s ${NEWKERNEL} linux | tee -a ${INSTALLLOG} ${ECHO} cp -pr ${HOMEDIR}/update/.config linux/ | tee -a ${INSTALLLOG} ${ECHO} cd linux echo -e "${GREEN}[+] Patching sources${NC}" | tee -a ${INSTALLLOG} ${ECHO} patch -p1 < ${HOMEDIR}/update/${NEWGRSEC} | tee -a ${INSTALLLOG} ${ECHO} cp -pr ${HOMEDIR}/update/${NEWGRSEC} ${HOMEDIR}/linux/ ; checkstatus | tee -a ${INSTALLLOG} ${ECHO} sk_delete localversion-grsec ${ECHO} touch localversion-grsec if [[ ${DOBRK} == 1 ]]; then echo -e "[-] you need to do make menuconfig in ${HOMEDIR}/linux/. This is because I have create kernel config from scratch.\n Enable what you want and place it in ${HOMEDIR}/linux/.config, then issue manually:\n export CONCURRENCY_LEVEL=$[`cat /proc/cpuinfo|grep ^processor|wc -l|awk '{print $1}'`] && make-kpkg clean && make-kpkg --rootcmd fakeroot --initrd kernel_image kernel_headers\n Exiting now." | tee -a ${INSTALLLOG} sk_mailadmin "you need to do make menuconfig in ${HOMEDIR}/linux/" exit 1 fi echo -e "${GREEN}[+] Done${NC}" | tee -a ${INSTALLLOG} ${ECHO} cd ${HOMEDIR}/linux sk_checkstatus echo -e "${GREEN}[+] Compiling kernel${NC}" | tee -a ${INSTALLLOG} ${ECHO} make-kpkg clean ; checkstatus| tee -a ${INSTALLLOG} ${ECHO} export CONCURRENCY_LEVEL=$[`cat /proc/cpuinfo|grep ^processor|wc -l|awk '{print $1}'`] ${ECHO} make-kpkg --rootcmd fakeroot --initrd kernel_image kernel_headers ; checkstatus | tee -a ${INSTALLLOG} sk_mailadmin "New kernel ready for installation (run chpax -ps /usr/sbin/grub-probe first)" else echo -e "${RED}[-] No new updates available. Abort.${NC}" | tee -a ${INSTALLLOG} exit 1 fi } function sk_mailadmin(){ MAILSUBJECTPREFIX="[kernel] " MAILSUBJECT="${MAILSUBJECTPREFIX} ${1}" MAILFILE=/tmp/mailfile.txt MAILBODY=/tmp/mailbody.txt echo -e "Details,\n kernel link: ${NEWKERNEL_LINK} kernel name: ${NEWKERNEL_NAME} kernel version: ${NEWKERNEL_VERS} grsec name: ${NEWGRSEC_NAME} grsec link: ${NEWGRSEC_LINK}\n\n\n === INSTALLATION LOG === \n\n\n" > ${MAILFILE} cat ${MAILFILE} ${INSTALLLOG} > ${MAILBODY} for addr in ${MAILRCPT}; do mailx -a "FROM: `whoami`@`uname -n`" -s "${MAILSUBJECT}" ${addr} < ${MAILBODY} done } function sk_cleanup(){ for clean in ${INSTALLLOG} ${MAILFILE} ${KRFILE} ${GRFILE} ${MAILBODY} ${HOMEDIR}/update; do if [[ -e ${clean} ]]; then ${ECHO} sk_delete ${clean} silent fi done if [[ ! -e ${HOMEDIR}/update ]]; then ${ECHO} mkdir -p ${HOMEDIR}/update fi if [[ ! -e ${LOCALDATA} ]]; then ${ECHO} mkdir -p ${LOCALDATA} fi ${ECHO} touch ${CURGR} ${ECHO} cd ${HOMEDIR} } function sk_delete(){ # sk_delete file [silent] if [[ ${DEBUG} == 1 ]]; then echo -e "*** fname: ${FUNCNAME} ***" caller 0 fi if [[ ${#*} == 0 ]]; then echo -e "usage: ${FUNCNAME} {file} [silent]" echo -e "example: ${FUNCNAME} /tmp/test.txt silent" return 0 fi local sk_deleteWHAT=${1} local sk_deleteISSILENT=${2} for removeme in ${sk_deleteWHAT}; do if [[ (${removeme} != "") && ($(sk_checkvar ${removeme}) == 0) ]]; then if [[ ${sk_deleteISSILENT} != silent ]]; then echo -e "${GREEN}Removing${NC} ${LCYAN}${removeme}${NC}" fi ${ECHO}rm -rf ${removeme} 2>/dev/null sk_checkstatus $[LINENO-1] ${FUNCNAME} else echo -en "${LRED}Can't delete${NC} ${LCYAN}${removeme}${NC} ${LRED}Continue?${NC} (yes/[no]) " if [[ $(sk_yesno) == 1 ]]; then echo -e "${RED}Aborting.${NC}" exit 1 else echo -e "${LRED}Continuing regardless previous errors.${NC}" fi fi done } function sk_checkvar(){ # VAR=$(sk_checkvar ${NAME}) if [[ ${DEBUG} == 1 ]]; then echo -e "*** fname: ${FUNCNAME} ***" caller 0 fi if [[ ${#*} == 0 ]]; then echo -e "usage: ${FUNCNAME} {var}" echo -e "example: ${FUNCNAME} /tmp" return 0 fi local sk_checkvarVARIABLE="$(sk_removeslashes ${1})" local sk_checkvarFORBIDDENLIST="/ /usr /root /home /etc /var /tmp /srv /sys /selinux /scripts /sbin /proc /opt /mnt /media /lib32 /lib /export /dev /boot /bin /vol /tftpboot /system /storage /storage2 /platform /net /kernel /home/kernel /devices /data /data1 /data2 /data01 /data01 /cdrom $HOME $HOME/bin" for forbidden in ${sk_checkvarFORBIDDENLIST}; do if [[ (${sk_checkvarVARIABLE} == ${forbidden}) || (${sk_checkvarVARIABLE} == ${forbidden}/) ]]; then #echo -e "${checkvarVARIABLE} contains forbiden string" local sk_checkvarFORBIDDEN=1 break else local sk_checkvarFORBIDDEN=0 fi done if [[ ${sk_checkvarFORBIDDEN} == 0 ]]; then echo 0 else echo 1 fi } function sk_cwhoami(){ # sk_cwhoami root if [[ ${DEBUG} == 1 ]] then echo -e "*** fname: ${FUNCNAME} ***" caller 0 fi if [[ ${#*} == 0 ]] then echo -e "usage: ${FUNCNAME} {var}" echo -e "example: ${FUNCNAME} root" return 0 fi local sk_cwhoamiREQUIRED_USER=${1} if [[ `whoami` != ${sk_cwhoamiREQUIRED_USER} ]] then echo -e "${RED}[-] You are not${NC} ${LCYAN}${sk_cwhoamiREQUIRED_USER}${NC}${RED}. Aborting.${NC}" exit 1 fi } function sk_removeslashes(){ if [[ ${DEBUG} == 1 ]] then echo -e "*** fname: ${FUNCNAME} ***" caller 0 fi echo ${1}|sed -e 's,//*,/,g' } if [[ ${SSH_CLIENT} != "" ]]; then sk_setcolors YESALL=0 fi sk_cwhoami root sk_cleanup sk_probe_kernel sk_cleanup