#!/bin/sh
#
#  This file is managed by FirewallFabrik - do not edit
#
#  FirewallFabrik fwf-nft v{{ version }}
#
#  Generated {{ timestamp }} {{ tz }} by {{ user }}
#
{% if manifest %}
{{ manifest }}
#
{% endif %}
{% if comment %}
{{ comment }}
#
{% endif %}
{% if errors_and_warnings %}
{{ errors_and_warnings }}
{% endif %}

{{ shell_debug }}
FWBDEBUG=""

PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}"
export PATH

NFT="{{ nft_path }}"
{% if shell_functions %}
IP="{{ ip_path }}"
LOGGER="logger"
{% endif %}

{% if shell_functions %}
{{ shell_functions }}
{% else %}
log() {
    echo "$1"
    which logger > /dev/null 2>&1 && logger -p info "$1"
}
{% endif %}

check_nft() {
    if [ ! -x "$NFT" ]; then
        echo "Error: nft not found at $NFT"
        exit 1
    fi
}
{% if verify_interfaces_code %}

verify_interfaces() {
    :
{{ verify_interfaces_code }}
}
{% endif %}

prolog_commands() {
    echo "Running prolog script"
    {{ prolog_script }}
    echo "Prolog script done"
}

epilog_commands() {
    echo "Running epilog script"
    {{ epilog_script }}
    echo "Epilog script done"
}

run_epilog_and_exit() {
    epilog_commands
    exit "$1"
}
{% if configure_interfaces_code %}

configure_interfaces() {
    :
{{ configure_interfaces_code }}
}
{% endif %}

script_body() {
    $NFT -f /dev/stdin <<'NFT_RULES'
{{ nft_rules_body }}
NFT_RULES
}

{% if routing_output %}
routing_script() {
    {{ routing_output }}
}

{% endif %}
ip_forward() {
    :
    {{ ip_forward_commands }}
}

block_action() {
    $NFT flush ruleset
    # block all traffic by default
    $NFT add table inet block
    $NFT add chain inet block input '{ type filter hook input priority 0; policy drop; }'
    $NFT add chain inet block forward '{ type filter hook forward priority 0; policy drop; }'
    $NFT add chain inet block output '{ type filter hook output priority 0; policy drop; }'
{% if mgmt_access %}
    # backup ssh access
    $NFT add rule inet block input tcp dport 22 ip saddr {{ ssh_management_address }} ct state new,established accept
    $NFT add rule inet block output tcp sport 22 ip daddr {{ ssh_management_address }} ct state established accept
{% endif %}
}

stop_action() {
    $NFT flush ruleset
}

check_nft_status() {
    tables=$($NFT list tables 2>/dev/null)
    if [ -n "$tables" ]; then
        return 0
    fi
    return 3
}

status_action() {
    check_nft_status
    ret=$?
    if [ $ret -eq 0 ]; then
        return 0
    fi
    echo "Firewall is not configured"
    exit 3
}

# See how we were called.
# For backwards compatibility missing argument is equivalent to 'start'

cmd=$1
test -z "$cmd" && {
    cmd="start"
}

case "$cmd" in
    start)
        log "Activating firewall script generated {{ timestamp }} by {{ user }}"
        check_nft
{% if prolog_place == 'top' %}
        prolog_commands
{% endif %}
{% if configure_interfaces_code %}
        configure_interfaces
{% endif %}
{% if verify_interfaces_code %}
        verify_interfaces
{% endif %}
{% if prolog_place == 'after_interfaces' %}
        prolog_commands
{% endif %}
        stop_action
{% if prolog_place == 'after_flush' %}
        prolog_commands
{% endif %}
        script_body || run_epilog_and_exit 1
{% if routing_output %}
        routing_script
{% endif %}
        ip_forward
        epilog_commands
        log "Firewall script is done"
        RETVAL=$?
        ;;

    stop)
        stop_action
        RETVAL=$?
        ;;

    status)
        status_action
        RETVAL=$?
        ;;

    block)
        block_action
        RETVAL=$?
        ;;

    reload)
        $0 stop
        $0 start
        RETVAL=$?
        ;;
{% if configure_interfaces_code %}

    interfaces)
        configure_interfaces
        RETVAL=$?
        ;;

    test_interfaces)
        FWBDEBUG="echo"
        configure_interfaces
        RETVAL=$?
        ;;
{% endif %}

    *)
{% if configure_interfaces_code %}
        echo "Usage $0 [start|stop|status|block|reload|interfaces|test_interfaces]"
{% else %}
        echo "Usage $0 [start|stop|status|block|reload]"
{% endif %}
        ;;

esac

exit "$RETVAL"
