mirror of
https://github.com/unifi-utilities/unifios-utilities.git
synced 2024-08-30 18:32:21 +00:00
Auto set correct data path (#491)
* Corrected file path by removing /mnt * Update 20-zerotier.sh * Update README.md * removed /mnt directory as evertyhing is done in /data * Corrected URL * Update remote_install.sh * Auto check data dir * fixed adguard installation * More data fixes * Fix dns common data path * fixed haproxy readme
This commit is contained in:
parent
2a1f6a5478
commit
162d4ce478
@ -2,47 +2,49 @@
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
1. Run AdguardHome on your UDM with a completely isolated network stack. This will not port conflict or be influenced by any changes on by Ubiquiti
|
1. Run AdguardHome on your UDM with a completely isolated network stack. This will not port conflict or be influenced by any changes on by Ubiquiti
|
||||||
2. Persists through reboots and firmware updates.
|
2. Persists through reboots and firmware updates.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
1. You have setup the on boot script described [here](https://github.com/unifi-utilities/unifios-utilities/tree/main/on-boot-script)
|
1. You have setup the on boot script described [here](https://github.com/unifi-utilities/unifios-utilities/tree/main/on-boot-script)
|
||||||
1. AdguardHome persists through firmware updates as it will store the configuration in a folder (you need to create this). It needs 2 folders, a Work and Configuration folder. Please create the 2 folders in "/mnt/data/". In my example I created "AdguardHome-Confdir" and "AdguardHome-Workdir"
|
1. AdguardHome persists through firmware updates as it will store the configuration in a folder (you need to create this). It needs 2 folders, a Work and Configuration folder. Please create the 2 folders in "/data/". In my example I created "AdguardHome-Confdir" and "AdguardHome-Workdir"
|
||||||
|
|
||||||
## Customization
|
## Customization
|
||||||
|
|
||||||
* Feel free to change [20-dns.conflist](../cni-plugins/20-dns.conflist) to change the IP and MAC address of the container.
|
- Feel free to change [20-dns.conflist](../cni-plugins/20-dns.conflist) to change the IP and MAC address of the container.
|
||||||
* Update [10-dns.sh](../dns-common/on_boot.d/10-dns.sh) with your own values
|
- Update [10-dns.sh](../dns-common/on_boot.d/10-dns.sh) with your own values
|
||||||
* If you want IPv6 support use [20-dnsipv6.conflist](../cni-plugins/20-dnsipv6.conflist) and update [10-dns.sh](../dns-common/on_boot.d/10-dns.sh) with the IPv6 addresses. Also, please provide IPv6 servers to podman using --dns arguments.
|
- If you want IPv6 support use [20-dnsipv6.conflist](../cni-plugins/20-dnsipv6.conflist) and update [10-dns.sh](../dns-common/on_boot.d/10-dns.sh) with the IPv6 addresses. Also, please provide IPv6 servers to podman using --dns arguments.
|
||||||
|
|
||||||
## Steps
|
## Steps
|
||||||
Please note if you have firmware v2 or above you have to copy all files into /data instead of /mnt/data. You can see what version you are running by running: ubnt-device-info firmware
|
|
||||||
|
|
||||||
1. Copy [05-install-cni-plugins.sh](../cni-plugins/05-install-cni-plugins.sh) to /mnt/data/on_boot.d
|
Please note if you have firmware v2 or above you have to copy all files into /data instead of /data. You can see what version you are running by running: ubnt-device-info firmware
|
||||||
1. On your controller, make a Corporate network with no DHCP server and give it a VLAN. For this example we are using VLAN 5. You should confirm the bridge is created for this VLAN by running `netstat -r` otherwise the script will fail. If it is not there, initiate a provisioning of the UDM (Controller > UDM > Config > Manage Device > Force provision).
|
|
||||||
1. Copy [10-dns.sh](../dns-common/on_boot.d/10-dns.sh) to `/mnt/data/on_boot.d` and update its values to reflect your environment
|
|
||||||
1. Copy [20-dns.conflist](../cni-plugins/20-dns.conflist) to `/mnt/data/podman/cni` after generating a MAC address. This will create your podman macvlan network.
|
|
||||||
1. Execute /mnt/data/on_boot.d/05-install-cni-plugins.sh
|
|
||||||
3. Execute `/mnt/data/on_boot.d/10-dns.sh`
|
|
||||||
4. Run the AdguardHome docker container, be sure to make the directories for your persistent AdguardHome configuration. They are mounted as volumes in the command below.
|
|
||||||
|
|
||||||
```shell script
|
1. Check if you have either `/mnt/data/` or `/data/` and use the correct one below.
|
||||||
mkdir /mnt/data/AdguardHome-Confdir
|
2. Copy [05-install-cni-plugins.sh](../cni-plugins/05-install-cni-plugins.sh) to /data/on_boot.d
|
||||||
mkdir /mnt/data/AdguardHome-Workdir
|
3. On your controller, make a Corporate network with no DHCP server and give it a VLAN. For this example we are using VLAN 5. You should confirm the bridge is created for this VLAN by running `netstat -r` otherwise the script will fail. If it is not there, initiate a provisioning of the UDM (Controller > UDM > Config > Manage Device > Force provision).
|
||||||
|
4. Copy [10-dns.sh](../dns-common/on_boot.d/10-dns.sh) to `/data/on_boot.d` and update its values to reflect your environment
|
||||||
podman run -d --network dns --restart always \
|
5. Copy [20-dns.conflist](../cni-plugins/20-dns.conflist) to `/data/podman/cni` after generating a MAC address. This will create your podman macvlan network.
|
||||||
--name adguardhome \
|
6. Execute /data/on_boot.d/05-install-cni-plugins.sh
|
||||||
-v "/mnt/data/AdguardHome-Confdir/:/opt/adguardhome/conf/" \
|
7. Execute `/data/on_boot.d/10-dns.sh`
|
||||||
-v "/mnt/data/AdguardHome-Workdir/:/opt/adguardhome/work/" \
|
8. Run the AdguardHome docker container, be sure to make the directories for your persistent AdguardHome configuration. They are mounted as volumes in the command below.
|
||||||
--dns=127.0.0.1 --dns=1.1.1.1 \
|
|
||||||
--hostname adguardhome \
|
|
||||||
adguard/adguardhome:latest
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Browse to 10.0.5.3:3000 and follow the setup wizard
|
```shell script
|
||||||
1. Update your DNS Servers to 10.0.5.3 (or your custom ip) in all your DHCP configs.
|
mkdir /data/AdguardHome-Confdir
|
||||||
1. Access the AdguardHome like you would normally.
|
mkdir /data/AdguardHome-Workdir
|
||||||
|
|
||||||
|
podman run -d --network dns --restart always \
|
||||||
|
--name adguardhome \
|
||||||
|
-v "/data/AdguardHome-Confdir/:/opt/adguardhome/conf/" \
|
||||||
|
-v "/data/AdguardHome-Workdir/:/opt/adguardhome/work/" \
|
||||||
|
--dns=127.0.0.1 --dns=1.1.1.1 \
|
||||||
|
--hostname adguardhome \
|
||||||
|
adguard/adguardhome:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
9. Browse to 10.0.5.3:3000 and follow the setup wizard
|
||||||
|
10. Update your DNS Servers to 10.0.5.3 (or your custom ip) in all your DHCP configs.
|
||||||
|
11. Access the AdguardHome like you would normally.
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ Script to persist ssh keys after reboot or firmware update.
|
|||||||
| WireGuard kernel module | <https://github.com/tusc/wireguard-kmod> | Uses a prebuilt linux kernel module, without the need to move to a custom kernel. |
|
| WireGuard kernel module | <https://github.com/tusc/wireguard-kmod> | Uses a prebuilt linux kernel module, without the need to move to a custom kernel. |
|
||||||
| OpenConnect VPN | <https://github.com/shuguet/openconnect-udm> | OpenConnect VPN Client for the UniFi Dream Machine Pro (Unofficial).|
|
| OpenConnect VPN | <https://github.com/shuguet/openconnect-udm> | OpenConnect VPN Client for the UniFi Dream Machine Pro (Unofficial).|
|
||||||
| split-vpn | <https://github.com/peacey/split-vpn> |A split tunnel VPN script for the UDM with policy based routing. This helper script can be used on your UDM to route select VLANs, clients, or even domains through a VPN connection. It supports OpenVPN, WireGuard, and OpenConnect (Cisco AnyConnect) clients running directly on your UDM, and external VPN clients running on other servers on your network. |
|
| split-vpn | <https://github.com/peacey/split-vpn> |A split tunnel VPN script for the UDM with policy based routing. This helper script can be used on your UDM to route select VLANs, clients, or even domains through a VPN connection. It supports OpenVPN, WireGuard, and OpenConnect (Cisco AnyConnect) clients running directly on your UDM, and external VPN clients running on other servers on your network. |
|
||||||
|
| Zerotier | <zerotier.com/> |ZeroTier provides network control and P2P functionality · Use ZeroTier to create products which run on their own decentralized networks |
|
||||||
|
|
||||||
|
|
||||||
## DNS Providers
|
## DNS Providers
|
||||||
|
@ -1,20 +1,47 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
|
||||||
wan_iface="eth8" # "eth9" for UDM Pro WAN2
|
# Get DataDir location
|
||||||
vlans="br0" # "br0 br100 br101..."
|
DATA_DIR="/data"
|
||||||
domain="example.invalid" # DNS domain
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
# Check if the directory exists
|
||||||
|
if [ ! -d "$DATA_DIR" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "$DATA_DIR"
|
||||||
|
echo "Directory '$DATA_DIR' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '$DATA_DIR' already exists. Moving on."
|
||||||
|
fi
|
||||||
|
|
||||||
|
wan_iface="eth8" # "eth9" for UDM Pro WAN2
|
||||||
|
vlans="br0" # "br0 br100 br101..."
|
||||||
|
domain="example.invalid" # DNS domain
|
||||||
dns6="[2001:4860:4860::8888],[2001:4860:4860::8844]" # Google
|
dns6="[2001:4860:4860::8888],[2001:4860:4860::8844]" # Google
|
||||||
|
|
||||||
CONTAINER=att-ipv6
|
CONTAINER=att-ipv6
|
||||||
confdir=/mnt/data/att-ipv6
|
confdir=${DATA_DIR}/att-ipv6
|
||||||
|
|
||||||
# main
|
# main
|
||||||
mkdir -p "${confdir}/dhcpcd"
|
mkdir -p "${confdir}/dhcpcd"
|
||||||
|
|
||||||
test -f "${confdir}/dhcpcd.conf" || {
|
test -f "${confdir}/dhcpcd.conf" || {
|
||||||
: > "${confdir}/dhcpcd.conf.tmp"
|
: >"${confdir}/dhcpcd.conf.tmp"
|
||||||
cat >> "${confdir}/dhcpcd.conf.tmp" <<EOF
|
cat >>"${confdir}/dhcpcd.conf.tmp" <<EOF
|
||||||
allowinterfaces ${wan_iface}
|
allowinterfaces ${wan_iface}
|
||||||
nodev
|
nodev
|
||||||
noup
|
noup
|
||||||
@ -37,14 +64,14 @@ EOF
|
|||||||
ix=0
|
ix=0
|
||||||
for vv in $vlans; do
|
for vv in $vlans; do
|
||||||
echo " ia_pd ${ix} ${vv}/0"
|
echo " ia_pd ${ix} ${vv}/0"
|
||||||
ix=$((ix+1))
|
ix=$((ix + 1))
|
||||||
done >> "${confdir}/dhcpcd.conf.tmp"
|
done >>"${confdir}/dhcpcd.conf.tmp"
|
||||||
mv "${confdir}/dhcpcd.conf.tmp" "${confdir}/dhcpcd.conf"
|
mv "${confdir}/dhcpcd.conf.tmp" "${confdir}/dhcpcd.conf"
|
||||||
}
|
}
|
||||||
|
|
||||||
test -f "${confdir}/att-ipv6-dnsmasq.conf" || {
|
test -f "${confdir}/att-ipv6-dnsmasq.conf" || {
|
||||||
: > "${confdir}/att-ipv6-dnsmasq.conf.tmp"
|
: >"${confdir}/att-ipv6-dnsmasq.conf.tmp"
|
||||||
cat >> "${confdir}/att-ipv6-dnsmasq.conf.tmp" <<EOF
|
cat >>"${confdir}/att-ipv6-dnsmasq.conf.tmp" <<EOF
|
||||||
#
|
#
|
||||||
# via att-ipv6
|
# via att-ipv6
|
||||||
#
|
#
|
||||||
@ -62,18 +89,16 @@ dhcp-option=tag:att-ipv6-${vv},option6:dns-server,${dns6}
|
|||||||
domain=${domain}|${vv}
|
domain=${domain}|${vv}
|
||||||
ra-param=${vv},high,0
|
ra-param=${vv},high,0
|
||||||
EOF
|
EOF
|
||||||
done >> "${confdir}/att-ipv6-dnsmasq.conf.tmp"
|
done >>"${confdir}/att-ipv6-dnsmasq.conf.tmp"
|
||||||
mv "${confdir}/att-ipv6-dnsmasq.conf.tmp" "${confdir}/att-ipv6-dnsmasq.conf"
|
mv "${confdir}/att-ipv6-dnsmasq.conf.tmp" "${confdir}/att-ipv6-dnsmasq.conf"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if podman container exists "$CONTAINER"; then
|
if podman container exists "$CONTAINER"; then
|
||||||
podman start "$CONTAINER"
|
podman start "$CONTAINER"
|
||||||
else
|
else
|
||||||
podman run -d --restart=always --name "$CONTAINER" -v "${confdir}/dhcpcd.conf:/etc/dhcpcd.conf" -v "${confdir}/dhcpcd:/var/lib/dhcpcd" --net=host --privileged ghcr.io/michaelw/dhcpcd
|
podman run -d --restart=always --name "$CONTAINER" -v "${confdir}/dhcpcd.conf:/etc/dhcpcd.conf" -v "${confdir}/dhcpcd:/var/lib/dhcpcd" --net=host --privileged ghcr.io/michaelw/dhcpcd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Fix DHCP, assumes DHCPv6 is turned off in UI
|
# Fix DHCP, assumes DHCPv6 is turned off in UI
|
||||||
cp "${confdir}/att-ipv6-dnsmasq.conf" /run/dnsmasq.conf.d/
|
cp "${confdir}/att-ipv6-dnsmasq.conf" /run/dnsmasq.conf.d/
|
||||||
start-stop-daemon -K -q -x /usr/sbin/dnsmasq
|
start-stop-daemon -K -q -x /usr/sbin/dnsmasq
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# AT&T IPv6
|
# AT&T IPv6
|
||||||
|
|
||||||
On ATT IPv6, the RG (residential gateway) receives a /60 prefix itself, but only hands out one /64 to routers in IP Passthrough mode, regardless how big of a prefix was requested. The RG keeps the lower 8 /64s for its own purposes (`2600:1700:X:yyy0::/63`), and Unifi normally only receives `2600:1700:X:yyyf::/64`.
|
On ATT IPv6, the RG (residential gateway) receives a /60 prefix itself, but only hands out one /64 to routers in IP Passthrough mode, regardless how big of a prefix was requested. The RG keeps the lower 8 /64s for its own purposes (`2600:1700:X:yyy0::/63`), and Unifi normally only receives `2600:1700:X:yyyf::/64`.
|
||||||
|
|
||||||
This script enables UDM to receive up to 8 PDs on ATT IPv6 (tested with RG BGW320-500), usually starting at `2600:1700:X:yyyf::/64` down to `2600:1700:X:yyy8::/64`.
|
This script enables UDM to receive up to 8 PDs on ATT IPv6 (tested with RG BGW320-500), usually starting at `2600:1700:X:yyyf::/64` down to `2600:1700:X:yyy8::/64`.
|
||||||
Note that these may not always be assigned contiguous or in order.
|
Note that these may not always be assigned contiguous or in order.
|
||||||
@ -14,10 +14,10 @@ Firewall and routing rules remain functional, however.
|
|||||||
2. You must set up the ATT RG in ["IP Passthrough" mode](https://patrickdomingues.com/2022/09/03/udm-pro-vpn-on-att-fiber-bgw320/)
|
2. You must set up the ATT RG in ["IP Passthrough" mode](https://patrickdomingues.com/2022/09/03/udm-pro-vpn-on-att-fiber-bgw320/)
|
||||||
3. You must turn off IPv6 on the ATT WAN connection, AND on each network/VLAN (IPv6 Interface Type: None)
|
3. You must turn off IPv6 on the ATT WAN connection, AND on each network/VLAN (IPv6 Interface Type: None)
|
||||||
4. You must add Firewall rules equivalent to (this can be done in the UI, select `Internet v6 Local` chain)
|
4. You must add Firewall rules equivalent to (this can be done in the UI, select `Internet v6 Local` chain)
|
||||||
```
|
```
|
||||||
-A UBIOS_WAN_LOCAL_USER -p udp -m udp --sport 547 --dport 546 -j RETURN # select IPv6 Protocol "UDP" and create port groups for source port 547 and dest port 546
|
-A UBIOS_WAN_LOCAL_USER -p udp -m udp --sport 547 --dport 546 -j RETURN # select IPv6 Protocol "UDP" and create port groups for source port 547 and dest port 546
|
||||||
-A UBIOS_WAN_LOCAL_USER -p ipv6-icmp -m icmp6 --icmpv6-type 134 -j RETURN # select IPv6 Protocol "ICMPv6" and IPv6ICMP Type Name "Router Advertisement"
|
-A UBIOS_WAN_LOCAL_USER -p ipv6-icmp -m icmp6 --icmpv6-type 134 -j RETURN # select IPv6 Protocol "ICMPv6" and IPv6ICMP Type Name "Router Advertisement"
|
||||||
```
|
```
|
||||||
5. You may want to add a "Traffic Management" route on your ATT WAN device to access 192.168.1.254/32, so that you can access the RG after it is in passthrough mode.
|
5. You may want to add a "Traffic Management" route on your ATT WAN device to access 192.168.1.254/32, so that you can access the RG after it is in passthrough mode.
|
||||||
|
|
||||||
## Customization
|
## Customization
|
||||||
@ -31,13 +31,13 @@ Near the top of `10-att-ipv6.sh`:
|
|||||||
dns6="[2001:4860:4860::8888],[2001:4860:4860::8844]" # Google
|
dns6="[2001:4860:4860::8888],[2001:4860:4860::8844]" # Google
|
||||||
```
|
```
|
||||||
|
|
||||||
This generates configuration files in directory `/mnt/data/att-ipv6`, if they don't exist.
|
This generates configuration files in directory `/data/att-ipv6`, if they don't exist.
|
||||||
The files can be edited, or regenerated by deleting them and re-running the script.
|
The files can be edited, or regenerated by deleting them and re-running the script.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd /mnt/data/on_boot.d
|
cd /data/on_boot.d
|
||||||
curl -LO https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/HEAD/att-ipv6/10-att-ipv6.sh
|
curl -LO https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/HEAD/att-ipv6/10-att-ipv6.sh
|
||||||
chmod +x 10-att-ipv6.sh
|
chmod +x 10-att-ipv6.sh
|
||||||
./10-att-ipv6.sh
|
./10-att-ipv6.sh
|
||||||
@ -47,11 +47,12 @@ The dhcpcd container being used is built [here](https://github.com/michaelw/dhcp
|
|||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
Running the script starts dhcpcd within the `att-ipv6` container on `eth8` (WAN1) and only for the default network (`br0`). This can be customized, see above.
|
Running the script starts dhcpcd within the `att-ipv6` container on `eth8` (WAN1) and only for the default network (`br0`). This can be customized, see above.
|
||||||
|
|
||||||
To check that everything is working as expected, and the ATT RG delegates multiple prefixes:
|
To check that everything is working as expected, and the ATT RG delegates multiple prefixes:
|
||||||
|
|
||||||
On UDM:
|
On UDM:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ ip -6 r # should see a default route on the WAN interface, and a 2600:1700:X:Y::/64 prefix on each configured VLAN bridge interface
|
$ ip -6 r # should see a default route on the WAN interface, and a 2600:1700:X:Y::/64 prefix on each configured VLAN bridge interface
|
||||||
2600:1700:X:yyy0::/64 dev eth9 proto ra metric 203 mtu 1500 pref medium
|
2600:1700:X:yyy0::/64 dev eth9 proto ra metric 203 mtu 1500 pref medium
|
||||||
@ -106,8 +107,8 @@ $ ps auxw|grep dnsmasq # should see dnsmasq running
|
|||||||
|
|
||||||
On BGW320-500, check https://192.168.1.254/cgi-bin/lanstatistics.ha for multiple PDs in `IPv6 Delegated Prefix Subnet (including length)`.
|
On BGW320-500, check https://192.168.1.254/cgi-bin/lanstatistics.ha for multiple PDs in `IPv6 Delegated Prefix Subnet (including length)`.
|
||||||
|
|
||||||
|
|
||||||
On clients:
|
On clients:
|
||||||
|
|
||||||
```
|
```
|
||||||
ip -6 addr show # should see SLAAC and/or DHCPv6 addresses received (if not, check dnsmasq configuration in `/run/dnsmasq.conf.d`)
|
ip -6 addr show # should see SLAAC and/or DHCPv6 addresses received (if not, check dnsmasq configuration in `/run/dnsmasq.conf.d`)
|
||||||
```
|
```
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Cloudflare Dynamic DNS
|
# Cloudflare Dynamic DNS
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
Complete feature list and documentation can be found [here](https://github.com/timothymiller/cloudflare-ddns)
|
Complete feature list and documentation can be found [here](https://github.com/timothymiller/cloudflare-ddns)
|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
1. You have successfully setup the on boot script described [here](https://github.com/unifi-utilities/unifios-utilities/tree/main/on-boot-script)
|
1. You have successfully setup the on boot script described [here](https://github.com/unifi-utilities/unifios-utilities/tree/main/on-boot-script)
|
||||||
@ -18,6 +17,7 @@ Complete feature list and documentation can be found [here](https://github.com/t
|
|||||||
## Customization
|
## Customization
|
||||||
|
|
||||||
Update [config.json](configs/config.json) with the following options:
|
Update [config.json](configs/config.json) with the following options:
|
||||||
|
|
||||||
- your cloudflare api token
|
- your cloudflare api token
|
||||||
- your zone id
|
- your zone id
|
||||||
- each subdomain you'd like to point at your udm-pro
|
- each subdomain you'd like to point at your udm-pro
|
||||||
@ -28,14 +28,14 @@ Update [config.json](configs/config.json) with the following options:
|
|||||||
|
|
||||||
2. Make a directory for your configuration
|
2. Make a directory for your configuration
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mkdir -p /mnt/data/cloudflare-ddns
|
mkdir -p /data/cloudflare-ddns
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Create a [cloudflare-ddns configuration](configs/config.json) in `/mnt/data/cloudflare-ddns` and update the configuration to meet your needs.
|
3. Create a [cloudflare-ddns configuration](configs/config.json) in `/data/cloudflare-ddns` and update the configuration to meet your needs.
|
||||||
4. Copy [30-cloudflare-ddns.sh](on_boot.d/30-cloudflare-ddns.sh) to `/mnt/data/on_boot.d`.
|
4. Copy [30-cloudflare-ddns.sh](on_boot.d/30-cloudflare-ddns.sh) to `/data/on_boot.d`.
|
||||||
5. Execute /mnt/data/on_boot.d/[30-cloudflare-ddns.sh](on_boot.d/30-cloudflare-ddns.sh)
|
5. Execute /data/on_boot.d/[30-cloudflare-ddns.sh](on_boot.d/30-cloudflare-ddns.sh)
|
||||||
7. Execute `podman logs cloudflare-ddns` to verify the continer is running without error (ipv6 warnings are normal).
|
6. Execute `podman logs cloudflare-ddns` to verify the continer is running without error (ipv6 warnings are normal).
|
||||||
|
|
||||||
### Useful commands
|
### Useful commands
|
||||||
|
|
||||||
@ -43,4 +43,3 @@ Update [config.json](configs/config.json) with the following options:
|
|||||||
# view cloudflare-ddns logs to verify the continer is running without error (ipv6 warnings are normal).
|
# view cloudflare-ddns logs to verify the continer is running without error (ipv6 warnings are normal).
|
||||||
podman logs cloudflare-ddns
|
podman logs cloudflare-ddns
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
CONTAINER=cloudflare-ddns
|
CONTAINER=cloudflare-ddns
|
||||||
|
|
||||||
# Starts a cloudflare ddns container that is deleted after it is stopped.
|
# Starts a cloudflare ddns container that is deleted after it is stopped.
|
||||||
# All configs stored in /mnt/data/cloudflare-ddns
|
# All configs stored in /data/cloudflare-ddns
|
||||||
if podman container exists "$CONTAINER"; then
|
if podman container exists "$CONTAINER"; then
|
||||||
podman start "$CONTAINER"
|
podman start "$CONTAINER"
|
||||||
else
|
else
|
||||||
@ -10,6 +10,6 @@ else
|
|||||||
--net=host \
|
--net=host \
|
||||||
--name "$CONTAINER" \
|
--name "$CONTAINER" \
|
||||||
--security-opt=no-new-privileges \
|
--security-opt=no-new-privileges \
|
||||||
-v /mnt/data/cloudflare-ddns/config.json:/config.json \
|
-v /data/cloudflare-ddns/config.json:/config.json \
|
||||||
timothyjmiller/cloudflare-ddns:latest
|
timothyjmiller/cloudflare-ddns:latest
|
||||||
fi
|
fi
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Get DataDir location
|
# Get DataDir location
|
||||||
DATA_DIR="/mnt/data"
|
DATA_DIR="/data"
|
||||||
case "$(ubnt-device-info firmware || true)" in
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
1*)
|
1*)
|
||||||
DATA_DIR="/mnt/data"
|
DATA_DIR="/mnt/data"
|
||||||
@ -22,9 +22,9 @@ case "$(ubnt-device-info firmware || true)" in
|
|||||||
# Examples of valid version code would be "latest", "v0.9.1" and "v0.9.0".
|
# Examples of valid version code would be "latest", "v0.9.1" and "v0.9.0".
|
||||||
CNI_PLUGIN_VER=latest
|
CNI_PLUGIN_VER=latest
|
||||||
# location of the CNI Plugin cached tar files
|
# location of the CNI Plugin cached tar files
|
||||||
CNI_CACHE="$DATA_DIR/.cache/cni-plugins"
|
CNI_CACHE="${DATA_DIR}/.cache/cni-plugins"
|
||||||
# location of the conf files to go in the net.d folder of the cni-plugin directory
|
# location of the conf files to go in the net.d folder of the cni-plugin directory
|
||||||
CNI_NETD="$DATA_DIR/podman/cni"
|
CNI_NETD="${DATA_DIR}/podman/cni"
|
||||||
# The checksum to use. For CNI Plugin sha1, sha256 and sha512 are available.
|
# The checksum to use. For CNI Plugin sha1, sha256 and sha512 are available.
|
||||||
CNI_CHECKSUM="sha256"
|
CNI_CHECKSUM="sha256"
|
||||||
# Maximum number of loops to attempt to download the plugin if required - setting a 0 or negative value will reinstalled the currently installed version (if in cache)
|
# Maximum number of loops to attempt to download the plugin if required - setting a 0 or negative value will reinstalled the currently installed version (if in cache)
|
||||||
|
@ -10,26 +10,31 @@
|
|||||||
|
|
||||||
## Customization
|
## Customization
|
||||||
|
|
||||||
While a 100Mb log limit per container should give plenty of log data for all featured in this repo projects, you can increase or decrease max_log_size value in /mnt/data/on_boot.d/05-container-common.sh file after installation.
|
While a 100Mb log limit per container should give plenty of log data for all featured in this repo projects, you can increase or decrease max_log_size value in /data/on_boot.d/05-container-common.sh file after installation.
|
||||||
|
|
||||||
## Steps
|
## Steps
|
||||||
|
|
||||||
1. Run as root on UDM Pro to download and set permissions of on_boot.d script:
|
1. Run as root on UDM Pro to download and set permissions of on_boot.d script:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Download 05-container-common.sh from GitHub
|
# Download 05-container-common.sh from GitHub
|
||||||
curl -L https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/main/container-common/on_boot.d/05-container-common.sh -o /mnt/data/on_boot.d/05-container-common.sh;
|
curl -L https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/main/container-common/on_boot.d/05-container-common.sh -o /data/on_boot.d/05-container-common.sh;
|
||||||
# Set execute permission
|
# Set execute permission
|
||||||
chmod a+x /mnt/data/on_boot.d/05-container-common.sh;
|
chmod a+x /data/on_boot.d/05-container-common.sh;
|
||||||
```
|
```
|
||||||
2. Review the script /mnt/data/on_boot.d/05-container-common.sh and when happy execute it.
|
|
||||||
|
2. Review the script /data/on_boot.d/05-container-common.sh and when happy execute it.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Review script
|
# Review script
|
||||||
cat /mnt/data/on_boot.d/05-container-common.sh;
|
cat /data/on_boot.d/05-container-common.sh;
|
||||||
# Apply container-common settings
|
# Apply container-common settings
|
||||||
/mnt/data/on_boot.d/05-container-common.sh;
|
/data/on_boot.d/05-container-common.sh;
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Already running containers will pick up new defaults after either container restart ("podman restart \<container-name\>") or after UDM Pro restart. New containers will pick up a change from first run.
|
3. Already running containers will pick up new defaults after either container restart ("podman restart \<container-name\>") or after UDM Pro restart. New containers will pick up a change from first run.
|
||||||
4. To list containers that are running with log size limits:
|
4. To list containers that are running with log size limits:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# List container monitor processes with "--log-size-max" custom argument set
|
# List container monitor processes with "--log-size-max" custom argument set
|
||||||
ps -ef | grep conmon | grep log-size-max
|
ps -ef | grep conmon | grep log-size-max
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
## configuration variables:
|
## configuration variables:
|
||||||
VLAN=5
|
VLAN=5
|
||||||
IPV4_IP="10.0.5.3"
|
IPV4_IP="10.0.5.3"
|
||||||
@ -32,9 +48,9 @@ FORCED_INTFC=""
|
|||||||
CONTAINER=pihole
|
CONTAINER=pihole
|
||||||
|
|
||||||
if ! test -f /opt/cni/bin/macvlan; then
|
if ! test -f /opt/cni/bin/macvlan; then
|
||||||
echo "Error: CNI plugins not found. You can install it with the following command:" >&2
|
echo "Error: CNI plugins not found. You can install it with the following command:" >&2
|
||||||
echo " curl -fsSLo /mnt/data/on_boot.d/05-install-cni-plugins.sh https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/main/cni-plugins/05-install-cni-plugins.sh && /bin/sh /mnt/data/on_boot.d/05-install-cni-plugins.sh" >&2
|
echo " curl -fsSLo ${DATA_DIR}/on_boot.d/05-install-cni-plugins.sh https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/main/cni-plugins/05-install-cni-plugins.sh && /bin/sh ${DATA_DIR}/on_boot.d/05-install-cni-plugins.sh" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# set VLAN bridge promiscuous
|
# set VLAN bridge promiscuous
|
||||||
@ -63,8 +79,8 @@ fi
|
|||||||
|
|
||||||
# Make DNSMasq listen to the container network for split horizon or conditional forwarding
|
# Make DNSMasq listen to the container network for split horizon or conditional forwarding
|
||||||
if ! grep -qxF "interface=br${VLAN}.mac" /run/dnsmasq.conf.d/custom.conf; then
|
if ! grep -qxF "interface=br${VLAN}.mac" /run/dnsmasq.conf.d/custom.conf; then
|
||||||
echo "interface=br${VLAN}.mac" >> /run/dnsmasq.conf.d/custom.conf
|
echo "interface=br${VLAN}.mac" >>/run/dnsmasq.conf.d/custom.conf
|
||||||
kill -9 "$(cat /run/dnsmasq.pid)"
|
kill -9 "$(cat /run/dnsmasq.pid)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if podman container exists "${CONTAINER}"; then
|
if podman container exists "${CONTAINER}"; then
|
||||||
|
@ -1,14 +1,41 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
CONTAINER=haproxy
|
CONTAINER=haproxy
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check if the directory exists
|
||||||
|
if [ ! -d "${DATA_DIR}/haproxy" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "${DATA_DIR}/haproxy"
|
||||||
|
echo "Directory '${DATA_DIR}/haproxy' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '${DATA_DIR}/haproxy' already exists. Moving on."
|
||||||
|
fi
|
||||||
|
|
||||||
# Starts an haproxy container that is deleted after it is stopped.
|
# Starts an haproxy container that is deleted after it is stopped.
|
||||||
# All configs stored in /mnt/data/haproxy
|
# All configs stored in /data/haproxy
|
||||||
if podman container exists "$CONTAINER"; then
|
if podman container exists "$CONTAINER"; then
|
||||||
podman start "$CONTAINER"
|
podman start "$CONTAINER"
|
||||||
else
|
else
|
||||||
podman run -d --net=host --restart always \
|
podman run -d --net=host --restart always \
|
||||||
--name haproxy \
|
--name haproxy \
|
||||||
--hostname ha.proxy \
|
--hostname ha.proxy \
|
||||||
-v "/mnt/data/haproxy/:/usr/local/etc/haproxy/" \
|
-v "${DATA_DIR}/haproxy/:/usr/local/etc/haproxy/" \
|
||||||
haproxy:latest
|
haproxy:latest
|
||||||
fi
|
fi
|
||||||
|
@ -12,30 +12,29 @@
|
|||||||
|
|
||||||
## Steps
|
## Steps
|
||||||
|
|
||||||
1. Pull your image with `podman pull docker.io/library/haproxy`.
|
1. Check if you either have `/mnt/data` or `/data/` and adjust below accordingly
|
||||||
|
2. Pull your image with `podman pull docker.io/library/haproxy`.
|
||||||
|
3. Copy [50-haproxy.sh](./50-haproxy.sh) to `/data/on_boot.d/50-haproxy.sh`.
|
||||||
|
4. Choose network configuration - You can run either on the host network or on a seperate docker network. Running on the host network is easier but does mean you can't clash with the ports already in use on the UDM.
|
||||||
|
1. If you want to run on the host network
|
||||||
|
1. You don't have to do anything extra to run on the host network all the instructions / scripts assume this setup.
|
||||||
|
2. If you want to run on a custom docker network do the following:
|
||||||
|
1. Setup the network - there are some instructions in the Customizations setting of the pihole instructions: https://github.com/unifi-utilities/unifios-utilities/tree/main/run-pihole#customizations
|
||||||
|
2. Copy [21-haproxy.conflist](./21-haproxy.conflist) to `/data/podman/cni/` and update its values to reflect your environment.
|
||||||
|
3. Execute the `/data/on_boot.d/05-install-cni-plugins.sh` script to create the network.
|
||||||
|
4. Edit `/data/on_boot.d/50-haproxy.sh` and change `--net=host` to `--network haproxy`
|
||||||
|
5. Create a persistant directory and config for haproxy to use:
|
||||||
|
|
||||||
1. Copy [50-haproxy.sh](./50-haproxy.sh) to `/mnt/data/on_boot.d/50-haproxy.sh`.
|
```sh
|
||||||
|
mkdir -p /data/haproxy
|
||||||
|
touch /data/haproxy/haproxy.cfg
|
||||||
|
```
|
||||||
|
|
||||||
1. Choose network configuration - You can run either on the host network or on a seperate docker network. Running on the host network is easier but does mean you can't clash with the ports already in use on the UDM.
|
6. Add your config to `/data/haproxy/haproxy.cfg`. Each configuration is unique, so check out some resouces like [haproxy.com](https://www.haproxy.com/documentation/hapee/latest/configuration/config-sections/) for basics.
|
||||||
1. If you want to run on the host network
|
7. Run `/data/on_boot.d/50-haproxy.sh`
|
||||||
1. You don't have to do anything extra to run on the host network all the instructions / scripts assume this setup.
|
|
||||||
1. If you want to run on a custom docker network do the following:
|
|
||||||
1. Setup the network - there are some instructions in the Customizations setting of the pihole instructions: https://github.com/unifi-utilities/unifios-utilities/tree/main/run-pihole#customizations
|
|
||||||
1. Copy [21-haproxy.conflist](./21-haproxy.conflist) to `/mnt/data/podman/cni/` and update its values to reflect your environment.
|
|
||||||
1. Execute the `/mnt/data/on_boot.d/05-install-cni-plugins.sh` script to create the network.
|
|
||||||
1. Edit `/mnt/data/on_boot.d/50-haproxy.sh` and change `--net=host` to `--network haproxy`
|
|
||||||
1. Create a persistant directory and config for haproxy to use:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
mkdir -p /mnt/data/haproxy
|
|
||||||
touch /mnt/data/haproxy/haproxy.cfg
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Add your config to `/mnt/data/haproxy/haproxy.cfg`. Each configuration is unique, so check out some resouces like [haproxy.com](https://www.haproxy.com/documentation/hapee/latest/configuration/config-sections/) for basics.
|
|
||||||
1. Run `/mnt/data/on_boot.d/50-haproxy.sh`
|
|
||||||
|
|
||||||
## Upgrading Easily (if at all)
|
## Upgrading Easily (if at all)
|
||||||
|
|
||||||
1. Edit [update-haproxy.sh](./update-haproxy.sh) to use the same command you used at installation (if changed). If you added your own network config ensure you change the `--net=host` to `--network haproxy`
|
1. Edit [update-haproxy.sh](./update-haproxy.sh) to use the same command you used at installation (if changed). If you added your own network config ensure you change the `--net=host` to `--network haproxy`
|
||||||
2. Copy the [update-haproxy.sh](./update-haproxy.sh) to `/mnt/data/scripts`
|
2. Copy the [update-haproxy.sh](./update-haproxy.sh) to `/data/scripts`
|
||||||
3. Anytime you want to update your installation, simply run `/mnt/data/scripts/update-haproxy.sh`
|
3. Anytime you want to update your installation, simply run `/data/scripts/update-haproxy.sh`
|
||||||
|
@ -1,4 +1,21 @@
|
|||||||
IMAGE=haproxy:latest
|
IMAGE=haproxy:latest
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
podman pull $IMAGE
|
podman pull $IMAGE
|
||||||
podman stop haproxy
|
podman stop haproxy
|
||||||
@ -6,5 +23,5 @@ podman rm haproxy
|
|||||||
podman run -d --net=host --restart always \
|
podman run -d --net=host --restart always \
|
||||||
--name haproxy \
|
--name haproxy \
|
||||||
--hostname ha.proxy \
|
--hostname ha.proxy \
|
||||||
-v "/mnt/data/haproxy/:/usr/local/etc/haproxy/" \
|
-v "${DATA_DIR}/haproxy/:/usr/local/etc/haproxy/" \
|
||||||
$IMAGE
|
$IMAGE
|
||||||
|
@ -1,5 +1,32 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Place cross compiled version of `socat` in /mnt/data/hdhomerun
|
# Place cross compiled version of `socat` in /data/hdhomerun
|
||||||
HDHOMERUN_IP=10.10.30.146
|
HDHOMERUN_IP=10.10.30.146
|
||||||
|
|
||||||
/mnt/data/hdhomerun/socat -d -d -v udp4-recvfrom:65001,broadcast,fork udp4-sendto:$HDHOMERUN_IP:65001 &
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
# Check if the directory exists
|
||||||
|
if [ ! -d "$DATA_DIR" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "$DATA_DIR"
|
||||||
|
echo "Directory '$DATA_DIR' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '$DATA_DIR' already exists. Moving on."
|
||||||
|
fi
|
||||||
|
|
||||||
|
${DATA_DIR}/hdhomerun/socat -d -d -v udp4-recvfrom:65001,broadcast,fork udp4-sendto:$HDHOMERUN_IP:65001 &
|
||||||
|
@ -1,37 +1,39 @@
|
|||||||
# Run Homebridge on your UDM
|
# Run Homebridge on your UDM
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
1. Run [Homebridge](https://homebridge.io/) on your UDM(P).
|
1. Run [Homebridge](https://homebridge.io/) on your UDM(P).
|
||||||
2. Integrate Unifi Protect cameras in HomeKit via `homebridge-unifi-protect`.
|
2. Integrate Unifi Protect cameras in HomeKit via `homebridge-unifi-protect`.
|
||||||
3. Persists through reboots and firmware updates.
|
3. Persists through reboots and firmware updates.
|
||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
|
|
||||||
1. You have successfully setup the on boot script described [here](https://github.com/unifi-utilities/unifios-utilities/tree/main/on-boot-script).
|
1. You have successfully setup the on boot script described [here](https://github.com/unifi-utilities/unifios-utilities/tree/main/on-boot-script).
|
||||||
2. You have applied [container-common](https://github.com/unifi-utilities/unifios-utilities/tree/main/container-common) change to prevent UDM storage to fill up with Homebridge logs and addon error messages that can move fast.
|
2. You have applied [container-common](https://github.com/unifi-utilities/unifios-utilities/tree/main/container-common) change to prevent UDM storage to fill up with Homebridge logs and addon error messages that can move fast.
|
||||||
3. You have applied [cni-plugins](https://github.com/unifi-utilities/unifios-utilities/tree/main/cni-plugins "cni-plugins") to setup for cni configeration. (You dont need the configeration files, just place the script in the on boot folder.)
|
3. You have applied [cni-plugins](https://github.com/unifi-utilities/unifios-utilities/tree/main/cni-plugins "cni-plugins") to setup for cni configeration. (You dont need the configeration files, just place the script in the on boot folder.)
|
||||||
|
|
||||||
### Steps
|
### Steps
|
||||||
|
|
||||||
1. Type this command: `mkdir -p /mnt/data/homebridge/run`
|
1. Type this command: `mkdir -p /data/homebridge/run`
|
||||||
2. Copy [25-homebridge.sh](on_boot.d/25-homebridge.sh) to `/mnt/data/on_boot.d`. To do this, cd into `/mnt/data/on_boot.d`, then type `vim 25-homebridge.sh` then go to [this page](https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/main/homebridge/on_boot.d/25-homebridge.sh "this page") and copy everything using CTRL + A and then CTRL + C and then paste it into vim then click ESC and then type `:x` then click the enter key.
|
2. Copy [25-homebridge.sh](on_boot.d/25-homebridge.sh) to `/data/on_boot.d`. To do this, cd into `/data/on_boot.d`, then type `vim 25-homebridge.sh` then go to [this page](https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/main/homebridge/on_boot.d/25-homebridge.sh "this page") and copy everything using CTRL + A and then CTRL + C and then paste it into vim then click ESC and then type `:x` then click the enter key.
|
||||||
3. Copy [90-homebridge.conflist](cni/90-homebridge.conflist) to `/mnt/data/podman/cni`. This will create the podman network that bridges the container to your VLAN. To do this, cd into `/mnt/data/podman/cni` and type `vim 90-homebridge.conflist` then go to [this page](https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/main/homebridge/cni/90-homebridge.conflist "this page") and the press CTRL + A and then CTRL + C and then paste it into vim and click ESC and then type `:x` then click the enter key.
|
3. Copy [90-homebridge.conflist](cni/90-homebridge.conflist) to `/data/podman/cni`. This will create the podman network that bridges the container to your VLAN. To do this, cd into `/data/podman/cni` and type `vim 90-homebridge.conflist` then go to [this page](https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/main/homebridge/cni/90-homebridge.conflist "this page") and the press CTRL + A and then CTRL + C and then paste it into vim and click ESC and then type `:x` then click the enter key.
|
||||||
4. Run the Homebridge docker container. Change the timezone (`-e TZ`) to match your timezone, and DNS (`--dns`) to match your VLAN gateway.
|
4. Run the Homebridge docker container. Change the timezone (`-e TZ`) to match your timezone, and DNS (`--dns`) to match your VLAN gateway.
|
||||||
|
|
||||||
```shell script
|
```shell script
|
||||||
podman run -d --restart always \
|
podman run -d --restart always \
|
||||||
--privileged \
|
--privileged \
|
||||||
--name homebridge \
|
--name homebridge \
|
||||||
--net homebridge \
|
--net homebridge \
|
||||||
--dns 192.168.1.1 \
|
--dns 192.168.1.1 \
|
||||||
--dns-search lan \
|
--dns-search lan \
|
||||||
-e TZ=America/Chicago \
|
-e TZ=America/Chicago \
|
||||||
-e PGID=0 -e PUID=0 \
|
-e PGID=0 -e PUID=0 \
|
||||||
-e HOMEBRIDGE_CONFIG_UI=1 \
|
-e HOMEBRIDGE_CONFIG_UI=1 \
|
||||||
-e HOMEBRIDGE_CONFIG_UI_PORT=80 \
|
-e HOMEBRIDGE_CONFIG_UI_PORT=80 \
|
||||||
-v "/mnt/data/homebridge/:/homebridge/" \
|
-v "/data/homebridge/:/homebridge/" \
|
||||||
-v "/mnt/data/homebridge/run/:/run/" \
|
-v "/data/homebridge/run/:/run/" \
|
||||||
oznu/homebridge:latest
|
oznu/homebridge:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
5. Access the Homebridge UI based on the IP you assigned, like [http://192.168.1.20/](http://192.168.1.20/).
|
5. Access the Homebridge UI based on the IP you assigned, like [http://192.168.1.20/](http://192.168.1.20/).
|
||||||
6. If using the UDM Pro, the `homebridge-unifi-protect` plugin can be installed via the Homebridge UI to integrate Unifi Protect cameras.
|
6. If using the UDM Pro, the `homebridge-unifi-protect` plugin can be installed via the Homebridge UI to integrate Unifi Protect cameras.
|
||||||
|
@ -1,31 +1,56 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
CONTAINER=homebridge
|
CONTAINER=homebridge
|
||||||
|
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
## network configuration and startup:
|
## network configuration and startup:
|
||||||
CNI_PATH=/mnt/data/podman/cni
|
CNI_PATH=${DATA_DIR}/podman/cni
|
||||||
|
# Check if the directory exists
|
||||||
|
if [ ! -d "$CNI_PATH" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "$CNI_PATH"
|
||||||
|
echo "Directory '$CNI_PATH' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '$CNI_PATH' already exists. Moving on."
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -f "$CNI_PATH"/tuning ]; then
|
if [ ! -f "$CNI_PATH"/tuning ]; then
|
||||||
mkdir -p $CNI_PATH
|
mkdir -p $CNI_PATH
|
||||||
curl -L https://github.com/containernetworking/plugins/releases/download/v0.9.1/cni-plugins-linux-arm64-v0.9.1.tgz | tar -xz -C $CNI_PATH
|
curl -L https://github.com/containernetworking/plugins/releases/download/v0.9.1/cni-plugins-linux-arm64-v0.9.1.tgz | tar -xz -C $CNI_PATH
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p /opt/cni
|
mkdir -p /opt/cni
|
||||||
rm -f /opt/cni/bin
|
rm -f /opt/cni/bin
|
||||||
ln -s $CNI_PATH /opt/cni/bin
|
ln -s $CNI_PATH /opt/cni/bin
|
||||||
|
|
||||||
for file in "$CNI_PATH"/*.conflist
|
for file in "$CNI_PATH"/*.conflist; do
|
||||||
do
|
if [ -f "$file" ]; then
|
||||||
if [ -f "$file" ]; then
|
ln -s "$file" "/etc/cni/net.d/$(basename "$file")"
|
||||||
ln -s "$file" "/etc/cni/net.d/$(basename "$file")"
|
fi
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
# Starts the homebridge container on boot.
|
# Starts the homebridge container on boot.
|
||||||
# All configs stored in /mnt/data/homebridge
|
# All configs stored in /data/homebridge
|
||||||
|
|
||||||
if podman container exists ${CONTAINER}; then
|
if podman container exists ${CONTAINER}; then
|
||||||
podman start ${CONTAINER}
|
podman start ${CONTAINER}
|
||||||
else
|
else
|
||||||
logger -s -t homebridge -p ERROR Container $CONTAINER not found, make sure you set the proper name, you can ignore this error if it is your first time setting it up
|
logger -s -t homebridge -p ERROR Container $CONTAINER not found, make sure you set the proper name, you can ignore this error if it is your first time setting it up
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -25,16 +25,16 @@ Here's an example snippet of an iptable modified by this program:
|
|||||||
|
|
||||||
## Steps
|
## Steps
|
||||||
|
|
||||||
1. Copy [on_boot.d/30-ipt-enable-logs-launch.sh](./on_boot.d/30-ipt-enable-logs-launch.sh) to /mnt/data/on_boot.d
|
1. Copy [on_boot.d/30-ipt-enable-logs-launch.sh](./on_boot.d/30-ipt-enable-logs-launch.sh) to /data/on_boot.d
|
||||||
1. Copy the [scripts/ipt-enable-logs](./scripts/ipt-enable-logs) folder to /mnt/data/scripts
|
1. Copy the [scripts/ipt-enable-logs](./scripts/ipt-enable-logs) folder to /data/scripts
|
||||||
1. Copy [scripts/ipt-enable-logs.sh](./scripts/ipt-enable-logs.sh) to /mnt/data/scripts
|
1. Copy [scripts/ipt-enable-logs.sh](./scripts/ipt-enable-logs.sh) to /data/scripts
|
||||||
1. Execute /mnt/data/on_boot.d/30-ipt-enable-logs-launch.sh
|
1. Execute /data/on_boot.d/30-ipt-enable-logs-launch.sh
|
||||||
1. Copy [scripts/refresh-iptables.sh](./scripts/refresh-iptables.sh) to /mnt/data/scripts
|
1. Copy [scripts/refresh-iptables.sh](./scripts/refresh-iptables.sh) to /data/scripts
|
||||||
|
|
||||||
## Refreshing iptables
|
## Refreshing iptables
|
||||||
|
|
||||||
Whenever you update the firewall rules on the Network application, the iptables will be reprovisioned and will need to be reprocessed
|
Whenever you update the firewall rules on the Network application, the iptables will be reprovisioned and will need to be reprocessed
|
||||||
by calling /mnt/data/scripts/refresh-iptables.sh.
|
by calling /data/scripts/refresh-iptables.sh.
|
||||||
|
|
||||||
## Looking at logs
|
## Looking at logs
|
||||||
|
|
||||||
|
@ -1,9 +1,37 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check if the directory exists
|
||||||
|
if [ ! -d "${DATA_DIR}/scripts" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "${DATA_DIR}/scripts"
|
||||||
|
echo "Directory '${DATA_DIR}/scripts' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '${DATA_DIR}/scripts' already exists. Moving on."
|
||||||
|
fi
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if ! iptables-save | grep -e '\-A UBIOS_.* \--log-prefix "\[' > /dev/null; then
|
if ! iptables-save | grep -e '\-A UBIOS_.* \--log-prefix "\[' >/dev/null; then
|
||||||
/mnt/data/scripts/ipt-enable-logs.sh | iptables-restore -c
|
${DATA_DIR}/scripts/ipt-enable-logs.sh | iptables-restore -c
|
||||||
else
|
else
|
||||||
echo "iptables already contains USER log prefixes, ignoring."
|
echo "iptables already contains USER log prefixes, ignoring."
|
||||||
fi
|
fi
|
||||||
|
@ -1,7 +1,34 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check if the directory exists
|
||||||
|
if [ ! -d "${DATA_DIR}/scripts" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "${DATA_DIR}/scripts"
|
||||||
|
echo "Directory '${DATA_DIR}/scripts' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '${DATA_DIR}/scripts' already exists. Moving on."
|
||||||
|
fi
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
docker run -it --rm -v /mnt/data/scripts/ipt-enable-logs:/src -w /src --network=none golang:1.17.3 go build -v -o /src/ipt-enable-logs /src >&2
|
docker run -it --rm -v ${DATA_DIR}/scripts/ipt-enable-logs:/src -w /src --network=none golang:1.17.3 go build -v -o /src/ipt-enable-logs /src >&2
|
||||||
|
|
||||||
/mnt/data/scripts/ipt-enable-logs/ipt-enable-logs
|
${DATA_DIR}/scripts/ipt-enable-logs/ipt-enable-logs
|
||||||
|
@ -1,13 +1,39 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check if the directory exists
|
||||||
|
if [ ! -d "${DATA_DIR}/on_boot.d" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "${DATA_DIR}/on_boot.d"
|
||||||
|
echo "Directory '${DATA_DIR}/on_boot.d' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '${DATA_DIR}/on_boot.d' already exists. Moving on."
|
||||||
|
fi
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [ -f /mnt/data/on_boot.d/10-dns.sh ]; then
|
if [ -f ${DATA_DIR}/on_boot.d/10-dns.sh ]; then
|
||||||
if ! iptables-save | grep -e '\-A PREROUTING.* \--log-prefix "\[' > /dev/null; then
|
if ! iptables-save | grep -e '\-A PREROUTING.* \--log-prefix "\[' >/dev/null; then
|
||||||
/mnt/data/on_boot.d/10-dns.sh
|
${DATA_DIR}/on_boot.d/10-dns.sh
|
||||||
else
|
else
|
||||||
echo "iptables already contains DNAT log prefixes, ignoring."
|
echo "iptables already contains DNAT log prefixes, ignoring."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
/mnt/data/on_boot.d/30-ipt-enable-logs-launch.sh
|
${DATA_DIR}/on_boot.d/30-ipt-enable-logs-launch.sh
|
||||||
|
@ -23,44 +23,44 @@ _Adjust according to your setup._
|
|||||||
|
|
||||||
1. First, lets create the folder structure we'll be working with.
|
1. First, lets create the folder structure we'll be working with.
|
||||||
|
|
||||||
`$ mkdir -p /mnt/data/mosquitto/config /mnt/data/mosquitto/data`
|
`$ mkdir -p /data/mosquitto/config /data/mosquitto/data`
|
||||||
|
|
||||||
This is where Mosquitto's configuration file and data ("persistence database"; if enabled) will live.
|
This is where Mosquitto's configuration file and data ("persistence database"; if enabled) will live.
|
||||||
If you're unsure on how to configure mosquitto, use the provided barebone config [`config/mosquitto.conf`](config/mosquitto.conf) to get it initially running.
|
If you're unsure on how to configure mosquitto, use the provided barebone config [`config/mosquitto.conf`](config/mosquitto.conf) to get it initially running.
|
||||||
|
|
||||||
2. **Optional:** Customize [`on_boot.d/45-mosquitto.sh`](on_boot.d/45-mosquitto.sh) to your setup and copy to `/mnt/data/on_boot.d/`.
|
2. **Optional:** Customize [`on_boot.d/45-mosquitto.sh`](on_boot.d/45-mosquitto.sh) to your setup and copy to `/data/on_boot.d/`.
|
||||||
Most likely you'll need to mark the script as executable, this will do the trick:
|
Most likely you'll need to mark the script as executable, this will do the trick:
|
||||||
|
|
||||||
`$ chmod a+x /mnt/data/on_boot.d/45-mosquitto.sh`
|
`$ chmod a+x /data/on_boot.d/45-mosquitto.sh`
|
||||||
|
|
||||||
3. Then take a loot at [`cni/45-mosquitto.conflist`](cni/45-mosquitto.conflist) and make sure it matches your previously defined configuration; then place it in `/mnt/data/podman/cni/`
|
3. Then take a loot at [`cni/45-mosquitto.conflist`](cni/45-mosquitto.conflist) and make sure it matches your previously defined configuration; then place it in `/data/podman/cni/`
|
||||||
|
|
||||||
4. Run boot script (to create the mosquitto network set it's ip routes)
|
4. Run boot script (to create the mosquitto network set it's ip routes)
|
||||||
|
|
||||||
`$ sh /mnt/data/on_boot.d/45-mosquitto.sh`
|
`$ sh /data/on_boot.d/45-mosquitto.sh`
|
||||||
|
|
||||||
It fail when trying to run the container, but thats okay, its just for setting op needed configuration before initial image run.
|
It fail when trying to run the container, but thats okay, its just for setting op needed configuration before initial image run.
|
||||||
The script will also create a [minimal configuration](config/mosquitto.conf) for Mosquitto in `/mnt/data/mosquitto/config/`, _**only if it doesn't already exist**_.
|
The script will also create a [minimal configuration](config/mosquitto.conf) for Mosquitto in `/data/mosquitto/config/`, _**only if it doesn't already exist**_.
|
||||||
|
|
||||||
> **Note:** You can use this config to get everything started, but I highly recommend securing your instance with authentication (links to the offical documentation & other resources are at the bottom)
|
> **Note:** You can use this config to get everything started, but I highly recommend securing your instance with authentication (links to the offical documentation & other resources are at the bottom)
|
||||||
|
|
||||||
5. Register the container with podman:
|
5. Register the container with podman:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ podman run -d --network mosquitto \
|
$ podman run -d --network mosquitto \
|
||||||
--restart always \
|
--restart always \
|
||||||
--security-opt=no-new-privileges \
|
--security-opt=no-new-privileges \
|
||||||
--name mosquitto \
|
--name mosquitto \
|
||||||
--hostname mosquitto.local \
|
--hostname mosquitto.local \
|
||||||
-e "TZ=Europe/Berlin" \
|
-e "TZ=Europe/Berlin" \
|
||||||
-v /mnt/data/mosquitto/config/:/mosquitto/config \
|
-v /data/mosquitto/config/:/mosquitto/config \
|
||||||
-v /mnt/data/mosquitto/data/:/mosquitto/data \
|
-v /data/mosquitto/data/:/mosquitto/data \
|
||||||
eclipse-mosquitto:latest
|
eclipse-mosquitto:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
6. Run boot script again and we are done!
|
6. Run boot script again and we are done!
|
||||||
|
|
||||||
`$ sh /mnt/data/on_boot.d/45-mosquitto.sh`
|
`$ sh /data/on_boot.d/45-mosquitto.sh`
|
||||||
|
|
||||||
> You should now be able to connect with any MQTT client to Mosquitto, in my case `mqtt://10.0.20.4:1883`
|
> You should now be able to connect with any MQTT client to Mosquitto, in my case `mqtt://10.0.20.4:1883`
|
||||||
|
|
||||||
|
@ -1,17 +1,43 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check if the directory exists
|
||||||
|
if [ ! -d "${DATA_DIR}/podman/cni" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "${DATA_DIR}/podman/cni"
|
||||||
|
echo "Directory '${DATA_DIR}/podman/cni' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '${DATA_DIR}/podman/cni' already exists. Moving on."
|
||||||
|
fi
|
||||||
## network configuration
|
## network configuration
|
||||||
VLAN_ID=20
|
VLAN_ID=20
|
||||||
IPV4_IP_CONTAINER="10.0.20.4"
|
IPV4_IP_CONTAINER="10.0.20.4"
|
||||||
IPV4_IP_GATEWAY="10.0.20.1"
|
IPV4_IP_GATEWAY="10.0.20.1"
|
||||||
CONTAINER_NAME="mosquitto"
|
CONTAINER_NAME="mosquitto"
|
||||||
CONTAINER_CNI_PATH="/mnt/data/podman/cni/45-mosquitto.conflist"
|
CONTAINER_CNI_PATH="${DATA_DIR}/podman/cni/45-mosquitto.conflist"
|
||||||
|
|
||||||
# make sure cni plugs are installed
|
# make sure cni plugs are installed
|
||||||
if ! test -f /opt/cni/bin/macvlan; then
|
if ! test -f /opt/cni/bin/macvlan; then
|
||||||
echo "Error: CNI plugins not found. You can install it with the following command:" >&2
|
echo "Error: CNI plugins not found. You can install it with the following command:" >&2
|
||||||
echo " curl -fsSLo /mnt/data/on_boot.d/05-install-cni-plugins.sh https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/main/cni-plugins/05-install-cni-plugins.sh && /bin/sh /mnt/data/on_boot.d/05-install-cni-plugins.sh" >&2
|
echo " curl -fsSLo ${DATA_DIR}/on_boot.d/05-install-cni-plugins.sh https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/main/cni-plugins/05-install-cni-plugins.sh && /bin/sh ${DATA_DIR}/on_boot.d/05-install-cni-plugins.sh" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
## network configuration and startup
|
## network configuration and startup
|
||||||
@ -38,9 +64,9 @@ ip link set br${VLAN_ID}.mac up
|
|||||||
ip route add ${IPV4_IP_CONTAINER}/32 dev br${VLAN_ID}.mac
|
ip route add ${IPV4_IP_CONTAINER}/32 dev br${VLAN_ID}.mac
|
||||||
|
|
||||||
# create basic config if not exist
|
# create basic config if not exist
|
||||||
if ! test -f /mnt/data/mosquitto/config/mosquitto.conf; then
|
if ! test -f "$DATA_DIR"/mosquitto/config/mosquitto.conf; then
|
||||||
mkdir -p /mnt/data/mosquitto/data /mnt/data/mosquitto/config
|
mkdir -p "$DATA_DIR"/mosquitto"$DATA_DIR" "$DATA_DIR"/mosquitto/config
|
||||||
cat > /mnt/data/mosquitto/config/mosquitto.conf<< EOF
|
cat >"$DATA_DIR"/mosquitto/config/mosquitto.conf <<EOF
|
||||||
listener 1883
|
listener 1883
|
||||||
allow_anonymous true
|
allow_anonymous true
|
||||||
|
|
||||||
@ -55,10 +81,8 @@ log_timestamp true
|
|||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if podman container exists ${CONTAINER_NAME}; then
|
if podman container exists ${CONTAINER_NAME}; then
|
||||||
podman start ${CONTAINER_NAME}
|
podman start ${CONTAINER_NAME}
|
||||||
else
|
else
|
||||||
logger -s -t podman-mosquitto -p ERROR Container $CONTAINER_NAME not found, make sure you set the proper name, you can ignore this error if it is your first time setting it up
|
logger -s -t podman-mosquitto -p ERROR Container $CONTAINER_NAME not found, make sure you set the proper name, you can ignore this error if it is your first time setting it up
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
# Run NextDNS on your UDM
|
# Run NextDNS on your UDM
|
||||||
|
|
||||||
# THIS IS NO LONGER MAINTAINED. VENDOR PROVIDES DIRECT SUPPORT
|
# THIS IS NO LONGER MAINTAINED. VENDOR PROVIDES DIRECT SUPPORT
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
1. Run NextDNS on your UDM with a completely isolated network stack. This will not port conflict or be influenced by any changes on by Ubiquiti.
|
1. Run NextDNS on your UDM with a completely isolated network stack. This will not port conflict or be influenced by any changes on by Ubiquiti.
|
||||||
2. Resolves IP addresses handed out by DHCP on the UDM!
|
2. Resolves IP addresses handed out by DHCP on the UDM!
|
||||||
3. Persists through reboots and firmware updates.
|
3. Persists through reboots and firmware updates.
|
||||||
4. If you are already using PiHole and want to test NextDNS out, you can just stop your PiHole container and start this one in its place using the same IP/CNI config.
|
4. If you are already using PiHole and want to test NextDNS out, you can just stop your PiHole container and start this one in its place using the same IP/CNI config.
|
||||||
@ -13,15 +15,15 @@
|
|||||||
|
|
||||||
## Customization
|
## Customization
|
||||||
|
|
||||||
* Feel free to change [20-dns.conflist](../cni-plugins/20-dns.conflist) to change the IP and MAC address of the container.
|
- Feel free to change [20-dns.conflist](../cni-plugins/20-dns.conflist) to change the IP and MAC address of the container.
|
||||||
* The NextDNS docker image is not supported by NextDNS. It is built out of this repo. If you make any enhancements please contribute back via a Pull Request.
|
- The NextDNS docker image is not supported by NextDNS. It is built out of this repo. If you make any enhancements please contribute back via a Pull Request.
|
||||||
* If you want to inject custom DNS names into NextDNS use --add-host docker commands. The /etc/resolv.conf and /etc/hosts is generated from that and --dns.
|
- If you want to inject custom DNS names into NextDNS use --add-host docker commands. The /etc/resolv.conf and /etc/hosts is generated from that and --dns.
|
||||||
* Edit [10-dns.sh](../dns-common/on_boot.d/10-dns.sh) and update its values to reflect your environment (specifically the container name)
|
- Edit [10-dns.sh](../dns-common/on_boot.d/10-dns.sh) and update its values to reflect your environment (specifically the container name)
|
||||||
* If you want IPv6 support use [20-dnsipv6.conflist](../cni-plugins/20-dnsipv6.conflist) and update [10-dns.sh](../dns-common/on_boot.d/10-dns.sh) with the IPv6 addresses. Also, please provide IPv6 servers to podman using --dns arguments.
|
- If you want IPv6 support use [20-dnsipv6.conflist](../cni-plugins/20-dnsipv6.conflist) and update [10-dns.sh](../dns-common/on_boot.d/10-dns.sh) with the IPv6 addresses. Also, please provide IPv6 servers to podman using --dns arguments.
|
||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
|
|
||||||
The official repo is boostchicken/nextdns. Latest will always refer to the latest builds, there are also tags for each NextDNS release (e.g. 1.6.4).
|
The official repo is boostchicken/nextdns. Latest will always refer to the latest builds, there are also tags for each NextDNS release (e.g. 1.6.4).
|
||||||
|
|
||||||
The Dockerfile is included, you can build it locally on your UDM if you don't want to pull from Docker Hub or make customizations
|
The Dockerfile is included, you can build it locally on your UDM if you don't want to pull from Docker Hub or make customizations
|
||||||
|
|
||||||
@ -29,7 +31,7 @@ The Dockerfile is included, you can build it locally on your UDM if you don't wa
|
|||||||
podman build . -t nextdns:latest
|
podman build . -t nextdns:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
Building from another device is possible. You must have [buildx](https://github.com/docker/buildx/) installed to do cross platform builds. This is useful if you want to mirror to a private repo
|
Building from another device is possible. You must have [buildx](https://github.com/docker/buildx/) installed to do cross platform builds. This is useful if you want to mirror to a private repo
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker buildx build --platform linux/arm64/v8 -t nextdns:latest .
|
docker buildx build --platform linux/arm64/v8 -t nextdns:latest .
|
||||||
@ -39,24 +41,24 @@ docker buildx build --platform linux/arm64/v8 -t nextdns:latest .
|
|||||||
|
|
||||||
If you have already installed PiHole, skip right to step 5.
|
If you have already installed PiHole, skip right to step 5.
|
||||||
|
|
||||||
1. Copy [05-install-cni-plugins.sh](../cni-plugins/05-install-cni-plugins.sh) to /mnt/data/on_boot.d
|
1. Copy [05-install-cni-plugins.sh](../cni-plugins/05-install-cni-plugins.sh) to /data/on_boot.d
|
||||||
1. Execute /mnt/data/on_boot.d/05-install-cni-plugins.sh
|
1. Execute /data/on_boot.d/05-install-cni-plugins.sh
|
||||||
1. On your controller, make a Corporate network with no DHCP server and give it a VLAN. For this example we are using VLAN 5.
|
1. On your controller, make a Corporate network with no DHCP server and give it a VLAN. For this example we are using VLAN 5.
|
||||||
2. Copy [10-dns.sh](../dns-common/on_boot.d/10-dns.sh) to /mnt/data/on_boot.d and update its values to reflect your environment
|
1. Copy [10-dns.sh](../dns-common/on_boot.d/10-dns.sh) to /data/on_boot.d and update its values to reflect your environment
|
||||||
3. Copy [20-dns.conflist](../cni-plugins/20-dns.conflist) to /mnt/data/podman/cni. This will create your podman macvlan network
|
1. Copy [20-dns.conflist](../cni-plugins/20-dns.conflist) to /data/podman/cni. This will create your podman macvlan network
|
||||||
4. Execute /mnt/data/on_boot.d/[10-dns.sh](../dns-common/on_boot.d/10-dns.sh)
|
1. Execute /data/on_boot.d/[10-dns.sh](../dns-common/on_boot.d/10-dns.sh)
|
||||||
5. Create /mnt/data/nextdns and copy [nextdns.conf](udm-files/nextdns.conf) to it.
|
1. Create /data/nextdns and copy [nextdns.conf](udm-files/nextdns.conf) to it.
|
||||||
6. Run the NextDNS docker container. Mounting dbus and running in privileged is only required for mDNS. Also, please change the --dns arguments to whatever was provided by NextDNS.
|
1. Run the NextDNS docker container. Mounting dbus and running in privileged is only required for mDNS. Also, please change the --dns arguments to whatever was provided by NextDNS.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
podman run -d -it --privileged --network dns --restart always \
|
podman run -d -it --privileged --network dns --restart always \
|
||||||
--name nextdns \
|
--name nextdns \
|
||||||
-v "/mnt/data/nextdns/:/etc/nextdns/" \
|
-v "/data/nextdns/:/etc/nextdns/" \
|
||||||
-v /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket \
|
-v /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket \
|
||||||
--mount type=bind,source=/config/dnsmasq.lease,target=/tmp/dnsmasq.leases \
|
--mount type=bind,source=/config/dnsmasq.lease,target=/tmp/dnsmasq.leases \
|
||||||
--dns=45.90.28.163 --dns=45.90.30.163 \
|
--dns=45.90.28.163 --dns=45.90.30.163 \
|
||||||
--hostname nextdns \
|
--hostname nextdns \
|
||||||
boostchicken/nextdns:latest
|
boostchicken/nextdns:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
7. Update your DNS Servers to 10.0.5.3 (or your custom ip) in all your DHCP configs.
|
1. Update your DNS Servers to 10.0.5.3 (or your custom ip) in all your DHCP configs.
|
||||||
|
@ -8,21 +8,21 @@
|
|||||||
|
|
||||||
1. Should work on any UDM/UDMPro after 2.4.x
|
1. Should work on any UDM/UDMPro after 2.4.x
|
||||||
|
|
||||||
|
- [build_deb.sh](build_deb.sh) can be used to build the package by yourself.
|
||||||
|
|
||||||
* [build_deb.sh](build_deb.sh) can be used to build the package by yourself.
|
- [dpkg-build-files](dpkg-build-files) contains the sources that debuild uses to build the package if you want to build it yourself / change it
|
||||||
* [dpkg-build-files](dpkg-build-files) contains the sources that debuild uses to build the package if you want to build it yourself / change it
|
- by default it uses docker or podman to build the debian package
|
||||||
* by default it uses docker or podman to build the debian package
|
- use `./build_deb.sh build` to not use a container
|
||||||
* use ```./build_deb.sh build``` to not use a container
|
- the resulting package will be in [packages/](packages/)
|
||||||
* the resulting package will be in [packages/](packages/)
|
|
||||||
|
|
||||||
* Built on Ubuntu-20.04 on Windows 10/WSL2
|
- Built on Ubuntu-20.04 on Windows 10/WSL2
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
You can execute in UDM/Pro/SE and UDR with:
|
You can execute in UDM/Pro/SE and UDR with:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -fsL "https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/HEAD/on-boot-script/remote_install.sh" | /bin/sh
|
curl -fsL "https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/HEAD/on-boot-script-2.x/remote_install.sh" | /bin/sh
|
||||||
```
|
```
|
||||||
|
|
||||||
This is a force to install script so will uninstall any previous version and install on_boot keeping your on boot files.
|
This is a force to install script so will uninstall any previous version and install on_boot keeping your on boot files.
|
||||||
@ -33,28 +33,29 @@ This will also install CNI Plugins & CNI Bridge scripts. If you are using UDMSE/
|
|||||||
|
|
||||||
1. Get into the unifios shell on your udm
|
1. Get into the unifios shell on your udm
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
unifi-os shell
|
unifi-os shell
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Download [udm-boot-2x_1.0.1_all.deb](packages/udm-boot_1.0.0-2x_all.deb) and install it and go back to the UDM.
|
2. Download [udm-boot-2x_1.0.1_all.deb](packages/udm-boot_1.0.0-2x_all.deb) and install it and go back to the UDM.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -L [[https://udm-boot.boostchicken.dev](https://unifi.boostchicken.io/udm-boot-2x_1.0.0_all.deb)](https://unifi.boostchicken.io/udm-boot-2x_1.0.0_all.deb) -o udm-boot-2x_1.0.0_all.deb
|
curl -L [[https://udm-boot.boostchicken.dev](https://unifi.boostchicken.io/udm-boot-2x_1.0.0_all.deb)](https://unifi.boostchicken.io/udm-boot-2x_1.0.0_all.deb) -o udm-boot-2x_1.0.0_all.deb
|
||||||
dpkg -i udm-boot-2x_1.0.0_all.deb
|
dpkg -i udm-boot-2x_1.0.0_all.deb
|
||||||
systemctl enable udm-boot
|
systemctl enable udm-boot
|
||||||
exit
|
exit
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Copy any shell scripts you want to run to /mnt/data/on_boot.d on your UDM (not the unifi-os shell) and make sure they are executable and have the correct shebang (#!/bin/sh). Additionally, scripts need to have a `.sh` extention in their filename.
|
3. Copy any shell scripts you want to run to /data/on_boot.d on your UDM (not the unifi-os shell) and make sure they are executable and have the correct shebang (#!/bin/sh). Additionally, scripts need to have a `.sh` extention in their filename.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
* Start a DNS Container [10-dns.sh](../dns-common/on_boot.d/10-dns.sh)
|
|
||||||
* Start wpa_supplicant [on_boot.d/10-wpa_supplicant.sh](examples/udm-files/on_boot.d/10-wpa_supplicant.sh)
|
- Start a DNS Container [10-dns.sh](../dns-common/on_boot.d/10-dns.sh)
|
||||||
* Add a persistent ssh key for the root user [on_boot.d/15-add-root-ssh-keys.sh](examples/udm-files/on_boot.d/15-add-root-ssh-keys.sh)
|
- Start wpa_supplicant [on_boot.d/10-wpa_supplicant.sh](examples/udm-files/on_boot.d/10-wpa_supplicant.sh)
|
||||||
|
- Add a persistent ssh key for the root user [on_boot.d/15-add-root-ssh-keys.sh](examples/udm-files/on_boot.d/15-add-root-ssh-keys.sh)
|
||||||
|
|
||||||
## Version History
|
## Version History
|
||||||
|
|
||||||
### 1.0.0
|
### 1.0.0
|
||||||
|
|
||||||
* First release that persists through firmware
|
- First release that persists through firmware
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
## Configure shell profile
|
## Configure shell profile
|
||||||
|
|
||||||
device_info() {
|
device_info() {
|
||||||
@ -7,7 +23,7 @@ device_info() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Modify login banner (motd)
|
# Modify login banner (motd)
|
||||||
cat > /etc/motd <<EOF
|
cat >/etc/motd <<EOF
|
||||||
Welcome to UniFi Dream Machine!
|
Welcome to UniFi Dream Machine!
|
||||||
(c) 2010-$(date +%Y) Ubiquiti Inc. | http://www.ui.com
|
(c) 2010-$(date +%Y) Ubiquiti Inc. | http://www.ui.com
|
||||||
|
|
||||||
@ -17,13 +33,13 @@ MAC Address: $(device_info mac)
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Extend UbiOS prompt to include useful information
|
# Extend UbiOS prompt to include useful information
|
||||||
cat > /etc/profile.d/prompt.sh <<'EOF'
|
cat >/etc/profile.d/prompt.sh <<'EOF'
|
||||||
UDM_NAME="$(grep -m 1 '^name:' /data/unifi-core/config/settings.yaml | awk -F: '{ gsub(/^[ \t]+|[ \t]+$/, "", $2); print tolower($2) }')"
|
UDM_NAME="$(grep -m 1 '^name:' ${DATA_DIR}/unifi-core/config/settings.yaml | awk -F: '{ gsub(/^[ \t]+|[ \t]+$/, "", $2); print tolower($2) }')"
|
||||||
PROMPT_MAIN="\u@${UDM_NAME}:\w"
|
PROMPT_MAIN="\u@${UDM_NAME}:\w"
|
||||||
|
|
||||||
export PS1="[UDM] ${PROMPT_MAIN}${PS1}"
|
export PS1="[UDM] ${PROMPT_MAIN}${PS1}"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Copy all global profile scripts (for all users) from `/mnt/data/on_boot.d/settings/profile/global.profile.d/` directory
|
# Copy all global profile scripts (for all users) from `${DATA_DIR}/on_boot.d/settings/profile/global.profile.d/` directory
|
||||||
mkdir -p /mnt/data/on_boot.d/settings/profile/global.profile.d
|
mkdir -p ${DATA_DIR}/on_boot.d/settings/profile/global.profile.d
|
||||||
cp -rf /mnt/data/on_boot.d/settings/profile/global.profile.d/* /etc/profile.d/
|
cp -rf ${DATA_DIR}/on_boot.d/settings/profile/global.profile.d/* /etc/profile.d/
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
cp -f /mnt/data/on_boot.d/files/.profile /root/
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
cp -f ${DATA_DIR}/on_boot.d/files/.profile /root/
|
||||||
|
@ -1,16 +1,34 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
## Config Variables - please edit these
|
## Config Variables - please edit these
|
||||||
# Set to true to download public keys from a github user account
|
# Set to true to download public keys from a github user account
|
||||||
USE_GITHUB_KEYS=true
|
USE_GITHUB_KEYS=true
|
||||||
# Enter your username on github to get the public keys for
|
# Enter your username on github to get the public keys for
|
||||||
GITHUB_USER="<YOUR_USERNAME>"
|
GITHUB_USER="<YOUR_USERNAME>"
|
||||||
# File location for the output of the git download
|
# File location for the output of the git download
|
||||||
GITHUB_KEY_PATH="/mnt/data/podman/ssh"
|
GITHUB_KEY_PATH="${DATA_DIR}/podman/ssh"
|
||||||
GITHUB_KEY_FILE="${GITHUB_KEY_PATH}/github.keys"
|
GITHUB_KEY_FILE="${GITHUB_KEY_PATH}/github.keys"
|
||||||
# Set to true to use a file containing a key per line in the format ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAA...\n
|
# Set to true to use a file containing a key per line in the format ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAA...\n
|
||||||
USE_KEY_FILE=true
|
USE_KEY_FILE=true
|
||||||
# IF using an input file, list it here
|
# IF using an input file, list it here
|
||||||
INPUT_KEY_PATH="/mnt/data/podman/ssh"
|
INPUT_KEY_PATH="${DATA_DIR}/podman/ssh"
|
||||||
INPUT_KEY_FILE="${INPUT_KEY_PATH}/ssh.keys"
|
INPUT_KEY_FILE="${INPUT_KEY_PATH}/ssh.keys"
|
||||||
# The target key file for the script
|
# The target key file for the script
|
||||||
OUTPUT_KEY_PATH="/root/.ssh"
|
OUTPUT_KEY_PATH="/root/.ssh"
|
||||||
@ -18,7 +36,7 @@ OUTPUT_KEY_FILE="${OUTPUT_KEY_PATH}/authorized_keys"
|
|||||||
|
|
||||||
## Functions
|
## Functions
|
||||||
# This function downloads the keys from the selected github user
|
# This function downloads the keys from the selected github user
|
||||||
download_from_github(){
|
download_from_github() {
|
||||||
if curl --output /dev/null --silent --head --fail https://github.com/${GITHUB_USER}.keys; then
|
if curl --output /dev/null --silent --head --fail https://github.com/${GITHUB_USER}.keys; then
|
||||||
curl https://github.com/${GITHUB_USER}.keys -o ${GITHUB_KEY_FILE}
|
curl https://github.com/${GITHUB_USER}.keys -o ${GITHUB_KEY_FILE}
|
||||||
echo "Downloaded keys from Github"
|
echo "Downloaded keys from Github"
|
||||||
@ -27,26 +45,25 @@ download_from_github(){
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
# Write line to the output line. Add the input line as an arguement.
|
# Write line to the output line. Add the input line as an arguement.
|
||||||
write_to_output(){
|
write_to_output() {
|
||||||
# Check the file exits
|
# Check the file exits
|
||||||
if ! test -f ${OUTPUT_KEY_FILE}; then
|
if ! test -f ${OUTPUT_KEY_FILE}; then
|
||||||
echo "File at ${OUTPUT_KEY_FILE} does not exist, creating it"
|
echo "File at ${OUTPUT_KEY_FILE} does not exist, creating it"
|
||||||
touch ${OUTPUT_KEY_FILE}
|
touch ${OUTPUT_KEY_FILE}
|
||||||
fi
|
fi
|
||||||
echo "${1}" >> ${OUTPUT_KEY_FILE}
|
echo "${1}" >>${OUTPUT_KEY_FILE}
|
||||||
}
|
}
|
||||||
# This function reads keys from a file into the requested file. The arguement is the input file.
|
# This function reads keys from a file into the requested file. The arguement is the input file.
|
||||||
use_key_from_file(){
|
use_key_from_file() {
|
||||||
if ! test -f $1; then
|
if ! test -f $1; then
|
||||||
echo "File $1 does not exist"
|
echo "File $1 does not exist"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
counter=0;
|
counter=0
|
||||||
while IFS= read -r line;
|
while IFS= read -r line; do
|
||||||
do
|
|
||||||
write_to_output "${line}"
|
write_to_output "${line}"
|
||||||
let "counter++"
|
let "counter++"
|
||||||
done < $1
|
done <$1
|
||||||
echo "${counter} number of entries read from "
|
echo "${counter} number of entries read from "
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,24 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
## Places public keys in ~/.ssh/authorized_keys
|
## Places public keys in ~/.ssh/authorized_keys
|
||||||
|
|
||||||
KEYS_SOURCE_FILE="/mnt/data/on_boot.d/settings/ssh/authorized_keys"
|
KEYS_SOURCE_FILE="${DATA_DIR}/on_boot.d/settings/ssh/authorized_keys"
|
||||||
KEYS_TARGET_FILE="/root/.ssh/authorized_keys"
|
KEYS_TARGET_FILE="/root/.ssh/authorized_keys"
|
||||||
|
|
||||||
count_added=0
|
count_added=0
|
||||||
@ -11,19 +27,19 @@ while read -r key; do
|
|||||||
# Places public key in ~/.ssh/authorized_keys if not present
|
# Places public key in ~/.ssh/authorized_keys if not present
|
||||||
if ! grep -Fxq "$key" "$KEYS_TARGET_FILE"; then
|
if ! grep -Fxq "$key" "$KEYS_TARGET_FILE"; then
|
||||||
let count_added++
|
let count_added++
|
||||||
echo "$key" >> "$KEYS_TARGET_FILE"
|
echo "$key" >>"$KEYS_TARGET_FILE"
|
||||||
else
|
else
|
||||||
let count_skipped++
|
let count_skipped++
|
||||||
fi
|
fi
|
||||||
done < "$KEYS_SOURCE_FILE"
|
done <"$KEYS_SOURCE_FILE"
|
||||||
|
|
||||||
echo "${count_added} keys added to ${KEYS_TARGET_FILE}"
|
echo "${count_added} keys added to ${KEYS_TARGET_FILE}"
|
||||||
if [ $count_skipped -gt 0 ]; then
|
if [ $count_skipped -gt 0 ]; then
|
||||||
echo "${count_skipped} already added keys skipped"
|
echo "${count_skipped} already added keys skipped"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Convert ssh key to dropbear for shell interaction
|
# Convert ssh key to dropbear for shell interaction
|
||||||
echo "Converting SSH private key to dropbear format"
|
echo "Converting SSH private key to dropbear format"
|
||||||
dropbearconvert openssh dropbear /mnt/data/ssh/id_rsa /root/.ssh/id_dropbear
|
dropbearconvert openssh dropbear ${DATA_DIR}/ssh/id_rsa /root/.ssh/id_dropbear
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
#####################################################
|
#####################################################
|
||||||
# ADD KNOWN HOSTS AS BELOW - CHANGE BEFORE RUNNING #
|
# ADD KNOWN HOSTS AS BELOW - CHANGE BEFORE RUNNING #
|
||||||
#####################################################
|
#####################################################
|
||||||
@ -8,22 +24,19 @@
|
|||||||
# "one per line, last line has no backslash" #
|
# "one per line, last line has no backslash" #
|
||||||
#####################################################
|
#####################################################
|
||||||
set -- "hostname ecdsa-sha2-nistp256 AAAABIGHOSTIDENTIFIERWITHMAGICSTUFF=" \
|
set -- "hostname ecdsa-sha2-nistp256 AAAABIGHOSTIDENTIFIERWITHMAGICSTUFF=" \
|
||||||
"otherhost ecdsa-sha2-nistp256 AAAADIFFERENTHOSTMAGICSTUFF!@HJKSL="
|
"otherhost ecdsa-sha2-nistp256 AAAADIFFERENTHOSTMAGICSTUFF!@HJKSL="
|
||||||
|
|
||||||
KNOWN_HOSTS_FILE="/root/.ssh/known_hosts"
|
KNOWN_HOSTS_FILE="/root/.ssh/known_hosts"
|
||||||
|
|
||||||
|
|
||||||
counter=0
|
counter=0
|
||||||
for host in "$@"
|
for host in "$@"; do
|
||||||
do
|
|
||||||
## Places known host in ~/.ssh/known_hosts if not present
|
## Places known host in ~/.ssh/known_hosts if not present
|
||||||
if ! grep -Fxq "$host" "$KNOWN_HOSTS_FILE"; then
|
if ! grep -Fxq "$host" "$KNOWN_HOSTS_FILE"; then
|
||||||
let counter++
|
let counter++
|
||||||
echo "$host" >> "$KNOWN_HOSTS_FILE"
|
echo "$host" >>"$KNOWN_HOSTS_FILE"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
echo $counter hosts added to $KNOWN_HOSTS_FILE
|
echo $counter hosts added to $KNOWN_HOSTS_FILE
|
||||||
|
|
||||||
|
exit 0
|
||||||
exit 0;
|
|
||||||
|
@ -1,13 +1,29 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
mkdir -p ${DATA_DIR}/.home
|
||||||
|
|
||||||
mkdir -p /mnt/data/.home
|
for file in .ash_history .bash_history; do
|
||||||
|
if [ ! -f ${DATA_DIR}/.home/$file ]; then
|
||||||
for file in .ash_history .bash_history
|
touch /root/$file
|
||||||
if [ ! -f /mnt/data/.home/$file ]; then
|
cp /root/$file ${DATA_DIR}/.home/$file
|
||||||
touch /root/$file
|
chown root:root ${DATA_DIR}/.home/$file
|
||||||
cp /root/$file /mnt/data/.home/$file
|
chmod 0600 ${DATA_DIR}/.home/$file
|
||||||
chown root:root /mnt/data/.home/$file
|
fi
|
||||||
chmod 0600 /mnt/data/.home/$file
|
ln -sf ${DATA_DIR}/.home/$file /root/$file
|
||||||
fi
|
done
|
||||||
ln -sf /mnt/data/.home/$file /root/$file
|
|
||||||
|
|
||||||
|
@ -1,9 +1,25 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
## Store crontab files in /mnt/data/cronjobs/ (you will need to create this folder).
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
## Store crontab files in ${DATA_DIR}/cronjobs/ (you will need to create this folder).
|
||||||
## This script will re-add them on startup.
|
## This script will re-add them on startup.
|
||||||
|
|
||||||
cp /mnt/data/cronjobs/* /etc/cron.d/
|
cp ${DATA_DIR}/cronjobs/* /etc/cron.d/
|
||||||
/etc/init.d/crond restart
|
/etc/init.d/crond restart
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -1,87 +1,100 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
## ----------------------------------------------------------------------
|
DATA_DIR="/data"
|
||||||
## Script to add/remove time-of-day restrictions on internet access for selected clients.
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
##
|
1*)
|
||||||
## Use DHCP reservations to encourage the selected clients to always obtain the same IP address.
|
DATA_DIR="/mnt/data"
|
||||||
##
|
;;
|
||||||
## To install:
|
2*)
|
||||||
## * Copy this script into /mnt/data/on_boot.d/, using something like WinSCP or SSH + vi.
|
DATA_DIR="/data"
|
||||||
## * Grant Execute permission: chmod +x /mnt/data/on_boot.d/iptables_timerestrict.sh
|
;;
|
||||||
## * Run it once, to activate it (crontab entries will keep it active forever after):
|
3*)
|
||||||
## Via SSH into UDM shell: /mnt/data/on_boot.d/iptables_timerestrict.sh
|
DATA_DIR="/data"
|
||||||
##
|
;;
|
||||||
## Notes:
|
*)
|
||||||
## * Changes to firewall rules in the Unifi Network Application will remove your restriction;
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
## re-run this script to re-apply the restriction rule, or wait for the next activation/deactivation hour.
|
exit 1
|
||||||
## * To apply changes to this script (i.e. new client addresses, or changes to the time of day),
|
;;
|
||||||
## re-run this script manually to apply the updates, or wait for the next activation/deactivation hour.
|
esac
|
||||||
## * When this script activates or deactivates the blocking, it will log to /var/log/messages.
|
## ----------------------------------------------------------------------
|
||||||
## * While the blocking is active, you'll see one "TIMERESTRICT BLOCK: " log message per hour
|
## Script to add/remove time-of-day restrictions on internet access for selected clients.
|
||||||
## in /var/log/messages if any blocked clients are attempting to use the internet.
|
##
|
||||||
##
|
## Use DHCP reservations to encourage the selected clients to always obtain the same IP address.
|
||||||
## Caveats:
|
##
|
||||||
## * No support for wake_minute/sleep_minute - currently this only turns on/off at the top of an hour.
|
## To install:
|
||||||
## * Assumption exists that sleep_hour is always greater-than wake_hour; i.e., you can't currently
|
## * Copy this script into ${DATA_DIR}/on_boot.d/, using something like WinSCP or SSH + vi.
|
||||||
## have a blocked time in the middle of the day.
|
## * Grant Execute permission: chmod +x ${DATA_DIR}/on_boot.d/iptables_timerestrict.sh
|
||||||
## ----------------------------------------------------------------------
|
## * Run it once, to activate it (crontab entries will keep it active forever after):
|
||||||
|
## Via SSH into UDM shell: ${DATA_DIR}/on_boot.d/iptables_timerestrict.sh
|
||||||
|
##
|
||||||
## List all client addresses you'd like to restrict. Separate multiple with spaces.
|
## Notes:
|
||||||
timerestricted_addresses='192.168.1.101 192.168.1.102'
|
## * Changes to firewall rules in the Unifi Network Application will remove your restriction;
|
||||||
|
## re-run this script to re-apply the restriction rule, or wait for the next activation/deactivation hour.
|
||||||
## Hour of day to remove the restriction.
|
## * To apply changes to this script (i.e. new client addresses, or changes to the time of day),
|
||||||
wake_hour=06
|
## re-run this script manually to apply the updates, or wait for the next activation/deactivation hour.
|
||||||
|
## * When this script activates or deactivates the blocking, it will log to /var/log/messages.
|
||||||
## Hour of day to activate the restriction.
|
## * While the blocking is active, you'll see one "TIMERESTRICT BLOCK: " log message per hour
|
||||||
sleep_hour=23
|
## in /var/log/messages if any blocked clients are attempting to use the internet.
|
||||||
|
##
|
||||||
|
## Caveats:
|
||||||
|
## * No support for wake_minute/sleep_minute - currently this only turns on/off at the top of an hour.
|
||||||
## ----------------------------------------------------------------------
|
## * Assumption exists that sleep_hour is always greater-than wake_hour; i.e., you can't currently
|
||||||
## ----------------------------------------------------------------------
|
## have a blocked time in the middle of the day.
|
||||||
## ----------------------------------------------------------------------
|
## ----------------------------------------------------------------------
|
||||||
|
|
||||||
myrule="FORWARD -i br0 -j TIMERESTRICT"
|
## List all client addresses you'd like to restrict. Separate multiple with spaces.
|
||||||
|
timerestricted_addresses='192.168.1.101 192.168.1.102'
|
||||||
## report on blocks if rule exists
|
|
||||||
iptables -C $myrule 2>/dev/null && iptables -vL TIMERESTRICT | logger
|
## Hour of day to remove the restriction.
|
||||||
|
wake_hour=06
|
||||||
echo "Setting up timerestrict firewall rules between $sleep_hour:00 and $wake_hour:00"
|
|
||||||
|
## Hour of day to activate the restriction.
|
||||||
## initial setup
|
sleep_hour=23
|
||||||
iptables -N TIMERESTRICT_LOGNDROP 2>/dev/null
|
|
||||||
iptables -F TIMERESTRICT_LOGNDROP 2>/dev/null
|
## ----------------------------------------------------------------------
|
||||||
iptables -A TIMERESTRICT_LOGNDROP -m limit --limit 1/hour --limit-burst 1 -j LOG --log-prefix "TIMERESTRICT BLOCK: "
|
## ----------------------------------------------------------------------
|
||||||
iptables -A TIMERESTRICT_LOGNDROP -j REJECT --reject-with icmp-net-prohibited
|
## ----------------------------------------------------------------------
|
||||||
|
|
||||||
iptables -N TIMERESTRICT 2>/dev/null
|
myrule="FORWARD -i br0 -j TIMERESTRICT"
|
||||||
iptables -F TIMERESTRICT 2>/dev/null
|
|
||||||
for ip in $timerestricted_addresses ; do
|
## report on blocks if rule exists
|
||||||
iptables -A TIMERESTRICT -s $ip -j TIMERESTRICT_LOGNDROP
|
iptables -C $myrule 2>/dev/null && iptables -vL TIMERESTRICT | logger
|
||||||
done
|
|
||||||
|
echo "Setting up timerestrict firewall rules between $sleep_hour:00 and $wake_hour:00"
|
||||||
myrule="FORWARD -i br0 -j TIMERESTRICT"
|
|
||||||
|
## initial setup
|
||||||
## install or remove rule based on current time and whether the rule already exists
|
iptables -N TIMERESTRICT_LOGNDROP 2>/dev/null
|
||||||
if [ `date +%H` -ge $sleep_hour ]; then
|
iptables -F TIMERESTRICT_LOGNDROP 2>/dev/null
|
||||||
logger "TIMERESTRICT: Activating sleep time"
|
iptables -A TIMERESTRICT_LOGNDROP -m limit --limit 1/hour --limit-burst 1 -j LOG --log-prefix "TIMERESTRICT BLOCK: "
|
||||||
iptables -C $myrule 2>/dev/null || iptables -I $myrule
|
iptables -A TIMERESTRICT_LOGNDROP -j REJECT --reject-with icmp-net-prohibited
|
||||||
elif [ `date +%H` -ge $wake_hour ]; then
|
|
||||||
logger "TIMERESTRICT: Activating awake time"
|
iptables -N TIMERESTRICT 2>/dev/null
|
||||||
iptables -C $myrule 2>/dev/null && iptables -D $myrule
|
iptables -F TIMERESTRICT 2>/dev/null
|
||||||
fi
|
for ip in $timerestricted_addresses; do
|
||||||
|
iptables -A TIMERESTRICT -s $ip -j TIMERESTRICT_LOGNDROP
|
||||||
## setup cron job to activate/deactivate on time of day
|
done
|
||||||
echo "00 $sleep_hour * * * `readlink -f $0`" > /etc/cron.d/iptables_timerestrict
|
|
||||||
echo "00 $wake_hour * * * `readlink -f $0`" >> /etc/cron.d/iptables_timerestrict
|
myrule="FORWARD -i br0 -j TIMERESTRICT"
|
||||||
## Format: <minute> <hour> <day> <month> <dow> <tags and command>
|
|
||||||
/etc/init.d/crond restart
|
## install or remove rule based on current time and whether the rule already exists
|
||||||
|
if [ $(date +%H) -ge $sleep_hour ]; then
|
||||||
echo "Done with firewall rule setup:"
|
logger "TIMERESTRICT: Activating sleep time"
|
||||||
echo "-------------------------------------------------------------------"
|
iptables -C $myrule 2>/dev/null || iptables -I $myrule
|
||||||
iptables -vL FORWARD | egrep '(Chain|pkts|TIMERESTRICT)'
|
elif [ $(date +%H) -ge $wake_hour ]; then
|
||||||
echo ...
|
logger "TIMERESTRICT: Activating awake time"
|
||||||
iptables -vL TIMERESTRICT
|
iptables -C $myrule 2>/dev/null && iptables -D $myrule
|
||||||
iptables -vL TIMERESTRICT_LOGNDROP
|
fi
|
||||||
echo
|
|
||||||
|
## setup cron job to activate/deactivate on time of day
|
||||||
|
echo "00 $sleep_hour * * * $(readlink -f $0)" >/etc/cron.d/iptables_timerestrict
|
||||||
|
echo "00 $wake_hour * * * $(readlink -f $0)" >>/etc/cron.d/iptables_timerestrict
|
||||||
|
## Format: <minute> <hour> <day> <month> <dow> <tags and command>
|
||||||
|
/etc/init.d/crond restart
|
||||||
|
|
||||||
|
echo "Done with firewall rule setup:"
|
||||||
|
echo "-------------------------------------------------------------------"
|
||||||
|
iptables -vL FORWARD | egrep '(Chain|pkts|TIMERESTRICT)'
|
||||||
|
echo ...
|
||||||
|
iptables -vL TIMERESTRICT
|
||||||
|
iptables -vL TIMERESTRICT_LOGNDROP
|
||||||
|
echo
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
# Get DataDir location
|
# Get DataDir location
|
||||||
DATA_DIR="/mnt/data"
|
DATA_DIR="/data"
|
||||||
case "$(ubnt-device-info firmware || true)" in
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
1*)
|
1*)
|
||||||
DATA_DIR="/mnt/data"
|
DATA_DIR="/mnt/data"
|
||||||
;;
|
;;
|
||||||
2*)
|
2*)
|
||||||
DATA_DIR="/data"
|
DATA_DIR="/data"
|
||||||
;;
|
;;
|
||||||
3*)
|
3*)
|
||||||
DATA_DIR="/data"
|
DATA_DIR="/data"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "ERROR: No persistent storage found." 1>&2
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# A change in the name udm-boot would need to be reflected as well in systemctl calls.
|
# A change in the name udm-boot would need to be reflected as well in systemctl calls.
|
||||||
SYSTEMCTL_PATH="/etc/systemd/system/udm-boot.service"
|
SYSTEMCTL_PATH="/etc/systemd/system/udm-boot.service"
|
||||||
@ -25,17 +25,16 @@ SYMLINK_SYSTEMCTL="/etc/systemd/system/multi-user.target.wants/udm-boot.service"
|
|||||||
CNI_PLUGINS_SCRIPT_RAW_URL="https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/HEAD/cni-plugins/05-install-cni-plugins.sh"
|
CNI_PLUGINS_SCRIPT_RAW_URL="https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/HEAD/cni-plugins/05-install-cni-plugins.sh"
|
||||||
CNI_PLUGINS_ON_BOOT_FILENAME="$(basename "$CNI_PLUGINS_SCRIPT_RAW_URL")"
|
CNI_PLUGINS_ON_BOOT_FILENAME="$(basename "$CNI_PLUGINS_SCRIPT_RAW_URL")"
|
||||||
|
|
||||||
CNI_BRIDGE_SCRIPT_RAW_URL="https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/main/on-boot-script/examples/udm-networking/on_boot.d/06-cni-bridge.sh"
|
CNI_BRIDGE_SCRIPT_RAW_URL="https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/main/on-boot-script-2.x/examples/udm-networking/on_boot.d/06-cni-bridge.sh"
|
||||||
CNI_BRIDGE_ON_BOOT_FILENAME="$(basename "$CNI_BRIDGE_SCRIPT_RAW_URL")"
|
CNI_BRIDGE_ON_BOOT_FILENAME="$(basename "$CNI_BRIDGE_SCRIPT_RAW_URL")"
|
||||||
|
|
||||||
GITHUB_API_URL="https://api.github.com/repos"
|
GITHUB_API_URL="https://api.github.com/repos"
|
||||||
GITHUB_REPOSITORY="unifi-utilities/unifios-utilities"
|
GITHUB_REPOSITORY="unifi-utilities/unifios-utilities"
|
||||||
|
|
||||||
|
|
||||||
# --- Functions ---
|
# --- Functions ---
|
||||||
|
|
||||||
header() {
|
header() {
|
||||||
cat << EOF
|
cat <<EOF
|
||||||
_ _ ___ __ __ ___ _
|
_ _ ___ __ __ ___ _
|
||||||
| | | | \| \/ | | _ ) ___ ___| |_
|
| | | | \| \/ | | _ ) ___ ___| |_
|
||||||
| |_| | |) | |\/| | | _ \/ _ \/ _ \ _|
|
| |_| | |) | |\/| | | _ \/ _ \/ _ \ _|
|
||||||
@ -57,29 +56,29 @@ depends_on() {
|
|||||||
|
|
||||||
udm_model() {
|
udm_model() {
|
||||||
case "$(ubnt-device-info model || true)" in
|
case "$(ubnt-device-info model || true)" in
|
||||||
"UniFi Dream Machine SE")
|
"UniFi Dream Machine SE")
|
||||||
echo "udmse"
|
echo "udmse"
|
||||||
;;
|
;;
|
||||||
"UniFi Dream Machine Pro")
|
"UniFi Dream Machine Pro")
|
||||||
if test $(ubnt-device-info firmware) \< "2.0.0"; then
|
if test $(ubnt-device-info firmware) \< "2.0.0"; then
|
||||||
echo "udmprolegacy"
|
echo "udmprolegacy"
|
||||||
else
|
else
|
||||||
echo "udmpro"
|
echo "udmpro"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
"UniFi Dream Machine")
|
"UniFi Dream Machine")
|
||||||
if test $(ubnt-device-info firmware) \< "2.0.0"; then
|
if test $(ubnt-device-info firmware) \< "2.0.0"; then
|
||||||
echo "udmlegacy"
|
echo "udmlegacy"
|
||||||
else
|
else
|
||||||
echo "udm"
|
echo "udm"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
"UniFi Dream Router")
|
"UniFi Dream Router")
|
||||||
echo "udr"
|
echo "udr"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "unknown"
|
echo "unknown"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +124,7 @@ install_on_boot_udm_series() {
|
|||||||
|
|
||||||
# Credits @peacey: https://github.com/unifi-utilities/unifios-utilities/issues/214#issuecomment-886869295
|
# Credits @peacey: https://github.com/unifi-utilities/unifios-utilities/issues/214#issuecomment-886869295
|
||||||
udmse_on_boot_systemd() {
|
udmse_on_boot_systemd() {
|
||||||
cat << EOF
|
cat <<EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Run On Startup UDM
|
Description=Run On Startup UDM
|
||||||
Wants=network-online.target
|
Wants=network-online.target
|
||||||
@ -133,7 +132,7 @@ After=network-online.target
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=forking
|
Type=forking
|
||||||
ExecStart=bash -c 'mkdir -p $DATA_DIR/on_boot.d && find -L $DATA_DIR/on_boot.d -mindepth 1 -maxdepth 1 -type f -print0 | sort -z | xargs -0 -r -n 1 -- bash -c \'if test -x "\$0"; then echo "%n: running \$0"; "\$0"; else case "\$0" in *.sh) echo "%n: sourcing \$0"; . "\$0";; *) echo "%n: ignoring \$0";; esac; fi\''
|
ExecStart=bash -c 'mkdir -p ${DATA_DIR}/on_boot.d && find -L ${DATA_DIR}/on_boot.d -mindepth 1 -maxdepth 1 -type f -print0 | sort -z | xargs -0 -r -n 1 -- bash -c \'if test -x "\$0"; then echo "%n: running \$0"; "\$0"; else case "\$0" in *.sh) echo "%n: sourcing \$0"; . "\$0";; *) echo "%n: ignoring \$0";; esac; fi\''
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
@ -147,7 +146,7 @@ install_on_boot_udr_se() {
|
|||||||
rm -f "$SYMLINK_SYSTEMCTL"
|
rm -f "$SYMLINK_SYSTEMCTL"
|
||||||
|
|
||||||
echo "Creating systemctl service file"
|
echo "Creating systemctl service file"
|
||||||
udmse_on_boot_systemd > "$SYSTEMCTL_PATH" || return 1
|
udmse_on_boot_systemd >"$SYSTEMCTL_PATH" || return 1
|
||||||
sleep 1s
|
sleep 1s
|
||||||
|
|
||||||
echo "Enabling UDM boot..."
|
echo "Enabling UDM boot..."
|
||||||
@ -165,43 +164,42 @@ header
|
|||||||
depends_on ubnt-device-info
|
depends_on ubnt-device-info
|
||||||
depends_on curl
|
depends_on curl
|
||||||
|
|
||||||
ON_BOOT_D_PATH="$DATA_DIR/on_boot.d"
|
ON_BOOT_D_PATH="${DATA_DIR}/on_boot.d"
|
||||||
|
|
||||||
case "$(udm_model)" in
|
case "$(udm_model)" in
|
||||||
udmlegacy|udmprolegacy)
|
udmlegacy | udmprolegacy)
|
||||||
echo "$(ubnt-device-info model) version $(ubnt-device-info firmware) was detected"
|
echo "$(ubnt-device-info model) version $(ubnt-device-info firmware) was detected"
|
||||||
echo "Installing on-boot script..."
|
echo "Installing on-boot script..."
|
||||||
depends_on podman
|
depends_on podman
|
||||||
|
|
||||||
if ! install_on_boot_udm_series; then
|
if ! install_on_boot_udm_series; then
|
||||||
echo
|
echo
|
||||||
echo "Failed to install on-boot script service" 1>&2
|
echo "Failed to install on-boot script service" 1>&2
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "UDM Boot Script installed"
|
|
||||||
;;
|
|
||||||
udr|udmse|udm|udmpro)
|
|
||||||
echo "$(ubnt-device-info model) version $(ubnt-device-info firmware) was detected"
|
|
||||||
echo "Installing on-boot script..."
|
|
||||||
depends_on systemctl
|
|
||||||
|
|
||||||
if ! install_on_boot_udr_se; then
|
|
||||||
echo
|
|
||||||
echo "Failed to install on-boot script service" 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "UDM Boot Script installed"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Unsupported model: $(ubnt-device-info model)" 1>&2
|
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
fi
|
||||||
|
|
||||||
|
echo "UDM Boot Script installed"
|
||||||
|
;;
|
||||||
|
udr | udmse | udm | udmpro)
|
||||||
|
echo "$(ubnt-device-info model) version $(ubnt-device-info firmware) was detected"
|
||||||
|
echo "Installing on-boot script..."
|
||||||
|
depends_on systemctl
|
||||||
|
|
||||||
|
if ! install_on_boot_udr_se; then
|
||||||
|
echo
|
||||||
|
echo "Failed to install on-boot script service" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "UDM Boot Script installed"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unsupported model: $(ubnt-device-info model)" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
echo
|
echo
|
||||||
|
|
||||||
|
|
||||||
if [ ! -f "${ON_BOOT_D_PATH}/${CNI_PLUGINS_ON_BOOT_FILENAME}" ]; then
|
if [ ! -f "${ON_BOOT_D_PATH}/${CNI_PLUGINS_ON_BOOT_FILENAME}" ]; then
|
||||||
echo "Downloading CNI plugins script..."
|
echo "Downloading CNI plugins script..."
|
||||||
if
|
if
|
||||||
@ -220,7 +218,6 @@ echo "Executing CNI plugins script..."
|
|||||||
"${ON_BOOT_D_PATH}/${CNI_PLUGINS_ON_BOOT_FILENAME}" || true
|
"${ON_BOOT_D_PATH}/${CNI_PLUGINS_ON_BOOT_FILENAME}" || true
|
||||||
echo
|
echo
|
||||||
|
|
||||||
|
|
||||||
if [ ! -f "${ON_BOOT_D_PATH}/${CNI_BRIDGE_ON_BOOT_FILENAME}" ]; then
|
if [ ! -f "${ON_BOOT_D_PATH}/${CNI_BRIDGE_ON_BOOT_FILENAME}" ]; then
|
||||||
echo "Downloading CNI bridge script..."
|
echo "Downloading CNI bridge script..."
|
||||||
if
|
if
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
1. Allows you to run a shell script at S95 anytime your UDM starts / reboots
|
1. Allows you to run a shell script at S95 anytime your UDM starts / reboots
|
||||||
1. Persists through reboot and **firmware updates**! It is able to do this because Ubiquiti caches all debian package installs on the UDM in /mnt/data, then re-installs them on reset of unifi-os container.
|
1. Persists through reboot and **firmware updates**! It is able to do this because Ubiquiti caches all debian package installs on the UDM in /data, then re-installs them on reset of unifi-os container.
|
||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
@ -12,21 +12,22 @@
|
|||||||
|
|
||||||
### Upgrade from earlier way
|
### Upgrade from earlier way
|
||||||
|
|
||||||
* As long as you didn't change the filenames, installing the deb package is all you need to do. If you want to clean up beforehand anyways....
|
- As long as you didn't change the filenames, installing the deb package is all you need to do. If you want to clean up beforehand anyways....
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rm /etc/init.d/udm.sh
|
rm /etc/init.d/udm.sh
|
||||||
systemctl disable udmboot
|
systemctl disable udmboot
|
||||||
rm /etc/systemd/system/udmboot.service
|
rm /etc/systemd/system/udmboot.service
|
||||||
```
|
```
|
||||||
|
|
||||||
* [build_deb.sh](build_deb.sh) can be used to build the package by yourself.
|
- [build_deb.sh](build_deb.sh) can be used to build the package by yourself.
|
||||||
* [dpkg-build-files](dpkg-build-files) contains the sources that debuild uses to build the package if you want to build it yourself / change it
|
|
||||||
* by default it uses docker or podman to build the debian package
|
|
||||||
* use ```./build_deb.sh build``` to not use a container
|
|
||||||
* the resulting package will be in [packages/](packages/)
|
|
||||||
|
|
||||||
* Built on Ubuntu-20.04 on Windows 10/WSL2
|
- [dpkg-build-files](dpkg-build-files) contains the sources that debuild uses to build the package if you want to build it yourself / change it
|
||||||
|
- by default it uses docker or podman to build the debian package
|
||||||
|
- use `./build_deb.sh build` to not use a container
|
||||||
|
- the resulting package will be in [packages/](packages/)
|
||||||
|
|
||||||
|
- Built on Ubuntu-20.04 on Windows 10/WSL2
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
@ -44,60 +45,61 @@ This will also install CNI Plugins & CNI Bridge scripts. If you are using UDMSE/
|
|||||||
|
|
||||||
1. Get into the unifios shell on your udm
|
1. Get into the unifios shell on your udm
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
unifi-os shell
|
unifi-os shell
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Download [udm-boot_1.0.7_all.deb](packages/udm-boot_1.0.7_all.deb) and install it and go back to the UDM. The latest package will always be found at https://udm-boot.boostchicken.dev
|
2. Download [udm-boot_1.0.7_all.deb](packages/udm-boot_1.0.7_all.deb) and install it and go back to the UDM. The latest package will always be found at https://udm-boot.boostchicken.dev
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -L https://unifi.boostchicken.io/udm-boot_1.0.7_all.deb -o udm-boot_1.0.7_all.deb
|
curl -L https://unifi.boostchicken.io/udm-boot_1.0.7_all.deb -o udm-boot_1.0.7_all.deb
|
||||||
dpkg -i udm-boot_1.0.7_all.deb
|
dpkg -i udm-boot_1.0.7_all.deb
|
||||||
systemctl enable udm-boot
|
systemctl enable udm-boot
|
||||||
exit
|
exit
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Copy any shell scripts you want to run to /mnt/data/on_boot.d on your UDM (not the unifi-os shell) and make sure they are executable and have the correct shebang (#!/bin/sh). Additionally, scripts need to have a `.sh` extention in their filename.
|
3. Copy any shell scripts you want to run to /data/on_boot.d on your UDM (not the unifi-os shell) and make sure they are executable and have the correct shebang (#!/bin/sh). Additionally, scripts need to have a `.sh` extention in their filename.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
* Start a DNS Container [10-dns.sh](../dns-common/on_boot.d/10-dns.sh)
|
|
||||||
* Start wpa_supplicant [on_boot.d/10-wpa_supplicant.sh](examples/udm-files/on_boot.d/10-wpa_supplicant.sh)
|
- Start a DNS Container [10-dns.sh](../dns-common/on_boot.d/10-dns.sh)
|
||||||
* Add a persistent ssh key for the root user [on_boot.d/15-add-root-ssh-keys.sh](examples/udm-files/on_boot.d/15-add-root-ssh-keys.sh)
|
- Start wpa_supplicant [on_boot.d/10-wpa_supplicant.sh](examples/udm-files/on_boot.d/10-wpa_supplicant.sh)
|
||||||
|
- Add a persistent ssh key for the root user [on_boot.d/15-add-root-ssh-keys.sh](examples/udm-files/on_boot.d/15-add-root-ssh-keys.sh)
|
||||||
|
|
||||||
## Version History
|
## Version History
|
||||||
|
|
||||||
### 1.0.7
|
### 1.0.7
|
||||||
|
|
||||||
* Support for Legacy and Current Firmware
|
- Support for Legacy and Current Firmware
|
||||||
|
|
||||||
### 1.0.6
|
### 1.0.6
|
||||||
|
|
||||||
* Fix timeouts
|
- Fix timeouts
|
||||||
|
|
||||||
### 1.0.5
|
### 1.0.5
|
||||||
|
|
||||||
* Remove on_boot.sh from UDM
|
- Remove on_boot.sh from UDM
|
||||||
* Follow symlinks
|
- Follow symlinks
|
||||||
* move to network-online.target
|
- move to network-online.target
|
||||||
|
|
||||||
### 1.0.4
|
### 1.0.4
|
||||||
|
|
||||||
* Fix 600s timeout issues
|
- Fix 600s timeout issues
|
||||||
* Fix rc.d policy issue
|
- Fix rc.d policy issue
|
||||||
|
|
||||||
### 1.0.3
|
### 1.0.3
|
||||||
|
|
||||||
* Fix not working after firmware upgrade
|
- Fix not working after firmware upgrade
|
||||||
* Added udm-boot.boostchicken.dev domain
|
- Added udm-boot.boostchicken.dev domain
|
||||||
|
|
||||||
### 1.0.2
|
### 1.0.2
|
||||||
|
|
||||||
* Some build improvements and more clean installation
|
- Some build improvements and more clean installation
|
||||||
|
|
||||||
### 1.0.1
|
### 1.0.1
|
||||||
|
|
||||||
* Fully automated install, all that is left is populating /mnt/data/on_boot.d
|
- Fully automated install, all that is left is populating /data/on_boot.d
|
||||||
|
|
||||||
### 1.0.0
|
### 1.0.0
|
||||||
|
|
||||||
* First release that persists through firmware
|
- First release that persists through firmware
|
||||||
|
@ -2,72 +2,73 @@
|
|||||||
|
|
||||||
## Automated Setup
|
## Automated Setup
|
||||||
|
|
||||||
* NB! THESE WILL NOT PERSIST THROUGH FIRMWARE. They still work however
|
- NB! THESE WILL NOT PERSIST THROUGH FIRMWARE. They still work however
|
||||||
|
|
||||||
1. Copy [install.sh](manual-install/install.sh) to your UDM and execute it
|
1. Copy [install.sh](manual-install/install.sh) to your UDM and execute it
|
||||||
1. Copy any shell scripts you want to run to /mnt/data/on_boot.d and make sure they are executable and have the correct shebang (#!/bin/sh)
|
1. Copy any shell scripts you want to run to /data/on_boot.d and make sure they are executable and have the correct shebang (#!/bin/sh)
|
||||||
Examples:
|
Examples:
|
||||||
* Start a DNS Container [10-dns.sh](../dns-common/on_boot.d/10-dns.sh)
|
- Start a DNS Container [10-dns.sh](../dns-common/on_boot.d/10-dns.sh)
|
||||||
* Start wpa_supplicant [on_boot.d/10-wpa_supplicant.sh](examples/udm-files/on_boot.d/10-start-containers.sh)
|
- Start wpa_supplicant [on_boot.d/10-wpa_supplicant.sh](examples/udm-files/on_boot.d/10-start-containers.sh)
|
||||||
|
|
||||||
## Manual Setup
|
## Manual Setup
|
||||||
|
|
||||||
1. Copy on_boot.sh and make on_boot.d and add scripts to on_boot.d
|
1. Copy on_boot.sh and make on_boot.d and add scripts to on_boot.d
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mkdir -p /mnt/data/on_boot.d
|
mkdir -p /data/on_boot.d
|
||||||
vi /mnt/data/on_boot.sh
|
vi /data/on_boot.sh
|
||||||
chmod u+x /mnt/data/on_boot.sh
|
chmod u+x /data/on_boot.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Example: [on_boot.sh](examples/udm-files/on_boot.sh)
|
Example: [on_boot.sh](examples/udm-files/on_boot.sh)
|
||||||
|
|
||||||
2. Enter the container shell
|
2. Enter the container shell
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
unifi-os shell
|
unifi-os shell
|
||||||
```
|
```
|
||||||
|
|
||||||
3. make a script that sshs to the udm and runs on our boot script. 127.0.1.1 always points to the UDM
|
3. make a script that sshs to the udm and runs on our boot script. 127.0.1.1 always points to the UDM
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
echo "#!/bin/sh
|
echo "#!/bin/sh
|
||||||
ssh -o StrictHostKeyChecking=no root@127.0.1.1 '/mnt/data/on_boot.sh'" > /etc/init.d/udm.sh
|
ssh -o StrictHostKeyChecking=no root@127.0.1.1 '/data/on_boot.sh'" > /etc/init.d/udm.sh
|
||||||
chmod u+x /etc/init.d/udm.sh
|
chmod u+x /etc/init.d/udm.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Example: [udm.sh](examples/unifi-os-files/udm.sh)
|
||||||
|
|
||||||
Example: [udm.sh](examples/unifi-os-files/udm.sh)
|
|
||||||
4. make a service that runs on startup, after we have networking
|
4. make a service that runs on startup, after we have networking
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
echo "[Unit]
|
echo "[Unit]
|
||||||
Description=Run On Startup UDM
|
Description=Run On Startup UDM
|
||||||
After=network.target
|
After=network.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=/etc/init.d/udm.sh
|
ExecStart=/etc/init.d/udm.sh
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target" > /etc/systemd/system/udmboot.service
|
WantedBy=multi-user.target" > /etc/systemd/system/udmboot.service
|
||||||
```
|
```
|
||||||
|
|
||||||
Example: [udmboot.service](examples/unifi-os-files/udmboot.service)
|
Example: [udmboot.service](examples/unifi-os-files/udmboot.service)
|
||||||
|
|
||||||
5. enable it and test
|
5. enable it and test
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
systemctl enable --now udmboot
|
systemctl enable --now udmboot
|
||||||
```
|
```
|
||||||
|
|
||||||
6. back to the udm
|
6. back to the udm
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
exit
|
exit
|
||||||
```
|
```
|
||||||
|
|
||||||
7. reboot your udm/udmpro and make sure it worked
|
7. reboot your udm/udmpro and make sure it worked
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
reboot
|
reboot
|
||||||
exit
|
exit
|
||||||
```
|
```
|
||||||
|
@ -22,7 +22,7 @@ set -e
|
|||||||
case "$1" in
|
case "$1" in
|
||||||
purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
||||||
if [ -x /sbin/ssh-proxy ]; then
|
if [ -x /sbin/ssh-proxy ]; then
|
||||||
/sbin/ssh-proxy rm -f /mnt/data/on_boot.sh
|
/sbin/ssh-proxy rm -f /data/on_boot.sh
|
||||||
fi
|
fi
|
||||||
true
|
true
|
||||||
;;
|
;;
|
||||||
|
@ -17,7 +17,7 @@ set -e
|
|||||||
case "$1" in
|
case "$1" in
|
||||||
install|upgrade)
|
install|upgrade)
|
||||||
if [ -x /sbin/ssh-proxy ]; then
|
if [ -x /sbin/ssh-proxy ]; then
|
||||||
/sbin/ssh-proxy rm -f /mnt/data/on_boot.sh
|
/sbin/ssh-proxy rm -f /data/on_boot.sh
|
||||||
fi
|
fi
|
||||||
true
|
true
|
||||||
;;
|
;;
|
||||||
|
@ -8,7 +8,7 @@ StartLimitBurst=5
|
|||||||
[Service]
|
[Service]
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
RestartSec=5s
|
RestartSec=5s
|
||||||
ExecStart=/sbin/ssh-proxy 'mkdir -p /mnt/data/on_boot.d && find -L /mnt/data/on_boot.d -mindepth 1 -maxdepth 1 -type f -print0 | sort -z | xargs -0 -r -n 1 -- sh -c '\''if test -x "$0"; then echo "%n: running $0"; "$0"; else case "$0" in *.sh) echo "%n: sourcing $0"; . "$0";; *) echo "%n: ignoring $0";; esac; fi'\'
|
ExecStart=/sbin/ssh-proxy 'mkdir -p /data/on_boot.d && find -L /data/on_boot.d -mindepth 1 -maxdepth 1 -type f -print0 | sort -z | xargs -0 -r -n 1 -- sh -c '\''if test -x "$0"; then echo "%n: running $0"; "$0"; else case "$0" in *.sh) echo "%n: sourcing $0"; . "$0";; *) echo "%n: ignoring $0";; esac; fi'\'
|
||||||
RemainAfterExit=true
|
RemainAfterExit=true
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
## Configure shell profile
|
## Configure shell profile
|
||||||
|
|
||||||
device_info() {
|
device_info() {
|
||||||
@ -7,7 +23,7 @@ device_info() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Modify login banner (motd)
|
# Modify login banner (motd)
|
||||||
cat > /etc/motd <<EOF
|
cat >/etc/motd <<EOF
|
||||||
Welcome to UniFi Dream Machine!
|
Welcome to UniFi Dream Machine!
|
||||||
(c) 2010-$(date +%Y) Ubiquiti Inc. | http://www.ui.com
|
(c) 2010-$(date +%Y) Ubiquiti Inc. | http://www.ui.com
|
||||||
|
|
||||||
@ -17,13 +33,13 @@ MAC Address: $(device_info mac)
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Extend UbiOS prompt to include useful information
|
# Extend UbiOS prompt to include useful information
|
||||||
cat > /etc/profile.d/prompt.sh <<'EOF'
|
cat >/etc/profile.d/prompt.sh <<'EOF'
|
||||||
UDM_NAME="$(grep -m 1 '^name:' /data/unifi-core/config/settings.yaml | awk -F: '{ gsub(/^[ \t]+|[ \t]+$/, "", $2); print tolower($2) }')"
|
UDM_NAME="$(grep -m 1 '^name:' ${DATA_DIR}/unifi-core/config/settings.yaml | awk -F: '{ gsub(/^[ \t]+|[ \t]+$/, "", $2); print tolower($2) }')"
|
||||||
PROMPT_MAIN="\u@${UDM_NAME}:\w"
|
PROMPT_MAIN="\u@${UDM_NAME}:\w"
|
||||||
|
|
||||||
export PS1="[UDM] ${PROMPT_MAIN}${PS1}"
|
export PS1="[UDM] ${PROMPT_MAIN}${PS1}"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Copy all global profile scripts (for all users) from `/mnt/data/on_boot.d/settings/profile/global.profile.d/` directory
|
# Copy all global profile scripts (for all users) from `${DATA_DIR}/on_boot.d/settings/profile/global.profile.d/` directory
|
||||||
mkdir -p /mnt/data/on_boot.d/settings/profile/global.profile.d
|
mkdir -p ${DATA_DIR}/on_boot.d/settings/profile/global.profile.d
|
||||||
cp -rf /mnt/data/on_boot.d/settings/profile/global.profile.d/* /etc/profile.d/
|
cp -rf ${DATA_DIR}/on_boot.d/settings/profile/global.profile.d/* /etc/profile.d/
|
||||||
|
@ -1,3 +1,20 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
cp -f /mnt/data/on_boot.d/files/.profile /root/
|
cp -f ${DATA_DIR}/on_boot.d/files/.profile /root/
|
||||||
|
@ -1,16 +1,35 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
## Config Variables - please edit these
|
## Config Variables - please edit these
|
||||||
# Set to true to download public keys from a github user account
|
# Set to true to download public keys from a github user account
|
||||||
USE_GITHUB_KEYS=true
|
USE_GITHUB_KEYS=true
|
||||||
# Enter your username on github to get the public keys for
|
# Enter your username on github to get the public keys for
|
||||||
GITHUB_USER="<YOUR_USERNAME>"
|
GITHUB_USER="<YOUR_USERNAME>"
|
||||||
# File location for the output of the git download
|
# File location for the output of the git download
|
||||||
GITHUB_KEY_PATH="/mnt/data/podman/ssh"
|
GITHUB_KEY_PATH="${DATA_DIR}/podman/ssh"
|
||||||
GITHUB_KEY_FILE="${GITHUB_KEY_PATH}/github.keys"
|
GITHUB_KEY_FILE="${GITHUB_KEY_PATH}/github.keys"
|
||||||
# Set to true to use a file containing a key per line in the format ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAA...\n
|
# Set to true to use a file containing a key per line in the format ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAA...\n
|
||||||
USE_KEY_FILE=true
|
USE_KEY_FILE=true
|
||||||
# IF using an input file, list it here
|
# IF using an input file, list it here
|
||||||
INPUT_KEY_PATH="/mnt/data/podman/ssh"
|
INPUT_KEY_PATH="${DATA_DIR}/podman/ssh"
|
||||||
INPUT_KEY_FILE="${INPUT_KEY_PATH}/ssh.keys"
|
INPUT_KEY_FILE="${INPUT_KEY_PATH}/ssh.keys"
|
||||||
# The target key file for the script
|
# The target key file for the script
|
||||||
OUTPUT_KEY_PATH="/root/.ssh"
|
OUTPUT_KEY_PATH="/root/.ssh"
|
||||||
@ -18,7 +37,7 @@ OUTPUT_KEY_FILE="${OUTPUT_KEY_PATH}/authorized_keys"
|
|||||||
|
|
||||||
## Functions
|
## Functions
|
||||||
# This function downloads the keys from the selected github user
|
# This function downloads the keys from the selected github user
|
||||||
download_from_github(){
|
download_from_github() {
|
||||||
if curl --output /dev/null --silent --head --fail https://github.com/${GITHUB_USER}.keys; then
|
if curl --output /dev/null --silent --head --fail https://github.com/${GITHUB_USER}.keys; then
|
||||||
curl https://github.com/${GITHUB_USER}.keys -o ${GITHUB_KEY_FILE}
|
curl https://github.com/${GITHUB_USER}.keys -o ${GITHUB_KEY_FILE}
|
||||||
echo "Downloaded keys from Github"
|
echo "Downloaded keys from Github"
|
||||||
@ -27,26 +46,25 @@ download_from_github(){
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
# Write line to the output line. Add the input line as an arguement.
|
# Write line to the output line. Add the input line as an arguement.
|
||||||
write_to_output(){
|
write_to_output() {
|
||||||
# Check the file exits
|
# Check the file exits
|
||||||
if ! test -f ${OUTPUT_KEY_FILE}; then
|
if ! test -f ${OUTPUT_KEY_FILE}; then
|
||||||
echo "File at ${OUTPUT_KEY_FILE} does not exist, creating it"
|
echo "File at ${OUTPUT_KEY_FILE} does not exist, creating it"
|
||||||
touch ${OUTPUT_KEY_FILE}
|
touch ${OUTPUT_KEY_FILE}
|
||||||
fi
|
fi
|
||||||
echo "${1}" >> ${OUTPUT_KEY_FILE}
|
echo "${1}" >>${OUTPUT_KEY_FILE}
|
||||||
}
|
}
|
||||||
# This function reads keys from a file into the requested file. The arguement is the input file.
|
# This function reads keys from a file into the requested file. The arguement is the input file.
|
||||||
use_key_from_file(){
|
use_key_from_file() {
|
||||||
if ! test -f $1; then
|
if ! test -f $1; then
|
||||||
echo "File $1 does not exist"
|
echo "File $1 does not exist"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
counter=0;
|
counter=0
|
||||||
while IFS= read -r line;
|
while IFS= read -r line; do
|
||||||
do
|
|
||||||
write_to_output "${line}"
|
write_to_output "${line}"
|
||||||
let "counter++"
|
let "counter++"
|
||||||
done < $1
|
done <$1
|
||||||
echo "${counter} number of entries read from "
|
echo "${counter} number of entries read from "
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,24 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
## Places public keys in ~/.ssh/authorized_keys
|
## Places public keys in ~/.ssh/authorized_keys
|
||||||
|
|
||||||
KEYS_SOURCE_FILE="/mnt/data/on_boot.d/settings/ssh/authorized_keys"
|
KEYS_SOURCE_FILE="${DATA_DIR}/on_boot.d/settings/ssh/authorized_keys"
|
||||||
KEYS_TARGET_FILE="/root/.ssh/authorized_keys"
|
KEYS_TARGET_FILE="/root/.ssh/authorized_keys"
|
||||||
|
|
||||||
count_added=0
|
count_added=0
|
||||||
@ -11,19 +27,19 @@ while read -r key; do
|
|||||||
# Places public key in ~/.ssh/authorized_keys if not present
|
# Places public key in ~/.ssh/authorized_keys if not present
|
||||||
if ! grep -Fxq "$key" "$KEYS_TARGET_FILE"; then
|
if ! grep -Fxq "$key" "$KEYS_TARGET_FILE"; then
|
||||||
let count_added++
|
let count_added++
|
||||||
echo "$key" >> "$KEYS_TARGET_FILE"
|
echo "$key" >>"$KEYS_TARGET_FILE"
|
||||||
else
|
else
|
||||||
let count_skipped++
|
let count_skipped++
|
||||||
fi
|
fi
|
||||||
done < "$KEYS_SOURCE_FILE"
|
done <"$KEYS_SOURCE_FILE"
|
||||||
|
|
||||||
echo "${count_added} keys added to ${KEYS_TARGET_FILE}"
|
echo "${count_added} keys added to ${KEYS_TARGET_FILE}"
|
||||||
if [ $count_skipped -gt 0 ]; then
|
if [ $count_skipped -gt 0 ]; then
|
||||||
echo "${count_skipped} already added keys skipped"
|
echo "${count_skipped} already added keys skipped"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Convert ssh key to dropbear for shell interaction
|
# Convert ssh key to dropbear for shell interaction
|
||||||
echo "Converting SSH private key to dropbear format"
|
echo "Converting SSH private key to dropbear format"
|
||||||
dropbearconvert openssh dropbear /mnt/data/ssh/id_rsa /root/.ssh/id_dropbear
|
dropbearconvert openssh dropbear ${DATA_DIR}/ssh/id_rsa /root/.ssh/id_dropbear
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -1,13 +1,29 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
mkdir -p ${DATA_DIR}/.home
|
||||||
|
|
||||||
mkdir -p /mnt/data/.home
|
for file in .ash_history .bash_history; do
|
||||||
|
if [ ! -f ${DATA_DIR}/.home/$file ]; then
|
||||||
for file in .ash_history .bash_history
|
touch /root/$file
|
||||||
if [ ! -f /mnt/data/.home/$file ]; then
|
cp /root/$file ${DATA_DIR}/.home/$file
|
||||||
touch /root/$file
|
chown root:root ${DATA_DIR}/.home/$file
|
||||||
cp /root/$file /mnt/data/.home/$file
|
chmod 0600 ${DATA_DIR}/.home/$file
|
||||||
chown root:root /mnt/data/.home/$file
|
fi
|
||||||
chmod 0600 /mnt/data/.home/$file
|
ln -sf ${DATA_DIR}/.home/$file /root/$file
|
||||||
fi
|
done
|
||||||
ln -sf /mnt/data/.home/$file /root/$file
|
|
||||||
|
|
||||||
|
@ -1,9 +1,25 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
## Store crontab files in /mnt/data/cronjobs/ (you will need to create this folder).
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
## Store crontab files in ${DATA_DIR}/cronjobs/ (you will need to create this folder).
|
||||||
## This script will re-add them on startup.
|
## This script will re-add them on startup.
|
||||||
|
|
||||||
cp /mnt/data/cronjobs/* /etc/cron.d/
|
cp ${DATA_DIR}/cronjobs/* /etc/cron.d/
|
||||||
/etc/init.d/crond restart
|
/etc/init.d/crond restart
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -1,87 +1,100 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
## ----------------------------------------------------------------------
|
DATA_DIR="/data"
|
||||||
## Script to add/remove time-of-day restrictions on internet access for selected clients.
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
##
|
1*)
|
||||||
## Use DHCP reservations to encourage the selected clients to always obtain the same IP address.
|
DATA_DIR="/mnt/data"
|
||||||
##
|
;;
|
||||||
## To install:
|
2*)
|
||||||
## * Copy this script into /mnt/data/on_boot.d/, using something like WinSCP or SSH + vi.
|
DATA_DIR="/data"
|
||||||
## * Grant Execute permission: chmod +x /mnt/data/on_boot.d/iptables_timerestrict.sh
|
;;
|
||||||
## * Run it once, to activate it (crontab entries will keep it active forever after):
|
3*)
|
||||||
## Via SSH into UDM shell: /mnt/data/on_boot.d/iptables_timerestrict.sh
|
DATA_DIR="/data"
|
||||||
##
|
;;
|
||||||
## Notes:
|
*)
|
||||||
## * Changes to firewall rules in the Unifi Network Application will remove your restriction;
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
## re-run this script to re-apply the restriction rule, or wait for the next activation/deactivation hour.
|
exit 1
|
||||||
## * To apply changes to this script (i.e. new client addresses, or changes to the time of day),
|
;;
|
||||||
## re-run this script manually to apply the updates, or wait for the next activation/deactivation hour.
|
esac
|
||||||
## * When this script activates or deactivates the blocking, it will log to /var/log/messages.
|
## ----------------------------------------------------------------------
|
||||||
## * While the blocking is active, you'll see one "TIMERESTRICT BLOCK: " log message per hour
|
## Script to add/remove time-of-day restrictions on internet access for selected clients.
|
||||||
## in /var/log/messages if any blocked clients are attempting to use the internet.
|
##
|
||||||
##
|
## Use DHCP reservations to encourage the selected clients to always obtain the same IP address.
|
||||||
## Caveats:
|
##
|
||||||
## * No support for wake_minute/sleep_minute - currently this only turns on/off at the top of an hour.
|
## To install:
|
||||||
## * Assumption exists that sleep_hour is always greater-than wake_hour; i.e., you can't currently
|
## * Copy this script into ${DATA_DIR}/on_boot.d/, using something like WinSCP or SSH + vi.
|
||||||
## have a blocked time in the middle of the day.
|
## * Grant Execute permission: chmod +x ${DATA_DIR}/on_boot.d/iptables_timerestrict.sh
|
||||||
## ----------------------------------------------------------------------
|
## * Run it once, to activate it (crontab entries will keep it active forever after):
|
||||||
|
## Via SSH into UDM shell: ${DATA_DIR}/on_boot.d/iptables_timerestrict.sh
|
||||||
|
##
|
||||||
## List all client addresses you'd like to restrict. Separate multiple with spaces.
|
## Notes:
|
||||||
timerestricted_addresses='192.168.1.101 192.168.1.102'
|
## * Changes to firewall rules in the Unifi Network Application will remove your restriction;
|
||||||
|
## re-run this script to re-apply the restriction rule, or wait for the next activation/deactivation hour.
|
||||||
## Hour of day to remove the restriction.
|
## * To apply changes to this script (i.e. new client addresses, or changes to the time of day),
|
||||||
wake_hour=06
|
## re-run this script manually to apply the updates, or wait for the next activation/deactivation hour.
|
||||||
|
## * When this script activates or deactivates the blocking, it will log to /var/log/messages.
|
||||||
## Hour of day to activate the restriction.
|
## * While the blocking is active, you'll see one "TIMERESTRICT BLOCK: " log message per hour
|
||||||
sleep_hour=23
|
## in /var/log/messages if any blocked clients are attempting to use the internet.
|
||||||
|
##
|
||||||
|
## Caveats:
|
||||||
|
## * No support for wake_minute/sleep_minute - currently this only turns on/off at the top of an hour.
|
||||||
## ----------------------------------------------------------------------
|
## * Assumption exists that sleep_hour is always greater-than wake_hour; i.e., you can't currently
|
||||||
## ----------------------------------------------------------------------
|
## have a blocked time in the middle of the day.
|
||||||
## ----------------------------------------------------------------------
|
## ----------------------------------------------------------------------
|
||||||
|
|
||||||
myrule="FORWARD -i br0 -j TIMERESTRICT"
|
## List all client addresses you'd like to restrict. Separate multiple with spaces.
|
||||||
|
timerestricted_addresses='192.168.1.101 192.168.1.102'
|
||||||
## report on blocks if rule exists
|
|
||||||
iptables -C $myrule 2>/dev/null && iptables -vL TIMERESTRICT | logger
|
## Hour of day to remove the restriction.
|
||||||
|
wake_hour=06
|
||||||
echo "Setting up timerestrict firewall rules between $sleep_hour:00 and $wake_hour:00"
|
|
||||||
|
## Hour of day to activate the restriction.
|
||||||
## initial setup
|
sleep_hour=23
|
||||||
iptables -N TIMERESTRICT_LOGNDROP 2>/dev/null
|
|
||||||
iptables -F TIMERESTRICT_LOGNDROP 2>/dev/null
|
## ----------------------------------------------------------------------
|
||||||
iptables -A TIMERESTRICT_LOGNDROP -m limit --limit 1/hour --limit-burst 1 -j LOG --log-prefix "TIMERESTRICT BLOCK: "
|
## ----------------------------------------------------------------------
|
||||||
iptables -A TIMERESTRICT_LOGNDROP -j REJECT --reject-with icmp-net-prohibited
|
## ----------------------------------------------------------------------
|
||||||
|
|
||||||
iptables -N TIMERESTRICT 2>/dev/null
|
myrule="FORWARD -i br0 -j TIMERESTRICT"
|
||||||
iptables -F TIMERESTRICT 2>/dev/null
|
|
||||||
for ip in $timerestricted_addresses ; do
|
## report on blocks if rule exists
|
||||||
iptables -A TIMERESTRICT -s $ip -j TIMERESTRICT_LOGNDROP
|
iptables -C $myrule 2>/dev/null && iptables -vL TIMERESTRICT | logger
|
||||||
done
|
|
||||||
|
echo "Setting up timerestrict firewall rules between $sleep_hour:00 and $wake_hour:00"
|
||||||
myrule="FORWARD -i br0 -j TIMERESTRICT"
|
|
||||||
|
## initial setup
|
||||||
## install or remove rule based on current time and whether the rule already exists
|
iptables -N TIMERESTRICT_LOGNDROP 2>/dev/null
|
||||||
if [ `date +%H` -ge $sleep_hour ]; then
|
iptables -F TIMERESTRICT_LOGNDROP 2>/dev/null
|
||||||
logger "TIMERESTRICT: Activating sleep time"
|
iptables -A TIMERESTRICT_LOGNDROP -m limit --limit 1/hour --limit-burst 1 -j LOG --log-prefix "TIMERESTRICT BLOCK: "
|
||||||
iptables -C $myrule 2>/dev/null || iptables -I $myrule
|
iptables -A TIMERESTRICT_LOGNDROP -j REJECT --reject-with icmp-net-prohibited
|
||||||
elif [ `date +%H` -ge $wake_hour ]; then
|
|
||||||
logger "TIMERESTRICT: Activating awake time"
|
iptables -N TIMERESTRICT 2>/dev/null
|
||||||
iptables -C $myrule 2>/dev/null && iptables -D $myrule
|
iptables -F TIMERESTRICT 2>/dev/null
|
||||||
fi
|
for ip in $timerestricted_addresses; do
|
||||||
|
iptables -A TIMERESTRICT -s $ip -j TIMERESTRICT_LOGNDROP
|
||||||
## setup cron job to activate/deactivate on time of day
|
done
|
||||||
echo "00 $sleep_hour * * * `readlink -f $0`" > /etc/cron.d/iptables_timerestrict
|
|
||||||
echo "00 $wake_hour * * * `readlink -f $0`" >> /etc/cron.d/iptables_timerestrict
|
myrule="FORWARD -i br0 -j TIMERESTRICT"
|
||||||
## Format: <minute> <hour> <day> <month> <dow> <tags and command>
|
|
||||||
/etc/init.d/crond restart
|
## install or remove rule based on current time and whether the rule already exists
|
||||||
|
if [ $(date +%H) -ge $sleep_hour ]; then
|
||||||
echo "Done with firewall rule setup:"
|
logger "TIMERESTRICT: Activating sleep time"
|
||||||
echo "-------------------------------------------------------------------"
|
iptables -C $myrule 2>/dev/null || iptables -I $myrule
|
||||||
iptables -vL FORWARD | egrep '(Chain|pkts|TIMERESTRICT)'
|
elif [ $(date +%H) -ge $wake_hour ]; then
|
||||||
echo ...
|
logger "TIMERESTRICT: Activating awake time"
|
||||||
iptables -vL TIMERESTRICT
|
iptables -C $myrule 2>/dev/null && iptables -D $myrule
|
||||||
iptables -vL TIMERESTRICT_LOGNDROP
|
fi
|
||||||
echo
|
|
||||||
|
## setup cron job to activate/deactivate on time of day
|
||||||
|
echo "00 $sleep_hour * * * $(readlink -f $0)" >/etc/cron.d/iptables_timerestrict
|
||||||
|
echo "00 $wake_hour * * * $(readlink -f $0)" >>/etc/cron.d/iptables_timerestrict
|
||||||
|
## Format: <minute> <hour> <day> <month> <dow> <tags and command>
|
||||||
|
/etc/init.d/crond restart
|
||||||
|
|
||||||
|
echo "Done with firewall rule setup:"
|
||||||
|
echo "-------------------------------------------------------------------"
|
||||||
|
iptables -vL FORWARD | egrep '(Chain|pkts|TIMERESTRICT)'
|
||||||
|
echo ...
|
||||||
|
iptables -vL TIMERESTRICT
|
||||||
|
iptables -vL TIMERESTRICT_LOGNDROP
|
||||||
|
echo
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
# Get DataDir location
|
# Get DataDir location
|
||||||
DATA_DIR="/mnt/data"
|
DATA_DIR="/data"
|
||||||
case "$(ubnt-device-info firmware || true)" in
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
1*)
|
1*)
|
||||||
DATA_DIR="/mnt/data"
|
DATA_DIR="/mnt/data"
|
||||||
;;
|
;;
|
||||||
2*)
|
2*)
|
||||||
DATA_DIR="/data"
|
DATA_DIR="/data"
|
||||||
;;
|
;;
|
||||||
3*)
|
3*)
|
||||||
DATA_DIR="/data"
|
DATA_DIR="/data"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "ERROR: No persistent storage found." 1>&2
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# A change in the name udm-boot would need to be reflected as well in systemctl calls.
|
# A change in the name udm-boot would need to be reflected as well in systemctl calls.
|
||||||
SYSTEMCTL_PATH="/etc/systemd/system/udm-boot.service"
|
SYSTEMCTL_PATH="/etc/systemd/system/udm-boot.service"
|
||||||
@ -31,11 +31,10 @@ CNI_BRIDGE_ON_BOOT_FILENAME="$(basename "$CNI_BRIDGE_SCRIPT_RAW_URL")"
|
|||||||
GITHUB_API_URL="https://api.github.com/repos"
|
GITHUB_API_URL="https://api.github.com/repos"
|
||||||
GITHUB_REPOSITORY="unifi-utilities/unifios-utilities"
|
GITHUB_REPOSITORY="unifi-utilities/unifios-utilities"
|
||||||
|
|
||||||
|
|
||||||
# --- Functions ---
|
# --- Functions ---
|
||||||
|
|
||||||
header() {
|
header() {
|
||||||
cat << EOF
|
cat <<EOF
|
||||||
_ _ ___ __ __ ___ _
|
_ _ ___ __ __ ___ _
|
||||||
| | | | \| \/ | | _ ) ___ ___| |_
|
| | | | \| \/ | | _ ) ___ ___| |_
|
||||||
| |_| | |) | |\/| | | _ \/ _ \/ _ \ _|
|
| |_| | |) | |\/| | | _ \/ _ \/ _ \ _|
|
||||||
@ -57,29 +56,29 @@ depends_on() {
|
|||||||
|
|
||||||
udm_model() {
|
udm_model() {
|
||||||
case "$(ubnt-device-info model || true)" in
|
case "$(ubnt-device-info model || true)" in
|
||||||
"UniFi Dream Machine SE")
|
"UniFi Dream Machine SE")
|
||||||
echo "udmse"
|
echo "udmse"
|
||||||
;;
|
;;
|
||||||
"UniFi Dream Machine Pro")
|
"UniFi Dream Machine Pro")
|
||||||
if test $(ubnt-device-info firmware) \< "2.0.0"; then
|
if test $(ubnt-device-info firmware) \< "2.0.0"; then
|
||||||
echo "udmprolegacy"
|
echo "udmprolegacy"
|
||||||
else
|
else
|
||||||
echo "udmpro"
|
echo "udmpro"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
"UniFi Dream Machine")
|
"UniFi Dream Machine")
|
||||||
if test $(ubnt-device-info firmware) \< "2.0.0"; then
|
if test $(ubnt-device-info firmware) \< "2.0.0"; then
|
||||||
echo "udmlegacy"
|
echo "udmlegacy"
|
||||||
else
|
else
|
||||||
echo "udm"
|
echo "udm"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
"UniFi Dream Router")
|
"UniFi Dream Router")
|
||||||
echo "udr"
|
echo "udr"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "unknown"
|
echo "unknown"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +124,7 @@ install_on_boot_udm_series() {
|
|||||||
|
|
||||||
# Credits @peacey: https://github.com/unifi-utilities/unifios-utilities/issues/214#issuecomment-886869295
|
# Credits @peacey: https://github.com/unifi-utilities/unifios-utilities/issues/214#issuecomment-886869295
|
||||||
udmse_on_boot_systemd() {
|
udmse_on_boot_systemd() {
|
||||||
cat << EOF
|
cat <<EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Run On Startup UDM
|
Description=Run On Startup UDM
|
||||||
Wants=network-online.target
|
Wants=network-online.target
|
||||||
@ -133,7 +132,7 @@ After=network-online.target
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=forking
|
Type=forking
|
||||||
ExecStart=bash -c 'mkdir -p $DATA_DIR/on_boot.d && find -L $DATA_DIR/on_boot.d -mindepth 1 -maxdepth 1 -type f -print0 | sort -z | xargs -0 -r -n 1 -- bash -c \'if test -x "\$0"; then echo "%n: running \$0"; "\$0"; else case "\$0" in *.sh) echo "%n: sourcing \$0"; . "\$0";; *) echo "%n: ignoring \$0";; esac; fi\''
|
ExecStart=bash -c 'mkdir -p ${DATA_DIR}/on_boot.d && find -L ${DATA_DIR}/on_boot.d -mindepth 1 -maxdepth 1 -type f -print0 | sort -z | xargs -0 -r -n 1 -- bash -c \'if test -x "\$0"; then echo "%n: running \$0"; "\$0"; else case "\$0" in *.sh) echo "%n: sourcing \$0"; . "\$0";; *) echo "%n: ignoring \$0";; esac; fi\''
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
@ -147,7 +146,7 @@ install_on_boot_udr_se() {
|
|||||||
rm -f "$SYMLINK_SYSTEMCTL"
|
rm -f "$SYMLINK_SYSTEMCTL"
|
||||||
|
|
||||||
echo "Creating systemctl service file"
|
echo "Creating systemctl service file"
|
||||||
udmse_on_boot_systemd > "$SYSTEMCTL_PATH" || return 1
|
udmse_on_boot_systemd >"$SYSTEMCTL_PATH" || return 1
|
||||||
sleep 1s
|
sleep 1s
|
||||||
|
|
||||||
echo "Enabling UDM boot..."
|
echo "Enabling UDM boot..."
|
||||||
@ -165,43 +164,42 @@ header
|
|||||||
depends_on ubnt-device-info
|
depends_on ubnt-device-info
|
||||||
depends_on curl
|
depends_on curl
|
||||||
|
|
||||||
ON_BOOT_D_PATH="$DATA_DIR/on_boot.d"
|
ON_BOOT_D_PATH="${DATA_DIR}/on_boot.d"
|
||||||
|
|
||||||
case "$(udm_model)" in
|
case "$(udm_model)" in
|
||||||
udmlegacy|udmprolegacy)
|
udmlegacy | udmprolegacy)
|
||||||
echo "$(ubnt-device-info model) version $(ubnt-device-info firmware) was detected"
|
echo "$(ubnt-device-info model) version $(ubnt-device-info firmware) was detected"
|
||||||
echo "Installing on-boot script..."
|
echo "Installing on-boot script..."
|
||||||
depends_on podman
|
depends_on podman
|
||||||
|
|
||||||
if ! install_on_boot_udm_series; then
|
if ! install_on_boot_udm_series; then
|
||||||
echo
|
echo
|
||||||
echo "Failed to install on-boot script service" 1>&2
|
echo "Failed to install on-boot script service" 1>&2
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "UDM Boot Script installed"
|
|
||||||
;;
|
|
||||||
udr|udmse|udm|udmpro)
|
|
||||||
echo "$(ubnt-device-info model) version $(ubnt-device-info firmware) was detected"
|
|
||||||
echo "Installing on-boot script..."
|
|
||||||
depends_on systemctl
|
|
||||||
|
|
||||||
if ! install_on_boot_udr_se; then
|
|
||||||
echo
|
|
||||||
echo "Failed to install on-boot script service" 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "UDM Boot Script installed"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Unsupported model: $(ubnt-device-info model)" 1>&2
|
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
fi
|
||||||
|
|
||||||
|
echo "UDM Boot Script installed"
|
||||||
|
;;
|
||||||
|
udr | udmse | udm | udmpro)
|
||||||
|
echo "$(ubnt-device-info model) version $(ubnt-device-info firmware) was detected"
|
||||||
|
echo "Installing on-boot script..."
|
||||||
|
depends_on systemctl
|
||||||
|
|
||||||
|
if ! install_on_boot_udr_se; then
|
||||||
|
echo
|
||||||
|
echo "Failed to install on-boot script service" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "UDM Boot Script installed"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unsupported model: $(ubnt-device-info model)" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
echo
|
echo
|
||||||
|
|
||||||
|
|
||||||
if [ ! -f "${ON_BOOT_D_PATH}/${CNI_PLUGINS_ON_BOOT_FILENAME}" ]; then
|
if [ ! -f "${ON_BOOT_D_PATH}/${CNI_PLUGINS_ON_BOOT_FILENAME}" ]; then
|
||||||
echo "Downloading CNI plugins script..."
|
echo "Downloading CNI plugins script..."
|
||||||
if
|
if
|
||||||
@ -220,7 +218,6 @@ echo "Executing CNI plugins script..."
|
|||||||
"${ON_BOOT_D_PATH}/${CNI_PLUGINS_ON_BOOT_FILENAME}" || true
|
"${ON_BOOT_D_PATH}/${CNI_PLUGINS_ON_BOOT_FILENAME}" || true
|
||||||
echo
|
echo
|
||||||
|
|
||||||
|
|
||||||
if [ ! -f "${ON_BOOT_D_PATH}/${CNI_BRIDGE_ON_BOOT_FILENAME}" ]; then
|
if [ ! -f "${ON_BOOT_D_PATH}/${CNI_BRIDGE_ON_BOOT_FILENAME}" ]; then
|
||||||
echo "Downloading CNI bridge script..."
|
echo "Downloading CNI bridge script..."
|
||||||
if
|
if
|
||||||
|
@ -11,20 +11,20 @@ For example, [configuring two IP addresses on your WAN interface, so that you ca
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
1. [Enable on-boot-script](https://github.com/unifi-utilities/unifios-utilities/blob/main/on-boot-script/README.md)
|
1. [Enable on-boot-script](https://github.com/unifi-utilities/unifios-utilities/blob/main/on-boot-script/README.md)
|
||||||
1. Copy `42-watch-for-changes.sh` to `/mnt/data/on_boot.d/`
|
1. Copy `42-watch-for-changes.sh` to `/data/on_boot.d/`
|
||||||
* Check the `FILE` variable, it should point to a file that exists, it might be in `/data` or in `/mnt/data`
|
- Check the `FILE` variable, it should point to a file that exists, it might be in `/data` or in `/data`
|
||||||
1. Copy `on-state-change.sh` to `/mnt/data/scripts/`
|
1. Copy `on-state-change.sh` to `/data/scripts/`
|
||||||
1. Edit `/mnt/data/scripts/on-state-change.sh` to your heart's content
|
1. Edit `/data/scripts/on-state-change.sh` to your heart's content
|
||||||
|
|
||||||
> Make sure that your script doesn't error in the likely case that it tries to execute an update which has already been made
|
> Make sure that your script doesn't error in the likely case that it tries to execute an update which has already been made
|
||||||
|
|
||||||
## Example: configuring two IP addresses on your WAN interface
|
## Example: configuring two IP addresses on your WAN interface
|
||||||
|
|
||||||
`/mnt/data/scripts/on-state-change.sh`
|
`/data/scripts/on-state-change.sh`
|
||||||
|
|
||||||
```
|
```
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# give port9 this IP, allows access to router web interface
|
# give port9 this IP, allows access to router web interface
|
||||||
ip addr add 192.168.0.2/24 dev eth8 || true
|
ip addr add 192.168.0.2/24 dev eth8 || true
|
||||||
```
|
```
|
||||||
|
@ -1,41 +1,68 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
EXECUTE01='/mnt/data/scripts/on-state-change.sh'
|
# Check if the directory exists
|
||||||
FILE="/data/udapi-config/ubios-udapi-server/ubios-udapi-server.state"
|
if [ ! -d "${DATA_DIR}/scripts" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "${DATA_DIR}/scripts"
|
||||||
|
echo "Directory '${DATA_DIR}/scripts' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '${DATA_DIR}/scripts' already exists. Moving on."
|
||||||
|
fi
|
||||||
|
|
||||||
|
EXECUTE01="${DATA_DIR}/scripts/on-state-change.sh"
|
||||||
|
FILE="${DATA_DIR}/udapi-config/ubios-udapi-server/ubios-udapi-server.state"
|
||||||
# /usr/bin/logger -t "${PROCESSNAME}" "$*"
|
# /usr/bin/logger -t "${PROCESSNAME}" "$*"
|
||||||
|
|
||||||
# run on boot aswell
|
# run on boot aswell
|
||||||
$EXECUTE01
|
$EXECUTE01
|
||||||
|
|
||||||
if [ "$1" = "DAEMON" ]; then
|
if [ "$1" = "DAEMON" ]; then
|
||||||
# is this necessary? Add other signals at will (TTIN TTOU INT STOP TSTP)
|
# is this necessary? Add other signals at will (TTIN TTOU INT STOP TSTP)
|
||||||
trap '' INT
|
trap '' INT
|
||||||
cd /tmp
|
cd /tmp || exit
|
||||||
shift
|
shift
|
||||||
### daemonized section ######
|
### daemonized section ######
|
||||||
# RUNNING=`ps aux | grep $CMD | grep -v grep | wc -l`
|
# RUNNING=`ps aux | grep $CMD | grep -v grep | wc -l`
|
||||||
# echo $RUNNING
|
# echo $RUNNING
|
||||||
# if [ "$RUNNING" -lt 1 ]; then
|
# if [ "$RUNNING" -lt 1 ]; then
|
||||||
LAST=`ls -l "$FILE"`
|
LAST=$(ls -l "$FILE")
|
||||||
# echo $LAST
|
# echo $LAST
|
||||||
while true; do
|
while true; do
|
||||||
sleep 1
|
sleep 1
|
||||||
NEW=`ls -l "$FILE"`
|
NEW=$(ls -l "$FILE")
|
||||||
# echo $NEW
|
# echo $NEW
|
||||||
if [ "$NEW" != "$LAST" ]; then
|
if [ "$NEW" != "$LAST" ]; then
|
||||||
DATE=`date`
|
DATE=$(date)
|
||||||
echo "${DATE}: Executing ${EXECUTE01}"
|
echo "${DATE}: Executing ${EXECUTE01}"
|
||||||
$EXECUTE01
|
$EXECUTE01
|
||||||
LAST="$NEW"
|
LAST="$NEW"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
# fi
|
# fi
|
||||||
#### end of daemonized section ####
|
#### end of daemonized section ####
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin
|
export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin
|
||||||
umask 022
|
umask 022
|
||||||
# You can add nice and ionice before nohup but they might not be installed
|
# You can add nice and ionice before nohup but they might not be installed
|
||||||
# nohup setsid $0 DAEMON $* 2>/var/log/mydaemon.err >/var/log/mydaemon.log &
|
# nohup setsid $0 DAEMON $* 2>/var/log/mydaemon.err >/var/log/mydaemon.log &
|
||||||
nohup setsid $0 DAEMON WATCH $* 2>/var/log/watch.err >/var/log/watch.log &
|
nohup setsid $0 DAEMON WATCH $* 2>/var/log/watch.err >/var/log/watch.log &
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
# update and reinstall podman each day
|
# update and reinstall podman each day
|
||||||
#00 00 * * * root sh -c '/data/on_boot.d/00-podman.sh --download-only && /data/on_boot.d/00-podman.sh --force'
|
#00 00 * * * root sh -c '/data/on_boot.d/00-podman.sh --download-only && /data/on_boot.d/00-podman.sh --force'
|
||||||
|
|
||||||
|
@ -7,61 +7,58 @@ fi
|
|||||||
|
|
||||||
udm_model() {
|
udm_model() {
|
||||||
case "$(ubnt-device-info model || true)" in
|
case "$(ubnt-device-info model || true)" in
|
||||||
"UniFi Dream Machine SE")
|
"UniFi Dream Machine SE")
|
||||||
echo "udmse"
|
echo "udmse"
|
||||||
;;
|
;;
|
||||||
"UniFi Dream Machine Pro")
|
"UniFi Dream Machine Pro")
|
||||||
echo "udmpro"
|
echo "udmpro"
|
||||||
;;
|
;;
|
||||||
"UniFi Dream Machine")
|
"UniFi Dream Machine")
|
||||||
echo "udm"
|
echo "udm"
|
||||||
;;
|
;;
|
||||||
"UniFi Dream Router")
|
"UniFi Dream Router")
|
||||||
echo "udr"
|
echo "udr"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "unknown"
|
echo "unknown"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DESIRED_ZIPFILE='udmse-podman-install.zip'
|
DESIRED_ZIPFILE='udmse-podman-install.zip'
|
||||||
case "$(udm_model)" in
|
case "$(udm_model)" in
|
||||||
udmse|udmpro)
|
udmse | udmpro)
|
||||||
DESIRED_ZIPFILE="$(udm_model)-podman-install.zip"
|
DESIRED_ZIPFILE="$(udm_model)-podman-install.zip"
|
||||||
;;
|
;;
|
||||||
udm)
|
udm)
|
||||||
# base UDM works fine with udmpro podman version, but has issues with udmse variant
|
# base UDM works fine with udmpro podman version, but has issues with udmse variant
|
||||||
DESIRED_ZIPFILE="udmpro-podman-install.zip"
|
DESIRED_ZIPFILE="udmpro-podman-install.zip"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# shrug
|
# shrug
|
||||||
# udmse-podman-install.zip seems to work fine on UDM 2.4.x
|
# udmse-podman-install.zip seems to work fine on UDM 2.4.x
|
||||||
true
|
true
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|
||||||
# Get DataDir location
|
# Get DataDir location
|
||||||
DATA_DIR="/mnt/data"
|
DATA_DIR="/data"
|
||||||
case "$(ubnt-device-info firmware || true)" in
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
1*)
|
1*)
|
||||||
DATA_DIR="/mnt/data"
|
DATA_DIR="/mnt/data"
|
||||||
;;
|
;;
|
||||||
2*)
|
2*)
|
||||||
DATA_DIR="/data"
|
DATA_DIR="/data"
|
||||||
;;
|
;;
|
||||||
3*)
|
3*)
|
||||||
DATA_DIR="/data"
|
DATA_DIR="/data"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "ERROR: No persistent storage found." 1>&2
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|
||||||
CACHE_DIR="${DATA_DIR}/podman/cache"
|
CACHE_DIR="${DATA_DIR}/podman/cache"
|
||||||
INSTALL_ROOT="${DATA_DIR}/podman/install"
|
INSTALL_ROOT="${DATA_DIR}/podman/install"
|
||||||
CONF_DIR="${DATA_DIR}/podman/conf"
|
CONF_DIR="${DATA_DIR}/podman/conf"
|
||||||
@ -71,9 +68,9 @@ mkdir -p "${CACHE_DIR}" "${INSTALL_ROOT}" "${CONF_DIR}"
|
|||||||
URL="https://unifi.boostchicken.io/${DESIRED_ZIPFILE}"
|
URL="https://unifi.boostchicken.io/${DESIRED_ZIPFILE}"
|
||||||
|
|
||||||
if [ "$1" = '--download-only' ]; then
|
if [ "$1" = '--download-only' ]; then
|
||||||
echo "downloading ${URL}" \
|
echo "downloading ${URL}" &&
|
||||||
&& curl -Lsfo "${CACHE_DIR}/${DESIRED_ZIPFILE}" "${URL}" \
|
curl -Lsfo "${CACHE_DIR}/${DESIRED_ZIPFILE}" "${URL}" &&
|
||||||
&& echo "downloaded ${URL}"
|
echo "downloaded ${URL}"
|
||||||
exit $?
|
exit $?
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -88,8 +85,8 @@ fi
|
|||||||
|
|
||||||
if [ -f "${CACHE_DIR}/${DESIRED_ZIPFILE}" ]; then
|
if [ -f "${CACHE_DIR}/${DESIRED_ZIPFILE}" ]; then
|
||||||
echo "(using cache at ${CACHE_DIR}/${DESIRED_ZIPFILE})"
|
echo "(using cache at ${CACHE_DIR}/${DESIRED_ZIPFILE})"
|
||||||
elif echo "downloading ${URL}" \
|
elif echo "downloading ${URL}" &&
|
||||||
&& curl -Lsfo "${CACHE_DIR}/${DESIRED_ZIPFILE}" "${URL}"; then
|
curl -Lsfo "${CACHE_DIR}/${DESIRED_ZIPFILE}" "${URL}"; then
|
||||||
echo "downloaded ${URL}"
|
echo "downloaded ${URL}"
|
||||||
else
|
else
|
||||||
echo 'download failed'
|
echo 'download failed'
|
||||||
@ -119,4 +116,3 @@ fi
|
|||||||
|
|
||||||
echo 'Something went wrong'
|
echo 'Something went wrong'
|
||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
|
@ -1,13 +1,39 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
mkdir -p /mnt/data/.cache
|
# Check if the directory exists
|
||||||
|
if [ ! -d "${DATA_DIR}/scripts" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "${DATA_DIR}/scripts"
|
||||||
|
echo "Directory '${DATA_DIR}/scripts' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '${DATA_DIR}/scripts' already exists. Moving on."
|
||||||
|
fi
|
||||||
|
mkdir -p ${DATA_DIR}/.cache
|
||||||
|
|
||||||
PODMAN_VERSION=3.3.0
|
PODMAN_VERSION=3.3.0
|
||||||
RUNC_VERSION=1.0.2
|
RUNC_VERSION=1.0.2
|
||||||
CONMON_VERSION=2.0.29
|
CONMON_VERSION=2.0.29
|
||||||
PODMAN_DL=/mnt/data/.cache/podman-$PODMAN_VERSION
|
PODMAN_DL=${DATA_DIR}/.cache/podman-$PODMAN_VERSION
|
||||||
RUNC_DL=/mnt/data/.cache/runc-$RUNC_VERSION
|
RUNC_DL=${DATA_DIR}/.cache/runc-$RUNC_VERSION
|
||||||
CONMON_DL=/mnt/data/.cache/conmon-$CONMON_VERSION
|
CONMON_DL=${DATA_DIR}/.cache/conmon-$CONMON_VERSION
|
||||||
SECCOMP=/usr/share/containers/seccomp.json
|
SECCOMP=/usr/share/containers/seccomp.json
|
||||||
|
|
||||||
while [ ! -f $CONMON_DL ]; do
|
while [ ! -f $CONMON_DL ]; do
|
||||||
@ -46,4 +72,3 @@ sed -i 's/driver = ""/driver = "overlay"/' /etc/containers/storage.conf
|
|||||||
sed -i 's/ostree_repo = ""/#ostree_repo = ""/' /etc/containers/storage.conf
|
sed -i 's/ostree_repo = ""/#ostree_repo = ""/' /etc/containers/storage.conf
|
||||||
# Comment out if you don't want to enable docker-compose or remote docker admin
|
# Comment out if you don't want to enable docker-compose or remote docker admin
|
||||||
/usr/bin/podman system service --time=0 tcp:0.0.0.0:2375 &
|
/usr/bin/podman system service --time=0 tcp:0.0.0.0:2375 &
|
||||||
|
|
||||||
|
@ -1,21 +1,48 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
CONTAINER=rclone
|
CONTAINER=rclone
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check if the directory exists
|
||||||
|
if [ ! -d "${DATA_DIR}/backups" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "${DATA_DIR}/backups"
|
||||||
|
echo "Directory '${DATA_DIR}/backups' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '${DATA_DIR}/backups' already exists. Moving on."
|
||||||
|
fi
|
||||||
|
|
||||||
if podman container exists "$CONTAINER"; then
|
if podman container exists "$CONTAINER"; then
|
||||||
podman start "$CONTAINER"
|
podman start "$CONTAINER"
|
||||||
else
|
else
|
||||||
podman run -i -d --rm \
|
podman run -i -d --rm \
|
||||||
--net=host \
|
--net=host \
|
||||||
-v /mnt/data/rclone:/data/backups/rclone \
|
-v ${DATA_DIR}/rclone:${DATA_DIR}/backups/rclone \
|
||||||
-v /mnt/data/pihole:/data/backups/pihole \
|
-v ${DATA_DIR}/pihole:${DATA_DIR}/backups/pihole \
|
||||||
-v /mnt/data/on_boot.d:/data/backups/on_boot.d \
|
-v ${DATA_DIR}/on_boot.d:${DATA_DIR}/backups/on_boot.d \
|
||||||
-v /data/unifi/data/backup/autobackup:/data/backups//data/unifi/data/backup/autobackup \
|
-v ${DATA_DIR}/unifi/data/backup/autobackup:${DATA_DIR}/backup/unifi/autobackup \
|
||||||
-v /mnt/data/podman/cni:/data/backups/podman/cni \
|
-v ${DATA_DIR}/podman/cni:${DATA_DIR}/backups/podman/cni \
|
||||||
-v /mnt/data/rclone:/config/rclone \
|
-v ${DATA_DIR}/rclone:/config/rclone \
|
||||||
-v /mnt/data/rclone/sync.sh:/data/sync.sh \
|
-v ${DATA_DIR}/rclone/sync.sh:${DATA_DIR}/sync.sh \
|
||||||
--name "$CONTAINER" \
|
--name "$CONTAINER" \
|
||||||
--security-opt=no-new-privileges \
|
--security-opt=no-new-privileges \
|
||||||
rclone/rclone:latest \
|
rclone/rclone:latest \
|
||||||
rcd --rc-web-gui --rc-addr :5572 \
|
rcd --rc-web-gui --rc-addr :5572 \
|
||||||
--rc-user rclone --rc-pass randompassword12345
|
--rc-user rclone --rc-pass randompassword12345
|
||||||
fi
|
fi
|
||||||
|
@ -12,22 +12,22 @@
|
|||||||
|
|
||||||
1. Make a directory for your configuration
|
1. Make a directory for your configuration
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mkdir -p /mnt/data/rclone
|
mkdir -p /data/rclone
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Create [rclone.conf](https://rclone.org/commands/rclone_config/) in `/mnt/data/rclone` and update it to meet yours needs.
|
2. Create [rclone.conf](https://rclone.org/commands/rclone_config/) in `/data/rclone` and update it to meet yours needs.
|
||||||
3. Copy [sync.sh](sync.sh) in `/mnt/data/rclone` and update it to meet your needs.
|
3. Copy [sync.sh](sync.sh) in `/data/rclone` and update it to meet your needs.
|
||||||
4. Copy [10-rclone.sh](10-rclone.sh) to `/mnt/data/on_boot.d` and update it to meet your needs.
|
4. Copy [10-rclone.sh](10-rclone.sh) to `/data/on_boot.d` and update it to meet your needs.
|
||||||
5. Execute `/mnt/data/on_boot.d/10-rclone.sh`
|
5. Execute `/data/on_boot.d/10-rclone.sh`
|
||||||
6. Execute `podman logs rclone`, this will provide a link to the Web GUI.
|
6. Execute `podman logs rclone`, this will provide a link to the Web GUI.
|
||||||
7. Copy [rclone](rclone) in `/etc/cron.hourly/`.
|
7. Copy [rclone](rclone) in `/etc/cron.hourly/`.
|
||||||
8. Set permissions to executable `chmod +x /etc/cron.hourly/rclone`.
|
8. Set permissions to executable `chmod +x /etc/cron.hourly/rclone`.
|
||||||
|
|
||||||
## Customization
|
## Customization
|
||||||
|
|
||||||
1. Login to run rclone commands locally to create and test configs
|
1. Login to run rclone commands locally to create and test configs
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
podman exec -ti rclone /bin/sh
|
podman exec -ti rclone /bin/sh
|
||||||
```
|
```
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
ARCH=$(uname -m)
|
ARCH=$(uname -m)
|
||||||
if [ $ARCH == "x86_64" ]
|
if [ "$ARCH" == "x86_64" ]; then
|
||||||
then
|
|
||||||
ARCH="amd64"
|
ARCH="amd64"
|
||||||
elif [ $ARCH == "aarch64" ]; then
|
elif [ "$ARCH" == "aarch64" ]; then
|
||||||
ARCH="arm64"
|
ARCH="arm64"
|
||||||
fi
|
fi
|
||||||
curl -fsSLo "/opt/cloudflared" https://github.com/cloudflare/cloudflared/releases/download/2021.5.9/cloudflared-linux-$ARCH
|
curl -fsSLo "/opt/cloudflared" https://github.com/cloudflare/cloudflared/releases/download/2021.5.9/cloudflared-linux-"$ARCH"
|
||||||
chmod +x /opt/cloudflared
|
chmod +x /opt/cloudflared
|
||||||
|
|
||||||
/opt/cloudflared update
|
/opt/cloudflared update
|
||||||
/opt/cloudflared proxy-dns $CLOUDFLARED_OPTS &
|
/opt/cloudflared proxy-dns "$CLOUDFLARED_OPTS" &
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
1. Run Pi-hole on your UDM with a completely isolated network stack. This will not port conflict or be influenced by any changes on by Ubiquiti
|
1. Run Pi-hole on your UDM with a completely isolated network stack. This will not port conflict or be influenced by any changes on by Ubiquiti
|
||||||
2. Persists through reboots and firmware updates.
|
2. Persists through reboots and firmware updates.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
@ -13,108 +13,103 @@
|
|||||||
|
|
||||||
Note: IP and VLAN settings for you pihole network, 20-dns-conflist and 10-dns.sh MUST all match each other.
|
Note: IP and VLAN settings for you pihole network, 20-dns-conflist and 10-dns.sh MUST all match each other.
|
||||||
|
|
||||||
* Example settings for pihole network:
|
- Example settings for pihole network:
|
||||||
Network Name: Pihole
|
Network Name: Pihole
|
||||||
Host address: 10.0.5.1
|
Host address: 10.0.5.1
|
||||||
Netmask: 24
|
Netmask: 24
|
||||||
VLAN ID: 5
|
VLAN ID: 5
|
||||||
Network Type: Standard
|
Network Type: Standard
|
||||||
Multicast DNS: Enable
|
Multicast DNS: Enable
|
||||||
DHCP: None
|
DHCP: None
|
||||||
Ipv6 Interface Type: None
|
Ipv6 Interface Type: None
|
||||||
|
|
||||||
|
- YOU WILL NEED TO CHANGE [`20-dns.conflist`](../cni-plugins/20-dns.conflist)
|
||||||
* YOU WILL NEED TO CHANGE [`20-dns.conflist`](../cni-plugins/20-dns.conflist)
|
|
||||||
Change the line:
|
Change the line:
|
||||||
"mac": "add 3 fake hex portions, replacing x's here 00:1c:b4:xx:xx:xx",
|
"mac": "add 3 fake hex portions, replacing x's here 00:1c:b4:xx:xx:xx",
|
||||||
to create a legitimate mac address that matches some vendor space(first 6 digits ). It needs to be unique on your network.
|
to create a legitimate mac address that matches some vendor space(first 6 digits ). It needs to be unique on your network.
|
||||||
The example gives one option. Locally administered mac addresses do not work.
|
The example gives one option. Locally administered mac addresses do not work.
|
||||||
|
|
||||||
If you are using a different IP address than the example:
|
If you are using a different IP address than the example:
|
||||||
Change these lines to match your settings:
|
Change these lines to match your settings:
|
||||||
"address": "10.0.5.3/24",
|
"address": "10.0.5.3/24",
|
||||||
"gateway": "10.0.5.1"
|
"gateway": "10.0.5.1"
|
||||||
|
|
||||||
If you are using a different VLAN than the example:
|
If you are using a different VLAN than the example:
|
||||||
Change this line to match your VLAN number:
|
Change this line to match your VLAN number:
|
||||||
"master": "br5",
|
"master": "br5",
|
||||||
|
|
||||||
* You MAY need to change[`10-dns.sh`](../dns-common/on_boot.d/10-dns.sh).
|
- You MAY need to change[`10-dns.sh`](../dns-common/on_boot.d/10-dns.sh).
|
||||||
If you are using a different IP address than the example:
|
If you are using a different IP address than the example:
|
||||||
Change these lines to match your settings:
|
Change these lines to match your settings:
|
||||||
IPV4_IP="10.0.5.3"
|
IPV4_IP="10.0.5.3"
|
||||||
IPV4_GW="10.0.5.1/24"
|
IPV4_GW="10.0.5.1/24"
|
||||||
|
|
||||||
If you are using a different VLAN than the example:
|
If you are using a different VLAN than the example:
|
||||||
Change this line to match your VLAN number:
|
Change this line to match your VLAN number:
|
||||||
VLAN=5
|
VLAN=5
|
||||||
|
|
||||||
If you want the pihole container to have a different name than the example:
|
If you want the pihole container to have a different name than the example:
|
||||||
Change this line to match the different name:
|
Change this line to match the different name:
|
||||||
CONTAINER=pihole
|
CONTAINER=pihole
|
||||||
|
- If you want IPv6 support
|
||||||
* If you want IPv6 support
|
|
||||||
Use 20-dnsipv6.conflist and update 10-dns.sh with the IPv6 addresses.
|
Use 20-dnsipv6.conflist and update 10-dns.sh with the IPv6 addresses.
|
||||||
Also, please provide IPv6 servers to podman using --dns arguments.
|
Also, please provide IPv6 servers to podman using --dns arguments.
|
||||||
|
|
||||||
## Steps
|
## Steps
|
||||||
|
|
||||||
### Configuration files and scripts
|
### Configuration files and scripts
|
||||||
|
|
||||||
1.0 Copy [`05-install-cni-plugins.sh`](../cni-plugins/05-install-cni-plugins.sh) to `/mnt/data/on_boot.d`
|
1.0 Copy [`05-install-cni-plugins.sh`](../cni-plugins/05-install-cni-plugins.sh) to `/data/on_boot.d`
|
||||||
1.1 Execute `chmod +x /mnt/data/on_boot.d/05-install-cni-plugins.sh`
|
1.1 Execute `chmod +x /data/on_boot.d/05-install-cni-plugins.sh`
|
||||||
1.2 Execute `/mnt/data/on_boot.d/05-install-cni-plugins.sh`
|
1.2 Execute `/data/on_boot.d/05-install-cni-plugins.sh`
|
||||||
|
|
||||||
2.0 On your controller, create a network with no DHCP server and give it a VLAN.(see example settings above).
|
2.0 On your controller, create a network with no DHCP server and give it a VLAN.(see example settings above).
|
||||||
2.1 Copy YOUR modified [`20-dns.conflist`] to `/mnt/data/podman/cni`
|
2.1 Copy YOUR modified [`20-dns.conflist`] to `/data/podman/cni`
|
||||||
2.2 Execute `chmod +x /mnt/data/podman/cni/20-dns.conflist`
|
2.2 Execute `chmod +x /data/podman/cni/20-dns.conflist`
|
||||||
2.3 Execute `cp /mnt/data/podman/cni/20-dns.conflist /etc/cni/net.d/dns.conflist`
|
2.3 Execute `cp /data/podman/cni/20-dns.conflist /etc/cni/net.d/dns.conflist`
|
||||||
|
|
||||||
To check progress - run the command:
|
To check progress - run the command:
|
||||||
```shell
|
```shell
|
||||||
podman network inspect dns
|
podman network inspect dns
|
||||||
```
|
```
|
||||||
You should see a copy of your 20-dns.conflist displayed.
|
You should see a copy of your 20-dns.conflist displayed.
|
||||||
|
|
||||||
3.0 Copy your [`10-dns.sh`] to `/mnt/data/on_boot.d`
|
|
||||||
3.1 Execute `chmod +x /mnt/data/on_boot.d/10-dns.sh`
|
|
||||||
3.2 Execute `/mnt/data/on_boot.d/10-dns.sh`
|
|
||||||
|
|
||||||
|
3.0 Copy your [`10-dns.sh`] to `/data/on_boot.d`
|
||||||
|
3.1 Execute `chmod +x /data/on_boot.d/10-dns.sh`
|
||||||
|
3.2 Execute `/data/on_boot.d/10-dns.sh`
|
||||||
|
|
||||||
### Create directories for persistent Pi-hole configuration
|
### Create directories for persistent Pi-hole configuration
|
||||||
|
|
||||||
4.0 Execute the following commands:
|
4.0 Execute the following commands:
|
||||||
```sh
|
|
||||||
mkdir -p /mnt/data/etc-pihole
|
```sh
|
||||||
mkdir -p /mnt/data/pihole/etc-dnsmasq.d
|
mkdir -p /data/etc-pihole
|
||||||
```
|
mkdir -p /data/pihole/etc-dnsmasq.d
|
||||||
|
```
|
||||||
|
|
||||||
### Create the pihole container
|
### Create the pihole container
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
--name MUST match the name you set in 10-dns.sh
|
--name MUST match the name you set in 10-dns.sh
|
||||||
-e FTLCONF_REPLY_ADDR4 MUST be in the range you set for your pihole network
|
-e FTLCONF_REPLY_ADDR4 MUST be in the range you set for your pihole network
|
||||||
-e TZ MUST match the timezone for your controller
|
-e TZ MUST match the timezone for your controller
|
||||||
|
|
||||||
The example uses these upstream DNS servers The following command sets the upstream DNS servers to `1.1.1.1` ([Cloudflare DNS](https://1.1.1.1/)) and `8.8.8.8` ([Google DNS](https://developers.google.com/speed/public-dns/)).
|
The example uses these upstream DNS servers The following command sets the upstream DNS servers to `1.1.1.1` ([Cloudflare DNS](https://1.1.1.1/)) and `8.8.8.8` ([Google DNS](https://developers.google.com/speed/public-dns/)).
|
||||||
If you want to use different upstream DNS servers, change the following lines:
|
If you want to use different upstream DNS servers, change the following lines:
|
||||||
--dns=1.1.1.1 \
|
--dns=1.1.1.1 \
|
||||||
--dns=8.8.8.8 \
|
--dns=8.8.8.8 \
|
||||||
|
|
||||||
If you want to run a DHCP server as well you need to add the following lines:
|
If you want to run a DHCP server as well you need to add the following lines:
|
||||||
--cap-add=NET_ADMIN
|
--cap-add=NET_ADMIN
|
||||||
|
|
||||||
5.0 Run the following (or your modified version) by copy / pasting the entire set.
|
5.0 Run the following (or your modified version) by copy / pasting the entire set.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
podman run -d \
|
podman run -d \
|
||||||
--network dns \
|
--network dns \
|
||||||
--restart always \
|
--restart always \
|
||||||
--name pihole \
|
--name pihole \
|
||||||
-e TZ="America/Los Angeles" \
|
-e TZ="America/Los Angeles" \
|
||||||
--cap-add=NET_ADMIN \
|
--cap-add=NET_ADMIN \
|
||||||
-v "/mnt/data/etc-pihole/:/etc/pihole/" \
|
-v "/data/etc-pihole/:/etc/pihole/" \
|
||||||
-v "/mnt/data/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/" \
|
-v "/data/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/" \
|
||||||
--dns=127.0.0.1 \
|
--dns=127.0.0.1 \
|
||||||
--dns=1.1.1.1 \
|
--dns=1.1.1.1 \
|
||||||
--dns=8.8.8.8 \
|
--dns=8.8.8.8 \
|
||||||
@ -125,19 +120,20 @@ If you want to run a DHCP server as well you need to add the following lines:
|
|||||||
-e IPv6="False" \
|
-e IPv6="False" \
|
||||||
pihole/pihole:latest
|
pihole/pihole:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
The below errors are expected and acceptable:
|
The below errors are expected and acceptable:
|
||||||
|
|
||||||
> ```
|
> ```
|
||||||
> ERRO[0022] unable to get systemd connection to add healthchecks: dial unix /run/systemd/private: connect: no such file or directory
|
> ERRO[0022] unable to get systemd connection to add healthchecks: dial unix /run/systemd/private: connect: no such file or directory
|
||||||
> ERRO[0022] unable to get systemd connection to start healthchecks: dial unix /run/systemd/private: connect: no such file or directory
|
> ERRO[0022] unable to get systemd connection to start healthchecks: dial unix /run/systemd/private: connect: no such file or directory
|
||||||
> ```
|
> ```
|
||||||
|
|
||||||
6.0 Set the pihole admin password
|
6.0 Set the pihole admin password
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
podman exec -it pihole pihole -a -p YOURNEWPASSHERE
|
podman exec -it pihole pihole -a -p YOURNEWPASSHERE
|
||||||
```
|
```
|
||||||
|
|
||||||
## Set the new DNS in your UDM
|
## Set the new DNS in your UDM
|
||||||
|
|
||||||
7.0 Update your DNS Servers to `10.0.5.3` (or your custom ip) for each of your Networks (UDM GUI | Networks | Advanced | DHCP Name Server)
|
7.0 Update your DNS Servers to `10.0.5.3` (or your custom ip) for each of your Networks (UDM GUI | Networks | Advanced | DHCP Name Server)
|
||||||
@ -145,27 +141,27 @@ If you want to run a DHCP server as well you need to add the following lines:
|
|||||||
|
|
||||||
## Upgrading your PiHole container
|
## Upgrading your PiHole container
|
||||||
|
|
||||||
1. Edit `upd_pihole.sh` script to use the same `podman run` command you used at installation.
|
1. Edit `upd_pihole.sh` script to use the same `podman run` command you used at installation.
|
||||||
2. Copy the `upd_pihole.sh` script to /mnt/data/scripts
|
2. Copy the `upd_pihole.sh` script to /data/scripts
|
||||||
3. Anytime you want to update your pihole installation, simply run `/mnt/data/scripts/upd_pihole.sh`
|
3. Anytime you want to update your pihole installation, simply run `/data/scripts/upd_pihole.sh`
|
||||||
|
|
||||||
## Optional Builds
|
## Optional Builds
|
||||||
|
|
||||||
The cloudflared command is written in Go and is not very lightweight. In my
|
The cloudflared command is written in Go and is not very lightweight. In my
|
||||||
experience, it's not made for long-term running. Instead, the project DoTe
|
experience, it's not made for long-term running. Instead, the project DoTe
|
||||||
has a tiny memory footprint and operates on an event loop with some major
|
has a tiny memory footprint and operates on an event loop with some major
|
||||||
optimisations for connection caching. It allows you to forward traffic to any
|
optimisations for connection caching. It allows you to forward traffic to any
|
||||||
DNS-over-TLS provider.
|
DNS-over-TLS provider.
|
||||||
|
|
||||||
### PiHole with CloudFlareD Command
|
### PiHole with CloudFlareD Command
|
||||||
|
|
||||||
podman run -d \
|
podman run -d \
|
||||||
--network dns
|
--network dns
|
||||||
--restart always \
|
--restart always \
|
||||||
--name pihole \
|
--name pihole \
|
||||||
-e TZ="America/Los Angeles" \
|
-e TZ="America/Los Angeles" \
|
||||||
-v "/mnt/data/etc-pihole/:/etc/pihole/" \
|
-v "/data/etc-pihole/:/etc/pihole/" \
|
||||||
-v "/mnt/data/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/" \
|
-v "/data/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/" \
|
||||||
--dns=127.0.0.1 \
|
--dns=127.0.0.1 \
|
||||||
--dns=1.1.1.1 \
|
--dns=1.1.1.1 \
|
||||||
--hostname pi.hole \
|
--hostname pi.hole \
|
||||||
@ -179,8 +175,8 @@ DNS-over-TLS provider.
|
|||||||
|
|
||||||
### PiHole with DoTe
|
### PiHole with DoTe
|
||||||
|
|
||||||
Simply copy the `custom_pihole_dote.sh` script to `/mnt/data/scripts` and run it
|
Simply copy the `custom_pihole_dote.sh` script to `/data/scripts` and run it
|
||||||
to forward all DNS traffic over TLS to Cloudflare 1.1.1.1 / 1.0.0.1. You can modify the
|
to forward all DNS traffic over TLS to Cloudflare 1.1.1.1 / 1.0.0.1. You can modify the
|
||||||
script to forward to different services with ease and full configuration
|
script to forward to different services with ease and full configuration
|
||||||
options including certificate pinning is available in the DoTe README here:
|
options including certificate pinning is available in the DoTe README here:
|
||||||
https://github.com/chrisstaite/DoTe/
|
https://github.com/chrisstaite/DoTe/
|
||||||
@ -190,8 +186,8 @@ https://github.com/chrisstaite/DoTe/
|
|||||||
--restart always \
|
--restart always \
|
||||||
--name pihole \
|
--name pihole \
|
||||||
-e TZ="America/Los Angeles" \
|
-e TZ="America/Los Angeles" \
|
||||||
-v "/mnt/data/etc-pihole/:/etc/pihole/" \
|
-v "/data/etc-pihole/:/etc/pihole/" \
|
||||||
-v "/mnt/data/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/" \
|
-v "/data/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/" \
|
||||||
--dns=127.0.0.1 \
|
--dns=127.0.0.1 \
|
||||||
--dns=1.1.1.1 \
|
--dns=1.1.1.1 \
|
||||||
--hostname pi.hole \
|
--hostname pi.hole \
|
||||||
@ -202,6 +198,6 @@ https://github.com/chrisstaite/DoTe/
|
|||||||
-e PIHOLE_DNS_="127.0.0.1#5053" \
|
-e PIHOLE_DNS_="127.0.0.1#5053" \
|
||||||
-e IPv6="False" \
|
-e IPv6="False" \
|
||||||
boostchicken/pihole-dote:latest
|
boostchicken/pihole-dote:latest
|
||||||
|
|
||||||
|
|
||||||
## New releases will be made when PiHole updates their labels
|
|
||||||
|
## New releases will be made when PiHole updates their labels
|
||||||
|
@ -1,11 +1,38 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check if the directory exists
|
||||||
|
if [ ! -d "${DATA_DIR}/pihole" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "${DATA_DIR}/pihole"
|
||||||
|
mkdir -p "${DATA_DIR}/pihole/etc"
|
||||||
|
echo "Directory '${DATA_DIR}/pihole' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '${DATA_DIR}/pihole' already exists. Moving on."
|
||||||
|
fi
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
tmpdir="$(mktemp -d)"
|
tmpdir="$(mktemp -d)"
|
||||||
curl -sSLo "${tmpdir}/dote" https://github.com/chrisstaite/DoTe/releases/latest/download/dote_arm64
|
curl -sSLo "${tmpdir}/dote" https://github.com/chrisstaite/DoTe/releases/latest/download/dote_arm64
|
||||||
|
|
||||||
cat > "${tmpdir}/Dockerfile" <<EOF
|
cat >"${tmpdir}/Dockerfile" <<EOF
|
||||||
FROM pihole/pihole:latest
|
FROM pihole/pihole:latest
|
||||||
ENV DOTE_OPTS="-s 127.0.0.1:5053"
|
ENV DOTE_OPTS="-s 127.0.0.1:5053"
|
||||||
COPY dote /opt/dote
|
COPY dote /opt/dote
|
||||||
@ -23,8 +50,8 @@ podman rm pihole
|
|||||||
podman run -d --network dns --restart always \
|
podman run -d --network dns --restart always \
|
||||||
--name pihole \
|
--name pihole \
|
||||||
-e TZ="America/Chicago" \
|
-e TZ="America/Chicago" \
|
||||||
-v "/mnt/data/etc-pihole/:/etc/pihole/" \
|
-v "${DATA_DIR}/etc-pihole/:/etc/pihole/" \
|
||||||
-v "/mnt/data/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/" \
|
-v "${DATA_DIR}/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/" \
|
||||||
--dns=127.0.0.1 \
|
--dns=127.0.0.1 \
|
||||||
--hostname pi.hole \
|
--hostname pi.hole \
|
||||||
-e DOTE_OPTS="-s 127.0.0.1:5053 -f 1.1.1.1 -f 1.0.0.1 -m 10" \
|
-e DOTE_OPTS="-s 127.0.0.1:5053 -f 1.1.1.1 -f 1.0.0.1 -m 10" \
|
||||||
|
@ -1,16 +1,42 @@
|
|||||||
|
|
||||||
# Change to boostchicken/pihole:latest for DoH
|
# Change to boostchicken/pihole:latest for DoH
|
||||||
# Change to boostchicken/pihole-dote:latest for DoTE
|
# Change to boostchicken/pihole-dote:latest for DoTE
|
||||||
IMAGE=pihole/pihole:latest
|
IMAGE=pihole/pihole:latest
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check if the directory exists
|
||||||
|
if [ ! -d "${DATA_DIR}/pihole" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "${DATA_DIR}/pihole"
|
||||||
|
mkdir -p "${DATA_DIR}/pihole/etc"
|
||||||
|
echo "Directory '${DATA_DIR}/pihole' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '${DATA_DIR}/pihole' already exists. Moving on."
|
||||||
|
fi
|
||||||
podman pull $IMAGE
|
podman pull $IMAGE
|
||||||
podman stop pihole
|
podman stop pihole
|
||||||
podman rm pihole
|
podman rm pihole
|
||||||
podman run -d --network dns --restart always \
|
podman run -d --network dns --restart always \
|
||||||
--name pihole \
|
--name pihole \
|
||||||
-e TZ="America/Chicago" \
|
-e TZ="America/Chicago" \
|
||||||
-v "/mnt/data/etc-pihole/:/etc/pihole/" \
|
-v "${DATA_DIR}/pihole/etc:/etc/pihole/" \
|
||||||
-v "/mnt/data/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/" \
|
-v "${DATA_DIR}/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/" \
|
||||||
--dns=127.0.0.1 \
|
--dns=127.0.0.1 \
|
||||||
--dns=1.1.1.1 \
|
--dns=1.1.1.1 \
|
||||||
--dns=1.0.0.1 \
|
--dns=1.0.0.1 \
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# Run Suricata 5.0.3 with custom rules
|
# Run Suricata 5.0.3 with custom rules
|
||||||
|
|
||||||
## UBNT updated Suricata in 1.9.x firmwares make this unneeded
|
## UBNT updated Suricata in 1.9.x firmwares make this unneeded
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
1. Run a newer suricata with custom rules
|
1. Run a newer suricata with custom rules
|
||||||
@ -11,9 +13,9 @@
|
|||||||
|
|
||||||
## Customization
|
## Customization
|
||||||
|
|
||||||
* Put customs rules files in /mnt/data/suricata-rules
|
- Put customs rules files in /data/suricata-rules
|
||||||
|
|
||||||
## Steps
|
## Steps
|
||||||
|
|
||||||
1. Copy [25-suricata.sh](on_boot.d/25-suricata.sh) to /mnt/data/on_boot.d and update its values to reflect your environment
|
1. Copy [25-suricata.sh](on_boot.d/25-suricata.sh) to /data/on_boot.d and update its values to reflect your environment
|
||||||
2. Execute /mnt/data/on_boot.d/25-suricata.sh
|
2. Execute /data/on_boot.d/25-suricata.sh
|
||||||
|
@ -1,10 +1,36 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check if the directory exists
|
||||||
|
if [ ! -d "${DATA_DIR}/suricata-rules" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "${DATA_DIR}/suricata-rules"
|
||||||
|
echo "Directory '${DATA_DIR}/suricata-rules' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '${DATA_DIR}/suricata-rules' already exists. Moving on."
|
||||||
|
fi
|
||||||
APP_PID="/run/suricata.pid"
|
APP_PID="/run/suricata.pid"
|
||||||
|
|
||||||
cat <<"EOF" > /tmp/suricata.sh
|
cat <<"EOF" >/tmp/suricata.sh
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
CUSTOM_RULES="/mnt/data/suricata-rules"
|
CUSTOM_RULES="${DATA_DIR}/suricata-rules"
|
||||||
|
|
||||||
for file in $(find ${CUSTOM_RULES} -name '*.rules' -print)
|
for file in $(find ${CUSTOM_RULES} -name '*.rules' -print)
|
||||||
do
|
do
|
||||||
|
@ -1,23 +1,29 @@
|
|||||||
# Tailscale
|
# Tailscale
|
||||||
Run Tailscale in a container on your Unifi Dream Machine.
|
|
||||||
In combination with the DNS modules, setting up a Tailscale exit node on the UDM Pro can be quite powerful.
|
Run Tailscale in a container on your Unifi Dream Machine.
|
||||||
Additionally, the UDM is well positioned to add a tailscale subnet router to permit remote access to the manged network.
|
In combination with the DNS modules, setting up a Tailscale exit node on the UDM Pro can be quite powerful.
|
||||||
|
Additionally, the UDM is well positioned to add a tailscale subnet router to permit remote access to the manged network.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
Follow the instructions and set up the scripts in these directories (in order) before continuing further:
|
Follow the instructions and set up the scripts in these directories (in order) before continuing further:
|
||||||
|
|
||||||
1. `on-boot-script`
|
1. `on-boot-script`
|
||||||
2. `container-common`
|
2. `container-common`
|
||||||
3. `cni-plugins`
|
3. `cni-plugins`
|
||||||
4. (optional, but recommended if you want to set up an exit node and benefit from ad-blocking) `dns-common` followed by your favorite DNS server such as `run-pihole` or `AdguardHome`
|
4. (optional, but recommended if you want to set up an exit node and benefit from ad-blocking) `dns-common` followed by your favorite DNS server such as `run-pihole` or `AdguardHome`
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
1. Copy `on_boot.d/20-tailscale.sh` to `/mnt/data/on_boot.d/20-tailscale.sh`.
|
|
||||||
2. Make sure the boot script is executable with `chmod +x /mnt/data/on_boot.d/20-tailscale.sh`.
|
1. Copy `on_boot.d/20-tailscale.sh` to `/data/on_boot.d/20-tailscale.sh`.
|
||||||
|
2. Make sure the boot script is executable with `chmod +x /data/on_boot.d/20-tailscale.sh`.
|
||||||
|
|
||||||
## Tailscale Configuration
|
## Tailscale Configuration
|
||||||
After installing the boot script, you will want to set up the included shell alias and check network connectivity before continuing.
|
|
||||||
1. Run `/mnt/data/on_boot.d/20-tailscale.sh alias` to print a helpful shell alias to the terminal, inside a shell comment.
|
|
||||||
2. Add the alias to your running session, after which you can run `tailscale status` or `tailscale netcheck` from the host shell to make sure the running tailscale agent is healthy and has a good network connection.
|
|
||||||
3. `/mnt/data/on_boot.d/20-tailscale.sh status` will also perform status checks, if the alias setup isn't working for some reason.
|
|
||||||
|
|
||||||
How to proceed from here is largely up to you. It is possible to authenticate by simply running `tailscale up` (if you installed the shell alias) and doing most of the rest of the configuration in the admin console. You will likely want to provide additional options to `tailscale up` to use an auth key, advertise tags or subnet routes, or other configuration.
|
After installing the boot script, you will want to set up the included shell alias and check network connectivity before continuing.
|
||||||
|
|
||||||
|
1. Run `/data/on_boot.d/20-tailscale.sh alias` to print a helpful shell alias to the terminal, inside a shell comment.
|
||||||
|
2. Add the alias to your running session, after which you can run `tailscale status` or `tailscale netcheck` from the host shell to make sure the running tailscale agent is healthy and has a good network connection.
|
||||||
|
3. `/data/on_boot.d/20-tailscale.sh status` will also perform status checks, if the alias setup isn't working for some reason.
|
||||||
|
|
||||||
|
How to proceed from here is largely up to you. It is possible to authenticate by simply running `tailscale up` (if you installed the shell alias) and doing most of the rest of the configuration in the admin console. You will likely want to provide additional options to `tailscale up` to use an auth key, advertise tags or subnet routes, or other configuration.
|
||||||
|
@ -14,12 +14,12 @@ In the current examples, the DNS resolver (e.g., pi-hole) is listening on `10.0.
|
|||||||
|
|
||||||
Follow the steps in [run-pihole](../run-pihole) to create a separate IP address, by copying the files in the sub-directories to UDM/P.
|
Follow the steps in [run-pihole](../run-pihole) to create a separate IP address, by copying the files in the sub-directories to UDM/P.
|
||||||
|
|
||||||
Adjust the `11-unbound-macvlanip` and `.conflist` files, run [init_unbound.sh](./scripts/init_unbound.sh), *or* execute the commands below manually.
|
Adjust the `11-unbound-macvlanip` and `.conflist` files, run [init_unbound.sh](./scripts/init_unbound.sh), _or_ execute the commands below manually.
|
||||||
|
|
||||||
* Link the boot script [11-unbound-macvlanip.sh](./on_boot.d/11-unbound-macvlanip.sh) -> `ln -s /mnt/data/unbound/on_boot.d/11-unbound-macvlanip.sh /mnt/data/on_boot.d/11-unbound-macvlanip.sh`
|
- Link the boot script [11-unbound-macvlanip.sh](./on_boot.d/11-unbound-macvlanip.sh) -> `ln -s /data/unbound/on_boot.d/11-unbound-macvlanip.sh /data/on_boot.d/11-unbound-macvlanip.sh`
|
||||||
* Link the IPv4 only configuration: [21-unbound.conflist](./cni_plugins/21-unbound.conflist) -> `ln -s /mnt/data/unbound/cni_plugins/21-unbound.conflist /etc/cni/net.d/21-unbound.conflist` *or*
|
- Link the IPv4 only configuration: [21-unbound.conflist](./cni_plugins/21-unbound.conflist) -> `ln -s /data/unbound/cni_plugins/21-unbound.conflist /etc/cni/net.d/21-unbound.conflist` _or_
|
||||||
* Link the IPv4 and IPv6 configuration: [21-unboundipv6.conflist](./cni_plugins/21-unboundipv6.conflist) -> `ln -s /mnt/data/unbound/cni_plugins/21-unboundipv6.conflist /etc/cni/net.d/21-unbound.conflist`
|
- Link the IPv4 and IPv6 configuration: [21-unboundipv6.conflist](./cni_plugins/21-unboundipv6.conflist) -> `ln -s /data/unbound/cni_plugins/21-unboundipv6.conflist /etc/cni/net.d/21-unbound.conflist`
|
||||||
* Create the network
|
- Create the network
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
podman network create unbound
|
podman network create unbound
|
||||||
@ -42,9 +42,9 @@ Two things are left to do: set the upstream server and de-activate caching in Pi
|
|||||||
|
|
||||||
To use `unbound` as the upstream server for Pi-hole, change the following settings in Pi-hole's admin interface:
|
To use `unbound` as the upstream server for Pi-hole, change the following settings in Pi-hole's admin interface:
|
||||||
|
|
||||||
* Settings -> DNS -> Upstream DNS Servers
|
- Settings -> DNS -> Upstream DNS Servers
|
||||||
* Custom 1 (IPv4): 10.0.5.3 (or the IPv4 address you chose)
|
- Custom 1 (IPv4): 10.0.5.3 (or the IPv4 address you chose)
|
||||||
* Custom 2 (IPv6): fdca:5c13:1fb8::3 (or the IPv6 address you chose)
|
- Custom 2 (IPv6): fdca:5c13:1fb8::3 (or the IPv6 address you chose)
|
||||||
|
|
||||||
Both Pi-hole as well as `unbound` are caching their requests. To make the changes of your upstream DNS and to de-activate caching in Pi-hole permanent, modify your `podman run` command **for pi-hole** in this way:
|
Both Pi-hole as well as `unbound` are caching their requests. To make the changes of your upstream DNS and to de-activate caching in Pi-hole permanent, modify your `podman run` command **for pi-hole** in this way:
|
||||||
|
|
||||||
@ -52,8 +52,8 @@ Both Pi-hole as well as `unbound` are caching their requests. To make the change
|
|||||||
podman run -d --network dns --restart always \
|
podman run -d --network dns --restart always \
|
||||||
--name pihole \
|
--name pihole \
|
||||||
-e TZ="America/Los Angeles" \
|
-e TZ="America/Los Angeles" \
|
||||||
-v "/mnt/data/pihole/etc-pihole/:/etc/pihole/" \
|
-v "/data/pihole/etc-pihole/:/etc/pihole/" \
|
||||||
-v "/mnt/data/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/" \
|
-v "/data/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/" \
|
||||||
--dns=127.0.0.1 \
|
--dns=127.0.0.1 \
|
||||||
--dns=10.0.5.3 \
|
--dns=10.0.5.3 \
|
||||||
--hostname pi.hole \
|
--hostname pi.hole \
|
||||||
|
@ -1,4 +1,32 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check if the directory exists
|
||||||
|
if [ ! -d "${DATA_DIR}/unbound" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "${DATA_DIR}/unbound"
|
||||||
|
mkdir -p "${DATA_DIR}/unbound.conf.d"
|
||||||
|
echo "Directory '${DATA_DIR}/unbound' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '${DATA_DIR}/unbound' already exists. Moving on."
|
||||||
|
fi
|
||||||
|
|
||||||
## configuration variables:
|
## configuration variables:
|
||||||
VLAN=5
|
VLAN=5
|
||||||
@ -31,9 +59,9 @@ IPV6_GW="fdca:5c13:1fb8::1/64"
|
|||||||
CONTAINER=unbound
|
CONTAINER=unbound
|
||||||
|
|
||||||
if ! test -f /opt/cni/bin/macvlan; then
|
if ! test -f /opt/cni/bin/macvlan; then
|
||||||
echo "Error: CNI plugins not found. You can install it with the following command:" >&2
|
echo "Error: CNI plugins not found. You can install it with the following command:" >&2
|
||||||
echo " curl -fsSLo /mnt/data/on_boot.d/05-install-cni-plugins.sh https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/main/cni-plugins/05-install-cni-plugins.sh && /bin/sh /mnt/data/on_boot.d/05-install-cni-plugins.sh" >&2
|
echo " curl -fsSLo ${DATA_DIR}/on_boot.d/05-install-cni-plugins.sh https://raw.githubusercontent.com/unifi-utilities/unifios-utilities/main/cni-plugins/05-install-cni-plugins.sh && /bin/sh ${DATA_DIR}/on_boot.d/05-install-cni-plugins.sh" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# we assume that the VLAN bridge already exists, created by the filtering DNS (pi-hole) script
|
# we assume that the VLAN bridge already exists, created by the filtering DNS (pi-hole) script
|
||||||
|
@ -1,20 +1,37 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
# init unbound container - quick and dirty for now
|
# init unbound container - quick and dirty for now
|
||||||
# no checks, no balances
|
# no checks, no balances
|
||||||
|
|
||||||
echo "Creating links..."
|
echo "Creating links..."
|
||||||
# link the script to create an IP on the macvlan for unbound
|
# link the script to create an IP on the macvlan for unbound
|
||||||
ln -s /mnt/data/unbound/on_boot.d/11-unbound-macvlanip.sh /mnt/data/on_boot.d/11-unbound-macvlanip.sh
|
ln -s ${DATA_DIR}/unbound/on_boot.d/11-unbound-macvlanip.sh ${DATA_DIR}/on_boot.d/11-unbound-macvlanip.sh
|
||||||
|
|
||||||
# configure either IPv4 only or IPv4 and IPv6 by uncommenting the proper line
|
# configure either IPv4 only or IPv4 and IPv6 by uncommenting the proper line
|
||||||
#
|
#
|
||||||
|
|
||||||
# link the IPv4 configuration for CNI
|
# link the IPv4 configuration for CNI
|
||||||
# ln -s /mnt/data/unbound/cni_plugins/21-unbound.conflist /etc/cni/net.d/21-unbound.conflist
|
# ln -s ${DATA_DIR}/unbound/cni_plugins/21-unbound.conflist /etc/cni/net.d/21-unbound.conflist
|
||||||
|
|
||||||
# link the IPv4 and IPv6 configuration for CNI
|
# link the IPv4 and IPv6 configuration for CNI
|
||||||
ln -s /mnt/data/unbound/cni_plugins/21-unboundipv6.conflist /etc/cni/net.d/21-unbound.conflist
|
ln -s ${DATA_DIR}/unbound/cni_plugins/21-unboundipv6.conflist /etc/cni/net.d/21-unbound.conflist
|
||||||
|
|
||||||
# create the podman network unbound
|
# create the podman network unbound
|
||||||
echo "Creating podman network..."
|
echo "Creating podman network..."
|
||||||
@ -22,4 +39,4 @@ podman network create unbound
|
|||||||
|
|
||||||
# create the container IP
|
# create the container IP
|
||||||
echo "Creating container IP..."
|
echo "Creating container IP..."
|
||||||
sh /mnt/data/on_boot.d/11-unbound-macvlanip.sh
|
sh ${DATA_DIR}/on_boot.d/11-unbound-macvlanip.sh
|
||||||
|
@ -1,4 +1,33 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check if the directory exists
|
||||||
|
if [ ! -d "${DATA_DIR}/unbound" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "${DATA_DIR}/unbound"
|
||||||
|
mkdir -p "${DATA_DIR}/unbound.conf.d"
|
||||||
|
echo "Directory '${DATA_DIR}/unbound' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '${DATA_DIR}/unbound' already exists. Moving on."
|
||||||
|
fi
|
||||||
|
|
||||||
CONTAINER=unbound
|
CONTAINER=unbound
|
||||||
IMAGE=klutchell/unbound:latest
|
IMAGE=klutchell/unbound:latest
|
||||||
|
|
||||||
@ -7,12 +36,11 @@ podman pull $IMAGE
|
|||||||
echo "Stopping container..."
|
echo "Stopping container..."
|
||||||
podman stop $CONTAINER
|
podman stop $CONTAINER
|
||||||
echo "Removing container..."
|
echo "Removing container..."
|
||||||
podman rm $CONTAINER
|
podman rm $CONTAINER
|
||||||
echo "Updating root hints..."
|
echo "Updating root hints..."
|
||||||
mkdir -p /mnt/data/unbound/unbound.conf.d/
|
curl -m 30 -o ${DATA_DIR}/unbound/unbound.conf.d/root.hints https://www.internic.net/domain/named.root
|
||||||
curl -m 30 -o /mnt/data/unbound/unbound.conf.d/root.hints https://www.internic.net/domain/named.root
|
|
||||||
echo "Running $CONTAINER container"
|
echo "Running $CONTAINER container"
|
||||||
podman run -d --net unbound --restart always \
|
podman run -d --net unbound --restart always \
|
||||||
--name $CONTAINER \
|
--name $CONTAINER \
|
||||||
-v "/mnt/data/unbound/unbound.conf.d/:/opt/unbound/etc/unbound/ " \
|
-v "${DATA_DIR}/unbound/unbound.conf.d/:/opt/unbound/etc/unbound/ " \
|
||||||
$IMAGE
|
$IMAGE
|
||||||
|
@ -13,44 +13,44 @@
|
|||||||
|
|
||||||
## Customization
|
## Customization
|
||||||
|
|
||||||
* Update [wg0.conf](configs/wg0.conf) to match your environment
|
- Update [wg0.conf](configs/wg0.conf) to match your environment
|
||||||
* You can use a custom interface name by changing wg0.conf to whatever you like
|
- You can use a custom interface name by changing wg0.conf to whatever you like
|
||||||
* Use PostUp and PostDown in your wg.conf to execute any commands after the interface is created or destroyed
|
- Use PostUp and PostDown in your wg.conf to execute any commands after the interface is created or destroyed
|
||||||
|
|
||||||
## Steps
|
## Steps
|
||||||
|
|
||||||
1. Make a directory for your keys and configuration:
|
1. Make a directory for your keys and configuration:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mkdir -p /mnt/data/wireguard
|
mkdir -p /data/wireguard
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Create your public and private keys:
|
2. Create your public and private keys:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
podman run -i --rm --net=host --name wireguard_conf masipcat/wireguard-go wg genkey > /mnt/data/wireguard/privatekey
|
podman run -i --rm --net=host --name wireguard_conf masipcat/wireguard-go wg genkey > /data/wireguard/privatekey
|
||||||
podman run -i --rm --net=host --name wireguard_conf masipcat/wireguard-go wg pubkey < /mnt/data/wireguard/privatekey > /mnt/data/wireguard/publickey
|
podman run -i --rm --net=host --name wireguard_conf masipcat/wireguard-go wg pubkey < /data/wireguard/privatekey > /data/wireguard/publickey
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Create a [Wireguard configuration](configs/wg0.conf) in /mnt/data/wireguard
|
3. Create a [Wireguard configuration](configs/wg0.conf) in /data/wireguard
|
||||||
4. Copy [20-wireguard.sh](on_boot.d/20-wireguard.sh) to /mnt/data/on_boot.d and update its values to reflect your environment
|
4. Copy [20-wireguard.sh](on_boot.d/20-wireguard.sh) to /data/on_boot.d and update its values to reflect your environment
|
||||||
5. Execute /mnt/data/on_boot.d/[20-wireguard.sh](on_boot.d/20-wireguard.sh)
|
5. Execute /data/on_boot.d/[20-wireguard.sh](on_boot.d/20-wireguard.sh)
|
||||||
6. If you are running a server, make the appropriate firewall rules / port forwards
|
6. If you are running a server, make the appropriate firewall rules / port forwards
|
||||||
7. Execute the wg command in the container to verify the tunnel is up. It should look something like this:
|
7. Execute the wg command in the container to verify the tunnel is up. It should look something like this:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ podman exec -it wireguard wg
|
$ podman exec -it wireguard wg
|
||||||
interface: wg0
|
interface: wg0
|
||||||
public key: <your public key here>
|
public key: <your public key here>
|
||||||
private key: (hidden)
|
private key: (hidden)
|
||||||
listening port: 54321
|
listening port: 54321
|
||||||
|
|
||||||
peer: <your peers public key>
|
peer: <your peers public key>
|
||||||
endpoint: 10.0.0.2:54321
|
endpoint: 10.0.0.2:54321
|
||||||
allowed ips: 10.1.0.0/16, 10.2.0.0/16
|
allowed ips: 10.1.0.0/16, 10.2.0.0/16
|
||||||
latest handshake: 1 day, 14 hours, 46 minutes, 27 seconds ago
|
latest handshake: 1 day, 14 hours, 46 minutes, 27 seconds ago
|
||||||
transfer: 138.44 MiB received, 5.00 GiB sent
|
transfer: 138.44 MiB received, 5.00 GiB sent
|
||||||
```
|
```
|
||||||
|
|
||||||
### Useful commands
|
### Useful commands
|
||||||
|
|
||||||
|
@ -1,14 +1,42 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check if the directory exists
|
||||||
|
if [ ! -d "${DATA_DIR}/wireguard" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "${DATA_DIR}/wireguard"
|
||||||
|
echo "Directory '${DATA_DIR}/wireguard' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '${DATA_DIR}/wireguard' already exists. Moving on."
|
||||||
|
fi
|
||||||
|
|
||||||
CONTAINER=wireguard
|
CONTAINER=wireguard
|
||||||
# Starts a wireguard container that is deleted after it is stopped.
|
# Starts a wireguard container that is deleted after it is stopped.
|
||||||
# All configs stored in /mnt/data/wireguard
|
# All configs stored in ${DATA_DIR}/wireguard
|
||||||
if podman container exists ${CONTAINER}; then
|
if podman container exists ${CONTAINER}; then
|
||||||
podman start ${CONTAINER}
|
podman start ${CONTAINER}
|
||||||
else
|
else
|
||||||
podman run -i -d --rm --net=host --name ${CONTAINER} --privileged \
|
podman run -i -d --rm --net=host --name ${CONTAINER} --privileged \
|
||||||
-v /mnt/data/wireguard:/etc/wireguard \
|
-v ${DATA_DIR}/wireguard:/etc/wireguard \
|
||||||
-v /dev/net/tun:/dev/net/tun \
|
-v /dev/net/tun:/dev/net/tun \
|
||||||
-e LOG_LEVEL=info -e WG_COLOR_MODE=always \
|
-e LOG_LEVEL=info -e WG_COLOR_MODE=always \
|
||||||
masipcat/wireguard-go:0.0.20210424
|
masipcat/wireguard-go:0.0.20210424
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -1,10 +1,37 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Get DataDir location
|
||||||
|
DATA_DIR="/data"
|
||||||
|
case "$(ubnt-device-info firmware || true)" in
|
||||||
|
1*)
|
||||||
|
DATA_DIR="/mnt/data"
|
||||||
|
;;
|
||||||
|
2*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
3*)
|
||||||
|
DATA_DIR="/data"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: No persistent storage found." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check if the directory exists
|
||||||
|
if [ ! -d "${DATA_DIR}/zerotier-one" ]; then
|
||||||
|
# If it does not exist, create the directory
|
||||||
|
mkdir -p "${DATA_DIR}/zerotier-one"
|
||||||
|
echo "Directory '${DATA_DIR}/zerotier-one' created."
|
||||||
|
else
|
||||||
|
# If it already exists, print a message
|
||||||
|
echo "Directory '${DATA_DIR}/zerotier-one' already exists. Moving on."
|
||||||
|
fi
|
||||||
|
|
||||||
CONTAINER=zerotier-one
|
CONTAINER=zerotier-one
|
||||||
# Starts a ZeroTier container that is deleted after it is stopped.
|
# Starts a ZeroTier container that is deleted after it is stopped.
|
||||||
# All configs stored in /mnt/data/zerotier-one
|
# All configs stored in ${DATA_DIR}/zerotier-one
|
||||||
if podman container exists ${CONTAINER}; then
|
if podman container exists ${CONTAINER}; then
|
||||||
podman start ${CONTAINER}
|
podman start ${CONTAINER}
|
||||||
else
|
else
|
||||||
podman run --device=/dev/net/tun --net=host --cap-add=NET_ADMIN --cap-add=SYS_ADMIN --cap-add=CAP_SYS_RAWIO -v /mnt/data/zerotier-one:/var/lib/zerotier-one --name zerotier-one -d bltavares/zerotier
|
podman run --device=/dev/net/tun --net=host --cap-add=NET_ADMIN --cap-add=SYS_ADMIN --cap-add=CAP_SYS_RAWIO -v ${DATA_DIR}/zerotier-one:/var/lib/zerotier-one --name zerotier-one -d bltavares/zerotier
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
# Run ZeroTier VPN on your UDM
|
# Run ZeroTier VPN on your UDM
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
1. Copy 20-zerotier.sh to /mnt/data/on_boot.d
|
|
||||||
|
1. Copy 20-zerotier.sh to /data/on_boot.d
|
||||||
2. Create directories for persistent Zerotier configuration
|
2. Create directories for persistent Zerotier configuration
|
||||||
|
|
||||||
```
|
```
|
||||||
mkdir -p /mnt/data/zerotier-one
|
mkdir -p /data/zerotier-one
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Start the zeriotier container
|
3. Start the zeriotier container
|
||||||
```
|
```
|
||||||
podman run -d \
|
podman run -d \
|
||||||
@ -16,7 +18,7 @@
|
|||||||
--cap-add=NET_ADMIN \
|
--cap-add=NET_ADMIN \
|
||||||
--cap-add=SYS_ADMIN \
|
--cap-add=SYS_ADMIN \
|
||||||
--cap-add=CAP_SYS_RAWIO \
|
--cap-add=CAP_SYS_RAWIO \
|
||||||
-v /mnt/data/zerotier-one:/var/lib/zerotier-one \
|
-v /data/zerotier-one:/var/lib/zerotier-one \
|
||||||
bltavares/zerotier
|
bltavares/zerotier
|
||||||
```
|
```
|
||||||
4. Join your zerotier network
|
4. Join your zerotier network
|
||||||
|
Loading…
Reference in New Issue
Block a user