#!/bin/bash # Copyright: 2023 Virtuozzo International GmbH # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. #nft -j list table inet jelastic | jq ".nftables[] | select (.rule.handle == 7 or .rule.handle == 6 ) " FW_FILTER_TABLE_NAME='filter' FW_NAT_TABLE_NAME='nat' FW_FILTER_INPUT_CHAIN='INPUT' FW_FILTER_OUTPUT_CHAIN='OUTPUT' FW_FILTER_FORWARD_CHAIN='FORWARD' FW_FORWARD_CHECKS_CHAIN='fw_checks' FW_FORWARD_LANS_CHAIN='fw_lans' FW_FORWARD_ACCOUNTS_CHAIN='fw_accounts' FW_NAT_POSTROUTING_CHAIN="POSTROUTING" FW_NAT_PREROUTING_CHAIN="PREROUTING" #valid values are: ip,ip6,inet FW_DEFAULT_TABLE_TYPE='ip' FW_V4_TABLE="ip" FW_V6_TABLE="ip6" #valid values accept,drop FW_DEFAULT_POLICY='drop' FW_PLATFORM_DEFINED_FILE="/etc/nftables/platform-defined.nft" FW_RULESET_FILE="/etc/nftables/main.nft" FW_USER_DEFINED_FILE="/etc/nftables/user-defined.nft" FW_CONTAINER_DEFINED_FILE="/etc/nftables/container-defined.nft" # $1 - type listTables() { nft list tables $1 | sed -E 's/table $1[[:space:]]+//g' } # $1 - type # $2 - name removeTable() { nft delete table $1 $2 } clearTables() { #supported tables ip,ip6,inet local families=('ip', 'ip6', 'inet') for f in ${families[@]} ; do tables=($(listTables $f)) for t in ${tables[@]} ; do removeTable $f $t done done } putShabang() { echo '#!/usr/sbin/nft -f' } setExists() { : ${1:?"Missing param: name"}; out=$(nft -j list sets inet | jq '.nftables[] | select(.set) | select(.set.name|test($var))' --arg var $1) [[ -n "$out" ]] } getNumberOfActiveSets() { local mask="${1:='.*'}" local re='^[0-9]+$' out=$(nft -j list sets | jq 'def count(s): reduce s as $i (0; .+1); count(.nftables[].set| select(.!=null) | select(.name|test($var)))' --arg var $mask) if ! [[ $out =~ $re ]] ; then echo "0" else echo $out fi } # 1 - type # 2 - name tableExists() { local ttype="${1:=$FW_DEFAULT_TABLE_TYPE}" local tname="${2:=$FW_FILTER_TABLE_NAME}" out=$(nft -j list tables | jq '.nftables[].table | select(.!=null) | select(.family|test($fam)) | select(.name|test($name))' --arg fam $ttype --arg name $tname) [[ -n "$out" ]] } # 1 - type # 2 - table name # 3 - chain name chainExists() { local ttype="${1:=$FW_DEFAULT_TABLE_TYPE}" local tname="${2:=$FW_FILTER_TABLE_NAME}" local cname="${3:="FORWARD"}" out=$(nft -j list tables | jq '.nftables[].chain | select(.!=null) | select(.table|test($tname)) | select (.name|test($cname)) | select(.family|test($ttype))' --arg ttype $ttype --arg tname $tname --arg cname $cname) [[ -n "$out" ]] } #create required tables with checks #used for isolation init #here is only V4 tables because isolation is not support V6 initTablesCheck() { #check filter table if ! tableExists $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME ; then echo "add table $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME" fi # check for input if ! chainExists $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN; then echo "add chain $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN { type filter hook input priority 0 ; policy $FW_DEFAULT_POLICY ; }" fi # check for forward if ! chainExists $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_FORWARD_CHAIN; then echo "add chain $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_FORWARD_CHAIN { type filter hook forward priority 0 ; policy $FW_DEFAULT_POLICY ; }" fi # check for output if ! chainExists $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_OUTPUT_CHAIN; then echo "add chain $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_OUTPUT_CHAIN { type filter hook output priority 0 ; policy $FW_DEFAULT_POLICY ; }" fi # check for forward_checks if ! chainExists $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FORWARD_CHECKS_CHAIN; then echo "add chain $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FORWARD_CHECKS_CHAIN" fi # check for forward_lans if ! chainExists $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FORWARD_LANS_CHAIN; then echo "add chain $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FORWARD_LANS_CHAIN " fi # check for forward_accounts if ! chainExists $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FORWARD_ACCOUNTS_CHAIN; then echo "add chain $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FORWARD_ACCOUNTS_CHAIN" fi #---------------------------------------------------------------------------------------------------------------------------- #check nat table if ! tableExists $FW_DEFAULT_TABLE_TYPE $FW_NAT_TABLE_NAME ; then echo "add table $FW_DEFAULT_TABLE_TYPE $FW_NAT_TABLE_NAME" fi # check for prerouting if ! chainExists $FW_DEFAULT_TABLE_TYPE $FW_NAT_TABLE_NAME $FW_NAT_PREROUTING_CHAIN; then echo "add chain $FW_DEFAULT_TABLE_TYPE $FW_NAT_TABLE_NAME $FW_NAT_PREROUTING_CHAIN { type nat hook prerouting priority -100 ; }" fi # check for postrouting if ! chainExists $FW_DEFAULT_TABLE_TYPE $FW_NAT_TABLE_NAME $FW_NAT_POSTROUTING_CHAIN; then echo "add chain $FW_DEFAULT_TABLE_TYPE $FW_NAT_TABLE_NAME $FW_NAT_POSTROUTING_CHAIN { type nat hook postrouting priority 100 ; }" fi } initTables() { #default firewall policy applied only for INPUT chains. FORWARD and OUTPUT always have "accept policy" ## IPv4 tables echo "add table $FW_V4_TABLE $FW_FILTER_TABLE_NAME" echo "add chain $FW_V4_TABLE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN { type filter hook input priority 0 ; policy $FW_DEFAULT_POLICY ; }" echo "add chain $FW_V4_TABLE $FW_FILTER_TABLE_NAME $FW_FILTER_FORWARD_CHAIN { type filter hook forward priority 0 ; policy accept ; }" echo "add chain $FW_V4_TABLE $FW_FILTER_TABLE_NAME $FW_FILTER_OUTPUT_CHAIN { type filter hook output priority 0 ; policy accept ; }" echo "add table $FW_V4_TABLE $FW_NAT_TABLE_NAME" echo "add chain $FW_V4_TABLE $FW_NAT_TABLE_NAME $FW_NAT_PREROUTING_CHAIN { type nat hook prerouting priority -100 ; }" echo "add chain $FW_V4_TABLE $FW_NAT_TABLE_NAME $FW_NAT_POSTROUTING_CHAIN { type nat hook postrouting priority 100 ; }" ## IPv6 tables echo "add table $FW_V6_TABLE $FW_FILTER_TABLE_NAME" echo "add chain $FW_V6_TABLE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN { type filter hook input priority 0 ; policy $FW_DEFAULT_POLICY ; }" echo "add chain $FW_V6_TABLE $FW_FILTER_TABLE_NAME $FW_FILTER_FORWARD_CHAIN { type filter hook forward priority 0 ; policy accept ; }" echo "add chain $FW_V6_TABLE $FW_FILTER_TABLE_NAME $FW_FILTER_OUTPUT_CHAIN { type filter hook output priority 0 ; policy accept ; }" echo "add table $FW_V6_TABLE $FW_NAT_TABLE_NAME" echo "add chain $FW_V6_TABLE $FW_NAT_TABLE_NAME $FW_NAT_PREROUTING_CHAIN { type nat hook prerouting priority -100 ; }" echo "add chain $FW_V6_TABLE $FW_NAT_TABLE_NAME $FW_NAT_POSTROUTING_CHAIN { type nat hook postrouting priority 100 ; }" } _doInitTables() { local rulesFile=$(mktemp) putShabang > $rulesFile initTablesCheck >> $rulesFile nft -f $rulesFile 2>> $JEM_CALLS_LOG if [ $? -eq 0 ] ; then rm $rulesFile fi } # $cmd $proto $ptype $dport $srchost $dsthost $chain $tcptype $raction addRule() { protos="${2,,}" if [ "x$protos" == "xall" ] ; then protos=('tcp' 'udp') else protos=($protos) fi local filter_tt=$FW_DEFAULT_TABLE_TYPE chain="${7^^}" dport="${4,,}" raction="${9,,}" tcptype="${8^^}" if [ "x$tcptype" == "xALL" ] ; then ttype=('IPV4' 'IPV6') else ttype=($tcptype) fi for tcptype in ${ttype[@]} ; do src="${5^^}" src=${src/ALL/0.0.0.0\/0} dst="${6^^}" dst=${dst/ALL/0.0.0.0\/0} if [ "x$tcptype" == "xIPV4" ] ; then tcptype="ip" else tcptype="ip6" src=${src/0.0.0.0\/0/::\/0} dst=${dst/0.0.0.0\/0/::\/0} filter_tt="ip6" fi # command can be add, insert, delete. default add cmd="${1,,}" if [ "x$cmd" != "x" ] ; then case $cmd in i) cmd="insert" ;; a) cmd="add" ;; esac else cmd="add" fi #source address if [ "x$src" != "x" ] ; then if grep -q '!' <<< $src ; then src=${src//'!'/} src="$tcptype saddr != $src" else src="$tcptype saddr $src" fi fi #destination address if [ "x$dst" != "x" ] ; then if grep -q '!' <<< $dst ; then dst=${dst//'!'/} dst="$tcptype daddr != $dst" else dst="$tcptype daddr $dst" fi fi for proto in ${protos[@]} ; do p="" dp="" ptype="${3,,}" if [ "x$ptype" == "xrange" ] ; then #proto should be specified if [ "x$proto" == "x" ] ; then return 2 fi if [ "x$dport" != "x" ] ; then #replace : to - dp=${dport/:/-} dp="$proto dport { $dp}" fi else if [ "x$dport" != "x" ] ; then dp="$proto dport $dport" else p="meta l4proto $proto" fi fi echo "$cmd rule $filter_tt $FW_FILTER_TABLE_NAME $chain $p $src $dst $dp counter $raction" done done } function netfilterStop() { systemctl disable firewalld &>> $JEM_CALLS_LOG systemctl enable nftables &>> $JEM_CALLS_LOG systemctl start nftables &>> $JEM_CALLS_LOG FW_DEFAULT_POLICY='accept' [[ -e "/etc/sysconfig/nftables.conf" ]] && sed -i -e 's|#include "/etc/nftables/main.nft"|include "/etc/nftables/main.nft"|' "/etc/sysconfig/nftables.conf" echo "`date +%D.%k:%M:%S.%N`: $action:$subaction flushing ruleset" >>$JEM_CALLS_LOG nft flush ruleset 2>>$JEM_CALLS_LOG echo "`date +%D.%k:%M:%S.%N`: $action:$subaction generating default ruleset" >>$JEM_CALLS_LOG local rulesFile=$(mktemp) putShabang > $rulesFile initTables >> $rulesFile echo "insert rule $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN ct state related,established counter accept" >> $rulesFile nft -f $rulesFile 2>> $JEM_CALLS_LOG rm $rulesFile 2>>$JEM_CALLS_LOG echo "`date +%D.%k:%M:%S.%N`: $action:$subaction default ruleset applied" >>$JEM_CALLS_LOG if [ -f "$FW_CONTAINER_DEFINED_FILE" ] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction loading rules from $FW_CONTAINER_DEFINED_FILE" >>$JEM_CALLS_LOG nft -c -f "$FW_CONTAINER_DEFINED_FILE" >>$JEM_CALLS_LOG 2>&1 if [[ $? -gt 0 ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction Static netfilter rules not loaded due to errors in $FW_CONTAINER_DEFINED_FILE. See logs for details" >>$JEM_CALLS_LOG else nft -f "$FW_CONTAINER_DEFINED_FILE" >>$JEM_CALLS_LOG 2>&1 echo "`date +%D.%k:%M:%S.%N`: $action:$subaction rules loaded" >>$JEM_CALLS_LOG fi fi } function setDefaultPolicy() { #stub return 0 } function netfilterRedirect() { __PORT=$1 __SPORT=$2 __PROTO=$3 local rules_file=$(vzctPath $VZ_CTID_ROOT $FW_USER_DEFINED_FILE) local portExists=$(vzexecRunStdOut "nft -a list chain $FW_DEFAULT_TABLE_TYPE $FW_NAT_TABLE_NAME $FW_NAT_PREROUTING_CHAIN | grep -E \"redirect to :$__PORT\" | grep -E \"dport $__SPORT\" | grep \"$__PROTO\"") if [ ! -z "$portExists" ] ; then writeJSONResponseErr "result=>4099" "message=>This pair SPORT:DPORT already exists" return 1 fi rule="insert rule $FW_DEFAULT_TABLE_TYPE $FW_NAT_TABLE_NAME $FW_NAT_PREROUTING_CHAIN ip protocol $__PROTO $__PROTO dport $__SPORT counter redirect to $__PORT" cmd="nft $rule" if vzexecRun "$cmd" ; then echo "$rule" >> "$rules_file" writeJSONResponseOut "result=>0" "message=>Port has been redirected" "sport=>$__SPORT" "dport=>$__PORT" return 0 fi } function getUsedPorts() { echo $(nft -a list chain $FW_DEFAULT_TABLE_TYPE $FW_NAT_TABLE_NAME $FW_NAT_PREROUTING_CHAIN | grep -E 'dnat' | cut -d' ' -f 3 | awk '!seen[$0]++') } function netfilterForward() { __IP=$1 __PORT=$2 __PROTO=$3 __SPORT=$4 rules_file=$FW_USER_DEFINED_FILE if [ ! -z $VZ_CTID_ROOT ] ; then rules_file=$(vzctPath $VZ_CTID_ROOT $FW_USER_DEFINED_FILE) fi if ! isValidIP $__IP ; then writeJSONResponseErr "result=>4083" "message=>Invalid IP specified" exit 1 fi local port=$(nft -a list chain $FW_DEFAULT_TABLE_TYPE $FW_NAT_TABLE_NAME $FW_NAT_PREROUTING_CHAIN | grep -E "$__PROTO dport $__SPORT dnat to $__IP:$__PORT") if [[ ! -z "$port" ]] ; then writeJSONResponseErr "result=>4092" "message=>This pair IP:PORT already bind to port $port" "port=>$port" exit 1 fi local freeport=$(getFreePort $__SPORT) if [[ -z "$freeport" ]] ; then writeJSONResponseErr "result=>4084" "message=>Unable to bind IP. There is no free ports" exit 1 fi if nft add rule $FW_NAT_TABLE_NAME $FW_NAT_PREROUTING_CHAIN ip protocol $__PROTO $__PROTO dport $freeport dnat to $__IP:$__PORT ; then echo "add rule $FW_NAT_TABLE_NAME $FW_NAT_PREROUTING_CHAIN ip protocol $__PROTO $__PROTO dport $freeport dnat to $__IP:$__PORT" >> "$rules_file" writeJSONResponseOut "result=>0" "message=>Port has been added" "port=>$freeport" return 0 fi } function netfilterSNAT() { __IP=$1 __NETWORK=$2 __PROTO=$3 if ! isValidIP $__IP ; then writeJSONResponseErr "result=>4083" "message=>Invalid IP specified" ; exit 1; fi # Check if binding already exists {{{ local port=$(nft -a list chain $FW_NAT_TABLE_NAME $FW_NAT_POSTROUTING_CHAIN | grep -E "ip protocol $__PROTO ip daddr $__NETWORK snat to $__IP") if [[ ! -z $port ]] ; then writeJSONResponseErr "result=>4092" "message=>This pair IP:NETWORK ($__IP:$__PROTO) already bind" exit 1 fi # }}} if nft add rule $FW_NAT_TABLE_NAME $FW_NAT_POSTROUTING_CHAIN ip protocol $__PROTO ip daddr $__NETWORK snat to $__IP ; then echo "add rule $FW_NAT_TABLE_NAME $FW_NAT_POSTROUTING_CHAIN ip protocol $__PROTO ip daddr $__NETWORK snat to $__IP" >> "$rules_file" writeJSONResponseOut "result=>0" "message=>SNAT has been added"; return 0 ; fi } function netfilterUnbind() { __IP=$1 __PORT=$2 __PROTO=$3 } #filename to save function saveCurrentRules() { savefile="${1:-$FW_RULESET_FILE}" nft -s list ruleset > "$savefile" 2>> $JEM_CALLS_LOG } function netfilterStart() { echo "`date +%D.%k:%M:%S.%N`: $action:$subaction Starting firewall" >>$JEM_CALLS_LOG #making backup of current rules [ ! -d "/etc/jelastic" ] && mkdir -p "/etc/jelastic" 2>>$JEM_CALLS_LOG echo "`date +%D.%k:%M:%S.%N`: $action:$subaction backup current rules" >>$JEM_CALLS_LOG saveCurrentRules "/etc/jelastic/jelastic.nft" #test rule files if [ -f "$FW_PLATFORM_DEFINED_FILE" ] ; then nft -c -f "$FW_PLATFORM_DEFINED_FILE" >>$JEM_CALLS_LOG 2>&1 if [[ $? -gt 0 ]] ; then echo "Current iptables rules not modified due to errors in new rule-files" >>$JEM_CALLS_LOG return 2 fi fi echo "`date +%D.%k:%M:%S.%N`: $action:$subaction flushing current rules" >>$JEM_CALLS_LOG nft flush ruleset 2>> $JEM_CALLS_LOG if [ -f "$FW_PLATFORM_DEFINED_FILE" ] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction loading rules from $FW_PLATFORM_DEFINED_FILE" >>$JEM_CALLS_LOG nft -f "$FW_PLATFORM_DEFINED_FILE" >>$JEM_CALLS_LOG 2>&1 fi #exports set -f NFSIPS=() [ -e '/etc/exports' ] && NFSIPS=($($SED -re 's/.+(\s|\t)+((\*)|([0-9]+\.){3}[0-9]+(\/[0-9]{0,2})?).*/\2/g' -e '/#/d' '/etc/exports' | sort | uniq | $SED -e '/^$/d' -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g')) local __allnetwork=0 # for internal services: intips=($(getLANIPs)) for ip in ${intips[@]} ; do for nfsip in ${NFSIPS[@]} ; do if [[ "${#NFSPort}" -gt 0 ]] ; then if [ "$nfsip" == "*" ] ; then nft add rule $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol tcp ip daddr $ip tcp dport { $NFSPort} counter accept 2>>$JEM_CALLS_LOG nft add rule $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol udp ip daddr $ip udp dport { $NFSPort} counter accept 2>>$JEM_CALLS_LOG __allnetwork=1 else if [[ "$__allnetwork" -eq 0 ]] ; then nft add rule $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol tcp ip saddr $nfsip ip daddr $ip tcp dport { $NFSPort} counter accept 2>>$JEM_CALLS_LOG nft add rule $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol udp ip saddr $nfsip ip daddr $ip udp dport { $NFSPort} counter accept 2>>$JEM_CALLS_LOG fi fi fi if [[ "${#RPCPort}" -gt 0 ]] ; then if [ "$nfsip" == "*" ] ; then nft add rule $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol tcp ip daddr $ip tcp dport { $RPCPort} counter accept 2>>$JEM_CALLS_LOG nft add rule $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol udp ip daddr $ip udp dport { $RPCPort} counter accept 2>>$JEM_CALLS_LOG __allnetwork=1 else if [[ "$__allnetwork" -eq 0 ]] ; then nft add rule $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol tcp ip saddr $nfsip ip daddr $ip tcp dport { $RPCPort} counter accept 2>>$JEM_CALLS_LOG nft add rule $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol udp ip saddr $nfsip ip daddr $ip udp dport { $RPCPort} counter accept 2>>$JEM_CALLS_LOG fi fi fi done done; set +f #TODO: Remove it #tomcat has no this interface anymore #nft add rule $FW_DEFAULT_TABLE_TYPE $FW_TABLE_NAME input iifname "tap" accept redirPorts=($(isFunction _get$($SED -re 's/-/_/g' <<< ${COMPUTE_TYPE})RedirPorts && { _get$($SED -re 's/-/_/g' <<< ${COMPUTE_TYPE})RedirPorts; } || _defaultComputeNodeRedirPorts)); # process input chain NAT for port in ${redirPorts[@]} ; do local ruleParams=($($SED 's/:/ /g' <<< ${port})); nft add rule $FW_DEFAULT_TABLE_TYPE $FW_NAT_TABLE_NAME ${ruleParams[0]^^} ip saddr ${ruleParams[1]} ip daddr ${ruleParams[2]} tcp dport ${ruleParams[3]} counter ${ruleParams[5],,} to ${ruleParams[4]} 2>>$JEM_CALLS_LOG done; if [ -f "$FW_CONTAINER_DEFINED_FILE" ] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction loading rules from $FW_CONTAINER_DEFINED_FILE" >>$JEM_CALLS_LOG nft -c -f "$FW_CONTAINER_DEFINED_FILE" >>$JEM_CALLS_LOG 2>&1 if [[ $? -gt 0 ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction Static netfilter rules not loaded due to errors in $FW_CONTAINER_DEFINED_FILE. See logs for details" >>$JEM_CALLS_LOG else nft -f "$FW_CONTAINER_DEFINED_FILE" >>$JEM_CALLS_LOG 2>&1 echo "`date +%D.%k:%M:%S.%N`: $action:$subaction rules loaded" >>$JEM_CALLS_LOG fi fi if [ -f "$FW_USER_DEFINED_FILE" ] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction loading rules from $FW_USER_DEFINED_FILE" >>$JEM_CALLS_LOG nft -c -f "$FW_USER_DEFINED_FILE" >>$JEM_CALLS_LOG 2>&1 if [[ $? -gt 0 ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction Custom netfilter rules not loaded due to errors in $FW_USER_DEFINED_FILE. See logs for details" >>$JEM_CALLS_LOG else nft -f "$FW_USER_DEFINED_FILE" >>$JEM_CALLS_LOG 2>&1 echo "`date +%D.%k:%M:%S.%N`: $action:$subaction rules loaded" >>$JEM_CALLS_LOG fi fi if [ -f /proc/net/if_inet6 ] ; then nft insert rule $FW_V6_TABLE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN meta l4proto ipv6-icmp accept 2>>$JEM_CALLS_LOG nft insert rule $FW_V6_TABLE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN iifname "lo" counter accept 2>>$JEM_CALLS_LOG nft insert rule $FW_V6_TABLE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN ct state related,established counter accept 2>>$JEM_CALLS_LOG fi nft insert rule $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN $FW_DEFAULT_TABLE_TYPE protocol icmp counter accept 2>>$JEM_CALLS_LOG nft insert rule $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN iifname "lo" counter accept 2>>$JEM_CALLS_LOG nft insert rule $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN ct state related,established counter accept 2>>$JEM_CALLS_LOG #JE-67929 nft insert rule $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN icmp type timestamp-request counter drop 2>>$JEM_CALLS_LOG nft -a list chain ip filter INPUT | grep -q "reject with icmp host-prohibited" || nft add rule ip filter INPUT counter reject with icmp type host-prohibited 2>>$JEM_CALLS_LOG } function netfilterEnable() { systemctl disable firewalld &>> $JEM_CALLS_LOG systemctl enable nftables &>> $JEM_CALLS_LOG systemctl start nftables &>> $JEM_CALLS_LOG [[ -e "/etc/sysconfig/nftables.conf" ]] && sed -i -e 's|#include "/etc/nftables/main.nft"|include "/etc/nftables/main.nft"|' "/etc/sysconfig/nftables.conf" if [ -f "$FW_PLATFORM_DEFINED_FILE" ] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction loading rules from $FW_PLATFORM_DEFINED_FILE" >>$JEM_CALLS_LOG nft -f "$FW_PLATFORM_DEFINED_FILE" &>> $JEM_CALLS_LOG 2>&1 else #init required tables FW_DEFAULT_POLICY='accept' echo "`date +%D.%k:%M:%S.%N`: $action:$subaction $FW_PLATFORM_DEFINED_FILE not found" >>$JEM_CALLS_LOG echo "`date +%D.%k:%M:%S.%N`: $action:$subaction generating default ruleset" >>$JEM_CALLS_LOG local rulesFile=$(mktemp) putShabang > $rulesFile initTables >> $rulesFile echo "insert rule $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN ct state related,established counter accept" >> $rulesFile nft -f $rulesFile 2>> $JEM_CALLS_LOG rm $rulesFile 2>>$JEM_CALLS_LOG echo "`date +%D.%k:%M:%S.%N`: $action:$subaction default ruleset applied" >>$JEM_CALLS_LOG fi if [ -f "$FW_CONTAINER_DEFINED_FILE" ] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction loading rules from $FW_CONTAINER_DEFINED_FILE" >>$JEM_CALLS_LOG nft -c -f "$FW_CONTAINER_DEFINED_FILE" >>$JEM_CALLS_LOG 2>&1 if [[ $? -gt 0 ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction Static netfilter rules not loaded due to errors in $FW_CONTAINER_DEFINED_FILE. See logs for details" >>$JEM_CALLS_LOG else nft -f "$FW_CONTAINER_DEFINED_FILE" >>$JEM_CALLS_LOG 2>&1 echo "`date +%D.%k:%M:%S.%N`: $action:$subaction rules loaded" >>$JEM_CALLS_LOG fi fi nft -a list chain ip filter INPUT | \ grep -q 'iifname "lo" counter' || \ nft insert rule $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN iifname "lo" counter accept 2>>$JEM_CALLS_LOG } # global variable RULES required see firewall.module firewallSet() { if [ ${#RULES[@]} -eq 0 ] ; then echo "rules are epmty" return 1 fi putShabang > "$(vzctPath $VZ_CTID_ROOT $FW_PLATFORM_DEFINED_FILE)" initTables >> "$(vzctPath $VZ_CTID_ROOT $FW_PLATFORM_DEFINED_FILE)" for ruleraw in ${RULES[@]} ; do rulevars=$(awk -F, '{print "proto="$1";ptype="$2";dport="$3";srchost="$4";dsthost="$5";chain="$6";raction="$7";tcptype="$8";cmd="$9";"}' <<< $ruleraw ) eval $rulevars addRule "$cmd" "$proto" "$ptype" "$dport" "$srchost" "$dsthost" "$chain" "$tcptype" "$raction" >> "$(vzctPath $VZ_CTID_ROOT $FW_PLATFORM_DEFINED_FILE)" res=$? if [ $res -gt 0 ] ; then echo "error adding rules" return 1 fi done } function netfilterList() { nft list ruleset $@ }