├── README.md └── data ├── cronjobs └── update_ipv6_chains ├── ipv6 ├── configure-he-ipv6-chains.sh └── enable-he-ipv6.sh └── on_boot.d ├── 41-enable-he-ipv6.sh └── 99-add-cronjobs.sh /README.md: -------------------------------------------------------------------------------- 1 | # IPv6 via tunnelbroker on a UDMP, with Unifi Firewall Rules 2 | 3 | This set of scripts is intended to help you automate and setup a Hurricane Electric / TunnelBroker ipv6 tunnel on your UDMP. It also allows you to use the ipv6 firewall rules as you normally would and will ensure those rules are applied to the tunnel (otherwise by default your HE tunnel will be wide open) 4 | 5 | [![Commits](https://img.shields.io/github/last-commit/telnetdoogie/UDMP-ipv6/main)](https://github.com/telnetdoogie/UDMP-ipv6/commits/main) 6 | [![Issues](https://img.shields.io/github/issues/telnetdoogie/UDMP-ipv6)](https://github.com/telnetdoogie/UDMP-ipv6/issues) 7 | [![Pull Requests](https://img.shields.io/github/issues-pr-raw/telnetdoogie/UDMP-ipv6)](https://github.com/telnetdoogie/UDMP-ipv6/pulls) 8 | 9 | # Prerequisites 10 | 11 | This collection of scripts depends on [boostchicken's on_boot utility](https://github.com/boostchicken-dev/udm-utilities/blob/master/on-boot-script/README.md). That must be set up and running before you can use these scripts. 12 | 13 | You must first have an account set up with [tunnelbroker](https://tunnelbroker.net/) and a tunnel to use. Hurricane Electric will require that your UDMP be pingable from tunnelbroker's IP when you initially provide your IPv4 address, and that connectivity will need to continue if you're using something like ddclient or inadyn to update your IP with tunnelbroker dynamically. 14 | 15 | This is my port forward rule for allowing HE to ping my UDMP from the internet (not needed if you're already allowing ping from the internet as a general rule) - tunnelbroker's IP that the pings will come from is `66.220.2.74` at time of writing. 16 | 17 |

18 | 19 |

20 | 21 | # Caveat Emptor 22 | 23 | This script is not 'supported' in any way by Ubiquiti, and, based on the way the firewall rules are applied, you **MUST** disable ipv6 from your WAN interfaces before you set this up. In order to 'transpose' the Unifi Firewall rules over to the tunnel interface, the method I'm using here takes the ipv6 rules from your default WAN interface and removes them, applying them instead to your new tunnel interface. This is not a problem if you do not have ipv6 working from your ISP, but in the case where (without the tunnel) your WAN interface does have a valid ipv6 address already (perhaps you're just wanting to use a HE tunnel for a static ipv6 network), the firewall configuration script will leave your WAN exposed to ipv6 traffic. So, set your "IPv6 Connection" from your internet connection to `DISABLED` before you proceed. 24 | 25 | This set of scripts is intended for the user that is using a HE tunnel in order to get IPv6 connectivity on a single interface. Currently, if you have multiple WANs in a load-balanced setup, OR if your WAN fails over to a secondary WAN, this set of scripts isn't yet robust enough to handle those situations. (See [Issue #1](https://github.com/telnetdoogie/UDMP-ipv6/issues/1)) 26 | 27 | # Setting up the files 28 | 29 | * Add the two files [41-enable-he-ipv6.sh](data/on_boot.d/41-enable-he-ipv6.sh) and [99-add-cronjobs.sh](data/on_boot.d/99-add-cronjobs.sh) to `/data/on_boot.d/` 30 | * Make both of those files executable: 31 | * `chmod +x /data/on_boot.d/41-enable-he-ipv6.sh` 32 | * `chmod +x /data/on_boot.d/99-add-cronjobs.sh` 33 | * Create a folder, `mkdir /data/cronjobs/` and put the file [update_ipv6_chains](data/cronjobs/update_ipv6_chains) in that folder. 34 | * Create a folder, `mkdir /data/ipv6/` and drop both files [enable-he-ipv6.sh](/data/ipv6/enable-he-ipv6.sh) and [configure-he-ipv6-chains.sh](/data/ipv6/configure-he-ipv6-chains.sh) in that folder. 35 | * Make both of those files executable: 36 | * `chmod +x /data/ipv6/enable-he-ipv6.sh` 37 | * `chmod +x /data/ipv6/configure-he-ipv6-chains.sh` 38 | * Edit the file [/data/ipv6/enable-he-ipv6.sh](/data/ipv6/enable-he-ipv6.sh) and change the two properties `REMOTE_ENDPOINT` and `LOCAL_IPV6` to match the values from `Server IPv4 Address` and `Client IPv6 Address` respectively 39 | * those values can be found on tunnelbroker.net in your **tunnel details** page 40 | 41 | You can either reboot your UDMP at this point, or run `/data/on_boot.d/41-enable-he-ipv6.sh` and `/data/on_boot.d/99-add-cronjobs.sh`. 42 | 43 | Log entries related to scripts running will show in `/var/log/messages` with a prefix of `user.info` 44 | 45 | # Testing things out 46 | 47 | To confirm that ipv6 is working, while logged into the UDMP and after all scripts are installed and have been executed, run `ping6 2600::` and look for valid response: 48 | ``` 49 | # ping6 2600:: 50 | PING 2600:: (2600::): 56 data bytes 51 | 64 bytes from 2600::: seq=0 ttl=53 time=32.721 ms 52 | 64 bytes from 2600::: seq=1 ttl=53 time=32.720 ms 53 | 64 bytes from 2600::: seq=2 ttl=53 time=45.699 ms 54 | 64 bytes from 2600::: seq=3 ttl=53 time=32.905 ms 55 | 64 bytes from 2600::: seq=4 ttl=53 time=32.579 ms 56 | ^C 57 | --- 2600:: ping statistics --- 58 | 5 packets transmitted, 5 packets received, 0% packet loss 59 | round-trip min/avg/max = 32.579/35.324/45.699 ms 60 | ``` 61 | 62 | To confirm that your firewall rules are being applied to the `he-ipv6` interface, run `ip6tables-save | grep he-ipv6` 63 | You should see entries similar to this: 64 | ``` 65 | # ip6tables-save | grep he-ipv6 66 | -A UBIOS_FORWARD_IN_USER -i he-ipv6 -m comment --comment 00000001095216663483 -j UBIOS_WAN2_PF_IN_USER 67 | -A UBIOS_FORWARD_IN_USER -i he-ipv6 -m comment --comment 00000001095216663484 -j UBIOS_WAN_IN_USER 68 | -A UBIOS_FORWARD_OUT_USER -o he-ipv6 -m comment --comment 00000001095216663483 -j UBIOS_WAN2_PF_OUT_USER 69 | -A UBIOS_FORWARD_OUT_USER -o he-ipv6 -m comment --comment 00000001095216663484 -j UBIOS_WAN_OUT_USER 70 | -A UBIOS_FWD_IN_GEOIP_PRECHK -i he-ipv6 -j UBIOS_IN_GEOIP 71 | -A UBIOS_FWD_OUT_GEOIP_PRECHK -o he-ipv6 -j UBIOS_OUT_GEOIP 72 | -A UBIOS_INPUT_GEOIP_PRECHK -i he-ipv6 -j UBIOS_IN_GEOIP 73 | -A UBIOS_INPUT_USER_HOOK -i he-ipv6 -m comment --comment 00000001095216663482 -j UBIOS_WAN_LOCAL_USER 74 | ``` 75 | ...changing rules in the UDMP UI / Admin interface will have the side-effect of wiping firewall / iptables rules and re-applying them to `eth8` and `eth9`. The cron job will scrape the new rules and will re-apply them back to the `he-ipv6` interface if they have been removed. In the cronjob provided, this will occur as often as every minute (if the rules have indeed been changed) - so there may be a slight lag (1 minute or less) between changing firewall rules, and those rules being re-applied to the `he-ipv6` interface. 76 | 77 | You can test that the rules are continuing to be updated by the cron job by making a change somewhere in the UI / Admin interface and observing the return of the iptables entries: 78 | 79 | ``` 80 | # ip6tables-save | grep he-ipv6 81 | -A UBIOS_FORWARD_IN_USER -i he-ipv6 -m comment --comment 00000001095216663483 -j UBIOS_WAN2_PF_IN_USER 82 | -A UBIOS_FORWARD_IN_USER -i he-ipv6 -m comment --comment 00000001095216663484 -j UBIOS_WAN_IN_USER 83 | -A UBIOS_FORWARD_OUT_USER -o he-ipv6 -m comment --comment 00000001095216663483 -j UBIOS_WAN2_PF_OUT_USER 84 | -A UBIOS_FORWARD_OUT_USER -o he-ipv6 -m comment --comment 00000001095216663484 -j UBIOS_WAN_OUT_USER 85 | -A UBIOS_FWD_IN_GEOIP_PRECHK -i he-ipv6 -j UBIOS_IN_GEOIP 86 | -A UBIOS_FWD_OUT_GEOIP_PRECHK -o he-ipv6 -j UBIOS_OUT_GEOIP 87 | -A UBIOS_INPUT_GEOIP_PRECHK -i he-ipv6 -j UBIOS_IN_GEOIP 88 | -A UBIOS_INPUT_USER_HOOK -i he-ipv6 -m comment --comment 00000001095216663482 -j UBIOS_WAN_LOCAL_USER 89 | 90 | ( Admin / UI change made here, rules disappear ) 91 | 92 | # ip6tables-save | grep he-ipv6 93 | # ip6tables-save | grep he-ipv6 94 | 95 | ( Wait a while here, rules should return after ~1 minute thanks to cron ) 96 | 97 | # ip6tables-save | grep he-ipv6 98 | -A UBIOS_FORWARD_IN_USER -i he-ipv6 -m comment --comment 00000001095216663483 -j UBIOS_WAN2_PF_IN_USER 99 | -A UBIOS_FORWARD_IN_USER -i he-ipv6 -m comment --comment 00000001095216663484 -j UBIOS_WAN_IN_USER 100 | -A UBIOS_FORWARD_OUT_USER -o he-ipv6 -m comment --comment 00000001095216663483 -j UBIOS_WAN2_PF_OUT_USER 101 | -A UBIOS_FORWARD_OUT_USER -o he-ipv6 -m comment --comment 00000001095216663484 -j UBIOS_WAN_OUT_USER 102 | -A UBIOS_FWD_IN_GEOIP_PRECHK -i he-ipv6 -j UBIOS_IN_GEOIP 103 | -A UBIOS_FWD_OUT_GEOIP_PRECHK -o he-ipv6 -j UBIOS_OUT_GEOIP 104 | -A UBIOS_INPUT_GEOIP_PRECHK -i he-ipv6 -j UBIOS_IN_GEOIP 105 | -A UBIOS_INPUT_USER_HOOK -i he-ipv6 -m comment --comment 00000001095216663482 -j UBIOS_WAN_LOCAL_USER 106 | 107 | ``` 108 | 109 | # Assigning IPv6 Address to your LAN clients 110 | 111 | To assign IPv6 addresses to your LAN, you should request a routed /48 from tunnelbroker. You can now manually partition your /48 into as many /64s as you need, and use the "static" assignments on each LAN you want to serve IPv6 addresses to via DHCP. 112 | 113 | For example, if your /48 was `2000:ffff:1234::/48`, you could assign `2000:ffff:1234:1::1/64` as your VLAN1's "**IPv6 Gateway/Subnet**" (giving the UDMP itself an address of `2000:ffff:1234:1::1` on that VLAN) and use the range `2000:ffff:1234:1::3` to `2000:ffff:1234:1::7d1` as the DHCP range for that network. That would allow you to have VLANs with address ranges like `2000:ffff:1234:1::/64`, `2000:ffff:1234:2::/64`, `2000:ffff:1234:3::/64` etc etc., although you can partition the /48 however you'd like. My example uses /64s. 114 | 115 | In the UDMP Network page that would look like this: 116 | 117 |

118 | 119 |

120 | 121 | It's a good idea once your LAN clients have received an IPv6 address to ensure that your firewall rules are working as you intend. I use [this](http://www.ipv6scanner.com/cgi-bin/main.py) IPv6 capable port scanner to ensure that my expected rules are working correctly. 122 | 123 | # Updating your dynamic IP with TunnelBroker using inadyn 124 | 125 | Here is an example `inadyn.conf` entry for tunnelbroker: 126 | 127 | ```bash 128 | # he.net tunnelbroker 129 | provider default@tunnelbroker.net { 130 | checkip-server = default 131 | username = {your_tunnelbroker_login_id} 132 | password = {your_tunnel_update_key} # from the advanced tab in tunnel details 133 | hostname = tunnel{tunnelid}.tunnelbroker.net # the 'tid' number from the tunnel details page URL 134 | } 135 | ``` 136 | -------------------------------------------------------------------------------- /data/cronjobs/update_ipv6_chains: -------------------------------------------------------------------------------- 1 | MAILTO="" 2 | * * * * * root /data/ipv6/configure-he-ipv6-chains.sh | /usr/bin/logger 3 | -------------------------------------------------------------------------------- /data/ipv6/configure-he-ipv6-chains.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Default ip6tables path on UDMP 4 | IP6TABLES_PATH="/usr/sbin" 5 | #UDMP-SE path 6 | if test -f "/sbin/iptables-save"; then 7 | IP6TABLES_PATH="/sbin" 8 | fi 9 | 10 | #detect active WAN interface 11 | WAN_IFACE=$(ip route get 8.8.8.8 | awk '{ printf $5 }') 12 | 13 | if [[ ${WAN_IFACE} =~ \. ]]; then 14 | #may be a ppp0 interface 15 | WAN_IFACE=$(echo "${WAN_IFACE}" | grep -o '\.[^.]*$' | sed 's/\.//') 16 | fi 17 | 18 | # check to see if WAN interface rules have been re-created 19 | if ${IP6TABLES_PATH}/ip6tables-save | grep -Fqi "${WAN_IFACE}" ; then 20 | 21 | # if he-ipv6 entries still exist, remove them before proceeding 22 | if ${IP6TABLES_PATH}/ip6tables-save | grep -Fqi "he-ipv6" ; then 23 | echo "Removing old he-ipv6 references..." 24 | ${IP6TABLES_PATH}/ip6tables-save | sed '/he-ipv6/Id' | ${IP6TABLES_PATH}/ip6tables-restore 25 | fi 26 | 27 | # export ip6tables, replace WAN interface entries with he-ipv6 28 | echo "Updating ip6tables to replace ${WAN_IFACE} with he-ipv6..." 29 | ${IP6TABLES_PATH}/ip6tables-save | sed "s/${WAN_IFACE}/he-ipv6/g" | sed "s/${WAN_IFACE^^}/HE-IPV6/g" | ${IP6TABLES_PATH}/ip6tables-restore 30 | 31 | fi 32 | -------------------------------------------------------------------------------- /data/ipv6/enable-he-ipv6.sh: -------------------------------------------------------------------------------- 1 | #Remote endpoint used for your tunnel, HE calls this "Server IPv4 Address:" on tunnelbroker.net under Tunnel Details. 2 | REMOTE_ENDPOINT={your ipv4 HE endpoint} 3 | 4 | #Local IPV6 for tunnel, HE calls this "Client IPv6 Address:" on tunnelbroker.net under Tunnel Details 5 | LOCAL_IPV6={your HE ipv6 address} 6 | 7 | LOCAL_ENDPOINT=`/sbin/ip route get $REMOTE_ENDPOINT | awk -F"src " 'NR==1{split($2,a," ");print a[1]}'` 8 | 9 | /sbin/ip tunnel add he-ipv6 mode sit remote $REMOTE_ENDPOINT local $LOCAL_ENDPOINT ttl 255 10 | /sbin/ip link set he-ipv6 up 11 | 12 | /sbin/ip addr add $LOCAL_IPV6 dev he-ipv6 13 | /sbin/ip route add ::/0 dev he-ipv6 14 | 15 | logger -s -t enable-he-ipv6 -p INFO HE-IPV6 enabled 16 | -------------------------------------------------------------------------------- /data/on_boot.d/41-enable-he-ipv6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | DELAY=60 3 | 4 | #delay start, since networking is still not started yet 5 | echo "Adding he-ipv6 tunnel in $DELAY seconds..." | /usr/bin/logger 6 | sleep $DELAY && /data/ipv6/enable-he-ipv6.sh & 7 | -------------------------------------------------------------------------------- /data/on_boot.d/99-add-cronjobs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cp /data/cronjobs/* /etc/cron.d/ 4 | /etc/init.d/cron restart 5 | 6 | exit 0 7 | --------------------------------------------------------------------------------