├── cronjobs ├── update_letsencrypt_certs └── remove-ingress-limit ├── scripts ├── 99-add-cronjobs.sh ├── 10-tweak-network.sh ├── fix_ddns.sh ├── add_root_ssh_known_hosts.sh ├── add-speedtest-to-profile.sh ├── add_root_ssh_keys.sh ├── test_gro.sh └── update_ssl_certs.sh ├── README.md └── disable_gro.md /cronjobs/update_letsencrypt_certs: -------------------------------------------------------------------------------- 1 | MAILTO="" 2 | 0 1 * * * root /data/ssl_certs/update_ssl_certs.sh | /usr/bin/logger 3 | -------------------------------------------------------------------------------- /scripts/99-add-cronjobs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cp /data/cronjobs/* /etc/cron.d/ 4 | /etc/init.d/cron restart 5 | 6 | exit 0 7 | 8 | 9 | -------------------------------------------------------------------------------- /cronjobs/remove-ingress-limit: -------------------------------------------------------------------------------- 1 | MAILTO="" 2 | */5 * * * * root /sbin/tc qdisc show dev eth9 | grep -q 'ingress' && /sbin/tc qdisc del dev eth9 ingress 3 | */5 * * * * root /sbin/tc qdisc show dev eth8 | grep -q 'ingress' && /sbin/tc qdisc del dev eth8 ingress 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UDMP-Scripts 2 | A collection of scripts I've created that are useful for the Ubiquiti Dream Machine Pro 3 | 4 | # Having strange SSL or download issues on your UDM/P/SE ? 5 | 6 | If you're having download issues with your ISP and a UDM/P/SE device you may have found this repository from a forum or reddit. 7 | 8 | To test and/or fix `generic-receive-offload` problems with your device, see [disable_gro.md](./disable_gro.md) 9 | -------------------------------------------------------------------------------- /scripts/10-tweak-network.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # file placed in /mnt/data/on_boot.d/10-tweak-network.sh with 755 owned by root 4 | # see https://github.com/boostchicken/udm-utilities/blob/master/on-boot-script/README.md 5 | 6 | # to fix my own problem with GRO breaking SSL downloads 7 | # we will disable GRO for WAN interfaces (eth8 eth9) 8 | 9 | # 10 | echo disabling GRO for RJ45 WAN port... 11 | /usr/sbin/ethtool -K eth8 gro off 12 | echo disabling GRO for SFP+ WAN port... 13 | /usr/sbin/ethtool -K eth9 gro off 14 | 15 | exit 0 16 | -------------------------------------------------------------------------------- /scripts/fix_ddns.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # to fix DDNS client when using a private WAN IP (NATed) 4 | # run this as a cron job; DDNS config may be regenerated with each change to the Unifi UI 5 | # only makes change if '^iface' is present in the config, piping cron job to logger will ensure output in /var/log/messages: 6 | # example cron file 7 | # * * * * * /mnt/data/scripts/fix-ddns.sh | /usr/bin/logger 8 | 9 | DDNS_CONFIG=/run/ddns-eth9-inadyn.conf 10 | 11 | if grep -q "^iface" $DDNS_CONFIG; then 12 | echo "'iface' specified in $DDNS_CONFIG; Removing reference..." 13 | cat $DDNS_CONFIG | sed 's/iface/\#iface/g' > $DDNS_CONFIG.new 14 | mv $DDNS_CONFIG $DDNS_CONFIG.bkup 15 | mv $DDNS_CONFIG.new $DDNS_CONFIG 16 | killall inadyn 17 | fi 18 | 19 | exit 0 20 | -------------------------------------------------------------------------------- /scripts/add_root_ssh_known_hosts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ##################################################### 4 | # ADD KNOWN HOSTS AS BELOW - CHANGE BEFORE RUNNING # 5 | ##################################################### 6 | # set -- "known host text on a line with quotes " \ # 7 | # "second known host on another line " \ # 8 | # "one per line, last line has no backslash" # 9 | ##################################################### 10 | set -- "hostname ecdsa-sha2-nistp256 AAAAMAGICKEYHERE=" 11 | 12 | KNOWN_HOSTS_FILE="/root/.ssh/known_hosts" 13 | 14 | counter=0 15 | for host in "$@" 16 | do 17 | ## Places known host in ~/.ssh/known_hosts if not present 18 | if ! grep -Fxq "$host" "$KNOWN_HOSTS_FILE"; then 19 | let counter++ 20 | echo "$host" >> "$KNOWN_HOSTS_FILE" 21 | fi 22 | done 23 | 24 | echo $counter hosts added to $KNOWN_HOSTS_FILE 25 | 26 | 27 | exit 0; 28 | -------------------------------------------------------------------------------- /scripts/add-speedtest-to-profile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # this script intended to add speedtest to the root path / .profile each boot 4 | # add to /data/on_boot.d as something like 25-add-speedtest-to-profile.sh and add execute permissions 5 | # 6 | # to initially install speedtest on UDMP: 7 | # 8 | # curl -o speedtest.tgz https://install.speedtest.net/app/cli/ookla-speedtest-1.2.0-linux-aarch64.tgz 9 | # mkdir /data/speedtest 10 | # tar -xvf speedtest.tgz -C /data/speedtest 11 | # rm speedtest.tgz 12 | # 13 | 14 | SPEEDTEST_PATH="/data/speedtest/" 15 | PROFILE_FILE="/root/.profile" 16 | 17 | if grep -Fsq "$SPEEDTEST_PATH" $PROFILE_FILE; then 18 | echo "speedtest path already present in path in '$PROFILE_FILE'" 19 | else 20 | echo "Adding '$SPEEDTEST_PATH' to path in '$PROFILE_FILE'" 21 | echo "export PATH=\$PATH:$SPEEDTEST_PATH" >> $PROFILE_FILE 22 | fi 23 | 24 | chmod 600 $PROFILE_FILE 25 | 26 | exit 0 27 | -------------------------------------------------------------------------------- /scripts/add_root_ssh_keys.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ##################################################### 4 | # ADD RSA KEYS AS BELOW - CHANGE BEFORE RUNNING # 5 | ##################################################### 6 | # set -- "ssh-rsa first key here all keys quoted" \ # 7 | # "ssh-rsa each line appended with slash " \ # 8 | # "ssh-rsa last one has no backslash" # 9 | ##################################################### 10 | set -- "ssh-rsa AAABUNCHOFNONSENSE random Keyname" \ 11 | "ssh-rsa AAAAOTHERMAGICWORDS user@host" 12 | 13 | KEYS_FILE="/root/.ssh/authorized_keys" 14 | 15 | counter=0 16 | for key in "$@" 17 | do 18 | ## Places public key in ~/.ssh/authorized_keys if not present 19 | if ! grep -Fxq "$key" "$KEYS_FILE"; then 20 | let counter++ 21 | echo "$key" >> "$KEYS_FILE" 22 | fi 23 | done 24 | 25 | echo $counter keys added to $KEYS_FILE 26 | 27 | # removed for 2.4 - no dropbear 28 | #echo Converting SSH private key to dropbear format 29 | #convert ssh key to dropbear for shell interaction 30 | #dropbearconvert openssh dropbear /data/ssh/id_rsa /root/.ssh/id_dropbear 31 | 32 | exit 0; 33 | -------------------------------------------------------------------------------- /scripts/test_gro.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Check if the user provided an interface as an argument 4 | if [ -z "$1" ]; then 5 | echo 6 | echo "Please provide your WAN interface." 7 | echo 8 | echo "Usage: $0 " 9 | echo "Example: $0 eth9" 10 | echo 11 | exit 1 12 | fi 13 | 14 | # Use the provided interface 15 | INTERFACE=$1 16 | echo 17 | echo "Testing for GRO problem..." 18 | echo 19 | ethtool -K $INTERFACE gro on 20 | echo "Testing with $(ethtool -k $INTERFACE | grep generic-receive)" 21 | echo "Downloading File with GRO on" 22 | curl -# -o /root/testfile_gro_on.bin http://fw-download.ubnt.com/data/udm/713a-udmpro-1.9.3-c467d3f8c4e74e4281ede75c58a9d3fb.bin 23 | echo "Calculating Checksum..." 24 | FILE1=`md5sum -z < /root/testfile_gro_on.bin | awk '{print $1}'` 25 | echo "MD5 for GRO on = ${FILE1}" 26 | echo " ..deleting file" 27 | rm /root/testfile_gro_on.bin 28 | 29 | echo 30 | 31 | echo "Disabling GRO on $INTERFACE" 32 | ethtool -K $INTERFACE gro off 33 | echo "Testing with $(ethtool -k $INTERFACE | grep generic-receive)" 34 | echo "Downloading File" 35 | curl -# -o /root/testfile_gro_off.bin http://fw-download.ubnt.com/data/udm/713a-udmpro-1.9.3-c467d3f8c4e74e4281ede75c58a9d3fb.bin 36 | echo "Calculating Checksum..." 37 | FILE2=`md5sum -z < /root/testfile_gro_off.bin | awk '{print $1}'` 38 | echo "MD5 for GRO off = ${FILE2}" 39 | echo " ..deleting file" 40 | rm /root/testfile_gro_off.bin 41 | 42 | echo 43 | 44 | if [ "$FILE1" = "$FILE2" ]; then 45 | echo "Checksums are equal, you do not appear to have a GRO issue." 46 | echo "I will leave GRO on for $INTERFACE" 47 | ethtool -K $INTERFACE gro on 48 | else 49 | echo "Checksums do not match, there is a GRO issue." 50 | echo "I will leave GRO off for $INTERFACE" 51 | echo " - note: this setting will not persist a reboot." 52 | echo "See https://github.com/telnetdoogie/UDMP-Scripts/blob/main/disable_gro.md for fix" 53 | ethtool -K $INTERFACE gro off 54 | fi 55 | 56 | echo 57 | echo "Done. Exiting" 58 | -------------------------------------------------------------------------------- /scripts/update_ssl_certs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Updates installed certs if new certs are present on a known SCP host 3 | # Schedule as a daily cron job 4 | 5 | ID="SSL Certificate Updater $(date +"%Y-%m-%d-%H:%M:%S")" 6 | SRC_USER={username for SCP Host} 7 | SRC_HOST={SCP hostname} 8 | SRC_FOLDER='{SCP host folder for certs}' 9 | 10 | WORKING_PATH=/data/ssl_certs 11 | if [[ ! -d $WORKING_PATH ]] 12 | then 13 | echo "$ID: \$WORKING_PATH '$WORKING_PATH' folder doesn't exist! creating..." 14 | mkdir $WORKING_PATH 15 | fi 16 | 17 | #filename on the source for the keyfile 18 | SRC_KEY=privkey.pem 19 | #filename on the source for the cert 20 | SRC_CERT=fullchain.pem 21 | #filename on the source for the keystore 22 | SRC_KEYSTORE=keystore 23 | 24 | DEST_PATH=/data/unifi-core/config 25 | DEST_KEYSTORE_PATH=/data/unifi/data 26 | DEST_KEY=unifi-core.key 27 | DEST_CERT=unifi-core.crt 28 | DEST_KEYSTORE=keystore 29 | 30 | #Copy certs from SRC_HOST 31 | scp $SRC_USER@$SRC_HOST:$SRC_FOLDER/$SRC_CERT $WORKING_PATH/$SRC_CERT > /dev/null 2>&1 32 | scp $SRC_USER@$SRC_HOST:$SRC_FOLDER/$SRC_KEY $WORKING_PATH/$SRC_KEY > /dev/null 2>&1 33 | scp $SRC_USER@$SRC_HOST:$SRC_FOLDER/$SRC_KEYSTORE $WORKING_PATH/$SRC_KEYSTORE > /dev/null 2>&1 34 | 35 | if [[ ! -f $WORKING_PATH/$SRC_CERT ]] 36 | then 37 | echo "$ID: Certificate file '$SRC_CERT' not copied from host! exiting" 38 | exit 1 39 | fi 40 | if [[ ! -f $WORKING_PATH/$SRC_KEY ]] 41 | then 42 | echo "$ID: Key file '$SRC_KEY' not copied from host! exiting" 43 | exit 1 44 | fi 45 | if [[ ! -f $WORKING_PATH/$SRC_KEYSTORE ]] 46 | then 47 | echo "$ID: Keystore file '$SRC_KEYSTORE' not copied from host! exiting" 48 | exit 1 49 | fi 50 | 51 | chmod 644 $WORKING_PATH/$SRC_KEY 52 | chmod 644 $WORKING_PATH/$SRC_CERT 53 | chmod 644 $WORKING_PATH/$SRC_KEYSTORE 54 | 55 | #Compare versions to see if an update is needed 56 | SRC_VER=`md5sum $WORKING_PATH/$SRC_CERT | awk '{ print $1 }'` 57 | DEST_VER=`md5sum $DEST_PATH/$DEST_CERT | awk '{ print $1 }'` 58 | 59 | if [ $SRC_VER == $DEST_VER ]; then 60 | echo "$ID: LE Certificates unchanged; no action needed" 61 | else 62 | # Update is needed; move files and restart unifi 63 | echo "$ID: LE Certificates updated; updating system certs" 64 | 65 | # Backup previous files 66 | echo "$ID: Backing Up $DEST_PATH/$DEST_KEY to $DEST_PATH/$DEST_KEY.bkup" 67 | cp $DEST_PATH/$DEST_KEY $DEST_PATH/$DEST_KEY.bkup 68 | echo "$ID: Backing Up $DEST_PATH/$DEST_CERT to $DEST_PATH/$DEST_CERT.bkup" 69 | cp $DEST_PATH/$DEST_CERT $DEST_PATH/$DEST_CERT.bkup 70 | echo "$ID: Backing Up $DEST_KEYSTORE_PATH/$DEST_KEYSTORE to $DEST_KEYSTORE_PATH/$DEST_KEYSTORE.bkup" 71 | cp $DEST_KEYSTORE_PATH/$DEST_KEYSTORE $DEST_KEYSTORE_PATH/$DEST_KEYSTORE.bkup 72 | 73 | # Update certs 74 | echo "$ID: Overwriting $DEST_PATH/$DEST_KEY" 75 | cp $WORKING_PATH/$SRC_KEY $DEST_PATH/$DEST_KEY 76 | echo "$ID: Overwriting $DEST_PATH/$DEST_CERT" 77 | cp $WORKING_PATH/$SRC_CERT $DEST_PATH/$DEST_CERT 78 | 79 | # Update keystore 80 | echo "$ID: Overwriting $DEST_KEYSTORE_PATH/$DEST_KEYSTORE" 81 | cp $WORKING_PATH/$SRC_KEYSTORE $DEST_KEYSTORE_PATH/$DEST_KEYSTORE 82 | 83 | # Restart unifi-os 84 | systemctl restart unifi-core 85 | fi 86 | 87 | #cleaning up 88 | rm $WORKING_PATH/$SRC_KEY 89 | rm $WORKING_PATH/$SRC_CERT 90 | rm $WORKING_PATH/$SRC_KEYSTORE 91 | 92 | exit 0 93 | -------------------------------------------------------------------------------- /disable_gro.md: -------------------------------------------------------------------------------- 1 | # Steps to disable GRO on UDM/UDMP devices 2 | This solves file corruption issues with certain ISP devices on the WAN 3 | 4 | **Note: The automated fix below is for OS v4 and above** 5 | 6 | The way this problem typically manifests itself is when you get failed downloads usually over SSL. 7 | It's actually a problem with corrupted downloads always, however you may not notice them. 8 | 9 | The reason the SSL downloads most noticably fail is becuase the corruption will 'break' SSL and you'll see errors. 10 | Other symptoms would be frequent disconnects from streaming movies etc., and obviously weird file corruptions, a failure to update your UDM/P etc. 11 | 12 | ## Testing for presence of the problem 13 | 14 | To test for this problem, you can run the script [here](./scripts/test_gro.sh) on your UDM device. 15 | 16 | Usage: `./test_gro.sh ` 17 | > (run ifconfig and find the interface with your WAN ip - also see the below table for examples) 18 | 19 | If the output shows different MD5 checksums with GRO enabled and disabled, you have a GRO problem. 20 | 21 | * The test file used is an older known UDMP firmware. It's approximately 650MB and the **correct** md5sum should be `860e13a4e78372b6e593738db2b49b53` 22 | 23 | Output for the test should look like this: 24 | 25 | ``` 26 | Testing for GRO problem... 27 | 28 | Testing with generic-receive-offload: on 29 | Downloading File with GRO on 30 | ############################################################################## 100.0% 31 | Calculating Checksum... 32 | MD5 for GRO on = e958dd44fbc857175cad0c026e2bc7a7 33 | ..deleting file 34 | 35 | Disabling GRO on eth9 36 | Testing with generic-receive-offload: off 37 | Downloading File 38 | ############################################################################## 100.0% 39 | Calculating Checksum... 40 | MD5 for GRO off = 860e13a4e78372b6e593738db2b49b53 41 | ..deleting file 42 | 43 | Checksums do not match, there is a GRO issue. 44 | I will leave GRO off for eth9 45 | - note: this setting will not persist a reboot. 46 | See https://github.com/telnetdoogie/UDMP-Scripts/blob/main/disable_gro.md for fix 47 | 48 | Done. Exiting 49 | ``` 50 | 51 | ## Short term fix (done after each reboot) 52 | The simplest way would be to just run `ethtool -K eth8 gro off` each time you reboot your device, but change eth8 for whichever interface is your WAN interface 53 | > (run ifconfig and find the one with your WAN ip - also see the below table for examples) 54 | 55 | ## Typical WAN interfaces: 56 | (let me know if you have corrections or updates to this) 57 | 58 | | Model | Port | Interface | 59 | | ----- | ---- | --------- | 60 | | UDM | WAN | `eth4` | 61 | | UDMP/SE | RJ45 WAN | `eth8` | 62 | | UDMP/SE | SFP WAN (port 10) | `eth9` | 63 | | UDMP/SE | SFP WAN (port 11) | `eth10` | 64 | 65 | ## Automating disable GRO on UDM OS 4 and above 66 | 67 | add a file (make folders if necessary) `/data/scripts/disable_gro.sh` : 68 | 69 | ```bash 70 | #!/bin/bash 71 | WAN_INTERFACE=eth9 # edit this to match your WAN interface 72 | 73 | echo disabling GRO for $WAN_INTERFACE... 74 | /sbin/ethtool -K $WAN_INTERFACE gro off 75 | echo GRO state for $WAN_INTERFACE is now: 76 | echo " $(ethtool -k ${WAN_INTERFACE} | grep generic-receive)" 77 | ``` 78 | _(change the `WAN_INTERFACE` to match your interface)_ 79 | 80 | make the file executable 81 | 82 | ```bash 83 | chmod +x /data/scripts/disable_gro.sh 84 | ``` 85 | 86 | make a file, `/lib/systemd/system/disable_gro.service` : 87 | 88 | ```bash 89 | [Unit] 90 | Description=Disable GRO 91 | Wants=network-online.target 92 | After=network-online.target 93 | 94 | [Service] 95 | ExecStart=/data/scripts/disable_gro.sh 96 | Type=oneshot 97 | RemainAfterExit=true 98 | User=root 99 | 100 | [Install] 101 | WantedBy=multi-user.target 102 | ``` 103 | 104 | run the following: 105 | 106 | ```bash 107 | systemctl enable disable_gro.service 108 | systemctl start disable_gro.service 109 | ``` 110 | 111 | run `systemctl status disable_gro.service` to see what was output on execution. 112 | 113 | It should show something like: 114 | 115 | ``` 116 | disabling GRO for eth9... 117 | GRO state for eth9 is now: 118 | generic-receive-offload: off 119 | ``` 120 | 121 | you can also test to make sure it applied, and after each bootup by running: 122 | 123 | ```bash 124 | ethtool -k eth9 | grep generic-receive 125 | ``` 126 | 127 | ...again, replacing `eth9` with whatever interface is for your WAN 128 | 129 | the output should show that gro is off : 130 | ``` 131 | $ ethtool -k eth9 | grep generic-receive 132 | generic-receive-offload: off 133 | ``` 134 | --------------------------------------------------------------------------------