├── .gitignore ├── LICENSE ├── README.md ├── install.sh ├── on_boot.d ├── auth.sh └── openvpn.sh └── udm-patches ├── openvpn-N ├── openvpn-1.auth └── openvpn-1.conf ├── root ├── .profile └── .ssh │ └── authorized_keys └── scripts ├── openvpn-notify.sh └── openvpn-wrapper.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .history 2 | .local 3 | openvpn-1 4 | openvpn-2 5 | openvpn-3 6 | openvpn-4 7 | openvpn-5 8 | openvpn-6 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Clint Priest 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ubiquiti Dream Machine Pro onboot.d scripts 2 | 3 | This repository contains on boot scripts which handle various things, see below for more details. 4 | 5 | # Archived 6 | 7 | This patch is no longer necessary as the UDM Pro now has proper OpenVPN client capabilities built-in. 8 | 9 | ## Installation 10 | 1. First install the excellent UDM [on-boot-script](https://github.com/boostchicken/udm-utilities/tree/master/on-boot-script) package from [boostchicken/udm-utilities](https://github.com/boostchicken/udm-utilities). 11 | 2. Download this repository and adjust its configuration to your needs. 12 | 3. Edit the `install.sh` script and change the `ROUTER` to your routers IP address and run `install.sh` 13 | 4. Login to your UDM via ssh and run the on_boot.d scripts to activate them. 14 | 15 | They should persist across reboots and firmware updates per the on_boot project. 16 | 17 | ## on\_boot.d\auth.vpn 18 | 19 | This script appends the authorized\_keys file in udm-patches\root-ssh to the root authorized_keys file upon boot. 20 | 21 | ## on\_boot.d\openvpn.sh 22 | 23 | This script installs the openvpn-wrapper.sh symlink to intercept UDM openvpn start/stop requests and allows you to use an entirely customized OpenVPN config file (.ovpn) while keeping it integrated with the UDM OS. 24 | 25 | You should setup an openvpn-N directory within udm-patches with your custom openvpn.conf file. 26 | 27 | See the existing [openvpn-N](udm-patches/openvpn-N/openvpn-1.conf) file for instructions to modify your own config file. 28 | 29 | If you only have one VPN connection, the directory would be openvpn-1. If you have multiple tunnels you may override 30 | any or all of them by creating the appropriate `openvpn-N` directory where `N` corresponds to the tunnel number in use by the UDM. 31 | 32 | Once your configuration file is ready and in place, create a new site to site OpenVPN in the UDM gui using any parameters 33 | that will allow you to save. The wrapper script will re-route the openvpn call to utilize your custom config and setup tunnel 34 | masquerading. It is assumed that the server you are connecting to will push the routes to the UDM. 35 | 36 | ### Troubleshooting 37 | If you are having trouble with the connection, you can see the output of the last intercepted openvpn run by looking at the file `/tmp/openvpn-orig.log` on the base alpine image which is a redirect of the openvpn command output. 38 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ROUTER="192.168.210.1"; 4 | BASE_DIR="/mnt/data"; 5 | 6 | set -x; 7 | # echo "Copying ./on_boot.d scripts to $BASE_DIR/on_boot.d on $ROUTER..."; 8 | scp -p -r ./on_boot.d/* root@$ROUTER:/mnt/data/on_boot.d; 9 | # echo; 10 | 11 | # echo "Copying ./udm-patches/ to $BASE_DIR/udm-patches/ on $ROUTER..."; 12 | scp -p -r ./udm-patches/ root@$ROUTER:/mnt/data/; 13 | 14 | # echo "Setting +x on scripts..."; 15 | ssh root@$ROUTER "chmod -v +x $BASE_DIR/on_boot.d/* $BASE_DIR/udm-patches/scripts/*"; 16 | -------------------------------------------------------------------------------- /on_boot.d/auth.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | PKG_DIR=/mnt/data/udm-patches 4 | 5 | # Append the contents of root/.ssh/authorized_keys and root/.profile to /root/... files 6 | cat ${PKG_DIR}/root/.ssh/authorized_keys >> /root/.ssh/authorized_keys 7 | cat ${PKG_DIR}/root/.profile >> /root/.profile 8 | -------------------------------------------------------------------------------- /on_boot.d/openvpn.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | PKG_DIR=/mnt/data/udm-patches 4 | BIN_DIR=/usr/sbin 5 | 6 | # Wait till UDM have connectivity before run the wrapper. 7 | # This fix the issue where some UDMs get unresponsive on reboot. 8 | while ! grep -q '1' /var/run/linkcheck/connected > /dev/null 9 | do 10 | sleep 5 11 | done 12 | 13 | # Rename the openvpn binary and install our wrapper 14 | # The wrapper will be called by UDM to start an openvpn connection 15 | if [[ ! -e ${BIN_DIR}/openvpn-orig ]]; then 16 | mv ${BIN_DIR}/openvpn ${BIN_DIR}/openvpn-orig 17 | ln -s ${PKG_DIR}/scripts/openvpn-wrapper.sh ${BIN_DIR}/openvpn 18 | fi; 19 | 20 | # This script is run after native openvpn configs have already launched, this 21 | # kills existing connections which the UDM will re-launch, but now with our 22 | # wrapper in place 23 | for x in 1 2 3 4 5 6 7 8 9 10; do 24 | if [[ -e /run/openvpn-$x/peer.pid ]]; then 25 | kill `cat /run/openvpn-$x/peer.pid`; 26 | rm /run/openvpn-$x/peer.pid; 27 | fi 28 | done; 29 | -------------------------------------------------------------------------------- /udm-patches/openvpn-N/openvpn-1.auth: -------------------------------------------------------------------------------- 1 | your-username 2 | your-password 3 | -------------------------------------------------------------------------------- /udm-patches/openvpn-N/openvpn-1.conf: -------------------------------------------------------------------------------- 1 | # *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* 2 | # 3 | # This is a sample configuration from my active config 4 | # with sensitive parts snipped out, use only as an example 5 | # 6 | # You should get your own .opvn config file from your 7 | # server or admin and adjust accordingly. 8 | # 9 | # Notes: 10 | # UDM expects openvpn-1 to be `dev tun1`, I would expect 11 | # the 2nd tunnel would be openvpn-2 and dev tun2, etc. 12 | # 13 | # *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* 14 | 15 | # Automatically generated OpenVPN client config file 16 | # Generated on Mon Nov 23 22:25:56 2020 by ...snip... 17 | 18 | # Default Cipher 19 | cipher AES-256-CBC 20 | # Note: this config file contains inline private keys 21 | # and therefore should be kept confidential! 22 | # Note: this configuration is user-locked to the username below 23 | # Define the profile name of this particular configuration file 24 | # OVPN_ACCESS_SERVER_CLI_PREF_ALLOW_WEB_IMPORT=True 25 | # OVPN_ACCESS_SERVER_CLI_PREF_BASIC_CLIENT=False 26 | # OVPN_ACCESS_SERVER_CLI_PREF_ENABLE_CONNECT=False 27 | # OVPN_ACCESS_SERVER_CLI_PREF_ENABLE_XD_PROXY=True 28 | # OVPN_ACCESS_SERVER_WEB_CA_BUNDLE_START 29 | # -----BEGIN CERTIFICATE----- 30 | # 2rNf5YkzQWSYxhzi4oRWMhlY4DtLxCOkTaDy7UDh1uAMqgVPbySPpoPtSUMadpgA 31 | # ... snip ... 32 | # JrtTnyct7zrWibzLzMnGCyhxb5JWv4OQZ/4uFkH4G6w= 33 | # -----END CERTIFICATE----- 34 | # OVPN_ACCESS_SERVER_WEB_CA_BUNDLE_STOP 35 | # OVPN_ACCESS_SERVER_IS_OPENVPN_WEB_CA=1 36 | setenv FORWARD_COMPATIBLE 1 37 | client 38 | server-poll-timeout 4 39 | nobind 40 | remote ...snip... 1194 udp 41 | remote ...snip... 443 tcp 42 | 43 | # *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* 44 | # 45 | # These Need To Be Present In Your Own Config. 46 | # 47 | # Adjust /openvpn-1/ references accordingly. 48 | # 49 | # *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* 50 | --writepid /run/openvpn-1/peer.pid 51 | --script-security 2 52 | --up-restart 53 | --up "/mnt/data/udm-patches/scripts/openvpn-notify.sh up 1" 54 | --down-pre 55 | --down "/mnt/data/udm-patches/scripts/openvpn-notify.sh down 1" 56 | --up-delay 57 | # *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* 58 | 59 | # *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* 60 | # 61 | # The next line should correspond to the tunnel number that you 62 | # have created, openvpn-1 => dev1, openvpn-2 => dev2 63 | # 64 | # *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* 65 | dev tun1 66 | 67 | dev-type tun 68 | ns-cert-type server 69 | setenv opt tls-version-min 1.0 or-highest 70 | reneg-sec 604800 71 | sndbuf 0 72 | rcvbuf 0 73 | 74 | # *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* 75 | # 76 | # Uncommenting the line below will allow you to put a 77 | # user/pass in the below file 78 | # 79 | # *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* 80 | # auth-user-pass /mnt/data/udm-patches/openvpn-1/openvpn-1.auth 81 | 82 | verb 3 83 | setenv PUSH_PEER_INFO 84 | 85 | 86 | -----BEGIN CERTIFICATE----- 87 | MIICuDCCAaCgAwIBAgIEX4cbLDANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDDApP 88 | ... snip ... 89 | 6B0MuSAUFUFKr57ktVUiKn12ECwtdOUBL5zP1w== 90 | -----END CERTIFICATE----- 91 | 92 | 93 | 94 | -----BEGIN CERTIFICATE----- 95 | MIICwjCCAaqgAwIBAgIBDjANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDDApPcGVu 96 | ... snip ... 97 | A8f6lsatfS3ukKJhdKx0R+vOOZiKGZBTJyRvOFDFMdZBGTf4vqC= 98 | -----END CERTIFICATE----- 99 | 100 | 101 | 102 | -----BEGIN PRIVATE KEY----- 103 | Xyg/EBiJSM+z5Lhchwzs/yBxLv5aBAUQ4R2Ah+1h+7W7t5RMk78neldgsGmQ2LRb 104 | ... snip ... 105 | xU7oCK6jFQ2uIB6RiZHuNmG= 106 | -----END PRIVATE KEY----- 107 | 108 | 109 | key-direction 1 110 | 111 | # 112 | # 2048 bit OpenVPN static key (Server Agent) 113 | # 114 | -----BEGIN OpenVPN Static key V1----- 115 | 4b72ba84a4f146084c7bb28ab9532cf1 116 | ... snip ... 117 | 0c5d1256af8246951815ff9a4fad794b 118 | -----END OpenVPN Static key V1----- 119 | 120 | 121 | ## -----BEGIN RSA SIGNATURE----- 122 | ## DIGEST:sha256 123 | ## /VDSA04T1Rf/T9KRWPdmgwrKIExlU7wuHQcf8AmMSROx8JcHk3 124 | ## ... snip ... 125 | ## zE5h9fKleRki2rHFlM0XeJIiTuHElsWlo= 126 | ## -----END RSA SIGNATURE----- 127 | ## -----BEGIN CERTIFICATE----- 128 | ## AQQBsjEBAgIHMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BT 129 | ## ... snip ... 130 | ## 4gfp60xhr7UbB2FCrbHHrnHCXdxy7VSEI/S= 131 | ## -----END CERTIFICATE----- 132 | ## -----BEGIN CERTIFICATE----- 133 | ## QwYDVQQDDDxPcGVuVlBOIFdlYiBDQSAyMDIwLjEwLjE0IDE1OjM3OjIxIFVUQyBv 134 | ## ... snip ... 135 | ## 9fI5gPKO79v91gOhi0nB+QwpVF1W5kIkIsMOvh5TgGh= 136 | ## -----END CERTIFICATE----- 137 | -------------------------------------------------------------------------------- /udm-patches/root/.profile: -------------------------------------------------------------------------------- 1 | # Note that the base alpine image uses busybox shell which is ash, not full bash 2 | 3 | # Add some useful aliases to the .profile 4 | alias ll='ls -alh --color'; 5 | alias tf='tail -f -n 100'; 6 | alias pm='podman'; 7 | 8 | -------------------------------------------------------------------------------- /udm-patches/root/.ssh/authorized_keys: -------------------------------------------------------------------------------- 1 | # If you have the auth.sh script activated in on_boot.d then this file will be concatenated to the end of /root/.ssh/authorized_keys on boot 2 | ssh-rsa AAA/62...snip...3+Qs1L51xQ== username 3 | -------------------------------------------------------------------------------- /udm-patches/scripts/openvpn-notify.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Setup/Teardown masqeurade for the tunnel interface 4 | if [[ "$1" = "up" ]]; then 5 | iptables -t nat -I POSTROUTING -o tun${2} -j MASQUERADE 6 | elif [[ "$1" = "down" ]]; then 7 | iptables -t nat -D POSTROUTING -o tun${2} -j MASQUERADE 8 | fi; 9 | 10 | # Notify ubios as per its usual method 11 | ubios-udapi-client -n INTERNAL -r /vpn/openvpn/peers/${2} '{ "action": "'${1}'" }' 12 | -------------------------------------------------------------------------------- /udm-patches/scripts/openvpn-wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | args="$*"; 4 | 5 | PROFILE="$(echo \"$args\" | grep -oE 'openvpn-[0-9]+')"; 6 | 7 | UDM_DIR="/mnt/data/udm-patches" 8 | PROF_DIR="${UDM_DIR}/${PROFILE}/" 9 | LOG_FILE="/tmp/openvpn-orig.log"; 10 | 11 | { 12 | echo "********* OpenVPN Wrapper Intercept *********"; 13 | echo "UDM Called: $0 $*"; 14 | echo " PROFILE_NUM=${PROFILE}, PROF_DIR=${PROF_DIR}"; 15 | echo "********* OpenVPN Wrapper Intercept *********"; 16 | } >> "$LOG_FILE"; 17 | 18 | # If there is an openvpn-N profile directory, use that configuration instead 19 | if [[ -e "$PROF_DIR" ]]; then 20 | mkdir -p /run/${PROFILE}/.disabled; 21 | mv /run/${PROFILE}/* /run/${PROFILE}/.disabled; 22 | cp ${PROF_DIR}/*.conf /run/${PROFILE}/${PROFILE}.conf; 23 | 24 | exec /usr/sbin/openvpn-orig --config /run/${PROFILE}/${PROFILE}.conf 2>&1 >> "${LOG_FILE}"; 25 | else 26 | exec /usr/sbin/openvpn-orig $* 27 | fi; 28 | --------------------------------------------------------------------------------