Last active
September 10, 2022 11:44
-
-
Save madars/8817e3d836a84871ba493abeee7054e8 to your computer and use it in GitHub Desktop.
openwrt-nat6 from https://openwrt.org/docs/guide-user/network/ipv6/ipv6.nat6
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# NAT6 + masquerading firewall script | |
# https://github.com/akatrevorjay/openwrt-masq6 | |
# trevorj <github@trevor.joynson.io> | |
# | |
# You can configure in /etc/config/firewall per zone: | |
# * IPv4 masquerading | |
# option masq 1 | |
# * IPv6 masquerading | |
# option masq6 1 | |
# * IPv6 privacy extensions | |
# option masq6_privacy 1 | |
set -e -o pipefail | |
. /lib/functions.sh | |
. /lib/functions/network.sh | |
. /usr/share/libubox/jshn.sh | |
log() { | |
logger -t nat6 -s "${@}" | |
} | |
get_ula_prefix() { | |
uci get network.globals.ula_prefix | |
} | |
validate_ula_prefix() { | |
local ula_prefix="${1}" | |
if [ $(echo "${ula_prefix}" | grep -c -E -e "^([0-9a-fA-F]{4}):([0-9a-fA-F]{0,4}):") -ne 1 ] ; then | |
log "Fatal error: IPv6 ULA ula_prefix=\"${ula_prefix}\" seems invalid. Please verify that a ula_prefix is set and valid." | |
return 1 | |
fi | |
} | |
ip6t() { | |
ip6tables "${@}" | |
} | |
ip6t_add() { | |
if ! ip6t -C "${@}" &> /dev/null; then | |
ip6t -I "${@}" | |
fi | |
} | |
nat6_init() { | |
iptables-save -t nat \ | |
| sed -e " | |
/\sMASQUERADE$/d | |
/\s[DS]NAT\s/d | |
/\s--match-set\s\S*/s//\06/ | |
/,BROADCAST\s/s// /" \ | |
| ip6tables-restore -T nat | |
} | |
masq6_network() { | |
# ${config} contains the ID of the current section | |
local network_name="${1}" | |
local device | |
network_get_device device "${network_name}" || return 0 | |
local done_net_dev | |
for done_net_dev in ${DONE_NETWORK_DEVICES}; do | |
if [ "${done_net_dev}" = "${device}" ]; then | |
log "Already configured device=\"${device}\", so leaving as is." | |
return 0 | |
fi | |
done | |
log "Found device=\"${device}\" for network_name=\"${network_name}\"." | |
if [ "${zone_masq6_privacy}" -eq 1 ]; then | |
log "Enabling IPv6 temporary addresses for device=\"${device}\"." | |
log "Accepting router advertisements on ${device} even if forwarding is enabled (required for temporary addresses)" | |
echo 2 > "/proc/sys/net/ipv6/conf/${device}/accept_ra" \ | |
|| log "Error: Failed to change router advertisements accept policy on ${device} (required for temporary addresses)" | |
log "Using temporary addresses for outgoing connections on interface ${device}" | |
echo 2 > "/proc/sys/net/ipv6/conf/${device}/use_tempaddr" \ | |
|| log "Error: Failed to enable temporary addresses for outgoing connections on interface ${device}" | |
fi | |
append DONE_NETWORK_DEVICES "${device}" | |
} | |
handle_zone() { | |
# ${config} contains the ID of the current section | |
local config="${1}" | |
local zone_name | |
config_get zone_name "${config}" name | |
# Enable masquerading via NAT6 | |
local zone_masq6 | |
config_get_bool zone_masq6 "${config}" masq6 0 | |
log "Firewall config=\"${config}\" zone=\"${zone_name}\" zone_masq6=\"${zone_masq6}\"." | |
if [ "${zone_masq6}" -eq 0 ]; then | |
return 0 | |
fi | |
# IPv6 privacy extensions: Use temporary addrs for outgoing connections? | |
local zone_masq6_privacy | |
config_get_bool zone_masq6_privacy "${config}" masq6_privacy 1 | |
log "Found firewall zone_name=\"${zone_name}\" with zone_masq6=\"${zone_masq6}\" zone_masq6_privacy=\"${zone_masq6_privacy}\"." | |
log "Setting up masquerading nat6 for zone_name=\"${zone_name}\" with zone_masq6_privacy=\"${zone_masq6_privacy}\"" | |
local ula_prefix="$(get_ula_prefix)" | |
validate_ula_prefix "${ula_prefix}" || return 1 | |
local postrouting_chain="zone_${zone_name}_postrouting" | |
log "Ensuring ip6tables chain=\"${postrouting_chain}\" contains our MASQUERADE." | |
ip6t_add "${postrouting_chain}" -t nat \ | |
-m comment --comment "!fw3" -j MASQUERADE | |
local input_chain="zone_${zone_name}_input" | |
log "Ensuring ip6tables chain=\"${input_chain}\" contains our permissive DNAT rule." | |
ip6t_add "${input_chain}" -t filter -m conntrack --ctstate DNAT \ | |
-m comment --comment "!fw3: Accept port forwards" -j ACCEPT | |
local forward_chain="zone_${zone_name}_forward" | |
log "Ensuring ip6tables chain=\"${forward_chain}\" contains our permissive DNAT rule." | |
ip6t_add "${forward_chain}" -t filter -m conntrack --ctstate DNAT \ | |
-m comment --comment "!fw3: Accept port forwards" -j ACCEPT | |
local DONE_NETWORK_DEVICES="" | |
config_list_foreach "${config}" network masq6_network | |
log "Done setting up nat6 for zone=\"${zone_name}\" on devices: ${DONE_NETWORK_DEVICES}" | |
} | |
main() { | |
nat6_init | |
config_load firewall | |
config_foreach handle_zone zone | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment