#!/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 . # #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/bus' #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="30" # 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="bus@example.com" SSH_DEFAULT_PORT="6055" SSH_DEFAULT_IDENTITY="$BASEDIR/.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="/" DEFAULT_EXTRACT_PATH="/home/bus" 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 }