Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | |
| 3 | # Copyright 2019 Google Inc. All rights reserved. |
| 4 | |
| 5 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | # you may not use this file except in compliance with the License. |
| 7 | # You may obtain a copy of the License at |
| 8 | |
| 9 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | |
| 11 | # Unless required by applicable law or agreed to in writing, software |
| 12 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | # See the License for the specific language governing permissions and |
| 15 | # limitations under the License. |
| 16 | |
| 17 | if [[ "$OSTYPE" != "linux-gnu" ]]; then |
| 18 | echo "error: must be running linux" |
| 19 | exit 1 |
| 20 | fi |
| 21 | |
Tristan Muntsinger | 63c657a | 2019-10-23 23:19:40 -0700 | [diff] [blame] | 22 | # escalate to superuser |
| 23 | if [ "$UID" -ne 0 ]; then |
| 24 | exec sudo bash "$0" |
| 25 | fi |
| 26 | |
Tristan Muntsinger | a18d9e5 | 2019-10-24 14:52:38 -0700 | [diff] [blame] | 27 | cleanup() { |
| 28 | echo "Starting up network-manager..." |
| 29 | service network-manager start |
| 30 | if [ $? != 0 ]; then |
| 31 | echo "error: failed to start network-manager" |
| 32 | exit 1 |
| 33 | fi |
| 34 | |
| 35 | echo "Starting up networking..." |
| 36 | service networking start |
| 37 | if [ $? != 0 ]; then |
| 38 | echo "error: failed to start networking" |
| 39 | exit 1 |
| 40 | fi |
| 41 | if [ ! -z "$1" ]; then |
| 42 | exit $1 |
| 43 | fi |
| 44 | } |
| 45 | |
Tristan Muntsinger | e935b21 | 2019-10-09 21:53:11 -0700 | [diff] [blame] | 46 | sleep_time=0.1 |
Tristan Muntsinger | 63c657a | 2019-10-23 23:19:40 -0700 | [diff] [blame] | 47 | max_attempts=100 |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 48 | DEFAULTNET=$1 |
| 49 | if [ "$DEFAULTNET" == "" ]; then |
Tristan Muntsinger | e935b21 | 2019-10-09 21:53:11 -0700 | [diff] [blame] | 50 | warn_no_default_network=0 |
Tristan Muntsinger | e935b21 | 2019-10-09 21:53:11 -0700 | [diff] [blame] | 51 | warn_disconnect_rockpi=0 |
Tristan Muntsinger | 63c657a | 2019-10-23 23:19:40 -0700 | [diff] [blame] | 52 | attempts=0 |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 53 | while true; do |
Tristan Muntsinger | 63c657a | 2019-10-23 23:19:40 -0700 | [diff] [blame] | 54 | NETLIST=`ip link | grep "state UP" | sed 's/[0-9]*: \([^:]*\):.*/\1/'` |
| 55 | if [[ "${NETLIST}" == "" ]]; then |
Tristan Muntsinger | e935b21 | 2019-10-09 21:53:11 -0700 | [diff] [blame] | 56 | if [[ $warn_no_default_network -eq 0 ]]; then |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 57 | echo "error: couldn't detect any connected default network" |
Tristan Muntsinger | e935b21 | 2019-10-09 21:53:11 -0700 | [diff] [blame] | 58 | warn_no_default_network=1 |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 59 | fi |
| 60 | continue |
Tristan Muntsinger | 63c657a | 2019-10-23 23:19:40 -0700 | [diff] [blame] | 61 | elif [ `echo "${NETLIST}" | wc -l` -eq 1 ]; then |
| 62 | DEFAULTNET=${NETLIST} |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 63 | break |
Tristan Muntsinger | 63c657a | 2019-10-23 23:19:40 -0700 | [diff] [blame] | 64 | elif [ `echo "${NETLIST}" | wc -l` -ne 1 ]; then |
Tristan Muntsinger | e935b21 | 2019-10-09 21:53:11 -0700 | [diff] [blame] | 65 | if [[ $warn_disconnect_rockpi -eq 0 ]]; then |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 66 | echo "Please disconnect the network cable from the Rock Pi" |
Tristan Muntsinger | e935b21 | 2019-10-09 21:53:11 -0700 | [diff] [blame] | 67 | warn_disconnect_rockpi=1 |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 68 | fi |
Tristan Muntsinger | 63c657a | 2019-10-23 23:19:40 -0700 | [diff] [blame] | 69 | if [[ ${attempts} -gt ${max_attempts} ]]; then |
| 70 | echo -e "\nerror: detected multiple connected networks, please tell me what to do:" |
| 71 | count=1 |
| 72 | for net in ${NETLIST}; do |
| 73 | echo "${count}) $net" |
| 74 | let count+=1 |
| 75 | done |
| 76 | read -p "Enter the number of your default network connection: " num_default |
| 77 | count=1 |
| 78 | for net in ${NETLIST}; do |
| 79 | if [ ${count} -eq ${num_default} ]; then |
| 80 | echo "Setting default to: ${net}" |
| 81 | DEFAULTNET=${net} |
| 82 | fi |
| 83 | let count+=1 |
| 84 | done |
Tristan Muntsinger | e935b21 | 2019-10-09 21:53:11 -0700 | [diff] [blame] | 85 | warn_no_default_network=0 |
Tristan Muntsinger | 63c657a | 2019-10-23 23:19:40 -0700 | [diff] [blame] | 86 | break |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 87 | fi |
Tristan Muntsinger | 63c657a | 2019-10-23 23:19:40 -0700 | [diff] [blame] | 88 | echo -ne "\r" |
| 89 | printf "Manual configuration in %.1f seconds..." "$(( max_attempts-attempts ))e-1" |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 90 | sleep $sleep_time |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 91 | fi |
Tristan Muntsinger | 63c657a | 2019-10-23 23:19:40 -0700 | [diff] [blame] | 92 | let attempts+=1 |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 93 | done |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 94 | fi |
Tristan Muntsinger | e935b21 | 2019-10-09 21:53:11 -0700 | [diff] [blame] | 95 | echo "Found default network at ${DEFAULTNET}" |
Tristan Muntsinger | e935b21 | 2019-10-09 21:53:11 -0700 | [diff] [blame] | 96 | |
Tristan Muntsinger | 63c657a | 2019-10-23 23:19:40 -0700 | [diff] [blame] | 97 | if [ "${ROCKNET}" == "" ]; then |
| 98 | echo "Please reconnect network cable from Rock Pi to PC's spare network port" |
| 99 | attempts=0 |
| 100 | while true; do |
| 101 | NETLIST=`ip link | grep "state UP" | grep -v $DEFAULTNET | sed 's/[0-9]*: \([^:]*\):.*/\1/' | awk 'NF'` |
| 102 | networks=`echo "$NETLIST" | wc -l` |
| 103 | if [[ "${NETLIST}" == "" ]]; then |
| 104 | networks=0 |
| 105 | fi |
| 106 | if [ $networks -eq 1 ]; then |
| 107 | ROCKNET=${NETLIST} |
Tristan Muntsinger | e935b21 | 2019-10-09 21:53:11 -0700 | [diff] [blame] | 108 | break |
Tristan Muntsinger | 63c657a | 2019-10-23 23:19:40 -0700 | [diff] [blame] | 109 | elif [ $networks -gt 1 ]; then |
| 110 | if [[ ${attempts} -gt ${max_attempts} ]]; then |
| 111 | echo -e "\nerror: detected multiple connected networks, please tell me what to do:" |
| 112 | count=1 |
| 113 | for net in ${NETLIST}; do |
| 114 | echo "${count}) $net" |
| 115 | let count+=1 |
| 116 | done |
| 117 | read -p "Enter the number of your rock pi network connection: " num_rockpi |
| 118 | count=1 |
| 119 | for net in ${NETLIST}; do |
| 120 | if [ ${count} -eq ${num_rockpi} ]; then |
| 121 | echo "Setting rock pi to: ${net}" |
| 122 | ROCKNET=${net} |
| 123 | fi |
| 124 | let count+=1 |
| 125 | done |
| 126 | break |
| 127 | fi |
| 128 | echo -ne "\r" |
| 129 | printf "Manual configuration in %.1f seconds..." "$(( max_attempts-attempts ))e-1" |
| 130 | let attempts+=1 |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 131 | fi |
| 132 | sleep $sleep_time |
Tristan Muntsinger | 63c657a | 2019-10-23 23:19:40 -0700 | [diff] [blame] | 133 | done |
| 134 | fi |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 135 | echo "Found Rock Pi network at ${ROCKNET}" |
| 136 | sudo ifconfig ${ROCKNET} down |
| 137 | |
Tristan Muntsinger | a18d9e5 | 2019-10-24 14:52:38 -0700 | [diff] [blame] | 138 | echo "Downloading dnsmasq..." |
| 139 | apt-get install -d -y dnsmasq >/dev/null |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 140 | |
Tristan Muntsinger | a18d9e5 | 2019-10-24 14:52:38 -0700 | [diff] [blame] | 141 | echo "Shutting down network-manager to prevent interference..." |
| 142 | service network-manager stop |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 143 | if [ $? != 0 ]; then |
Tristan Muntsinger | a18d9e5 | 2019-10-24 14:52:38 -0700 | [diff] [blame] | 144 | echo "error: failed to stop network-manager" |
| 145 | cleanup 1 |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 146 | fi |
| 147 | |
Tristan Muntsinger | a18d9e5 | 2019-10-24 14:52:38 -0700 | [diff] [blame] | 148 | echo "Shutting down networking to prevent interference..." |
| 149 | service networking stop |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 150 | if [ $? != 0 ]; then |
Tristan Muntsinger | a18d9e5 | 2019-10-24 14:52:38 -0700 | [diff] [blame] | 151 | echo "error: failed to stop networking" |
| 152 | cleanup 1 |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 153 | fi |
| 154 | |
Tristan Muntsinger | a18d9e5 | 2019-10-24 14:52:38 -0700 | [diff] [blame] | 155 | echo "Installing dnsmasq..." |
| 156 | apt-get install dnsmasq >/dev/null |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 157 | |
| 158 | echo "Enabling dnsmasq daemon..." |
| 159 | cat /etc/default/dnsmasq | grep "ENABLED" >/dev/null |
| 160 | if [ $? == 0 ]; then |
| 161 | sed -i 's/.*ENABLED.*/ENABLED=1/' /etc/default/dnsmasq |
| 162 | else |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 163 | echo "ENABLED=1" >> /etc/default/dnsmasq |
| 164 | fi |
| 165 | |
| 166 | echo "Configuring dnsmasq for Rock Pi network..." |
| 167 | cat >/etc/dnsmasq.d/${ROCKNET}.conf << EOF |
| 168 | interface=${ROCKNET} |
| 169 | bind-interfaces |
| 170 | except-interface=lo |
| 171 | dhcp-authoritative |
| 172 | leasefile-ro |
| 173 | port=0 |
| 174 | dhcp-range=192.168.0.100,192.168.0.199 |
| 175 | EOF |
| 176 | |
Tristan Muntsinger | a18d9e5 | 2019-10-24 14:52:38 -0700 | [diff] [blame] | 177 | echo "Configuring udev rules..." |
| 178 | cat >/etc/udev/rules.d/82-${ROCKNET}.rules <<EOF |
| 179 | ACTION=="add", SUBSYSTEM=="net", KERNEL=="${ROCKNET}", ENV{NM_UNMANAGED}="1" |
| 180 | EOF |
| 181 | |
| 182 | echo "Configuring network interface..." |
| 183 | cat >/etc/network/interfaces.d/${ROCKNET}.conf <<EOF |
| 184 | auto ${ROCKNET} |
| 185 | iface ${ROCKNET} inet static |
| 186 | address 192.168.0.1 |
| 187 | netmask 255.255.255.0 |
| 188 | EOF |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 189 | |
| 190 | echo "Enabling IP forwarding..." |
| 191 | echo 1 >/proc/sys/net/ipv4/ip_forward |
| 192 | |
| 193 | echo "Creating IP tables rules script..." |
| 194 | cat > /usr/local/sbin/iptables-rockpi.sh << EOF |
| 195 | #!/bin/bash |
| 196 | /sbin/iptables -A FORWARD -i ${ROCKNET} -o ${DEFAULTNET} -m state --state RELATED,ESTABLISHED -j ACCEPT |
| 197 | /sbin/iptables -A FORWARD -i ${ROCKNET} -o ${DEFAULTNET} -j ACCEPT |
| 198 | /sbin/iptables -t nat -A POSTROUTING -o ${DEFAULTNET} -j MASQUERADE |
| 199 | EOF |
| 200 | sudo chown root:root /usr/local/sbin/iptables-rockpi.sh |
| 201 | sudo chmod 750 /usr/local/sbin/iptables-rockpi.sh |
| 202 | |
| 203 | echo "Creating IP tables rules service..." |
| 204 | cat > /etc/systemd/system/iptables-rockpi.service << EOF |
| 205 | [Unit] |
| 206 | Description=iptables rockpi service |
| 207 | After=network.target |
| 208 | |
| 209 | [Service] |
| 210 | Type=oneshot |
| 211 | ExecStart=/usr/local/sbin/iptables-rockpi.sh |
| 212 | RemainAfterExit=true |
| 213 | StandardOutput=journal |
| 214 | |
| 215 | [Install] |
| 216 | WantedBy=multi-user.target |
| 217 | EOF |
| 218 | |
| 219 | echo "Reloading systemd manager configuration..." |
| 220 | sudo systemctl daemon-reload |
| 221 | |
| 222 | echo "Start IP tables rules service..." |
| 223 | sudo systemctl enable iptables-rockpi |
| 224 | sudo systemctl start iptables-rockpi |
| 225 | |
Tristan Muntsinger | a18d9e5 | 2019-10-24 14:52:38 -0700 | [diff] [blame] | 226 | cleanup |
| 227 | |
| 228 | echo "Restarting dnsmasq service..." |
| 229 | service dnsmasq restart |
| 230 | if [ $? != 0 ]; then |
| 231 | echo "error: failed to restart dnsmasq" |
| 232 | exit 1 |
| 233 | fi |
| 234 | |
| 235 | # Verify the Rock Pi was configured correctly |
| 236 | ip link show ${ROCKNET} >/dev/null |
| 237 | if [ $? != 0 ]; then |
| 238 | echo "error: wasn't able to successfully configure connection to Rock Pi" |
| 239 | exit 1 |
| 240 | fi |
| 241 | |
Tristan Muntsinger | 16b4aa6 | 2019-07-30 16:00:17 -0700 | [diff] [blame] | 242 | echo "Searching for Rock Pi's IP address..." |
| 243 | while true; do |
| 244 | rockip=`cat /proc/net/arp | grep ${ROCKNET} | grep -v 00:00:00:00:00:00 | cut -d" " -f1` |
| 245 | if [[ ${#rockip} -ge 7 ]] && [[ ${#rockip} -le 15 ]]; then |
| 246 | break |
| 247 | fi |
| 248 | sleep 0.1 |
| 249 | done |
| 250 | |
| 251 | echo "Writing Rock Pi configuration to ~/.ssh/config..." |
| 252 | USER_HOME=$(getent passwd $SUDO_USER | cut -d: -f6) |
| 253 | grep -w "Host rock01" $USER_HOME/.ssh/config > /dev/null 2>&1 |
| 254 | if [ $? != 0 ]; then |
| 255 | cat >>$USER_HOME/.ssh/config << EOF |
| 256 | Host rock01 |
| 257 | HostName ${rockip} |
| 258 | User vsoc-01 |
| 259 | IdentityFile ~/.ssh/rock01_key |
| 260 | LocalForward 6520 127.0.0.1:6520 |
| 261 | LocalForward 6444 127.0.0.1:6444 |
| 262 | EOF |
| 263 | else |
| 264 | sed -i '/Host rock01/{n;s/.*/ HostName '${rockip}'/}' $USER_HOME/.ssh/config |
| 265 | fi |
| 266 | grep -w "Host rockpi01" $USER_HOME/.ssh/config > /dev/null 2>&1 |
| 267 | if [ $? != 0 ]; then |
| 268 | cat >>$USER_HOME/.ssh/config << EOF |
| 269 | Host rockpi01 |
| 270 | HostName ${rockip} |
| 271 | User vsoc-01 |
| 272 | IdentityFile ~/.ssh/rock01_key |
| 273 | EOF |
| 274 | else |
| 275 | sed -i '/Host rockpi01/{n;s/.*/ HostName '${rockip}'/}' $USER_HOME/.ssh/config |
| 276 | fi |
| 277 | |
| 278 | sudo chown $SUDO_USER:`id -ng $SUDO_USER` $USER_HOME/.ssh/config |
| 279 | sudo chmod 600 $USER_HOME/.ssh/config |
| 280 | |
| 281 | echo "Creating ssh key..." |
| 282 | sudo -u $SUDO_USER echo "n" | sudo -u $SUDO_USER ssh-keygen -q -t rsa -b 4096 -f $USER_HOME/.ssh/rock01_key -N '' >/dev/null 2>&1 |
| 283 | tmpfile=`mktemp` |
| 284 | echo "echo cuttlefish" > "$tmpfile" |
| 285 | chmod a+x "$tmpfile" |
| 286 | chown $SUDO_USER "$tmpfile" |
| 287 | sudo SSH_ASKPASS="${tmpfile}" DISPLAY=:0 su $SUDO_USER -c "setsid -w ssh-copy-id -i ${USER_HOME}/.ssh/rock01_key -o StrictHostKeyChecking=no vsoc-01@${rockip} >/dev/null 2>&1" |
| 288 | if [ $? != 0 ]; then |
| 289 | sed -i "/${rockip}/d" ${USER_HOME}/.ssh/known_hosts |
| 290 | sudo SSH_ASKPASS="${tmpfile}" DISPLAY=:0 su $SUDO_USER -c "setsid -w ssh-copy-id -i ${USER_HOME}/.ssh/rock01_key -o StrictHostKeyChecking=no vsoc-01@${rockip} >/dev/null 2>&1" |
| 291 | if [ $? != 0 ]; then |
| 292 | echo "error: wasn't able to connect to Rock Pi over ssh" |
| 293 | exit 1 |
| 294 | fi |
| 295 | fi |
| 296 | |
| 297 | echo "Successfully configured!" |
| 298 | echo " Host: 192.168.0.1" |
| 299 | echo "RockPi: ${rockip}" |
| 300 | echo "SSH Alias: rock01 (auto port-forwarding)" |
| 301 | echo "SSH Alias: rockpi01 (no port-forwarding)" |