Public
Snippet $237 authored by Rafael Monnerat

grandenet.sh

Edited
grandenet.sh
#!/bin/bash
# interactively run re6stnet on NayuOS

mountpoint="/media/removable"
configdir="/home/chronos/user/.re6stconf"
configfile="${configdir}/re6stnet.conf"
# shill should not care about these interfaces
blacklist_option="re6stnet-tcp,re6stnet10,re6stnet9,re6stnet8,re6stnet7,re6stnet6,re6stnet5,re6stnet4,re6stnet3,re6stnet2,re6stnet1,tun0,tun1,tun2"
logfile="/var/log/grandenet"

# Require script to be run via sudo, but not as root
if [[ $EUID != 0 ]]; then
    echo "This script requires root privileges! However, it may fail if running with root user. Please, run it again and prefix the command by 'sudo'."
    exit 1
fi

function configure {
    configoptions=('default')

    echo "
################ New configuration generation ####################
"
    read -p "Please, give your token (you can get one on http://www.grandenet.cn): " token
    if [ "${token}" == "" ] ; then
        echo "No token given. Exiting."
        exit 1
    fi

    read -p "Give the registry you want to use [http://re6stnet.grandenet.cn]: " registry
    if [ "${registry}" == "" ] ; then
        registry="http://re6stnet.grandenet.cn"
    fi


    # do not assume everything is clean already
    if [[ -f ${configdir} ]] ; then
        echo "A file called ${configdir} has been found and removed."
        rm "${configdir}"
    elif [[ $(ls -A "${configdir}"/* 2> /dev/null ) ]] ; then
        echo "Some files are into ${configdir}. Moving them to directory ${configdir}/old"
        install -d ${configdir}/old && mv "${configdir}"/* "${configdir}/old" 2> /dev/null
    fi

    re6st-conf --registry "${registry}" --token "${token}" --dir "${configdir}" || { echo "An error occured while generating the configuration. Created files in '${configdir}': " ; ls "${configdir}" ; echo "Exiting." ; exit 1 ;}

    printf '%s\n' "${configoptions[@]}" >> "${configfile}"

    echo "
*filter
:FORWARD ACCEPT [0:0]
:OUTPUT DROP [0:0]
-A INPUT -p udp -m udp --dport 6696 -j ACCEPT
-A INPUT -p udp -m udp --dport 326 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 9684 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 50005 -j ACCEPT
-A OUTPUT -p udp -m udp --dport 6696 -j ACCEPT
-A OUTPUT -p udp -m udp --dport 326 -j ACCEPT
COMMIT
" > "${configdir}/ip6tables.conf"

    read -p "Save configuration on an external device [Y/n]? " save
    if [ "$save" != "n" -a "$save" != "N" ] ; then
        if [[ $(ls -d "${mountpoint}"/*) ]]; then
            echo "Mounted external partitions list:"
            for mnt in "${mountpoint}"/* ; do
                echo "    * $mnt"
            done
        else
            echo "No external device partition mounted on ${mountpoint}."
        fi
        read -e -p "A folder called 're6stconf' will be generated in order to backup the freshly created configuration. Where should it be created (use tabulation for autocompletion)? " place
        place+="/re6stconf"
        echo "configuration will be saved in $place"

        install -d "${place}"
        for file in "${configdir}"/* ; do
            install "${file}" "${place}"
        done
    else
        echo -e "Configuration will be placed in ${configdir},\e[31m please do a manual backup later or you could lose your access to this network\e[0m."
    fi
    echo "
##################################################################
"
}

# function to clean up and exit
cleanup() {
    echo -e "
\e[1mCleaning up and exiting...\e[0m"
    if [ -r "${configdir}/ip6tables.save" ] ; then
         echo "Removing changes in ip6tables rules"
         ip6tables-restore < "${configdir}/ip6tables.save"
         rm "${configdir}/ip6tables.save"
         rm "${configdir}/current_ip6tables.conf"
    fi
}


echo "Welcome on Grandenet network. It is a resilient overlay mesh network providing IPv6."
if [[ $(pgrep re6stnet) ]] ; then
    iproute=$(ip -6 r | grep default )
    if [[ ${iproute} == "" ]] ; then
        echo -e "        \e[0;33mState: Starting...\e[0m
        You will soon be part of grandenet network, please, be patient and give it some time to connect!"
    else
        echo -e "        \e[0;32mState: Connected.\e[0m You are part of grandenet network.
        Your default IPv6 route is:
        ${iproute}"
    fi
    read -p "Do you want to leave grandenet network [y/N]? " stop
    if [ "$stop" == "y" -o "$stop" == "Y" ] ; then
        cleanup
        echo "Killing re6stnet process..."
        killall re6stnet
        echo "Exiting."
        exit 0
    else
        exit 0
    fi
fi

echo -e "        \e[0;31mState: Not connected.\e[0m
        After answering a few questions, you will be able to connect."


# there may be a configuration already installed
usefound="n"
path=""
if [ -r "${configfile}" -a -r "${configdir}/cert.crt" -a -r "${configdir}/cert.key" -a -r "${configdir}/ca.crt" ]; then
    read -p "Configuration was found in '${configdir}'. Use it: [Y/n]? (answering n will delete the previous config) " usefound
    if [ "$usefound" != "n" -a "$usefound" != "N" ]; then
        path=${configdir}
    else
        rm -R "${configdir}"
    fi
fi

# try to find a saved configuration
if [ ! -r "${configfile}" ] ; then
    echo "Looking for configuration directory on external devices..."
    path=$(find "${mountpoint}" -maxdepth 3 -type d | grep re6stconf | head -n 1)
    if [ "${path}" != "" ] ; then
        read -p "Use configuration directory found at: ${path} [Y/n]? " usefound
    else
        echo "No configuration directory was found."
    fi
fi

install -d "${configdir}"

# don't use possibly found configuration(s) if specified
if [ "$usefound" == "n" -o "$usefound" == "N" ]; then
    read -p "Do you already have a valid configuration that you would like to use (u) or do you need to generate a new configuration (n) [u/N]? " action
    if [ "${action}" == "U" -o "${action}" == "u" ] ; then
        read -e -p "Please give a path to the directory containing the re6stnet configuration if you already generated one: " path
        if [ "$path" == "" ] ; then
            echo "No configuration path given. Exiting."
            exit 1
        fi
    else
        configure || { echo "Problem occured while generating new configuration. Exiting." ; exit 1 ; }
        path="${configdir}"
    fi
fi

# copy the config if needed
if [ "${path}" == "${configdir}" -a -r "${path}/re6stnet.conf" -a -r "${path}/cert.crt" -a -r "${path}/cert.key" -a -r "${path}/ca.crt" ]; then
    echo "Using existing configuration in '${configdir}'."
elif [ ! -d "$path" ] ; then
    echo "Invalid path: '${path}' is not a directory. Exiting."
    exit 1
elif [ -r "${path}/re6stnet.conf" -a -r "${path}/cert.crt" -a -r "${path}/cert.key" -a -r "${path}/ca.crt" ]; then
    echo "Copying config to '${configdir}'..."
    for file in "${path}"/* ; do
        install -m 600 "${file}" "${configdir}"
    done
else
    echo "Some configuration files are missing in '${path}' so it is not possible to connect to grandenet. Files present are:"
    ls ${path}
    echo "Try generating another configuration or use a different one next time. Exiting."
    exit 1
fi

# saving current firewall configuration
ip6tables-save > "${configdir}/ip6tables.save"
cp "${configdir}/ip6tables.save" "${configdir}/current_ip6tables.conf"

# setup shill network manager
if [[ $( pgrep -a shill | grep ${blacklist_option} ) ]] ; then
    echo "shill was started with the right blacklist." >> ${logfile}
else
    read -p "The network manager shill was not started with the right blacklisted devices list. Restart it [Y/n]? " confirm
    if [ "$confirm" != "n" -a "$confirm" != "N" ] ; then
        if [[ $( status shill_respawn | grep running ) ]] ; then
            # shill_respawn job does not allow to pass arguments to shill
            stop shill_respawn
        fi
        if [[ $( status shill | grep running ) ]] ; then
            stop shill
        fi
        start shill BLACKLISTED_DEVICES="${blacklist_option}"
        # wait a bit for the interfaces to be back
        for i in {0..4} ; do
            echo -n "." ; sleep 1
        done
        echo ""
    fi
fi


# firewall configuration
if [ -r "${configdir}/ip6tables.conf" ] ; then
    # remove line containing "COMMIT"
    # add few rules
    cat "${configdir}/ip6tables.conf" >> "${configdir}/current_ip6tables.conf"
    ip6tables-restore < "${configdir}/current_ip6tables.conf"
else
    # accept ports needed for re6stnet
    ip6tables -P FORWARD ACCEPT
    ip6tables -A OUTPUT -p udp --dport 6696 -j ACCEPT
    ip6tables -A OUTPUT -p udp --dport 326 -j ACCEPT
    ip6tables -A INPUT -p udp --dport 6696 -j ACCEPT
    ip6tables -A INPUT -p udp --dport 326 -j ACCEPT

    # Accept ports needed for running any webrunner
    ip6tables  -A INPUT -p tcp --dport 9684 -j ACCEPT
    ip6tables  -A INPUT -p tcp --dport 50005 -j ACCEPT
fi

sysctl net.ipv6.conf.all.accept_ra=1  >> "${logfile}" 2>&1
sysctl net.ipv6.conf.all.forwarding=1 >> "${logfile}" 2>&1

echo "re6st will start, it may take a few minutes before beeing usable"

echo "
For debugging purpose, logs will be stored in ${logfile}.
To stop grandenet, run 'sudo ${0##*/}' command again."

# join re6st network
cd "${configdir}"
nohup re6stnet @re6stnet.conf >> "${logfile}" 2>&1 &