|
|
@@ -0,0 +1,282 @@
|
|
|
+#!/bin/bash
|
|
|
+#
|
|
|
+# Copyright (c) 2019 Clementine Computing LLC.
|
|
|
+#
|
|
|
+# This file is part of PopuFare.
|
|
|
+#
|
|
|
+# PopuFare is free software: you can redistribute it and/or modify
|
|
|
+# it under the terms of the GNU Affero General Public License as published by
|
|
|
+# the Free Software Foundation, either version 3 of the License, or
|
|
|
+# (at your option) any later version.
|
|
|
+#
|
|
|
+# PopuFare is distributed in the hope that it will be useful,
|
|
|
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
+# GNU Affero General Public License for more details.
|
|
|
+#
|
|
|
+# You should have received a copy of the GNU Affero General Public License
|
|
|
+# along with PopuFare. If not, see <https://www.gnu.org/licenses/>.
|
|
|
+#
|
|
|
+
|
|
|
+#THIS FILE IS NOT REALLY A SCRIPT, BUT RATHER A CENTRAL HOLDING TANK FOR SYSTEM CONFIG VALUES...
|
|
|
+#IT SHOULD BE SOURCED BY ALL OTHER SCRIPTS THAT NEED A CONTAINED VALUE, AND MAY SOME DAY BE PARSED
|
|
|
+#BY THE NATIVE APPLICATIONS. THUS: Keep it simple, in the following format:
|
|
|
+#
|
|
|
+##Comment on meaning of variable
|
|
|
+#VARIABLE="value"
|
|
|
+#
|
|
|
+#(variable name in all caps, no space, equals sign, quoted literal value (if there is even a remote chance that the value
|
|
|
+#is one that will be needed by the native app in the future)
|
|
|
+#
|
|
|
+
|
|
|
+BASEDIR="$HOME"
|
|
|
+
|
|
|
+#How long to sleep after a dial attempt before checking if we have a PPP session successfully constructed
|
|
|
+SLEEP_AFTER_DIAL="30"
|
|
|
+
|
|
|
+#How long to wait between redial attempts
|
|
|
+SLEEP_BETWEEN_REDIALS="60"
|
|
|
+
|
|
|
+# How long to sleep after the GRPS session comes up before testing the SSH tunnel (attempting to connect to the 'hello' server)
|
|
|
+#
|
|
|
+SLEEP_BEFORE_TUNNEL_TEST="5"
|
|
|
+
|
|
|
+# How long to sleep after an established tunnel goes down before allowing any SSH tunnel establishment retries
|
|
|
+#
|
|
|
+SLEEP_AFTER_TUNNEL_FAILURE="60"
|
|
|
+
|
|
|
+# How long to sleep after an established tunnel has been aborted
|
|
|
+#
|
|
|
+SLEEP_AFTER_TUNNEL_ABORT="60"
|
|
|
+
|
|
|
+# How many successive ssh tunnel failures do we accept before forcing a hard termination of pppd and a modem reset and redail
|
|
|
+#
|
|
|
+MAX_FAIL_HANGUP="5"
|
|
|
+
|
|
|
+# How frequently to test an SSH tunnel that predates the ppp-dialer.sh process (thus having no right to wait for its PID)
|
|
|
+#
|
|
|
+SLEEP_MONITORING_TUNNEL="120"
|
|
|
+
|
|
|
+# How frequently to perform SSH keepalive messages, and how many of them are allowed to drop before we tear the tunnel down
|
|
|
+# and wait to try again. This gets passed to the SSH client in the following form:
|
|
|
+# -o ServerAliveInterval=$SSH_SERVER_ALIVE_INTERVAL -o ServerAliveCountMax=$SSH_SERVER_ALIVE_MAXDROP
|
|
|
+#
|
|
|
+SSH_SERVER_ALIVE_INTERVAL="15"
|
|
|
+SSH_SERVER_ALIVE_MAXDROP="3"
|
|
|
+
|
|
|
+# These are the default server parameters the system will use if there is not a configured sync server.
|
|
|
+#The system will check
|
|
|
+SSH_DEFAULT_TARGET="$USER@example.com"
|
|
|
+SSH_DEFAULT_PORT="6055"
|
|
|
+SSH_DEFAULT_IDENTITY="$HOME/.ssh/id_rsa_bus"
|
|
|
+
|
|
|
+#This regular expression test is used to make sure we have a valid-looking FQDN or IP address
|
|
|
+SSH_TARGET_VALIDITY_CHECK="^[a-zA-Z][a-zA-Z0-9]*@([a-zA-Z0-9-]+\.)+([a-zA-Z0-9-]+)$"
|
|
|
+
|
|
|
+SSH_TARGET="$SSH_DEFAULT_TARGET"
|
|
|
+SSH_PORT="$SSH_DEFAULT_PORT"
|
|
|
+SSH_IDENTITY="$SSH_DEFAULT_IDENTITY"
|
|
|
+
|
|
|
+#--------------------------------------------------------------------------------
|
|
|
+#This is the list of forwarded ports we bring live when we set up our SSH tunnel:
|
|
|
+
|
|
|
+# 2857 -> AVLS
|
|
|
+AVLS_DAEMON_PORT="2857"
|
|
|
+
|
|
|
+# 7277 -> Bus Pass Daemon
|
|
|
+PASSDB_DAEMON_PORT="7277"
|
|
|
+
|
|
|
+# 2455 -> Billing Log Daemon
|
|
|
+BILLDB_DAEMON_PORT="2455"
|
|
|
+
|
|
|
+# 3556 -> "Hello" Daemon
|
|
|
+HELLO_DAEMON_PORT="3556"
|
|
|
+
|
|
|
+# 8377 -> Update / Version Server
|
|
|
+UPDATE_DAEMON_PORT="8377"
|
|
|
+
|
|
|
+
|
|
|
+# These are used to talk to the "Hello" daemon on the server to verify that
|
|
|
+#actual data can flow before notifying the system that the tunnel is up.
|
|
|
+HELLO_DAEMON_MESSAGE="Hello."
|
|
|
+
|
|
|
+
|
|
|
+#--------------------------------------------------------------------------------
|
|
|
+# This is a list of base ports on the server that we can use for the reverse-phone-home
|
|
|
+#functionality which forwards port BASE + client_id on the server to port 22 (sshd) on
|
|
|
+#the client to allow for remote troubleshooting and manual configuration.
|
|
|
+
|
|
|
+#Enable reverse-phone-home feature
|
|
|
+REVERSE_PHONE_HOME="1"
|
|
|
+
|
|
|
+# This is the base port (on the server) which the numbering for the reverse-phone-home
|
|
|
+#system starts at when numbered by equipment number:
|
|
|
+REVERSE_PHONE_HOME_EQNUM_BASE="10000"
|
|
|
+
|
|
|
+# This is the base port (on the server) which the numbering for the reverse-phone-home
|
|
|
+#system starts at when numbered by serial number (wireless_ip on transition busses):
|
|
|
+REVERSE_PHONE_HOME_SERIALNUM_BASE="30000"
|
|
|
+
|
|
|
+# This is the number above which an equipment number or other token will not be considered
|
|
|
+#as a phone home candidate on account of its likelyhood to overflow into the next port range.
|
|
|
+REVERSE_PHONE_HOME_MAX_TOKEN="19999"
|
|
|
+
|
|
|
+
|
|
|
+#--------------------------------------------------------------------------------
|
|
|
+#These paths lead to dropfiles in /tmp which are used to signal network state
|
|
|
+
|
|
|
+#This dropfile means we have an established GPRS/PPP session
|
|
|
+GPRS_DROPFILE="/tmp/network-is-up"
|
|
|
+#This dropfile means we have an established SSH tunnel to the server
|
|
|
+TUNNEL_DROPFILE="/tmp/tunnel-is-up"
|
|
|
+#This dropfile contains the process ID of our SSH client that's keeping the tunnel open
|
|
|
+SSH_TUNNEL_PIDFILE="/tmp/ssh_tunnel.pid"
|
|
|
+#This dropfile contains identifying information about our ethernet card, cell modem, and SIM
|
|
|
+NETWORK_ID_DROPFILE="/tmp/net_ids"
|
|
|
+
|
|
|
+#This dropfile becomes present to notify the update process to abort:
|
|
|
+UPDATE_ABORT_DROPFILE="/tmp/abort_update"
|
|
|
+TUNNEL_ABORT_DROPFILE="/tmp/abort_tunnel"
|
|
|
+
|
|
|
+
|
|
|
+#############################################################
|
|
|
+
|
|
|
+FIX_PACKAGE_PERMS="1"
|
|
|
+
|
|
|
+########################################################## Used only if FIX_PACKAGE_PERMS is nonzero ##############
|
|
|
+#This specifies who should own installed packages
|
|
|
+PACKAGE_OWNER_STRING="root:root"
|
|
|
+
|
|
|
+#These are the permissions applied to stuff in the bin directory
|
|
|
+PACKAGE_BIN_PERMISSIONS="755"
|
|
|
+#This is the egrep expression that must match to qualify something as a binary
|
|
|
+PACKAGE_BIN_PATTERN='(^[/]?'$BASEDIR'/bin/[a-z_A-Z0-9.]+$)|(.*\.sh$)'
|
|
|
+
|
|
|
+#These are the permissions applied to SSH related config files and directories
|
|
|
+PACKAGE_SSH_STRICT_FILE_PERMISSIONS="600"
|
|
|
+PACKAGE_SSH_MILD_FILE_PERMISSIONS="644"
|
|
|
+PACKAGE_SSH_DIR_PERMISSIONS="700"
|
|
|
+
|
|
|
+#this one is only used in its ALWAYS case
|
|
|
+PACKAGE_SYS_DIR_PERMISSIONS="755"
|
|
|
+
|
|
|
+#These are the egrep expressions that must match to qualify something as an SSH file or directory
|
|
|
+PACKAGE_SSH_STRICT_FILE_PATTERN="(^[/]?etc/ppp/id_rsa[^\.]*$)|(^[/]?root/\.ssh/id_rsa[^\.]*$)|(^[/]?root/\.ssh/authorized_keys)"
|
|
|
+PACKAGE_SSH_MILD_FILE_PATTERN="(^[/]?root/\.ssh/known_hosts)|(^[/]?etc/ppp/id_rsa[^\.]*.pub$)|(^[/]?root/\.ssh/id_rsa[^\.]*.pub)"
|
|
|
+PACKAGE_SSH_DIR_PATTERN="(^[/]?root[/]?$)|(^[/]?root/\.ssh[/]?$)"
|
|
|
+
|
|
|
+#These are the list of files to ALWAYS reset permissions on (whether or not they are in the update)
|
|
|
+ALWAYS_SSH_DIR_LIST="/root /root/.ssh"
|
|
|
+ALWAYS_SSH_STRICT_FILE_LIST="/root/.ssh/id_rsa /etc/ppp/id_rsa_bus /root/.ssh/authorized_keys $SYNC_PRIVATE_KEY"
|
|
|
+ALWAYS_SSH_MILD_FILE_LIST="/root/.ssh/known_hosts /root/.ssh/id_rsa.pub /etc/ppp/id_rsa_bus.pub /etc/ssh/sshd_config"
|
|
|
+ALWAYS_BIN_LIST="$BASEDIR/bin/init_bus.sh $BASEDIR/bin/update_loop.sh $BASEDIR/bin/apply_update.sh $BASEDIR/bin/fix_pkg_perm.sh $BASEDIR/bin/get_net_ids.sh"
|
|
|
+
|
|
|
+ALWAYS_SYS_DIR_LIST="/etc /etc/ssh /etc/ppp"
|
|
|
+
|
|
|
+DEFAULT_EXTRACT_PATH="/"
|
|
|
+EXTRACT_PATH_FILE="/tmp/pkg_extract_path"
|
|
|
+
|
|
|
+##################################################################################################################
|
|
|
+
|
|
|
+
|
|
|
+#These paths point to important bits of information for synchronizing
|
|
|
+EQUIP_NUM_FILE="$BASEDIR/config/equipnum.txt"
|
|
|
+SERIAL_NUM_FILE="$BASEDIR/config/serial_num"
|
|
|
+
|
|
|
+SERVER_CONFIG_DIR="$BASEDIR/config/server"
|
|
|
+
|
|
|
+SERVER_LIST_FILE="$SERVER_CONFIG_DIR/server_list"
|
|
|
+
|
|
|
+SYNC_DESC_FILE="$SERVER_CONFIG_DIR/sync_server_desc"
|
|
|
+SYNC_TARGET_FILE="$SERVER_CONFIG_DIR/sync_target"
|
|
|
+SYNC_PORT_FILE="$SERVER_CONFIG_DIR/sync_port"
|
|
|
+SYNC_KNOWN_HOSTS="/root/.ssh/known_hosts"
|
|
|
+SYNC_PRIVATE_KEY="/etc/ppp/id_rsa_client"
|
|
|
+
|
|
|
+###############################################################################################
|
|
|
+# CONFIGURATION VALUES USED PRIMARILY BY THE UPDATE LOOP SCRIPT #
|
|
|
+###############################################################################################
|
|
|
+
|
|
|
+#How long for update_loop.sh to sleep after spawning the client supervisor before (potentially) respawning it
|
|
|
+SLEEP_AFTER_SPAWN="60"
|
|
|
+
|
|
|
+#How long to sleep between attempts to download patches from the server
|
|
|
+SLEEP_BETWEEN_UPDATES="60"
|
|
|
+
|
|
|
+#The directory in which the current patch state is to be found
|
|
|
+CHECKSUM_AND_VERSION_PATH="$BASEDIR/config/"
|
|
|
+
|
|
|
+###############################################################################################
|
|
|
+# BELOW HERE, COMPOUND OPTIONS ARE ALLOWED (things that use variable substitution, etc...)#
|
|
|
+###############################################################################################
|
|
|
+
|
|
|
+#This looks for all environment variables that specify a port that we must forward...
|
|
|
+TUNNEL_PORT_LIST="`set | egrep "^[A-Z]+_DAEMON_PORT=" | cut -d '=' -f2 | egrep '^[0-9]+$' | xargs echo`"
|
|
|
+
|
|
|
+#This gathers the above list into something we can just hand to the SSH client...
|
|
|
+SSH_FORWARDS="`for port in $TUNNEL_PORT_LIST; do echo -n " -L$port:localhost:$port"; done`"
|
|
|
+
|
|
|
+#These are the flags to SSH that are specific to setting up the tunnel
|
|
|
+SSH_TUNNEL_FLAGS="-n -N -x"
|
|
|
+
|
|
|
+#These are the flags to SSH that are specific to our connection to the target host
|
|
|
+SSH_TARGET_OPTIONS="-o StrictHostKeyChecking=no"
|
|
|
+
|
|
|
+#These are the flags to SSH that specify the behavior of the protocol-level keepalive messages
|
|
|
+SSH_KEEPALIVE_OPTIONS="-o ServerAliveInterval=$SSH_SERVER_ALIVE_INTERVAL -o ServerAliveCountMax=$SSH_SERVER_ALIVE_MAXDROP"
|
|
|
+
|
|
|
+SSH_OPTIONS="$SSH_TUNNEL_FLAGS $SSH_KEEPALIVE_OPTIONS $SSH_TARGET_OPTIONS"
|
|
|
+SCP_OPTIONS="$SSH_KEEPALIVE_OPTIONS $SSH_TARGET_OPTIONS"
|
|
|
+
|
|
|
+# This function kills any currently open SSH or SCP sessions and puts dropfiles in /tmp telling
|
|
|
+#ppp-dialer.sh and update_loop.sh to refresh their Sync server parameters with the generate_ssh_targets
|
|
|
+#function before attempting to reconnect.
|
|
|
+#
|
|
|
+abort_tunnel_and_update() {
|
|
|
+
|
|
|
+ touch $UPDATE_ABORT_DROPFILE
|
|
|
+ touch $TUNNEL_ABORT_DROPFILE
|
|
|
+
|
|
|
+ sync
|
|
|
+ sleep 1
|
|
|
+
|
|
|
+ killall ssh
|
|
|
+ killall scp
|
|
|
+}
|
|
|
+
|
|
|
+# This function uses the dropfiles left by unpack_server_data.sh and constructs new SSH and SCP
|
|
|
+#parameters suitable to connect to the specified server. If there is no server specified, or if the
|
|
|
+#specified server does not pass a sanity check then the default server will be used.
|
|
|
+#
|
|
|
+function generate_ssh_targets
|
|
|
+{
|
|
|
+
|
|
|
+ if [ -f $SYNC_TARGET_FILE ]; then
|
|
|
+
|
|
|
+ alt_target="`cat $SYNC_TARGET_FILE`"
|
|
|
+ if echo "$alt_target" | egrep -q "$SSH_TARGET_VALIDITY_CHECK"; then
|
|
|
+
|
|
|
+ SSH_TARGET="`cat $SYNC_TARGET_FILE`"
|
|
|
+ SSH_PORT="`cat $SYNC_PORT_FILE`"
|
|
|
+ SSH_IDENTITY="$SYNC_PRIVATE_KEY"
|
|
|
+
|
|
|
+ echo "$0: Using sync server $SSH_TARGET port $SSH_PORT"
|
|
|
+ else
|
|
|
+
|
|
|
+ SSH_TARGET="$SSH_DEFAULT_SYNC_TARGET"
|
|
|
+ SSH_PORT="$SSH_DEFAULT_SYNC_PORT"
|
|
|
+ SSH_IDENTITY="$SSH_DEFAULT_IDENTITY"
|
|
|
+
|
|
|
+ echo "$0: Specified sync server name $alt_target is malformed. Using default $SSH_DEFAULT_SYNC_TARGET port $SSH_DEFAULT_SYNC_PORT"
|
|
|
+ fi
|
|
|
+ else
|
|
|
+
|
|
|
+ SSH_TARGET="$SSH_DEFAULT_TARGET"
|
|
|
+ SSH_PORT="$SSH_DEFAULT_PORT"
|
|
|
+ SSH_IDENTITY="$SSH_DEFAULT_IDENTITY"
|
|
|
+
|
|
|
+ echo "$0: No sync server selected. Using default $SSH_DEFAULT_TARGET port $SSH_DEFAULT_PORT"
|
|
|
+ fi
|
|
|
+
|
|
|
+}
|
|
|
+
|