From 3afaa507c0e2c2ff8a6c53c428d7411d7ed49c27 Mon Sep 17 00:00:00 2001 From: sbwml Date: Thu, 4 Jan 2024 23:12:01 +0800 Subject: [PATCH] nat6: new package Signed-off-by: sbwml --- Makefile | 28 ++++++++++++ files/60-luci-firewall-nat6 | 10 +++++ files/nat6.init | 89 +++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 Makefile create mode 100644 files/60-luci-firewall-nat6 create mode 100644 files/nat6.init diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1a7f86b --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=nat6 +PKG_VERSION:=1.0.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=sbwml + +include $(INCLUDE_DIR)/package.mk + +define Package/nat6 + SECTION:=net + CATEGORY:=Network + TITLE:=IPv6 NAT + DEPENDS:=+kmod-nft-nat +nftables-json +endef + +define Build/Compile +endef + +define Package/nat6/install + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/60-luci-firewall-nat6 $(1)/etc/uci-defaults + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/nat6.init $(1)/etc/init.d/nat6 +endef + +$(eval $(call BuildPackage,nat6)) diff --git a/files/60-luci-firewall-nat6 b/files/60-luci-firewall-nat6 new file mode 100644 index 0000000..1b2311a --- /dev/null +++ b/files/60-luci-firewall-nat6 @@ -0,0 +1,10 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@firewall[2] + add ucitrack firewall + set ucitrack.@firewall[2].init=nat6 + commit ucitrack +EOF + +exit 0 \ No newline at end of file diff --git a/files/nat6.init b/files/nat6.init new file mode 100644 index 0000000..b557294 --- /dev/null +++ b/files/nat6.init @@ -0,0 +1,89 @@ +#!/bin/sh /etc/rc.common + +START=90 + +interface() { + nic=$(ifconfig -a | grep -o '^[^ ]*') + dhcpv6_interface=$(uci -q show network | grep dhcpv6 | grep -o 'network\.\([^\.]*\)' | sed 's/network.//') + IFS=$'\n' + for interface_name in $dhcpv6_interface + do + device=$(uci -q show network.$interface_name.device | grep -o "'.*'" | awk -F"'" '{print $2}') + if [ "$(echo $device | grep -c @)" = 1 ]; then + alias_interface=$(echo $device | sed 's/@//') + device=$(uci -q show network.$alias_interface.device | grep -o "'.*'" | awk -F"'" '{print $2}') + if [ -z $(uci -q show network.$alias_interface.device) ]; then + ipaddr=$(uci -q show network.$alias_interface.ipaddr | grep -o "'.*'" | awk -F"'" '{print $2}') + device=$(ifconfig | grep -B 1 $ipaddr | head -1 | awk '{print $1}') + fi + fi + if [ $(ifconfig $device | grep -c "inet6 addr") -gt 0 ]; then + gateway=$(ip -6 route | grep "default from" | awk '{print $5}') + break + fi + done +} + +common_config() { + if [ -z $(uci -q get network.globals.ula_prefix) ] || [ $(uci -q get network.globals.ula_prefix | grep -c "/48") != 1 ]; then + r1=$(dd if=/dev/urandom bs=1 count=1 2>/dev/null | hexdump -e '1/1 "%02x"') + uci -q batch <<-EOF >/dev/null + set network.globals.ula_prefix="fd$r1:2024::/48" + commit network +EOF + fi + uci -q batch <<-EOF >/dev/null + set dhcp.lan.ra='server' + set dhcp.lan.dhcpv6='server' + del dhcp.lan.ndp + set dhcp.lan.ra_default='2' + del dhcp.lan.ra_slaac + commit dhcp +EOF + /etc/init.d/network reload + /etc/init.d/odhcpd reload +} + +start() { + [ "$(uci -q get firewall.@defaults[0].nat6)" != 1 ] && return 0 + interface + common_config + ip -6 r add default via $gateway dev $device 2>/dev/null + nft delete table ip6 nat 2>/dev/null + nft add table ip6 nat 2>/dev/null + nft add chain ip6 nat prerouting { type nat hook prerouting priority 0\; } 2>/dev/null + nft add chain ip6 nat postrouting { type nat hook postrouting priority 100\; } 2>/dev/null + nft add rule ip6 nat postrouting oif $device masquerade 2>/dev/null + [ ! -f /etc/hotplug.d/iface/90-nat6 ] && cat > /etc/hotplug.d/iface/90-nat6 << "EOF" +#!/bin/sh + +dhcpv6_interface=$(uci -q show network | grep dhcpv6 | grep -o 'network\.\([^\.]*\)' | sed 's/network.//') +IFS=$'\n' +for interface_name in $dhcpv6_interface +do + device=$(uci -q show network.$interface_name.device | grep -o "'.*'" | awk -F"'" '{print $2}') + if [ $(ifconfig $device | grep -c "inet6 addr") -gt 0 ]; then + interface_name=$interface_name + fi +done + +[ "$INTERFACE" = "$interface_name" ] || exit 0 + +if [ "$ACTION" = ifup ] || [ "$ACTION" = iflink ] || [ "$ACTION" = ifupdate ] || [ "$ACTION" = reload ]; then + /etc/init.d/nat6 restart +fi +EOF + logger -p notice -t network -s "nat6: IPv6 NAT is ready" +} + +stop() { + interface + nft delete table ip6 nat 2>/dev/null + ip -6 r del default via $gateway dev $device 2>/dev/null + rm -f /etc/hotplug.d/iface/90-nat6 + uci -q batch <<-EOF >/dev/null + del dhcp.lan.ra_default + commit dhcp +EOF + /etc/init.d/odhcpd reload +}