1#!/bin/bash 2 3### Exit error codes 4# 5# 0: everything went fine 6# 255: invalid command line-option 7# 254: no root privileges 8# 253: file or directory does not exist 9# 252: policy build failed 10# 251: policy install failed 11# 250: unsupported os/distribution/version 12# 249: conflicting parameters 13# 248: internal error at task selection 14# 246: syslog-ng not installed 15# 244: tty not available 16 17EL_FC= 18EL_TE= 19OS_VERSION= 20INSTALL_PATH="/opt/syslog-ng" 21# RHEL8 note: ports 10514/tcp, 10514/udp, 20514/tcp and 20514/udp have been 22# allowed by default 23# 24# Post-RHEL6.5 note: ports 514/udp, 6514/udp and 6514/tcp are allowed by default 25# if you wish to add further ports, just add them to the end of the list 26SYSLOG_NG_TCP_PORTS="601" 27SYSLOG_NG_UDP_PORTS="601" 28TASK_SELECTED="install_default" 29INPUT= 30 31get_console_tty() { 32 if is_available tty; then 33 CONSOLE_TTY=$( tty ) 34 else 35 echo "The 'tty' binary is not available!" >&2 36 exit 244 37 fi 38} 39 40 41query_install_path() { 42 echo -n "Please enter your installation path for Syslog-ng PE: [${INSTALL_PATH}] " 43 read INPUT <"${CONSOLE_TTY}" 44} 45 46 47check_dir() { 48 if [ -d "${1}" ]; then 49 return 0 50 else 51 echo "The directory you specified does not exist!" >&2 52 return 1 53 fi 54} 55 56 57verify_input() { 58 INPUT="${INPUT:-${INSTALL_PATH}}" 59 echo -n "You have entered '${INPUT}'. Is this correct? [y/N] " 60 read ACCEPT <"${CONSOLE_TTY}" 61 if [ "x${ACCEPT}x" != "xyx" ]; then return 0; fi 62 check_dir "${INPUT}" && return 1 || return 0 63} 64 65 66is_available () { 67 which "$1" >/dev/null 2>&1; 68} 69 70 71syslog_ng_is_not_installed() { 72 if is_available syslog-ng; then 73 return 1 74 elif [ -x "${INSTALL_PATH}/sbin/syslog-ng" ]; then 75 return 1 76 else 77 return 0 78 fi 79} 80 81 82install_precheck() { 83 if syslog_ng_is_not_installed; then 84 echo "Syslog-ng does not seem to be installed!" >&2 85 exit 246 86 fi 87} 88 89 90extract_version_string() { 91 sed -n 's:^[a-zA-Z ]\+\([0-9]\+\.[0-9]\+\)\(.[0-9]\+\)\?[a-zA-Z ()]\+$:\1:p' 92} 93 94 95detect_os_version() { 96 echo "Detecting RHEL/CentOS/Oracle Linux version..." 97 if [ -x "/usr/bin/lsb_release" ]; then 98 if lsb_release -d | grep -qE "Description:[[:space:]]+(CentOS|CentOS Linux|Red Hat Enterprise Linux Server|Oracle Linux Server|Enterprise Linux Enterprise Linux Server) release"; then 99 OS_VERSION=$( lsb_release -r | cut -f 2 ) 100 else 101 echo "You don't seem to be running a supported Linux distribution!" >&2 102 exit 250 103 fi 104 else 105 # The package redhat-lsb-core is most likely not installed... 106 if [ -f "/etc/redhat-release" ]; then 107 OS_VERSION=$( extract_version_string < "/etc/redhat-release" ) 108 else 109 echo "You don't seem to be running a supported OS!" >&2 110 exit 250 111 fi 112 fi 113} 114 115 116omit_allowed_tcp_ports() { 117 sed -e 's:^601::g' 118} 119 120 121omit_allowed_udp_ports() { 122 sed -e 's:^601::g' 123} 124 125 126omit_allowed_ports() { 127 SYSLOG_NG_TCP_PORTS=$( omit_allowed_tcp_ports <<<"${SYSLOG_NG_TCP_PORTS}" ) 128 SYSLOG_NG_UDP_PORTS=$( omit_allowed_udp_ports <<<"${SYSLOG_NG_UDP_PORTS}" ) 129} 130 131 132setup_vars() { 133 echo "Detected RHEL/CentOS/Oracle Linux ${OS_VERSION}." 134 case "${OS_VERSION}" in 135 5.*) 136 137 EL_FC="syslog_ng.el5.fc.in" 138 EL_TE="syslog_ng.el5.te.in" 139 ;; 140 6.*) 141 EL_FC="syslog_ng.el6.fc.in" 142 143 local MINORVER 144 MINORVER=$( cut -d. -f 2 <<<"${OS_VERSION}" ) 145 if [ "${MINORVER}" -lt 5 ]; then 146 EL_TE="syslog_ng.el6.0to4.te.in" 147 else 148 EL_TE="syslog_ng.el6.5up.te.in" 149 150 # 601/tcp and 601/udp are allowed by default on RHEL6.5+, so there is no need to enable them 151 omit_allowed_ports 152 fi 153 ;; 154 7.*) 155 EL_FC="syslog_ng.el78.fc.in" 156 EL_TE="syslog_ng.el7.te.in" 157 158 # 601/tcp and 601/udp are allowed by default on RHEL7, so there is no need to enable them 159 omit_allowed_ports 160 ;; 161 8.*) 162 EL_FC="syslog_ng.el78.fc.in" 163 EL_TE="syslog_ng.el8.te.in" 164 165 # 601/tcp and 601/udp are allowed by default on RHEL8, so there is no need to enable them 166 omit_allowed_ports 167 ;; 168 *) 169 echo "You don't seem to be running a supported version of RHEL!" >&2 170 exit 250 171 ;; 172 esac 173} 174 175 176substitute_install_path() { 177 sed -e "s:^\\\$PATH\\\$:${INSTALL_PATH}:g" "src/root_unsafe/${EL_FC}" 178 sed -e "s:^\\\$PATH\\\$:${INSTALL_PATH}:g" "src/root_safe/${EL_FC}" 179} 180 181 182omit_install_path() { 183 sed -e "s:^\\\$PATH\\\$::g" "src/root_safe/${EL_FC}" 184} 185 186 187prepare_files() { 188 echo "Using '${INSTALL_PATH}'..." 189 if [ "${INSTALL_PATH}" != "/" ]; then 190 191 substitute_install_path > "syslog_ng.fc" 192 else 193 omit_install_path > "syslog_ng.fc" 194 fi 195 cat "src/syslog_ng.module.version" "src/${EL_TE}" > "syslog_ng.te" 196} 197 198 199remove_trainling_slash() { 200 # the trailing slash in the install path (if present) breaks file context rules 201 # thus it needs to be removed (provided that the install path is not "/" itself) 202 sed -e 's:^\(.\+\)/$:\1:' 203} 204 205 206filter_bogus_build_output() { 207 #filter misleading output caused by RHEL bug 1861968 208 fgrep -v /usr/share/selinux/devel/include/services/container.if 209} 210 211 212build_module() { 213 echo "Building and Loading Policy" 214 build_output=$( make -f /usr/share/selinux/devel/Makefile syslog_ng.pp 2>&1 ) 215 retval=${?} 216 filter_bogus_build_output <<<"${build_output}" 217 [ ${retval} -eq 0 ] || exit 252 218} 219 220 221add_ports() { 222 for entry in ${@}; do 223 port=${entry%/*} 224 proto=${entry#*/} 225 semanage port -a -t syslogd_port_t -p ${proto} ${port} 2>/dev/null || \ 226 semanage port -m -t syslogd_port_t -p ${proto} ${port} 2>/dev/null 227 done 228} 229 230 231install_module() { 232 if /usr/sbin/semodule -l | grep -qw syslog_ng; then 233 echo "The Syslog-ng SELinux policy module is already installed. Nothing to do..." 234 echo "If it belongs to a previous version, then you will have to remove it first." 235 else 236 /usr/sbin/semodule -i syslog_ng.pp -v || exit 251 237 238 # set up syslog-ng specific ports 239 PORTS= 240 for port in ${SYSLOG_NG_TCP_PORTS}; do PORTS="${PORTS} ${port}/tcp"; done 241 for port in ${SYSLOG_NG_UDP_PORTS}; do PORTS="${PORTS} ${port}/udp"; done 242 add_ports "${PORTS}" 243 244 # Fixing the file context 245 /sbin/restorecon -F -Rv "${INSTALL_PATH}" 246 [ -f /etc/init.d/syslog-ng ] && /sbin/restorecon -F -v /etc/init.d/syslog-ng 247 [ -f /etc/rc.d/init.d/syslog-ng ] && /sbin/restorecon -F -v /etc/rc.d/init.d/syslog-ng 248 /sbin/restorecon -F -Rv /dev/log 249 250 echo -e "\nInstallation of the Syslog-ng SELinux policy module finished.\nPlease restart syslog-ng. You can find more information about this in the README file." 251 fi 252} 253 254remove_ports() { 255 for entry in ${@}; do 256 port=${entry%/*} 257 proto=${entry#*/} 258 semanage port -d -t syslogd_port_t -p ${proto} ${port} 2>/dev/null 259 done 260} 261 262remove_module() { 263 if /usr/sbin/semodule -l | grep -q syslog_ng; then 264 echo -n "Removing Syslog-ng SELinux policy module... " 265 266 /usr/sbin/semodule --remove=syslog_ng 267 268 # unconfigure syslog-ng specific ports 269 PORTS= 270 for port in ${SYSLOG_NG_TCP_PORTS}; do PORTS="${PORTS} ${port}/tcp"; done 271 for port in ${SYSLOG_NG_UDP_PORTS}; do PORTS="${PORTS} ${port}/udp"; done 272 remove_ports "${PORTS}" 273 274 [ -f syslog_ng.pp ] && rm -f syslog_ng.pp 275 [ -f syslog_ng.te ] && rm -f syslog_ng.te 276 [ -f syslog_ng.fc ] && rm -f syslog_ng.fc 277 [ -f syslog_ng.if ] && rm -f syslog_ng.if 278 [ -d tmp ] && rm -Rf tmp 279 280 echo "done." 281 else 282 echo "No installed Syslog-ng SELinux policy module was found. No removal is necessary. Skipping..." 283 fi 284} 285 286DIRNAME=$( dirname "${0}" ) 287cd "${DIRNAME}" 288USAGE="Usage: $0\t[ --install-dir <DIRECTORY> | --remove | --help ]\n\n$0:\tA tool for building and managing the SELinux policy for the\n\t\tdefault syslog-ng installation." 289 290 291while [ -n "${1}" ]; do 292 case "${1}" in 293 --help) 294 # if --help is supplied, the help message will be printed independently of any other options being specified 295 TASK_SELECTED="showhelp" 296 break 297 ;; 298 --install-dir) 299 [ "${TASK_SELECTED}" = "remove" ] && echo -e "ERROR: Conflicting options!\n\n${USAGE}" >&2 && exit 249 300 TASK_SELECTED="install" 301 check_dir "${2}" || exit 253 302 INPUT="${2}" 303 shift 2 304 ;; 305 --remove) 306 [ "${TASK_SELECTED}" = "install" ] && echo -e "ERROR: Conflicting options!\n\n${USAGE}" >&2 && exit 249 307 TASK_SELECTED="remove" 308 shift 309 ;; 310 *) 311 echo -e "ERROR: Invalid option: '${1}'\n${USAGE}" >&2 312 exit 255 313 ;; 314 esac 315 316done 317 318case "${TASK_SELECTED}" in 319 showhelp) 320 echo -e "${USAGE}" 321 exit 0 322 ;; 323 remove) 324 detect_os_version 325 setup_vars 326 remove_module 327 exit 0 328 ;; 329 install|install_default) 330 if [ $( id -u ) != 0 ]; then 331 echo 'You must be root to run this script!' >&2 332 exit 254 333 fi 334 335 get_console_tty 336 337 if [ -z "${INPUT}" ]; then 338 query_install_path 339 while verify_input; do 340 query_install_path 341 done 342 fi 343 344 INSTALL_PATH=$( remove_trainling_slash <<<"${INPUT}" ) 345 346 detect_os_version 347 install_precheck 348 setup_vars 349 prepare_files 350 build_module 351 install_module 352 ;; 353 *) 354 echo -e "ERROR: Invalid task: '${TASK_SELECTED}'!" >&2 355 exit 248 356 ;; 357esac 358