put a bunch of codes into functions

This commit is contained in:
garywill 2021-01-20 13:10:02 +08:00
parent c8c20c3094
commit 51b69cb5e5
2 changed files with 868 additions and 775 deletions

View File

@ -4,7 +4,7 @@ Set Linux as router in one command. Able to Provide Internet, or create Wifi hot
It wraps `iptables`, `dnsmasq` etc. stuff. Use in one command, restore in one command or by `control-c`.
[Buy me a coffee](https://github.com/garywill/receiving/blob/master/receiving_methods.md)
[Buy me a coffee](https://github.com/garywill/receiving/blob/master/receiving_methods.md) :)
## Features
@ -339,7 +339,7 @@ Options:
- WPA3
- Global IPv6
- Refactor clients(neighbors) listing
- Refactor clients(neighbors) listing function
- Explictly ban forwarding if not needed
## Donate

615
lnxrouter Normal file → Executable file
View File

@ -121,69 +121,83 @@ Examples:
EOF
}
if [[ "$1" == "" ]]; then
check_empty_option(){
if [[ "$1" == "" ]]; then
usage
exit 0
fi
fi
}
GATEWAY=
PREFIX6=
IID6=1
IPV6=0
NO4=0
BANLAN=0
DHCP_DNS=gateway
DHCP_DNS6=gateway
dnsmasq_NO_DNS=0
NO_DNSMASQ=0
CATCH_DNS=0
SHOW_DNS_QUERY=0
ETC_HOSTS=0
ADDN_HOSTS=
SUBNET_IFACE=
CONN_IFACE=
INTERNET_IFACE=
THISHOSTNAME=
SHARE_METHOD=nat
TP_PORT=
DNS=
USE_RANDOM_MAC=0
NEW_MACADDR=
OLD_MACADDR=
DAEMONIZE=0
define_global_variables(){
#======== Global variables for user options =====
GATEWAY= # IPv4 address for this host
PREFIX6= # IPv6 LAN address prefix for this host
IID6=1 # IPv6 LAN ID for this host
IPV6=0 # enable ipv6
NO4=0 # no IPv4 Internet
BANLAN=0 # ban clients from accessing private addresses
DHCP_DNS=gateway # which ipv4 DNS the DHCP gives clients
DHCP_DNS6=gateway # which ipv6 DNS the DHCP gives clients
dnsmasq_NO_DNS=0 # disable dns server
NO_DNSMASQ=0 # disable dnsmasq (dns and dhcp)
CATCH_DNS=0 # catch clients 53 port packets
SHOW_DNS_QUERY=0 # log dns
ETC_HOSTS=0
ADDN_HOSTS=
HIDDEN=0
WIFI_IFACE=
VWIFI_IFACE=
AP_IFACE=
CHANNEL=default
WPA_VERSION=2
MAC_FILTER=0
MAC_FILTER_ACCEPT=/etc/hostapd/hostapd.accept
IEEE80211N=0
IEEE80211AC=0
HT_CAPAB='[HT40+]'
VHT_CAPAB=
DRIVER=nl80211
NO_VIRT=0
COUNTRY=
FREQ_BAND=2.4
NO_HAVEGED=0
HOSTAPD_DEBUG_ARGS=
USE_PSK=0
ISOLATE_CLIENTS=0
QR=0
SUBNET_IFACE= # which interface to create network
CONN_IFACE= # which interface user choose to use to create network
INTERNET_IFACE= # which interface to get Internet from
THISHOSTNAME= # this host's name the DNS tells clients
LIST_RUNNING=0
STOP_ID=
LIST_CLIENTS_ID=
CONFDIR=
SHARE_METHOD=nat
TP_PORT= # transparent proxy port
DNS= # upstream DNS
ARGS=( "$@" )
USE_RANDOM_MAC=0
NEW_MACADDR=
OLD_MACADDR=
DAEMONIZE=0
while [[ -n "$1" ]]; do
# wifi hotspot
HIDDEN=0 # hidden wifi hotspot
WIFI_IFACE=
VWIFI_IFACE=
AP_IFACE=
CHANNEL=default
WPA_VERSION=2
MAC_FILTER=0
MAC_FILTER_ACCEPT=/etc/hostapd/hostapd.accept
IEEE80211N=0
IEEE80211AC=0
HT_CAPAB='[HT40+]'
VHT_CAPAB=
DRIVER=nl80211
NO_VIRT=0 # not use virtual interface
COUNTRY=
FREQ_BAND=2.4
NO_HAVEGED=0
HOSTAPD_DEBUG_ARGS=
USE_PSK=0
ISOLATE_CLIENTS=0
USE_IWCONFIG=0 # automatically decided
QR=0 # show wifi qr
#-- to deal with a running instance
LIST_RUNNING=0
STOP_ID=
LIST_CLIENTS_ID=
# -- variables for running
CONFDIR=
}
parse_user_options(){
while [[ -n "$1" ]]; do
case "$1" in
-h|--help)
usage
@ -438,8 +452,11 @@ while [[ -n "$1" ]]; do
exit 1
;;
esac
done
done
}
# seperate ip and port
sep_ip_port() {
local IP
local PORT
@ -472,8 +489,6 @@ sep_ip_port() {
printf -v "$3" %s "$PORT"
}
USE_IWCONFIG=0
is_interface() {
[[ -z "$1" ]] && return 1
[[ -d "/sys/class/net/${1}" ]]
@ -695,6 +710,8 @@ generate_random_ip6() {
PREFIX6="fd$r1:$r2$r3:$r4$r5:$r6$r7::"
}
# start haveged when needed
haveged_watchdog() {
local show_warn=1
@ -719,11 +736,14 @@ haveged_watchdog() {
# only support NetworkManager >= 0.9.9
NM_RUNNING=0
NM_UNM_LIST=
if (which nmcli >/dev/null 2>&1 ) && (nmcli -t -f RUNNING g 2>&1 | grep -E '^running$' >/dev/null 2>&1 ) ; then
nm_initcheck() {
NM_RUNNING=0
NM_UNM_LIST=
if (which nmcli >/dev/null 2>&1 ) && (nmcli -t -f RUNNING g 2>&1 | grep -E '^running$' >/dev/null 2>&1 ) ; then
NM_RUNNING=1
fi
fi
}
nm_knows() {
(nmcli dev show $1 | grep -E "^GENERAL.STATE:" >/dev/null 2>&1 ) && return 0 # nm sees
@ -1011,12 +1031,12 @@ _cleanup() {
ip addr flush ${SUBNET_IFACE}
if [[ -d $CONFDIR/sys_6_conf_iface ]]; then
cp -f $CONFDIR/sys_6_conf_iface/* /proc/sys/net/ipv6/conf/$SUBNET_IFACE/
if [[ -d "$CONFDIR/sys_6_conf_iface" ]]; then
cp -f "$CONFDIR/sys_6_conf_iface/*" "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/"
fi
rm -rf $CONFDIR
if [[ $WIFI_IFACE && $NO_VIRT -eq 0 ]]; then
if [[ "$WIFI_IFACE" && "$NO_VIRT" -eq 0 ]]; then
ip link set down dev ${AP_IFACE}
iw dev ${VWIFI_IFACE} del
dealloc_iface $VWIFI_IFACE
@ -1096,7 +1116,7 @@ clean_exit() { # SIGUSR1
exit 0
}
#========
#== functions to deal with running instances
list_running_conf() {
local x
@ -1144,8 +1164,8 @@ print_client_by_mac() {
local line ipaddr hostname
local mac="$1"
if [[ -f $CONFDIR/dnsmasq.leases ]]; then
line=$(grep " $mac " $CONFDIR/dnsmasq.leases | tail -n 1)
if [[ -f "$CONFDIR/dnsmasq.leases" ]]; then
line=$(grep " $mac " "$CONFDIR/dnsmasq.leases" | tail -n 1)
ipaddr=$(echo "$line" | cut -d' ' -f3)
hostname=$(echo "$line" | cut -d' ' -f4)
fi
@ -1160,7 +1180,7 @@ print_clients_in_leases() {
local line ipaddr hostname
local mac
if [[ -f $CONFDIR/dnsmasq.leases ]]; then
if [[ -f "$CONFDIR/dnsmasq.leases" ]]; then
while read line
do
mac=$(echo "$line" | cut -d' ' -f2)
@ -1169,7 +1189,7 @@ print_clients_in_leases() {
printf "%-20s %-18s %s\n" "MAC" "IP" "Hostname"
printf "%-20s %-18s %s\n" "$mac" "$ipaddr" "$hostname"
done < $CONFDIR/dnsmasq.leases
done < "$CONFDIR/dnsmasq.leases"
fi
}
@ -1191,7 +1211,7 @@ list_clients() {
Use --list-running to find it out."
[[ -z "$CONFDIR" ]] && CONFDIR=$(get_confdir_from_pid "$pid")
if [[ -f $CONFDIR/hostapd.conf && $USE_IWCONFIG -eq 0 ]]; then
if [[ -f "$CONFDIR/hostapd.conf" && $USE_IWCONFIG -eq 0 ]]; then
local awk_cmd='($1 ~ /Station$/) {print $2}'
local client_list=$(iw dev "$subn_iface" station dump | awk "$awk_cmd")
@ -1249,51 +1269,56 @@ send_stop() {
## ========================================================
## ========================================================
if [[ -d /dev/shm ]]; then
init_tmpdir(){
if [[ -d /dev/shm ]]; then
TMPD=/dev/shm
elif [[ -d /run/shm ]]; then
elif [[ -d /run/shm ]]; then
TMPD=/run/shm
else
else
TMPD=/tmp
fi
TMPDIR=$TMPD/lnxrouter_tmp
fi
TMPDIR=$TMPD/lnxrouter_tmp
}
#======
if [[ $LIST_RUNNING -eq 1 ]]; then
check_other_functions(){
if [[ $LIST_RUNNING -eq 1 ]]; then
echo -e "List of running $PROGNAME instances:\n"
list_running
exit 0
fi
fi
if [[ -n "$LIST_CLIENTS_ID" ]]; then
if [[ -n "$LIST_CLIENTS_ID" ]]; then
list_clients "$LIST_CLIENTS_ID"
exit 0
fi
fi
if [[ $(id -u) -ne 0 ]]; then
if [[ $(id -u) -ne 0 ]]; then
echo "You must run it as root." >&2
exit 1
fi
fi
if [[ -n "$STOP_ID" ]]; then
if [[ -n "$STOP_ID" ]]; then
echo "Trying to kill $PROGNAME instance associated with $STOP_ID..."
send_stop "$STOP_ID"
exit 0
fi
fi
}
#=============================================
#=============================================
if [[ $DAEMONIZE -eq 1 && $RUNNING_AS_DAEMON -eq 0 ]]; then
daemonizing_check(){
if [[ $DAEMONIZE -eq 1 && $RUNNING_AS_DAEMON -eq 0 ]]; then
echo "Running as Daemon..."
# run a detached lnxrouter
RUNNING_AS_DAEMON=1 setsid "$0" "${ARGS[@]}" &
exit 0
fi
fi
}
if [[ $WIFI_IFACE ]]; then
#============================
prepare_wifi() {
if [[ $WIFI_IFACE ]]; then
if [[ $FREQ_BAND != 2.4 && $FREQ_BAND != 5 ]]; then
echo "ERROR: Invalid frequency band" >&2
@ -1364,11 +1389,11 @@ if [[ $WIFI_IFACE ]]; then
echo "WARN: If AP doesn't work, read https://github.com/oblique/create_ap/blob/master/howto/realtek.md" >&2
fi
fi
fi
}
[[ "$USE_RANDOM_MAC" -eq 1 ]] && generate_random_mac
if [[ -n "$NEW_MACADDR" ]]; then
check_if_new_mac_valid() {
if [[ -n "$NEW_MACADDR" ]]; then
if ! is_unicast_macaddr "$NEW_MACADDR"; then
echo "ERROR: The first byte of MAC address (${NEW_MACADDR}) must be even" >&2
exit 1
@ -1377,70 +1402,39 @@ if [[ -n "$NEW_MACADDR" ]]; then
if [[ $(get_all_macaddrs | grep -c ${NEW_MACADDR}) -ne 0 ]]; then
echo "WARN: MAC address '${NEW_MACADDR}' already exists" >&2
fi
fi
fi
}
# checks finished
## ========================================================
## ========================================================
echo "PID: $$"
TARGET_IFACE= # This is the existing physical interface to use
if [[ $CONN_IFACE ]]; then
decide_target_interface() {
TARGET_IFACE= # This is the existing physical interface to use
if [[ $CONN_IFACE ]]; then
TARGET_IFACE=$CONN_IFACE
elif [[ $WIFI_IFACE ]]; then
elif [[ $WIFI_IFACE ]]; then
TARGET_IFACE=$WIFI_IFACE
else
else
echo "No target interface specified" 1>&2
exit 1
fi
echo "Target interface is ${TARGET_IFACE}"
fi
echo "Target interface is ${TARGET_IFACE}"
}
[[ "$USE_RANDOM_MAC" -eq 1 ]] && echo "Use random MAC address $NEW_MACADDR"
if [[ ! -n $GATEWAY ]]; then
decide_ip_addresses() {
if [[ ! -n $GATEWAY ]]; then
generate_random_ip4
echo "Use random IPv4 address $GATEWAY"
fi
if [[ $IPV6 -eq 1 && ! -n $PREFIX6 ]]; then
fi
if [[ $IPV6 -eq 1 && ! -n $PREFIX6 ]]; then
generate_random_ip6
echo "Use random IPv6 address ${PREFIX6}${IID6}"
fi
if [[ $IPV6 -eq 1 ]]; then
fi
if [[ $IPV6 -eq 1 ]]; then
GATEWAY6=${PREFIX6}${IID6}
fi
fi
}
if [[ $TP_PORT ]]; then
SHARE_METHOD=redsocks
fi
if [[ $DHCP_DNS != 'gateway' && $DHCP_DNS6 != 'gateway' ]]; then
dnsmasq_NO_DNS=1
fi
#=================
# begin to do some change on config files and system
trap "cleanup" EXIT
trap "clean_exit" SIGINT SIGUSR1 SIGTERM
trap "die" SIGUSR2
mkdir -p $TMPDIR
chmod 755 $TMPDIR 2>/dev/null
cd $TMPDIR || die "Couldn't change directory to linux-router's temporary path"
CONFDIR=$(mktemp -d $TMPDIR/lnxrouter.${TARGET_IFACE}.conf.XXX)
chmod 755 $CONFDIR
#echo "Config dir: $CONFDIR"
echo $$ > $CONFDIR/pid
COMMON_CONFDIR=$TMPDIR/lnxrouter_common.conf
mkdir -p $COMMON_CONFDIR
if [[ $WIFI_IFACE ]]; then
prepare_wifi_interface() {
if [[ $WIFI_IFACE ]]; then
if [[ $USE_IWCONFIG -eq 0 ]]; then
iw dev ${WIFI_IFACE} set power_save off
@ -1489,17 +1483,19 @@ if [[ $WIFI_IFACE ]]; then
AP_IFACE=${WIFI_IFACE}
fi
fi
fi
}
if [[ $WIFI_IFACE ]]; then
decide_subnet_interface() {
if [[ $WIFI_IFACE ]]; then
SUBNET_IFACE=${AP_IFACE}
else
else
SUBNET_IFACE=${TARGET_IFACE}
fi
fi
}
echo "$SUBNET_IFACE" > $CONFDIR/subn_iface
if [[ $WIFI_IFACE ]]; then
write_hostapd_conf() {
if [[ $WIFI_IFACE ]]; then
if [[ -n "$COUNTRY" && $USE_IWCONFIG -eq 0 ]]; then
iw reg set "$COUNTRY"
@ -1515,7 +1511,7 @@ if [[ $WIFI_IFACE ]]; then
[[ $ISOLATE_CLIENTS -eq 1 ]] && echo "Access Point's clients will be isolated!"
# hostapd config
cat <<- EOF > $CONFDIR/hostapd.conf
cat <<- EOF > "$CONFDIR/hostapd.conf"
beacon_int=100
ssid=${SSID}
interface=${AP_IFACE}
@ -1528,42 +1524,42 @@ if [[ $WIFI_IFACE ]]; then
EOF
if [[ -n "$COUNTRY" ]]; then
cat <<- EOF >> $CONFDIR/hostapd.conf
cat <<- EOF >> "$CONFDIR/hostapd.conf"
country_code=${COUNTRY}
ieee80211d=1
EOF
fi
if [[ $FREQ_BAND == 2.4 ]]; then
echo "hw_mode=g" >> $CONFDIR/hostapd.conf
echo "hw_mode=g" >> "$CONFDIR/hostapd.conf"
else
echo "hw_mode=a" >> $CONFDIR/hostapd.conf
echo "hw_mode=a" >> "$CONFDIR/hostapd.conf"
fi
if [[ $MAC_FILTER -eq 1 ]]; then
cat <<- EOF >> $CONFDIR/hostapd.conf
cat <<- EOF >> "$CONFDIR/hostapd.conf"
macaddr_acl=${MAC_FILTER}
accept_mac_file=${MAC_FILTER_ACCEPT}
EOF
fi
if [[ $IEEE80211N -eq 1 ]]; then
cat <<- EOF >> $CONFDIR/hostapd.conf
cat <<- EOF >> "$CONFDIR/hostapd.conf"
ieee80211n=1
ht_capab=${HT_CAPAB}
EOF
fi
if [[ $IEEE80211AC -eq 1 ]]; then
echo "ieee80211ac=1" >> $CONFDIR/hostapd.conf
echo "ieee80211ac=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ -n "$VHT_CAPAB" ]]; then
echo "vht_capab=${VHT_CAPAB}" >> $CONFDIR/hostapd.conf
echo "vht_capab=${VHT_CAPAB}" >> "$CONFDIR/hostapd.conf"
fi
if [[ $IEEE80211N -eq 1 ]] || [[ $IEEE80211AC -eq 1 ]]; then
echo "wmm_enabled=1" >> $CONFDIR/hostapd.conf
echo "wmm_enabled=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ -n "$PASSPHRASE" ]]; then
@ -1573,7 +1569,7 @@ if [[ $WIFI_IFACE ]]; then
else
WPA_KEY_TYPE=psk
fi
cat <<- EOF >> $CONFDIR/hostapd.conf
cat <<- EOF >> "$CONFDIR/hostapd.conf"
wpa=${WPA_VERSION}
wpa_${WPA_KEY_TYPE}=${PASSPHRASE}
wpa_key_mgmt=WPA-PSK
@ -1583,23 +1579,18 @@ if [[ $WIFI_IFACE ]]; then
else
echo "WARN: Wifi is not protected by password" >&2
fi
chmod 600 $CONFDIR/hostapd.conf
fi
chmod 600 "$CONFDIR/hostapd.conf"
fi
}
#===================================================
#===================================================
if [[ $NM_RUNNING -eq 1 ]] && nm_knows $TARGET_IFACE ; then
nm_set_unmanaged ${SUBNET_IFACE}
fi
if [[ $NO_DNSMASQ -eq 0 ]]; then
write_dnsmasq_conf() {
if [[ $NO_DNSMASQ -eq 0 ]]; then
if grep "^nobody:" /etc/group >/dev/null 2>&1 ; then
NOBODY_GROUP="nobody"
else
NOBODY_GROUP="nogroup"
fi
cat <<- EOF > $CONFDIR/dnsmasq.conf
cat <<- EOF > "$CONFDIR/dnsmasq.conf"
user=nobody
group=$NOBODY_GROUP
bind-dynamic
@ -1617,8 +1608,8 @@ if [[ $NO_DNSMASQ -eq 0 ]]; then
# 'log-dhcp'(Extra logging for DHCP) shows too much logs.
# if use '-d', 'log-facility' should = /dev/null
if [[ $SHARE_METHOD == "none" ]]; then
echo "no-resolv" >> $CONFDIR/dnsmasq.conf
echo "no-poll" >> $CONFDIR/dnsmasq.conf
echo "no-resolv" >> "$CONFDIR/dnsmasq.conf"
echo "no-poll" >> "$CONFDIR/dnsmasq.conf"
fi
if [[ "$DHCP_DNS" != "no" ]]; then
if [[ "$DHCP_DNS" == "gateway" ]]; then
@ -1626,22 +1617,22 @@ if [[ $NO_DNSMASQ -eq 0 ]]; then
else
dns_offer="$DHCP_DNS"
fi
echo "dhcp-option-force=option:dns-server,${dns_offer}" >> $CONFDIR/dnsmasq.conf
echo "dhcp-option-force=option:dns-server,${dns_offer}" >> "$CONFDIR/dnsmasq.conf"
fi
if [[ ! "$dnsmasq_NO_DNS" -eq 0 ]]; then
echo "port=0" >> $CONFDIR/dnsmasq.conf
echo "port=0" >> "$CONFDIR/dnsmasq.conf"
fi
[[ -n "$MTU" ]] && echo "dhcp-option-force=option:mtu,${MTU}" >> $CONFDIR/dnsmasq.conf
[[ $ETC_HOSTS -eq 0 ]] && echo no-hosts >> $CONFDIR/dnsmasq.conf
[[ -n "$ADDN_HOSTS" ]] && echo "addn-hosts=${ADDN_HOSTS}" >> $CONFDIR/dnsmasq.conf
[[ -n "$MTU" ]] && echo "dhcp-option-force=option:mtu,${MTU}" >> "$CONFDIR/dnsmasq.conf"
[[ $ETC_HOSTS -eq 0 ]] && echo no-hosts >> "$CONFDIR/dnsmasq.conf"
[[ -n "$ADDN_HOSTS" ]] && echo "addn-hosts=${ADDN_HOSTS}" >> "$CONFDIR/dnsmasq.conf"
if [[ "$THISHOSTNAME" ]]; then
[[ "$THISHOSTNAME" == "-" ]] && THISHOSTNAME="$(cat /etc/hostname)"
echo "interface-name=$THISHOSTNAME,$SUBNET_IFACE" >> $CONFDIR/dnsmasq.conf
echo "interface-name=$THISHOSTNAME,$SUBNET_IFACE" >> "$CONFDIR/dnsmasq.conf"
fi
if [[ ! "$SHOW_DNS_QUERY" -eq 0 ]]; then
echo log-queries=extra >> $CONFDIR/dnsmasq.conf
echo log-queries=extra >> "$CONFDIR/dnsmasq.conf"
fi
if [[ $DNS ]]; then
@ -1649,16 +1640,16 @@ if [[ $NO_DNSMASQ -eq 0 ]]; then
for (( i=1;i<=DNS_count;i++ )); do
sep_ip_port "$(echo $DNS | cut -d, -f$i)" DNS_IP DNS_PORT
[[ "$DNS_PORT" ]] && DNS_PORT_D="#$DNS_PORT"
echo "server=${DNS_IP}${DNS_PORT_D}" >> $CONFDIR/dnsmasq.conf
echo "server=${DNS_IP}${DNS_PORT_D}" >> "$CONFDIR/dnsmasq.conf"
done
cat <<- EOF >> $CONFDIR/dnsmasq.conf
cat <<- EOF >> "$CONFDIR/dnsmasq.conf"
no-resolv
no-poll
EOF
fi
if [[ $IPV6 -eq 1 ]];then
cat <<- EOF >> $CONFDIR/dnsmasq.conf
cat <<- EOF >> "$CONFDIR/dnsmasq.conf"
listen-address=${GATEWAY6}
enable-ra
#quiet-ra
@ -1670,37 +1661,19 @@ if [[ $NO_DNSMASQ -eq 0 ]]; then
else
dns_offer6="$DHCP_DNS6"
fi
echo "dhcp-option=option6:dns-server,${dns_offer6}" >> $CONFDIR/dnsmasq.conf
echo "dhcp-option=option6:dns-server,${dns_offer6}" >> "$CONFDIR/dnsmasq.conf"
fi
fi
fi
#===========================
# initialize subnet interface
ip link set down dev ${SUBNET_IFACE} || die "Failed setting ${SUBNET_IFACE} down"
ip addr flush ${SUBNET_IFACE} || die "Failed flush ${SUBNET_IFACE} IP"
if [[ -n "$NEW_MACADDR" ]]; then
ip link set dev ${SUBNET_IFACE} address ${NEW_MACADDR} || die "Failed setting new MAC address"
fi
if [[ $WIFI_IFACE ]]; then
if which rfkill > /dev/null 2>&1 ; then
PHY=$(get_phy_device ${SUBNET_IFACE})
[[ -n $PHY ]] && rfkill unblock $(rfkill | grep $PHY | awk '{print $1}') >/dev/null 2>&1
fi
fi
}
ip link set up dev ${SUBNET_IFACE} || die "Failed bringing ${SUBNET_IFACE} up"
if [[ $WIFI_IFACE ]]; then
run_wifi_ap_processes() {
if [[ $WIFI_IFACE ]]; then
if [[ $NO_HAVEGED -eq 0 ]]; then
haveged_watchdog &
HAVEGED_WATCHDOG_PID=$!
echo "$HAVEGED_WATCHDOG_PID" > $CONFDIR/haveged_watchdog.pid
echo "$HAVEGED_WATCHDOG_PID" > "$CONFDIR/haveged_watchdog.pid"
echo "haveged_watchdog PID: $HAVEGED_WATCHDOG_PID"
fi
@ -1714,9 +1687,9 @@ if [[ $WIFI_IFACE ]]; then
echo
echo "Starting hostapd"
# hostapd '-P' works only when use '-B' (run in background)
$STDBUF_PATH hostapd $HOSTAPD_DEBUG_ARGS -P $CONFDIR/hostapd.pid $CONFDIR/hostapd.conf &
$STDBUF_PATH hostapd $HOSTAPD_DEBUG_ARGS -P "$CONFDIR/hostapd.pid" "$CONFDIR/hostapd.conf" &
HOSTAPD_PID=$!
echo "$HOSTAPD_PID" > $CONFDIR/hostapd.pid
echo "$HOSTAPD_PID" > "$CONFDIR/hostapd.pid"
echo "hostapd PID: $HOSTAPD_PID"
#while [[ ! -f $CONFDIR/hostapd.pid ]]; do
# sleep 1
@ -1725,28 +1698,171 @@ if [[ $WIFI_IFACE ]]; then
( while [ -e /proc/$HOSTAPD_PID ]; do sleep 10; done ; die "hostapd exited" ) &
sleep 3
fi
}
backup_interface_ipv6_status() {
mkdir "$CONFDIR/sys_6_conf_iface"
if [[ $IPV6 -eq 1 ]]; then
cp "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/accept_ra" \
"/proc/sys/net/ipv6/conf/$SUBNET_IFACE/use_tempaddr" \
"/proc/sys/net/ipv6/conf/$SUBNET_IFACE/addr_gen_mode" \
"$CONFDIR/sys_6_conf_iface/"
echo 0 > "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/accept_ra"
echo 0 > "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/use_tempaddr"
echo 0 > "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/addr_gen_mode"
ip -6 addr add ${GATEWAY6}/64 dev ${SUBNET_IFACE} || die "Failed setting ${SUBNET_IFACE} IPv6"
else
cp "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/disable_ipv6" "$CONFDIR/sys_6_conf_iface/"
echo 1 > "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/disable_ipv6"
fi
}
start_dnsmasq() {
if [[ $NO_DNSMASQ -eq 0 ]]; then
start_dhcp
if which complain > /dev/null 2>&1; then
# openSUSE's apparmor does not allow dnsmasq to read files.
# remove restriction.
complain dnsmasq
fi
echo
echo "Starting dnsmasq"
# Using '-d'(no daemon) dnsmasq will not turn into 'nobody'
# '-x' works only when no '-d'
dnsmasq -k -C "$CONFDIR/dnsmasq.conf" -x "$CONFDIR/dnsmasq.pid" -l "$CONFDIR/dnsmasq.leases" &
#####DNSMASQ_PID=$! # only when with '-d'
######echo "dnsmasq PID: $DNSMASQ_PID" # only when with '-d'
i=0; while [[ ! -f "$CONFDIR/dnsmasq.pid" ]]; do
sleep 1
i=$((i + 1))
if [[ $i -gt 10 ]]; then die "Couldn't get dnsmasq PID" ; fi
done
echo -n "dnsmasq PID: " ; cat "$CONFDIR/dnsmasq.pid"
######(wait $DNSMASQ_PID ; die "dnsmasq failed") & # wait can't deal with non-child
( while [ -e "/proc/$DNSMASQ_PID" ]; do sleep 10; done ; die "dnsmasq exited" ) &
sleep 2
fi
}
check_if_need_rfkill_unblock_wifi() {
if [[ $WIFI_IFACE ]]; then
if which rfkill > /dev/null 2>&1 ; then
PHY=$(get_phy_device ${SUBNET_IFACE})
[[ -n $PHY ]] && rfkill unblock $(rfkill | grep $PHY | awk '{print $1}') >/dev/null 2>&1
fi
fi
}
#=========== Above are functions ======================
#=========== Executing begin ==============================
# show usage and exit if empty option
check_empty_option "$@"
# TODO: some global variables are still defined in those following code
define_global_variables
ARGS=( "$@" )
parse_user_options "$@"
nm_initcheck
init_tmpdir
# will exit after this if user choose to deal with running instances
check_other_functions
# will start new background process and exit this if user choose to daemonize
daemonizing_check
prepare_wifi
[[ "$USE_RANDOM_MAC" -eq 1 ]] && generate_random_mac
check_if_new_mac_valid
# checks finished
## ===== Above don't echo anything if no warning or error====================
## ========================================================
echo "PID: $$"
decide_target_interface
[[ "$USE_RANDOM_MAC" -eq 1 ]] && echo "Use random MAC address $NEW_MACADDR"
decide_ip_addresses
if [[ $TP_PORT ]]; then
SHARE_METHOD=redsocks
fi
if [[ $DHCP_DNS != 'gateway' && $DHCP_DNS6 != 'gateway' ]]; then
dnsmasq_NO_DNS=1
fi
#=================
# begin to do some change on config files and system
trap "cleanup" EXIT
trap "clean_exit" SIGINT SIGUSR1 SIGTERM
trap "die" SIGUSR2
mkdir -p "$TMPDIR"
chmod 755 "$TMPDIR" 2>/dev/null
cd "$TMPDIR" || die "Couldn't change directory to linux-router's temporary path"
CONFDIR="$(mktemp -d $TMPDIR/lnxrouter.${TARGET_IFACE}.conf.XXX)"
chmod 755 "$CONFDIR"
#echo "Config dir: $CONFDIR"
echo $$ > "$CONFDIR/pid"
COMMON_CONFDIR="$TMPDIR/lnxrouter_common.conf"
mkdir -p "$COMMON_CONFDIR"
prepare_wifi_interface
decide_subnet_interface
echo "$SUBNET_IFACE" > "$CONFDIR/subn_iface"
write_hostapd_conf
#===================================================
#===================================================
if [[ $NM_RUNNING -eq 1 ]] && nm_knows $TARGET_IFACE ; then
nm_set_unmanaged ${SUBNET_IFACE}
fi
write_dnsmasq_conf
#===========================
# initialize subnet interface
ip link set down dev ${SUBNET_IFACE} || die "Failed setting ${SUBNET_IFACE} down"
ip addr flush ${SUBNET_IFACE} || die "Failed flush ${SUBNET_IFACE} IP"
if [[ -n "$NEW_MACADDR" ]]; then
ip link set dev ${SUBNET_IFACE} address ${NEW_MACADDR} || die "Failed setting new MAC address"
fi
check_if_need_rfkill_unblock_wifi
ip link set up dev ${SUBNET_IFACE} || die "Failed bringing ${SUBNET_IFACE} up"
run_wifi_ap_processes
ip addr add ${GATEWAY}/24 broadcast ${GATEWAY%.*}.255 dev ${SUBNET_IFACE} || die "Failed setting ${SUBNET_IFACE} IP"
mkdir $CONFDIR/sys_6_conf_iface
if [[ $IPV6 -eq 1 ]]; then
cp /proc/sys/net/ipv6/conf/$SUBNET_IFACE/accept_ra \
/proc/sys/net/ipv6/conf/$SUBNET_IFACE/use_tempaddr \
/proc/sys/net/ipv6/conf/$SUBNET_IFACE/addr_gen_mode \
$CONFDIR/sys_6_conf_iface/
echo 0 > /proc/sys/net/ipv6/conf/$SUBNET_IFACE/accept_ra
echo 0 > /proc/sys/net/ipv6/conf/$SUBNET_IFACE/use_tempaddr
echo 0 > /proc/sys/net/ipv6/conf/$SUBNET_IFACE/addr_gen_mode
ip -6 addr add ${GATEWAY6}/64 dev ${SUBNET_IFACE} || die "Failed setting ${SUBNET_IFACE} IPv6"
else
cp /proc/sys/net/ipv6/conf/$SUBNET_IFACE/disable_ipv6 $CONFDIR/sys_6_conf_iface/
echo 1 > /proc/sys/net/ipv6/conf/$SUBNET_IFACE/disable_ipv6
fi
backup_interface_ipv6_status
# enable Internet sharing
if [[ "$SHARE_METHOD" == "none" ]]; then
@ -1756,16 +1872,16 @@ elif [[ "$SHARE_METHOD" == "nat" ]]; then
[[ "$INTERNET_IFACE" && "$dnsmasq_NO_DNS" -eq 0 ]] && echo -e "\nWARN: You specified Internet interface but this host is providing local DNS, queries may leak to other interfaces!!!\n" >&2
start_nat
[[ "$BANLAN" -eq 1 ]] && start_ban_lan
echo 1 > /proc/sys/net/ipv4/ip_forward || die "Failed enabling system ipv4 forwarding"
echo 1 > "/proc/sys/net/ipv4/ip_forward" || die "Failed enabling system ipv4 forwarding"
if [[ $IPV6 -eq 1 ]]; then
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding || die "Failed enabling system ipv6 forwarding"
echo 1 > "/proc/sys/net/ipv6/conf/all/forwarding" || die "Failed enabling system ipv6 forwarding"
fi
# to enable clients to establish PPTP connections we must
# load nf_nat_pptp module
modprobe nf_nat_pptp > /dev/null 2>&1
elif [[ "$SHARE_METHOD" == "redsocks" ]]; then
if [[ $IPV6 -eq 1 ]]; then
echo 1 > /proc/sys/net/ipv6/conf/$SUBNET_IFACE/forwarding || die "Failed enabling $SUBNET_IFACE ipv6 forwarding"
echo 1 > "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/forwarding" || die "Failed enabling $SUBNET_IFACE ipv6 forwarding"
fi
[[ "$dnsmasq_NO_DNS" -eq 0 && ! $DNS ]] && echo -e "\nWARN: You are using transparent proxy but this host is providing local DNS, this may cause privacy leak !!!\n" >&2
@ -1781,34 +1897,14 @@ fi
[[ "$CATCH_DNS" -eq 1 ]] && start_catch_dns
start_dnsmasq
if [[ $NO_DNSMASQ -eq 0 ]]; then
start_dhcp
echo
echo "== Setting up completed, now linux-router is working =="
if which complain > /dev/null 2>&1; then
# openSUSE's apparmor does not allow dnsmasq to read files.
# remove restriction.
complain dnsmasq
fi
echo
echo "Starting dnsmasq"
# Using '-d'(no daemon) dnsmasq will not turn into 'nobody'
# '-x' works only when no '-d'
dnsmasq -k -C $CONFDIR/dnsmasq.conf -x $CONFDIR/dnsmasq.pid -l $CONFDIR/dnsmasq.leases &
#####DNSMASQ_PID=$! # only when with '-d'
######echo "dnsmasq PID: $DNSMASQ_PID" # only when with '-d'
i=0; while [[ ! -f $CONFDIR/dnsmasq.pid ]]; do
sleep 1
i=$((i + 1))
if [[ $i -gt 10 ]]; then die "Couldn't get dnsmasq PID" ; fi
done
echo -n "dnsmasq PID: " ; cat $CONFDIR/dnsmasq.pid
######(wait $DNSMASQ_PID ; die "dnsmasq failed") & # wait can't deal with non-child
( while [ -e /proc/$DNSMASQ_PID ]; do sleep 10; done ; die "dnsmasq exited" ) &
sleep 2
fi
#============================================================
#============================================================
#============================================================
show_qr() {
local T S P H
@ -1826,15 +1922,12 @@ show_qr() {
echo " qrencode -m 2 -o <file> \"WIFI:T:${T};S:${S};P:${P};H:${H};\""
}
echo
echo "== Setting up completed, now linux-router is working =="
[[ "$QR" -eq 1 ]] && show_qr
# need loop to keep this script running
bash -c "while :; do sleep 8000 ; done " &
KEEP_RUNNING_PID=$!
echo "$KEEP_RUNNING_PID" > $CONFDIR/keep_running.pid
echo "$KEEP_RUNNING_PID" > "$CONFDIR/keep_running.pid"
wait $KEEP_RUNNING_PID
clean_exit