#!/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. inherit default os net; include log vzexec virtuozzo; DESCRIPTION="Manipulate DNAT iptables rules"; VERSION="1.2" DEFAULT_ACTION="Usage"; $PROGRAM 'iptables'; $PROGRAM 'tail'; $PROGRAM 'sed'; $PROGRAM 'grep'; FORWARD_RANGE_START=50000 FORWARD_RANGE_END=55000 NAT_ACTION='dnat' EXEC="/bin/bash -c " FIREWALL_RULES_DIR="/etc/jelastic/iptables" function doUsage() { showUsageMessage } function onModLoadCallback() { local args=$(getopt -o c:i:p:s:a: -l "ctid:,ip:,dport:,sport:,proto:,net:,action" -- "$@"); [[ $? != 0 ]] && die -q "Terminating..."; eval set -- "${args}"; while true ; do case "${1}" in -i|--ip) case "${2}" in "") die -q "Please specify IP address param." ;; *) __IP=${2}; shift 2 ;; esac ;; -p|--dport) case "${2}" in "") die -q "Please specify destination port param." ;; *) __PORT=${2}; shift 2 ;; esac ;; -s|--sport) case "${2}" in "") die -q "Please specify source port param." ;; *) __SPORT=${2}; shift 2 ;; esac ;; --proto) case "${2}" in "") die -q "Please specify proto param." ;; *) __PROTO=`echo ${2} | tr A-Z a-z`; shift 2 ;; esac ;; --net) case "${2}" in "") die -q "Please specify network param." ;; *) __NETWORK=${2}; shift 2 ;; esac ;; -a | --action) case "${2}" in "") die -q "Please specify action param." ;; *) NAT_ACTION=`echo ${2} | tr A-Z a-z`; shift 2 ;; esac ;; -c|--ctid) CTID=$2 vzexecSetCTID $CTID shift 2;; --) shift ; break ;; *) die -q "ROUTER.MODULE (onModLoadCallback) Internal error!"; esac; done [ -z "$__PROTO" ] && __PROTO=tcp ; if [[ ! -z "${CTID}" ]] ; then populateVEVarsVZ $CTID res=$? if [[ "$res" -eq 3 ]] ; then writeJSONResponseErr "result=>4003" "message=>ctid $CTID not found" die -q; fi VZ_CTID_ROOT=$VZ_VEID_ROOT else local issue_file="/etc/issue" local release_files="/etc/*-release" issue_string=$(set +f; cat $release_files $issue_file 2>/dev/null) VZ_VEID_OS=$(detectOS "$issue_string") VZ_VEID_OS_VER=$(getOSVersion "$issue_string") VZ_VEID_OS_VER=${VZ_VEID_OS_VER%%.*} fi if [ "x$VZ_VEID_OS" == "xalmalinux" -a "$VZ_VEID_OS_VER" -ge "9" ] ; then inherit nftables else inherit iptables fi return 0 } function getFreePort() { __SPORT=$1 [ ! -z "$__SPORT" ] && { echo $__SPORT ; return ; } local usedPorts=($(getUsedPorts)) eval "availablePorts=($(seq ${FORWARD_RANGE_START} ${FORWARD_RANGE_END}| sed -re 's/([0-9]+)/[\1]="0"/g'))" for port in "${!usedPorts[@]}"; do availablePorts[${usedPorts[$port]}]=1 done; freePorts=($( for key in "${!availablePorts[@]}"; do [[ ${availablePorts["${key}"]} -eq 0 ]] && echo "$key"; done | sort -n )) echo ${freePorts[0]} } function describeForward() { echo "Get and add free port for DNAT for specified local IP:Port"; } function describeForwardParameters() { echo "--ip --dport [--sport ] [--proto ]"; } function describeForwardOptions() { echo "--ip: destination IP address"; echo "--dport: destination port"; echo "--sport: source port"; echo "--proto: protocol"; } function doRedirect() { : ${__PORT? "Missing destination port" } : ${__SPORT? "Missing source port" } : ${__PROTO? "Missing protocol" } echo "`date +%D.%k:%M:%S.%N`: $action:$subaction performing redirect" >>$JEM_CALLS_LOG isFunction "netfilterRedirect" && netfilterRedirect $__PORT $__SPORT $__PROTO } function doForward() { echo "`date +%D.%k:%M:%S.%N`: $action:$subaction performing forward" >>$JEM_CALLS_LOG isFunction "netfilterForward" && netfilterForward $__IP $__PORT $__PROTO $__SPORT } function describeSNAT() { echo "Add SNAT"; } function describeForwardParameters() { echo "--ip --net [--proto ]"; } function describeForwardOptions() { echo "--ip: destination IP address"; echo "--net: network"; echo "--proto: protocol"; } function doSNAT() { : ${__IP? "Missing IP address" } : ${__NETWORK? "Missing network" } echo "`date +%D.%k:%M:%S.%N`: $action:$subaction performing SNAT" >>$JEM_CALLS_LOG isFunction "netfilterSNAT" && netfilterSNAT $__IP $__NETWORK $__PROTO } function describeUnbind() { echo "Delete specified IP[:Port] binding for DNAT"; } function describeUnbindParameters() { echo "--ip [--dport ] [--proto ]"; } function describeUnbindOptions { echo "--ip: destination IP address"; echo "--dport: destination port"; echo "--proto: protocol"; } function doUnbind() { : ${__IP? "Missing IP address" } : ${__PROTO? "Missing protocol" } echo "`date +%D.%k:%M:%S.%N`: $action:$subaction performing unbind" >>$JEM_CALLS_LOG isFunction "netfilterUnbind" && netfilterUnbind $__IP $__PORT $__PROTO } # vim: syntax=sh