diff --git a/net-firewall/nftables/Manifest b/net-firewall/nftables/Manifest new file mode 100644 index 000000000..49c3f0569 --- /dev/null +++ b/net-firewall/nftables/Manifest @@ -0,0 +1,4 @@ +DIST nftables-1.1.1.tar.xz 989700 BLAKE2B f273c78369ba755049c6afa63eba195cf29f926fa8fc9bf344022904c00a8c6c4259cc5093e23993a55fd25790af575305df79a7c28624fa7082661b2eed70d0 SHA512 676413d4adadffb15d52c1f8f6432636cab83a7bcda1a18d9f0e6b58819a2c027a49922588c02bd9ad386de930eaa697bfe74c0938b595bf1ee485bfa7cf2e50 +DIST nftables-1.1.1.tar.xz.sig 566 BLAKE2B b7debda3373972f69af9b4b23e1b66a8fd156440187aafba605bb7342c267207e5aa628256e96432ebd4583a6a9436e1969a33636111d2bd8d57185a01e2d502 SHA512 fc23034c512f686167203e827ff2a8f7cb64530211ce92a28793bd49577ce3bf519ffbe910b0071cb21925898497cb5cbf70121c68bfcdbfa4460c63a14203ac +DIST nftables-1.1.3.tar.xz 990172 BLAKE2B 35f4ece6c27b29a14bc71bb7893971134950509a713e84453e1f87df6b07cda327314d6dbbf048032a047652b8817f8ee8a5d74a56e356088495edd1dbbed000 SHA512 b5c244cb6db73eb232e5c999e07403b60c543efb9c4b9991838cc9c43a1bd08ca7b2926233536cbb0cc66e2a9acc4fbddc4b5565f5665e753c107a8739a86040 +DIST nftables-1.1.3.tar.xz.sig 566 BLAKE2B 4f0e9c89213b46d3445a729bf96b1790adc53725f31134f9028297e99d83ac43f5094f9cfa0efee903dc691781dd5d67a814583ff1c645776f1a46266dc2681f SHA512 7aa972c146e0dfaacc8faaef9b9ebbe419f7cbc5814d1fb978b35a4972d384aabe2e6e053fefc6d5d042acb9bff5f35e5f97cbee0c4a0152c53ab9c2e5b0335f diff --git a/net-firewall/nftables/files/libexec/nftables-mk.sh b/net-firewall/nftables/files/libexec/nftables-mk.sh new file mode 100644 index 000000000..27defe3c1 --- /dev/null +++ b/net-firewall/nftables/files/libexec/nftables-mk.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +main() { + local NFTABLES_SAVE=${2:-'/var/lib/nftables/rules-save'} + case "$1" in + "check") + nft -c -f "${NFTABLES_SAVE}" + ;; + "clear") + nft flush ruleset + ;; + "list") + nft ${SAVE_OPTIONS} list ruleset + ;; + "load") + # We use an include because cat fails with long rulesets see #675188 + printf 'flush ruleset\ninclude "%s"\n' "${NFTABLES_SAVE}" | nft -f - + ;; + "panic") + panic hard | nft -f - + ;; + "soft_panic") + panic soft | nft -f - + ;; + "store") + local tmp_save="${NFTABLES_SAVE}.tmp" + umask 177 + ( + printf '#!/sbin/nft -f\nflush ruleset\n' + nft ${SAVE_OPTIONS} list ruleset + ) > "$tmp_save" && mv ${tmp_save} ${NFTABLES_SAVE} + ;; + esac +} + +panic() { + local erule; + [ "$1" = soft ] && erule="ct state established,related accept;" || erule=""; + cat < ${tmp_save} + else + save_legacy ${tmp_save} + fi + retval=$? + if [ ${retval} ]; then + mv ${tmp_save} ${NFTABLES_SAVE} + fi + ;; + esac + return ${retval} +} + +clear_legacy() { + local l3f line table chain first_line + + first_line=1 + if manualwalk; then + for l3f in $(getfamilies); do + nft list tables ${l3f} | while read line; do + table=$(echo ${line} | sed "s/table[ \t]*//") + deletetable ${l3f} ${table} + done + done + else + nft list tables | while read line; do + l3f=$(echo ${line} | cut -d ' ' -f2) + table=$(echo ${line} | cut -d ' ' -f3) + deletetable ${l3f} ${table} + done + fi +} + +list_legacy() { + local l3f + + if manualwalk; then + for l3f in $(getfamilies); do + nft list tables ${l3f} | while read line; do + line=$(echo ${line} | sed "s/table/table ${l3f}/") + echo "$(nft list ${line})" + done + done + else + nft list tables | while read line; do + echo "$(nft list ${line})" + done + fi +} + +save_legacy() { + tmp_save=$1 + touch "${tmp_save}" + if manualwalk; then + for l3f in $(getfamilies); do + nft list tables ${l3f} | while read line; do + line=$(echo ${line} | sed "s/table/table ${l3f}/") + nft ${SAVE_OPTIONS} list ${line} >> ${tmp_save} + done + done + else + nft list tables | while read line; do + nft ${SAVE_OPTIONS} list ${line} >> "${tmp_save}" + done + fi +} + +use_legacy() { + local major_ver minor_ver + + major_ver=$(uname -r | cut -d '.' -f1) + minor_ver=$(uname -r | cut -d '.' -f2) + + [ $major_ver -ge 4 -o $major_ver -eq 3 -a $minor_ver -ge 18 ] && return 1 + return 0 +} + +CHECK_TABLE_NAME="GENTOO_CHECK_TABLE" + +getfamilies() { + local l3f families + + for l3f in ip arp ip6 bridge inet; do + if nft create table ${l3f} ${CHECK_TABLE_NAME} > /dev/null 2>&1; then + families="${families}${l3f} " + nft delete table ${l3f} ${CHECK_TABLE_NAME} + fi + done + echo ${families} +} + +manualwalk() { + local result l3f=`getfamilies | cut -d ' ' -f1` + + nft create table ${l3f} ${CHECK_TABLE_NAME} + nft list tables | read line + if [ $(echo $line | wc -w) -lt 3 ]; then + result=0 + fi + result=1 + nft delete table ${l3f} ${CHECK_TABLE_NAME} + + return $result +} + +deletetable() { + # family is $1 + # table name is $2 + nft flush table $1 $2 + nft list table $1 $2 | while read l; do + chain=$(echo $l | grep -o 'chain [^[:space:]]\+' | cut -d ' ' -f2) + if [ -n "${chain}" ]; then + nft flush chain $1 $2 ${chain} + nft delete chain $1 $2 ${chain} + fi + done + nft delete table $1 $2 +} + +main "$@" diff --git a/net-firewall/nftables/files/man-pages/gen-manpages.bash b/net-firewall/nftables/files/man-pages/gen-manpages.bash new file mode 100644 index 000000000..a2223d3dd --- /dev/null +++ b/net-firewall/nftables/files/man-pages/gen-manpages.bash @@ -0,0 +1,72 @@ +#!/bin/bash +# +# create manpages for nftables + +declare -A MAN_PAGES + +MAN_PAGES=( + [nft.8]="nft.txt" + [libnftables-json.5]="libnftables-json.adoc" + [libnftables.3]="libnftables.adoc" +) + +build_manpages() { + tar axf "${distfile}" -C "${srcdir}" || return + + pushd "${srcdir}/${version}/doc" > /dev/null || return + local manpage + for manpage in "${!MAN_PAGES[@]}"; do + a2x -L --doctype manpage --format manpage -D . "${MAN_PAGES[${manpage}]}" || return + done + popd > /dev/null || return + + local -a tarfiles + readarray -t tarfiles < <(printf -- "${version}/doc/%s\\n" "${!MAN_PAGES[@]}") + + tar -Jc --owner='root:0' --group='root:0' \ + --transform="s:^${version}/doc:${version}-manpages:" \ + -f "${version}-manpages.tar.xz" \ + -C "${srcdir}" \ + "${tarfiles[@]}" || return + + rm -rf "${srcdir:?}/${version}" || return +} + +main() { + shopt -s failglob + local version="${1}" srcdir="${0%/*}" + + if [[ -z ${version} ]]; then + # shellcheck disable=SC2016 + version=$( + find . -maxdepth 1 -type d -a -name 'nftables-*' -printf '%P\0' 2>/dev/null \ + | LC_COLLATE=C sort -z \ + | sed -z -n '${p;Q}' \ + | tr -d '\000' + ) + if [[ -z ${version} ]]; then + # shellcheck disable=SC2016 + version=$( + find . -maxdepth 3 -mindepth 3 -type f -a -name 'nftables-*.ebuild' -printf '%P\0' 2>/dev/null \ + | LC_COLLATE=C sort -z \ + | sed -r -z -n '${s:.*/::;s:-r[0-9]+::;s:[.]ebuild::;p;Q}' \ + | tr -d '\000' + ) + if [[ -z ${version} ]]; then + printf 'Usage %s \n' "${0}" >&2 + return 1 + fi + fi + elif [[ ${version} =~ [0-9.]+ ]]; then + version="nftables-${version}" + fi + + local distdir distfile + local -a distfiles + distdir="$(portageq distdir)" || return + distfiles=( "${distdir}/${version}.tar."* ) || return + distfile="${distfiles[-1]}" + build_manpages || return +} + +main "${@}" diff --git a/net-firewall/nftables/files/nftables-1.1.1-musl-xtables-ethhdr.patch b/net-firewall/nftables/files/nftables-1.1.1-musl-xtables-ethhdr.patch new file mode 100644 index 000000000..7ca047f3a --- /dev/null +++ b/net-firewall/nftables/files/nftables-1.1.1-musl-xtables-ethhdr.patch @@ -0,0 +1,27 @@ +diff --color -Naur nftables-1.1.1.old/src/xt.c nftables-1.1.1/src/xt.c +--- nftables-1.1.1.old/src/xt.c ++++ nftables-1.1.1/src/xt.c +@@ -10,6 +10,12 @@ + #include + + #include ++ ++#ifdef HAVE_LIBXTABLES ++/* include before net/if.h to prevent redefinition of ethhdr */ ++#include ++#endif ++ + #include + #include + #include /* for isspace */ +@@ -26,9 +32,8 @@ + #include + #include + +-#ifdef HAVE_LIBXTABLES +-#include + ++#ifdef HAVE_LIBXTABLES + static void *xt_entry_alloc(const struct xt_stmt *xt, uint32_t af); + #endif + diff --git a/net-firewall/nftables/files/nftables-mk.confd b/net-firewall/nftables/files/nftables-mk.confd new file mode 100644 index 000000000..5cda24030 --- /dev/null +++ b/net-firewall/nftables/files/nftables-mk.confd @@ -0,0 +1,26 @@ +# /etc/conf.d/nftables + +# Location in which nftables initscript will save set rules on +# service shutdown +NFTABLES_SAVE="/var/lib/nftables/rules-save" + +# Options to pass to nft on save +SAVE_OPTIONS="-n" + +# Save state on stopping nftables +SAVE_ON_STOP="yes" + +# Only for OpenRC systems. +# Set to "hard" or "soft" to panic when stopping instead of +# clearing the rules +# Soft panic loads a ruleset dropping any new or invalid connections +# Hard panic loads a ruleset dropping all traffic +PANIC_ON_STOP="" + +# If you need to log nftables messages as soon as nftables starts, +# AND your logger does NOT depend on the network, then you may wish +# to uncomment the next line. +# If your logger depends on the network, and you uncomment this line +# you will create an unresolvable circular dependency during startup. +# After commenting or uncommenting this line, you must run 'rc-update -u'. +#rc_use="logger" diff --git a/net-firewall/nftables/files/nftables-mk.init-r1 b/net-firewall/nftables/files/nftables-mk.init-r1 new file mode 100644 index 000000000..1f03301c0 --- /dev/null +++ b/net-firewall/nftables/files/nftables-mk.init-r1 @@ -0,0 +1,109 @@ +#!/sbin/openrc-run +# Copyright 1999-2020 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +extra_commands="check clear list panic save soft_panic" +extra_started_commands="reload" + +depend() { + need localmount #434774 + before net +} + +checkkernel() { + if ! /sbin/nft list ruleset >/dev/null 2>/dev/null ; then + eerror "Your kernel lacks nftables support, please load" + eerror "appropriate modules and try again." + return 1 + fi + return 0 +} + +checkconfig() { + if [ -z "${NFTABLES_SAVE}" ] || [ ! -f "${NFTABLES_SAVE}" ] ; then + eerror "Not starting nftables. First create some rules then run:" + eerror "/etc/init.d/${SVCNAME} save" + return 1 + fi + return 0 +} + +_nftables() { + export NFTABLES_SAVE SAVE_OPTIONS + /usr/libexec/nftables/nftables.sh "${@}" +} + +start_pre() { + checkconfig || return 1 + checkkernel || return 1 + check || return 1 +} + +start() { + ebegin "Loading ${SVCNAME} state and starting firewall" + _nftables load "${NFTABLES_SAVE}" + eend ${?} +} + +stop() { + if [ "${SAVE_ON_STOP}" = "yes" ] ; then + save || return 1 + fi + + ebegin "Stopping firewall" + if [ "${PANIC_ON_STOP}" = "hard" ]; then + _nftables panic + elif [ "${PANIC_ON_STOP}" = "soft" ]; then + _nftables soft_panic + else + _nftables clear + fi + eend ${?} +} + +reload() { + start_pre || return 1 + start +} + +clear() { + ebegin "Clearing rules" + _nftables clear + eend ${?} +} + +list() { + _nftables list +} + +check() { + ebegin "Checking rules" + _nftables check "${NFTABLES_SAVE}" + eend ${?} +} + +save() { + ebegin "Saving ${SVCNAME} state" + checkpath -q -d "$(dirname "${NFTABLES_SAVE}")" + checkpath -q -m 0600 -f "${NFTABLES_SAVE}" + _nftables store "${NFTABLES_SAVE}" + eend ${?} +} + +panic() { + if service_started "${SVCNAME}"; then + rc-service "${SVCNAME}" zap + fi + ebegin "Dropping all packets" + _nftables panic + eend ${?} +} + +soft_panic() { + if service_started "${SVCNAME}"; then + rc-service "${SVCNAME}" zap + fi + ebegin "Dropping new connections" + _nftables soft_panic + eend ${?} +} diff --git a/net-firewall/nftables/files/nftables.confd b/net-firewall/nftables/files/nftables.confd new file mode 100644 index 000000000..e83a4b962 --- /dev/null +++ b/net-firewall/nftables/files/nftables.confd @@ -0,0 +1,19 @@ +# /etc/conf.d/nftables + +# Location in which nftables initscript will save set rules on +# service shutdown +NFTABLES_SAVE="/var/lib/nftables/rules-save" + +# Options to pass to nft on save +SAVE_OPTIONS="-n" + +# Save state on stopping nftables +SAVE_ON_STOP="yes" + +# If you need to log nftables messages as soon as nftables starts, +# AND your logger does NOT depend on the network, then you may wish +# to uncomment the next line. +# If your logger depends on the network, and you uncomment this line +# you will create an unresolvable circular dependency during startup. +# After commenting or uncommenting this line, you must run 'rc-update -u'. +#rc_use="logger" diff --git a/net-firewall/nftables/files/nftables.init-r1 b/net-firewall/nftables/files/nftables.init-r1 new file mode 100644 index 000000000..60f1632f4 --- /dev/null +++ b/net-firewall/nftables/files/nftables.init-r1 @@ -0,0 +1,129 @@ +#!/sbin/openrc-run +# Copyright 2014-2017 Nicholas Vinson +# Copyright 1999-2020 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +extra_commands="clear list panic save" +extra_started_commands="reload" +depend() { + need localmount #434774 + before net +} + +_nftables() { + export NFTABLES_SAVE SAVE_OPTIONS + /usr/libexec/nftables/nftables.sh "${@}" +} + +start_pre() { + checkkernel || return 1 + checkconfig || return 1 + return 0 +} + +clear() { + _nftables clear || return 1 + return 0 +} + +list() { + _nftables list || return 1 + return 0 +} + +panic() { + checkkernel || return 1 + if service_started "${RC_SVCNAME}"; then + rc-service "${RC_SVCNAME}" stop + fi + + ebegin "Dropping all packets" + clear + if nft create table ip filter >/dev/null 2>&1; then + nft -f /dev/stdin <<-EOF + table ip filter { + chain input { + type filter hook input priority 0; + drop + } + chain forward { + type filter hook forward priority 0; + drop + } + chain output { + type filter hook output priority 0; + drop + } + } + EOF + fi + if nft create table ip6 filter >/dev/null 2>&1; then + nft -f /dev/stdin <<-EOF + table ip6 filter { + chain input { + type filter hook input priority 0; + drop + } + chain forward { + type filter hook forward priority 0; + drop + } + chain output { + type filter hook output priority 0; + drop + } + } + EOF + fi +} + +reload() { + checkkernel || return 1 + ebegin "Flushing firewall" + clear + start +} + +save() { + ebegin "Saving nftables state" + checkpath -q -d "$(dirname "${NFTABLES_SAVE}")" + checkpath -q -m 0600 -f "${NFTABLES_SAVE}" + export SAVE_OPTIONS + _nftables store "${NFTABLES_SAVE}" + return $? +} + +start() { + ebegin "Loading nftables state and starting firewall" + clear + _nftables load "${NFTABLES_SAVE}" + eend ${?} +} + +stop() { + if yesno "${SAVE_ON_STOP:-yes}"; then + save || return 1 + fi + + ebegin "Stopping firewall" + clear + eend ${?} +} + +checkconfig() { + if [ ! -f "${NFTABLES_SAVE}" ]; then + eerror "Not starting nftables. First create some rules then run:" + eerror "rc-service nftables save" + return 1 + fi + return 0 +} + +checkkernel() { + if ! nft list tables >/dev/null 2>&1; then + eerror "Your kernel lacks nftables support, please load" + eerror "appropriate modules and try again." + return 1 + fi + return 0 +} diff --git a/net-firewall/nftables/files/systemd/nftables-load.service b/net-firewall/nftables/files/systemd/nftables-load.service new file mode 100644 index 000000000..149ccac2f --- /dev/null +++ b/net-firewall/nftables/files/systemd/nftables-load.service @@ -0,0 +1,14 @@ +[Unit] +Description=Load nftables firewall rules +# if both are queued for some reason, don't store before restoring :) +Before=nftables-store.service +# sounds reasonable to have firewall up before any of the services go up +Before=network-pre.target +Wants=network-pre.target + +[Service] +Type=oneshot +ExecStart=/usr/libexec/nftables/nftables.sh load /var/lib/nftables/rules-save + +[Install] +WantedBy=basic.target diff --git a/net-firewall/nftables/files/systemd/nftables-restore.service b/net-firewall/nftables/files/systemd/nftables-restore.service new file mode 100644 index 000000000..4b68b0a5b --- /dev/null +++ b/net-firewall/nftables/files/systemd/nftables-restore.service @@ -0,0 +1,14 @@ +[Unit] +Description=Store and restore nftables firewall rules +ConditionPathExists=/var/lib/nftables/rules-save +Before=network-pre.target +Wants=network-pre.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/libexec/nftables/nftables.sh load /var/lib/nftables/rules-save +ExecStop=/usr/libexec/nftables/nftables.sh store /var/lib/nftables/rules-save + +[Install] +WantedBy=basic.target diff --git a/net-firewall/nftables/files/systemd/nftables-store.service b/net-firewall/nftables/files/systemd/nftables-store.service new file mode 100644 index 000000000..373f8b947 --- /dev/null +++ b/net-firewall/nftables/files/systemd/nftables-store.service @@ -0,0 +1,11 @@ +[Unit] +Description=Store nftables firewall rules +Before=shutdown.target +DefaultDependencies=No + +[Service] +Type=oneshot +ExecStart=/usr/libexec/nftables/nftables.sh store /var/lib/nftables/rules-save + +[Install] +WantedBy=shutdown.target diff --git a/net-firewall/nftables/metadata.xml b/net-firewall/nftables/metadata.xml new file mode 100644 index 000000000..c8347d8c5 --- /dev/null +++ b/net-firewall/nftables/metadata.xml @@ -0,0 +1,17 @@ + + + + + base-system@gentoo.org + Gentoo Base System + + + prometheanfire@gentoo.org + Matthew Thode + + + Create man pages for the package (requires app-text/asciidoc) + Enable JSON support via dev-libs/jansson + Add libxtables support to try to automatically translate rules added by iptables-compat + + diff --git a/net-firewall/nftables/nftables-1.1.1-r1.ebuild b/net-firewall/nftables/nftables-1.1.1-r1.ebuild new file mode 100644 index 000000000..eaf9472dc --- /dev/null +++ b/net-firewall/nftables/nftables-1.1.1-r1.ebuild @@ -0,0 +1,237 @@ +# Copyright 1999-2025 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +DISTUTILS_OPTIONAL=1 +DISTUTILS_USE_PEP517=setuptools +PYTHON_COMPAT=( python3_{10..13} ) +VERIFY_SIG_OPENPGP_KEY_PATH=/usr/share/openpgp-keys/netfilter.org.asc +inherit eapi9-ver edo linux-info distutils-r1 systemd verify-sig + +DESCRIPTION="Linux kernel firewall, NAT and packet mangling tools" +HOMEPAGE="https://netfilter.org/projects/nftables/" + +if [[ ${PV} =~ ^[9]{4,}$ ]]; then + inherit autotools git-r3 + EGIT_REPO_URI="https://git.netfilter.org/${PN}" + BDEPEND="app-alternatives/yacc" +else + SRC_URI=" + https://netfilter.org/projects/nftables/files/${P}.tar.xz + verify-sig? ( https://netfilter.org/projects/nftables/files/${P}.tar.xz.sig ) + " + KEYWORDS="amd64 arm arm64 hppa ~loong ~mips ppc ppc64 ~riscv ~sparc x86" + BDEPEND="verify-sig? ( sec-keys/openpgp-keys-netfilter )" +fi + +# See COPYING: new code is GPL-2+, existing code is GPL-2 +LICENSE="GPL-2 GPL-2+" +SLOT="0/1" +IUSE="debug doc +gmp json libedit python +readline static-libs test xtables" +RESTRICT="!test? ( test )" + +RDEPEND=" + >=net-libs/libmnl-1.0.4:= + >=net-libs/libnftnl-1.2.8:= + gmp? ( dev-libs/gmp:= ) + json? ( dev-libs/jansson:= ) + python? ( ${PYTHON_DEPS} ) + readline? ( sys-libs/readline:= ) + xtables? ( >=net-firewall/iptables-1.6.1:= ) +" +DEPEND="${RDEPEND}" +BDEPEND+=" + app-alternatives/lex + virtual/pkgconfig + doc? ( + app-text/asciidoc + >=app-text/docbook2X-0.8.8-r4 + ) + python? ( ${DISTUTILS_DEPS} ) +" + +REQUIRED_USE=" + python? ( ${PYTHON_REQUIRED_USE} ) + libedit? ( !readline ) +" + +PATCHES=( + "${FILESDIR}/${PN}-1.1.1-musl-xtables-ethhdr.patch" +) + +src_prepare() { + default + + if [[ ${PV} =~ ^[9]{4,}$ ]] ; then + eautoreconf + fi + + if use python; then + pushd py >/dev/null || die + distutils-r1_src_prepare + popd >/dev/null || die + fi +} + +src_configure() { + local myeconfargs=( + --sbindir="${EPREFIX}"/sbin + $(use_enable debug) + $(use_enable doc man-doc) + $(use_with !gmp mini_gmp) + $(use_with json) + $(use_with libedit cli editline) + $(use_with readline cli readline) + $(use_enable static-libs static) + $(use_with xtables) + ) + + econf "${myeconfargs[@]}" + + if use python; then + pushd py >/dev/null || die + distutils-r1_src_configure + popd >/dev/null || die + fi +} + +src_compile() { + default + + if use python; then + pushd py >/dev/null || die + distutils-r1_src_compile + popd >/dev/null || die + fi +} + +src_test() { + emake check + + if [[ ${EUID} == 0 ]]; then + edo tests/shell/run-tests.sh -v + else + ewarn "Skipping shell tests (requires root)" + fi + + if use python; then + pushd tests/py >/dev/null || die + distutils-r1_src_test + popd >/dev/null || die + fi +} + +python_test() { + if [[ ${EUID} == 0 ]]; then + edo "${EPYTHON}" nft-test.py + else + ewarn "Skipping Python tests (requires root)" + fi +} + +src_install() { + default + + if ! use doc && [[ ! ${PV} =~ ^[9]{4,}$ ]]; then + pushd doc >/dev/null || die + doman *.? + popd >/dev/null || die + fi + + # Do it here instead of in src_prepare to avoid eautoreconf + # rmdir lets us catch if more files end up installed in /etc/nftables + dodir /usr/share/doc/${PF}/skels/ + mv "${ED}"/etc/nftables/osf "${ED}"/usr/share/doc/${PF}/skels/osf || die + rmdir "${ED}"/etc/nftables || die + + exeinto /usr/libexec/${PN} + newexe "${FILESDIR}"/libexec/${PN}-mk.sh ${PN}.sh + newconfd "${FILESDIR}"/${PN}-mk.confd ${PN} + newinitd "${FILESDIR}"/${PN}-mk.init-r1 ${PN} + keepdir /var/lib/nftables + + systemd_dounit "${FILESDIR}"/systemd/${PN}-load.service + systemd_dounit "${FILESDIR}"/systemd/${PN}-store.service + + if use python ; then + pushd py >/dev/null || die + distutils-r1_src_install + popd >/dev/null || die + fi + + find "${ED}" -type f -name "*.la" -delete || die +} + +pkg_preinst() { + local stderr + + # There's a history of regressions with nftables upgrades. Perform a + # safety check to help us spot them earlier. For the check to pass, the + # currently loaded ruleset, if any, must be successfully evaluated by + # the newly built instance of nft(8). + if [[ -n ${ROOT} ]] || [[ ! -d /sys/module/nftables ]] || [[ ! -x /sbin/nft ]]; then + # Either nftables isn't yet in use or nft(8) cannot be executed. + return + elif ! stderr=$(umask 177; /sbin/nft -t list ruleset 2>&1 >"${T}"/ruleset.nft); then + # Report errors induced by trying to list the ruleset but don't + # treat them as being fatal. + printf '%s\n' "${stderr}" >&2 + elif [[ ${stderr} == *"is managed by iptables-nft"* ]]; then + # Rulesets generated by iptables-nft are special in nature and + # will not always be printed in a way that constitutes a valid + # syntax for ntf(8). Ignore them. + return + elif set -- "${ED}"/usr/lib*/libnftables.so; + ! LD_LIBRARY_PATH=${1%/*} "${ED}"/sbin/nft -c -f -- "${T}"/ruleset.nft + then + eerror "Your currently loaded ruleset cannot be parsed by the newly built instance of" + eerror "nft. This probably means that there is a regression introduced by v${PV}." + eerror "(To make the ebuild fail instead of warning, set NFTABLES_ABORT_ON_RELOAD_FAILURE=1.)" + if [[ -n ${NFTABLES_ABORT_ON_RELOAD_FAILURE} ]] ; then + die "Aborting because of failed nft reload!" + fi + fi +} + +pkg_postinst() { + local save_file + save_file="${EROOT}"/var/lib/nftables/rules-save + + # In order for the nftables-load systemd service to start + # the save_file must exist. + if [[ ! -f "${save_file}" ]]; then + ( umask 177; touch "${save_file}" ) + elif [[ $(( "$( stat --printf '%05a' "${save_file}" )" & 07177 )) -ne 0 ]]; then + ewarn "Your system has dangerous permissions for ${save_file}" + ewarn "It is probably affected by bug #691326." + ewarn "You may need to fix the permissions of the file. To do so," + ewarn "you can run the command in the line below as root." + ewarn " 'chmod 600 \"${save_file}\"'" + fi + + if has_version 'sys-apps/systemd'; then + if ver_replacing -lt "1.1.1-r1"; then + elog "Starting with ${PN}-1.1.1-r1, the ${PN}-restore.service has" + elog "been split into ${PN}-load.service and ${PN}-store.service." + elog + fi + elog "If you wish to enable the firewall rules on boot (on systemd) you" + elog "will need to enable the nftables-load service." + elog " 'systemctl enable ${PN}-load.service'" + elog + elog "Enable nftables-store.service if you want firewall rules to be" + elog "saved at shutdown." + fi + + if has_version 'sys-apps/openrc'; then + elog "If you wish to enable the firewall rules on boot (on openrc) you" + elog "will need to enable the nftables service." + elog " 'rc-update add ${PN} default'" + elog + elog "If you are creating or updating the firewall rules and wish to save" + elog "them to be loaded on the next restart, use the \"save\" functionality" + elog "in the init script." + elog " 'rc-service ${PN} save'" + fi +} diff --git a/net-firewall/nftables/nftables-1.1.1.ebuild b/net-firewall/nftables/nftables-1.1.1.ebuild new file mode 100644 index 000000000..18b24cff8 --- /dev/null +++ b/net-firewall/nftables/nftables-1.1.1.ebuild @@ -0,0 +1,232 @@ +# Copyright 1999-2025 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +DISTUTILS_OPTIONAL=1 +DISTUTILS_USE_PEP517=setuptools +PYTHON_COMPAT=( python3_{10..13} ) +VERIFY_SIG_OPENPGP_KEY_PATH=/usr/share/openpgp-keys/netfilter.org.asc +inherit edo linux-info distutils-r1 systemd verify-sig + +DESCRIPTION="Linux kernel firewall, NAT and packet mangling tools" +HOMEPAGE="https://netfilter.org/projects/nftables/" + +if [[ ${PV} =~ ^[9]{4,}$ ]]; then + inherit autotools git-r3 + EGIT_REPO_URI="https://git.netfilter.org/${PN}" + BDEPEND="app-alternatives/yacc" +else + SRC_URI=" + https://netfilter.org/projects/nftables/files/${P}.tar.xz + verify-sig? ( https://netfilter.org/projects/nftables/files/${P}.tar.xz.sig ) + " + KEYWORDS="amd64 arm arm64 hppa ~loong ~mips ppc ppc64 ~riscv sparc x86" + BDEPEND="verify-sig? ( sec-keys/openpgp-keys-netfilter )" +fi + +# See COPYING: new code is GPL-2+, existing code is GPL-2 +LICENSE="GPL-2 GPL-2+" +SLOT="0/1" +IUSE="debug doc +gmp json libedit python +readline static-libs test xtables" +RESTRICT="!test? ( test )" + +RDEPEND=" + >=net-libs/libmnl-1.0.4:= + >=net-libs/libnftnl-1.2.8:= + gmp? ( dev-libs/gmp:= ) + json? ( dev-libs/jansson:= ) + python? ( ${PYTHON_DEPS} ) + readline? ( sys-libs/readline:= ) + xtables? ( >=net-firewall/iptables-1.6.1:= ) +" +DEPEND="${RDEPEND}" +BDEPEND+=" + app-alternatives/lex + virtual/pkgconfig + doc? ( + app-text/asciidoc + >=app-text/docbook2X-0.8.8-r4 + ) + python? ( ${DISTUTILS_DEPS} ) +" + +REQUIRED_USE=" + python? ( ${PYTHON_REQUIRED_USE} ) + libedit? ( !readline ) +" + +PATCHES=( + "${FILESDIR}/${PN}-1.1.1-musl-xtables-ethhdr.patch" +) + +src_prepare() { + default + + if [[ ${PV} =~ ^[9]{4,}$ ]] ; then + eautoreconf + fi + + if use python; then + pushd py >/dev/null || die + distutils-r1_src_prepare + popd >/dev/null || die + fi +} + +src_configure() { + local myeconfargs=( + --sbindir="${EPREFIX}"/sbin + $(use_enable debug) + $(use_enable doc man-doc) + $(use_with !gmp mini_gmp) + $(use_with json) + $(use_with libedit cli editline) + $(use_with readline cli readline) + $(use_enable static-libs static) + $(use_with xtables) + ) + + econf "${myeconfargs[@]}" + + if use python; then + pushd py >/dev/null || die + distutils-r1_src_configure + popd >/dev/null || die + fi +} + +src_compile() { + default + + if use python; then + pushd py >/dev/null || die + distutils-r1_src_compile + popd >/dev/null || die + fi +} + +src_test() { + emake check + + if [[ ${EUID} == 0 ]]; then + edo tests/shell/run-tests.sh -v + else + ewarn "Skipping shell tests (requires root)" + fi + + if use python; then + pushd tests/py >/dev/null || die + distutils-r1_src_test + popd >/dev/null || die + fi +} + +python_test() { + if [[ ${EUID} == 0 ]]; then + edo "${EPYTHON}" nft-test.py + else + ewarn "Skipping Python tests (requires root)" + fi +} + +src_install() { + default + + if ! use doc && [[ ! ${PV} =~ ^[9]{4,}$ ]]; then + pushd doc >/dev/null || die + doman *.? + popd >/dev/null || die + fi + + # Do it here instead of in src_prepare to avoid eautoreconf + # rmdir lets us catch if more files end up installed in /etc/nftables + dodir /usr/share/doc/${PF}/skels/ + mv "${ED}"/etc/nftables/osf "${ED}"/usr/share/doc/${PF}/skels/osf || die + rmdir "${ED}"/etc/nftables || die + + exeinto /usr/libexec/${PN} + newexe "${FILESDIR}"/libexec/${PN}-mk.sh ${PN}.sh + newconfd "${FILESDIR}"/${PN}-mk.confd ${PN} + newinitd "${FILESDIR}"/${PN}-mk.init-r1 ${PN} + keepdir /var/lib/nftables + + systemd_dounit "${FILESDIR}"/systemd/${PN}-restore.service + + if use python ; then + pushd py >/dev/null || die + distutils-r1_src_install + popd >/dev/null || die + fi + + find "${ED}" -type f -name "*.la" -delete || die +} + +pkg_preinst() { + local stderr + + # There's a history of regressions with nftables upgrades. Perform a + # safety check to help us spot them earlier. For the check to pass, the + # currently loaded ruleset, if any, must be successfully evaluated by + # the newly built instance of nft(8). + if [[ -n ${ROOT} ]] || [[ ! -d /sys/module/nftables ]] || [[ ! -x /sbin/nft ]]; then + # Either nftables isn't yet in use or nft(8) cannot be executed. + return + elif ! stderr=$(umask 177; /sbin/nft -t list ruleset 2>&1 >"${T}"/ruleset.nft); then + # Report errors induced by trying to list the ruleset but don't + # treat them as being fatal. + printf '%s\n' "${stderr}" >&2 + elif [[ ${stderr} == *"is managed by iptables-nft"* ]]; then + # Rulesets generated by iptables-nft are special in nature and + # will not always be printed in a way that constitutes a valid + # syntax for ntf(8). Ignore them. + return + elif set -- "${ED}"/usr/lib*/libnftables.so; + ! LD_LIBRARY_PATH=${1%/*} "${ED}"/sbin/nft -c -f -- "${T}"/ruleset.nft + then + eerror "Your currently loaded ruleset cannot be parsed by the newly built instance of" + eerror "nft. This probably means that there is a regression introduced by v${PV}." + eerror "(To make the ebuild fail instead of warning, set NFTABLES_ABORT_ON_RELOAD_FAILURE=1.)" + if [[ -n ${NFTABLES_ABORT_ON_RELOAD_FAILURE} ]] ; then + die "Aborting because of failed nft reload!" + fi + fi +} + +pkg_postinst() { + local save_file + save_file="${EROOT}"/var/lib/nftables/rules-save + + # In order for the nftables-restore systemd service to start + # the save_file must exist. + if [[ ! -f "${save_file}" ]]; then + ( umask 177; touch "${save_file}" ) + elif [[ $(( "$( stat --printf '%05a' "${save_file}" )" & 07177 )) -ne 0 ]]; then + ewarn "Your system has dangerous permissions for ${save_file}" + ewarn "It is probably affected by bug #691326." + ewarn "You may need to fix the permissions of the file. To do so," + ewarn "you can run the command in the line below as root." + ewarn " 'chmod 600 \"${save_file}\"'" + fi + + if has_version 'sys-apps/systemd'; then + elog "If you wish to enable the firewall rules on boot (on systemd) you" + elog "will need to enable the nftables-restore service." + elog " 'systemctl enable ${PN}-restore.service'" + elog + elog "If you are creating firewall rules before the next system restart" + elog "the nftables-restore service must be manually started in order to" + elog "save those rules on shutdown." + fi + + if has_version 'sys-apps/openrc'; then + elog "If you wish to enable the firewall rules on boot (on openrc) you" + elog "will need to enable the nftables service." + elog " 'rc-update add ${PN} default'" + elog + elog "If you are creating or updating the firewall rules and wish to save" + elog "them to be loaded on the next restart, use the \"save\" functionality" + elog "in the init script." + elog " 'rc-service ${PN} save'" + fi +} diff --git a/net-firewall/nftables/nftables-1.1.3.ebuild b/net-firewall/nftables/nftables-1.1.3.ebuild new file mode 100644 index 000000000..6ccc377bc --- /dev/null +++ b/net-firewall/nftables/nftables-1.1.3.ebuild @@ -0,0 +1,240 @@ +# Copyright 1999-2025 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +DISTUTILS_OPTIONAL=1 +DISTUTILS_USE_PEP517=setuptools +PYTHON_COMPAT=( python3_{10..13} ) +VERIFY_SIG_OPENPGP_KEY_PATH=/usr/share/openpgp-keys/netfilter.org.asc +inherit eapi9-ver edo linux-info distutils-r1 systemd verify-sig + +DESCRIPTION="Linux kernel firewall, NAT and packet mangling tools" +HOMEPAGE="https://netfilter.org/projects/nftables/" + +if [[ ${PV} =~ ^[9]{4,}$ ]]; then + inherit autotools git-r3 + EGIT_REPO_URI="https://git.netfilter.org/${PN}" + BDEPEND="app-alternatives/yacc" +else + inherit libtool + SRC_URI=" + https://netfilter.org/projects/nftables/files/${P}.tar.xz + verify-sig? ( https://netfilter.org/projects/nftables/files/${P}.tar.xz.sig ) + " + KEYWORDS="~amd64 ~arm ~arm64 ~hppa ~loong ~mips ~ppc ~ppc64 ~riscv ~sparc ~x86" + BDEPEND="verify-sig? ( >=sec-keys/openpgp-keys-netfilter-20240415 )" +fi + +# See COPYING: new code is GPL-2+, existing code is GPL-2 +LICENSE="GPL-2 GPL-2+" +SLOT="0/1" +IUSE="debug doc +gmp json libedit python +readline static-libs test xtables" +RESTRICT="!test? ( test )" + +RDEPEND=" + >=net-libs/libmnl-1.0.4:= + >=net-libs/libnftnl-1.2.9:= + gmp? ( dev-libs/gmp:= ) + json? ( dev-libs/jansson:= ) + python? ( ${PYTHON_DEPS} ) + readline? ( sys-libs/readline:= ) + xtables? ( >=net-firewall/iptables-1.6.1:= ) +" +DEPEND="${RDEPEND}" +BDEPEND+=" + app-alternatives/lex + virtual/pkgconfig + doc? ( + app-text/asciidoc + >=app-text/docbook2X-0.8.8-r4 + ) + python? ( ${DISTUTILS_DEPS} ) +" + +REQUIRED_USE=" + python? ( ${PYTHON_REQUIRED_USE} ) + libedit? ( !readline ) +" + +PATCHES=( + "${FILESDIR}/${PN}-1.1.1-musl-xtables-ethhdr.patch" +) + +src_prepare() { + default + + if [[ ${PV} =~ ^[9]{4,}$ ]] ; then + eautoreconf + else + elibtoolize + fi + + if use python; then + pushd py >/dev/null || die + distutils-r1_src_prepare + popd >/dev/null || die + fi +} + +src_configure() { + local myeconfargs=( + --sbindir="${EPREFIX}"/sbin + $(use_enable debug) + $(use_enable doc man-doc) + $(use_with !gmp mini_gmp) + $(use_with json) + $(use_with libedit cli editline) + $(use_with readline cli readline) + $(use_enable static-libs static) + $(use_with xtables) + ) + + econf "${myeconfargs[@]}" + + if use python; then + pushd py >/dev/null || die + distutils-r1_src_configure + popd >/dev/null || die + fi +} + +src_compile() { + default + + if use python; then + pushd py >/dev/null || die + distutils-r1_src_compile + popd >/dev/null || die + fi +} + +src_test() { + emake check + + if [[ ${EUID} == 0 ]]; then + edo tests/shell/run-tests.sh -v + else + ewarn "Skipping shell tests (requires root)" + fi + + if use python; then + pushd tests/py >/dev/null || die + distutils-r1_src_test + popd >/dev/null || die + fi +} + +python_test() { + if [[ ${EUID} == 0 ]]; then + edo "${EPYTHON}" nft-test.py + else + ewarn "Skipping Python tests (requires root)" + fi +} + +src_install() { + default + + if ! use doc && [[ ! ${PV} =~ ^[9]{4,}$ ]]; then + pushd doc >/dev/null || die + doman *.? + popd >/dev/null || die + fi + + # Do it here instead of in src_prepare to avoid eautoreconf + # rmdir lets us catch if more files end up installed in /etc/nftables + dodir /usr/share/doc/${PF}/skels/ + mv "${ED}"/etc/nftables/osf "${ED}"/usr/share/doc/${PF}/skels/osf || die + rmdir "${ED}"/etc/nftables || die + + exeinto /usr/libexec/${PN} + newexe "${FILESDIR}"/libexec/${PN}-mk.sh ${PN}.sh + newconfd "${FILESDIR}"/${PN}-mk.confd ${PN} + newinitd "${FILESDIR}"/${PN}-mk.init-r1 ${PN} + keepdir /var/lib/nftables + + systemd_dounit "${FILESDIR}"/systemd/${PN}-load.service + systemd_dounit "${FILESDIR}"/systemd/${PN}-store.service + + if use python ; then + pushd py >/dev/null || die + distutils-r1_src_install + popd >/dev/null || die + fi + + find "${ED}" -type f -name "*.la" -delete || die +} + +pkg_preinst() { + local stderr + + # There's a history of regressions with nftables upgrades. Perform a + # safety check to help us spot them earlier. For the check to pass, the + # currently loaded ruleset, if any, must be successfully evaluated by + # the newly built instance of nft(8). + if [[ -n ${ROOT} ]] || [[ ! -d /sys/module/nftables ]] || [[ ! -x /sbin/nft ]]; then + # Either nftables isn't yet in use or nft(8) cannot be executed. + return + elif ! stderr=$(umask 177; /sbin/nft -t list ruleset 2>&1 >"${T}"/ruleset.nft); then + # Report errors induced by trying to list the ruleset but don't + # treat them as being fatal. + printf '%s\n' "${stderr}" >&2 + elif [[ ${stderr} == *"is managed by iptables-nft"* ]]; then + # Rulesets generated by iptables-nft are special in nature and + # will not always be printed in a way that constitutes a valid + # syntax for ntf(8). Ignore them. + return + elif set -- "${ED}"/usr/lib*/libnftables.so; + ! LD_LIBRARY_PATH=${1%/*} "${ED}"/sbin/nft -c -f -- "${T}"/ruleset.nft + then + eerror "Your currently loaded ruleset cannot be parsed by the newly built instance of" + eerror "nft. This probably means that there is a regression introduced by v${PV}." + eerror "(To make the ebuild fail instead of warning, set NFTABLES_ABORT_ON_RELOAD_FAILURE=1.)" + if [[ -n ${NFTABLES_ABORT_ON_RELOAD_FAILURE} ]] ; then + die "Aborting because of failed nft reload!" + fi + fi +} + +pkg_postinst() { + local save_file + save_file="${EROOT}"/var/lib/nftables/rules-save + + # In order for the nftables-load systemd service to start + # the save_file must exist. + if [[ ! -f "${save_file}" ]]; then + ( umask 177; touch "${save_file}" ) + elif [[ $(( "$( stat --printf '%05a' "${save_file}" )" & 07177 )) -ne 0 ]]; then + ewarn "Your system has dangerous permissions for ${save_file}" + ewarn "It is probably affected by bug #691326." + ewarn "You may need to fix the permissions of the file. To do so," + ewarn "you can run the command in the line below as root." + ewarn " 'chmod 600 \"${save_file}\"'" + fi + + if has_version 'sys-apps/systemd'; then + if ver_replacing -lt "1.1.1-r1"; then + elog "Starting with ${PN}-1.1.1-r1, the ${PN}-restore.service has" + elog "been split into ${PN}-load.service and ${PN}-store.service." + elog + fi + elog "If you wish to enable the firewall rules on boot (on systemd) you" + elog "will need to enable the nftables-load service." + elog " 'systemctl enable ${PN}-load.service'" + elog + elog "Enable nftables-store.service if you want firewall rules to be" + elog "saved at shutdown." + fi + + if has_version 'sys-apps/openrc'; then + elog "If you wish to enable the firewall rules on boot (on openrc) you" + elog "will need to enable the nftables service." + elog " 'rc-update add ${PN} default'" + elog + elog "If you are creating or updating the firewall rules and wish to save" + elog "them to be loaded on the next restart, use the \"save\" functionality" + elog "in the init script." + elog " 'rc-service ${PN} save'" + fi +}