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`. 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 ## Features
@ -339,7 +339,7 @@ Options:
- WPA3 - WPA3
- Global IPv6 - Global IPv6
- Refactor clients(neighbors) listing - Refactor clients(neighbors) listing function
- Explictly ban forwarding if not needed - Explictly ban forwarding if not needed
## Donate ## Donate

447
lnxrouter Normal file → Executable file
View File

@ -121,40 +121,48 @@ Examples:
EOF EOF
} }
check_empty_option(){
if [[ "$1" == "" ]]; then if [[ "$1" == "" ]]; then
usage usage
exit 0 exit 0
fi fi
}
GATEWAY=
PREFIX6=
IID6=1 define_global_variables(){
IPV6=0 #======== Global variables for user options =====
NO4=0 GATEWAY= # IPv4 address for this host
BANLAN=0 PREFIX6= # IPv6 LAN address prefix for this host
DHCP_DNS=gateway IID6=1 # IPv6 LAN ID for this host
DHCP_DNS6=gateway IPV6=0 # enable ipv6
dnsmasq_NO_DNS=0 NO4=0 # no IPv4 Internet
NO_DNSMASQ=0 BANLAN=0 # ban clients from accessing private addresses
CATCH_DNS=0 DHCP_DNS=gateway # which ipv4 DNS the DHCP gives clients
SHOW_DNS_QUERY=0 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 ETC_HOSTS=0
ADDN_HOSTS= ADDN_HOSTS=
SUBNET_IFACE=
CONN_IFACE= SUBNET_IFACE= # which interface to create network
INTERNET_IFACE= CONN_IFACE= # which interface user choose to use to create network
THISHOSTNAME= INTERNET_IFACE= # which interface to get Internet from
THISHOSTNAME= # this host's name the DNS tells clients
SHARE_METHOD=nat SHARE_METHOD=nat
TP_PORT= TP_PORT= # transparent proxy port
DNS= DNS= # upstream DNS
USE_RANDOM_MAC=0 USE_RANDOM_MAC=0
NEW_MACADDR= NEW_MACADDR=
OLD_MACADDR= OLD_MACADDR=
DAEMONIZE=0 DAEMONIZE=0
HIDDEN=0 # wifi hotspot
HIDDEN=0 # hidden wifi hotspot
WIFI_IFACE= WIFI_IFACE=
VWIFI_IFACE= VWIFI_IFACE=
AP_IFACE= AP_IFACE=
@ -167,22 +175,28 @@ IEEE80211AC=0
HT_CAPAB='[HT40+]' HT_CAPAB='[HT40+]'
VHT_CAPAB= VHT_CAPAB=
DRIVER=nl80211 DRIVER=nl80211
NO_VIRT=0 NO_VIRT=0 # not use virtual interface
COUNTRY= COUNTRY=
FREQ_BAND=2.4 FREQ_BAND=2.4
NO_HAVEGED=0 NO_HAVEGED=0
HOSTAPD_DEBUG_ARGS= HOSTAPD_DEBUG_ARGS=
USE_PSK=0 USE_PSK=0
ISOLATE_CLIENTS=0 ISOLATE_CLIENTS=0
QR=0 USE_IWCONFIG=0 # automatically decided
QR=0 # show wifi qr
#-- to deal with a running instance
LIST_RUNNING=0 LIST_RUNNING=0
STOP_ID= STOP_ID=
LIST_CLIENTS_ID= LIST_CLIENTS_ID=
# -- variables for running
CONFDIR= CONFDIR=
}
ARGS=( "$@" )
parse_user_options(){
while [[ -n "$1" ]]; do while [[ -n "$1" ]]; do
case "$1" in case "$1" in
-h|--help) -h|--help)
@ -439,7 +453,10 @@ while [[ -n "$1" ]]; do
;; ;;
esac esac
done done
}
# seperate ip and port
sep_ip_port() { sep_ip_port() {
local IP local IP
local PORT local PORT
@ -472,8 +489,6 @@ sep_ip_port() {
printf -v "$3" %s "$PORT" printf -v "$3" %s "$PORT"
} }
USE_IWCONFIG=0
is_interface() { is_interface() {
[[ -z "$1" ]] && return 1 [[ -z "$1" ]] && return 1
[[ -d "/sys/class/net/${1}" ]] [[ -d "/sys/class/net/${1}" ]]
@ -695,6 +710,8 @@ generate_random_ip6() {
PREFIX6="fd$r1:$r2$r3:$r4$r5:$r6$r7::" PREFIX6="fd$r1:$r2$r3:$r4$r5:$r6$r7::"
} }
# start haveged when needed # start haveged when needed
haveged_watchdog() { haveged_watchdog() {
local show_warn=1 local show_warn=1
@ -719,11 +736,14 @@ haveged_watchdog() {
# only support NetworkManager >= 0.9.9 # only support NetworkManager >= 0.9.9
nm_initcheck() {
NM_RUNNING=0 NM_RUNNING=0
NM_UNM_LIST= 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 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 NM_RUNNING=1
fi fi
}
nm_knows() { nm_knows() {
(nmcli dev show $1 | grep -E "^GENERAL.STATE:" >/dev/null 2>&1 ) && return 0 # nm sees (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} ip addr flush ${SUBNET_IFACE}
if [[ -d $CONFDIR/sys_6_conf_iface ]]; then if [[ -d "$CONFDIR/sys_6_conf_iface" ]]; then
cp -f $CONFDIR/sys_6_conf_iface/* /proc/sys/net/ipv6/conf/$SUBNET_IFACE/ cp -f "$CONFDIR/sys_6_conf_iface/*" "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/"
fi fi
rm -rf $CONFDIR 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} ip link set down dev ${AP_IFACE}
iw dev ${VWIFI_IFACE} del iw dev ${VWIFI_IFACE} del
dealloc_iface $VWIFI_IFACE dealloc_iface $VWIFI_IFACE
@ -1096,7 +1116,7 @@ clean_exit() { # SIGUSR1
exit 0 exit 0
} }
#======== #== functions to deal with running instances
list_running_conf() { list_running_conf() {
local x local x
@ -1144,8 +1164,8 @@ print_client_by_mac() {
local line ipaddr hostname local line ipaddr hostname
local mac="$1" local mac="$1"
if [[ -f $CONFDIR/dnsmasq.leases ]]; then if [[ -f "$CONFDIR/dnsmasq.leases" ]]; then
line=$(grep " $mac " $CONFDIR/dnsmasq.leases | tail -n 1) line=$(grep " $mac " "$CONFDIR/dnsmasq.leases" | tail -n 1)
ipaddr=$(echo "$line" | cut -d' ' -f3) ipaddr=$(echo "$line" | cut -d' ' -f3)
hostname=$(echo "$line" | cut -d' ' -f4) hostname=$(echo "$line" | cut -d' ' -f4)
fi fi
@ -1160,7 +1180,7 @@ print_clients_in_leases() {
local line ipaddr hostname local line ipaddr hostname
local mac local mac
if [[ -f $CONFDIR/dnsmasq.leases ]]; then if [[ -f "$CONFDIR/dnsmasq.leases" ]]; then
while read line while read line
do do
mac=$(echo "$line" | cut -d' ' -f2) 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" "IP" "Hostname"
printf "%-20s %-18s %s\n" "$mac" "$ipaddr" "$hostname" printf "%-20s %-18s %s\n" "$mac" "$ipaddr" "$hostname"
done < $CONFDIR/dnsmasq.leases done < "$CONFDIR/dnsmasq.leases"
fi fi
} }
@ -1191,7 +1211,7 @@ list_clients() {
Use --list-running to find it out." Use --list-running to find it out."
[[ -z "$CONFDIR" ]] && CONFDIR=$(get_confdir_from_pid "$pid") [[ -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 awk_cmd='($1 ~ /Station$/) {print $2}'
local client_list=$(iw dev "$subn_iface" station dump | awk "$awk_cmd") local client_list=$(iw dev "$subn_iface" station dump | awk "$awk_cmd")
@ -1249,7 +1269,7 @@ send_stop() {
## ======================================================== ## ========================================================
## ======================================================== ## ========================================================
init_tmpdir(){
if [[ -d /dev/shm ]]; then if [[ -d /dev/shm ]]; then
TMPD=/dev/shm TMPD=/dev/shm
elif [[ -d /run/shm ]]; then elif [[ -d /run/shm ]]; then
@ -1258,9 +1278,11 @@ else
TMPD=/tmp TMPD=/tmp
fi fi
TMPDIR=$TMPD/lnxrouter_tmp TMPDIR=$TMPD/lnxrouter_tmp
}
#====== #======
check_other_functions(){
if [[ $LIST_RUNNING -eq 1 ]]; then if [[ $LIST_RUNNING -eq 1 ]]; then
echo -e "List of running $PROGNAME instances:\n" echo -e "List of running $PROGNAME instances:\n"
list_running list_running
@ -1282,17 +1304,20 @@ if [[ -n "$STOP_ID" ]]; then
send_stop "$STOP_ID" send_stop "$STOP_ID"
exit 0 exit 0
fi fi
}
#=============================================
#=============================================
daemonizing_check(){
if [[ $DAEMONIZE -eq 1 && $RUNNING_AS_DAEMON -eq 0 ]]; then if [[ $DAEMONIZE -eq 1 && $RUNNING_AS_DAEMON -eq 0 ]]; then
echo "Running as Daemon..." echo "Running as Daemon..."
# run a detached lnxrouter # run a detached lnxrouter
RUNNING_AS_DAEMON=1 setsid "$0" "${ARGS[@]}" & RUNNING_AS_DAEMON=1 setsid "$0" "${ARGS[@]}" &
exit 0 exit 0
fi fi
}
#============================
prepare_wifi() {
if [[ $WIFI_IFACE ]]; then if [[ $WIFI_IFACE ]]; then
if [[ $FREQ_BAND != 2.4 && $FREQ_BAND != 5 ]]; then if [[ $FREQ_BAND != 2.4 && $FREQ_BAND != 5 ]]; then
@ -1365,9 +1390,9 @@ if [[ $WIFI_IFACE ]]; then
fi fi
fi fi
}
[[ "$USE_RANDOM_MAC" -eq 1 ]] && generate_random_mac check_if_new_mac_valid() {
if [[ -n "$NEW_MACADDR" ]]; then if [[ -n "$NEW_MACADDR" ]]; then
if ! is_unicast_macaddr "$NEW_MACADDR"; then if ! is_unicast_macaddr "$NEW_MACADDR"; then
echo "ERROR: The first byte of MAC address (${NEW_MACADDR}) must be even" >&2 echo "ERROR: The first byte of MAC address (${NEW_MACADDR}) must be even" >&2
@ -1378,13 +1403,9 @@ if [[ -n "$NEW_MACADDR" ]]; then
echo "WARN: MAC address '${NEW_MACADDR}' already exists" >&2 echo "WARN: MAC address '${NEW_MACADDR}' already exists" >&2
fi fi
fi fi
}
# checks finished decide_target_interface() {
## ========================================================
## ========================================================
echo "PID: $$"
TARGET_IFACE= # This is the existing physical interface to use TARGET_IFACE= # This is the existing physical interface to use
if [[ $CONN_IFACE ]]; then if [[ $CONN_IFACE ]]; then
TARGET_IFACE=$CONN_IFACE TARGET_IFACE=$CONN_IFACE
@ -1395,13 +1416,14 @@ else
exit 1 exit 1
fi fi
echo "Target interface is ${TARGET_IFACE}" echo "Target interface is ${TARGET_IFACE}"
}
[[ "$USE_RANDOM_MAC" -eq 1 ]] && echo "Use random MAC address $NEW_MACADDR" decide_ip_addresses() {
if [[ ! -n $GATEWAY ]]; then if [[ ! -n $GATEWAY ]]; then
generate_random_ip4 generate_random_ip4
echo "Use random IPv4 address $GATEWAY" echo "Use random IPv4 address $GATEWAY"
fi fi
if [[ $IPV6 -eq 1 && ! -n $PREFIX6 ]]; then if [[ $IPV6 -eq 1 && ! -n $PREFIX6 ]]; then
generate_random_ip6 generate_random_ip6
echo "Use random IPv6 address ${PREFIX6}${IID6}" echo "Use random IPv6 address ${PREFIX6}${IID6}"
@ -1409,37 +1431,9 @@ fi
if [[ $IPV6 -eq 1 ]]; then if [[ $IPV6 -eq 1 ]]; then
GATEWAY6=${PREFIX6}${IID6} GATEWAY6=${PREFIX6}${IID6}
fi fi
}
if [[ $TP_PORT ]]; then prepare_wifi_interface() {
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 if [[ $WIFI_IFACE ]]; then
if [[ $USE_IWCONFIG -eq 0 ]]; then if [[ $USE_IWCONFIG -eq 0 ]]; then
@ -1490,15 +1484,17 @@ if [[ $WIFI_IFACE ]]; then
fi fi
fi fi
}
decide_subnet_interface() {
if [[ $WIFI_IFACE ]]; then if [[ $WIFI_IFACE ]]; then
SUBNET_IFACE=${AP_IFACE} SUBNET_IFACE=${AP_IFACE}
else else
SUBNET_IFACE=${TARGET_IFACE} SUBNET_IFACE=${TARGET_IFACE}
fi fi
}
echo "$SUBNET_IFACE" > $CONFDIR/subn_iface write_hostapd_conf() {
if [[ $WIFI_IFACE ]]; then if [[ $WIFI_IFACE ]]; then
if [[ -n "$COUNTRY" && $USE_IWCONFIG -eq 0 ]]; then if [[ -n "$COUNTRY" && $USE_IWCONFIG -eq 0 ]]; then
@ -1515,7 +1511,7 @@ if [[ $WIFI_IFACE ]]; then
[[ $ISOLATE_CLIENTS -eq 1 ]] && echo "Access Point's clients will be isolated!" [[ $ISOLATE_CLIENTS -eq 1 ]] && echo "Access Point's clients will be isolated!"
# hostapd config # hostapd config
cat <<- EOF > $CONFDIR/hostapd.conf cat <<- EOF > "$CONFDIR/hostapd.conf"
beacon_int=100 beacon_int=100
ssid=${SSID} ssid=${SSID}
interface=${AP_IFACE} interface=${AP_IFACE}
@ -1528,42 +1524,42 @@ if [[ $WIFI_IFACE ]]; then
EOF EOF
if [[ -n "$COUNTRY" ]]; then if [[ -n "$COUNTRY" ]]; then
cat <<- EOF >> $CONFDIR/hostapd.conf cat <<- EOF >> "$CONFDIR/hostapd.conf"
country_code=${COUNTRY} country_code=${COUNTRY}
ieee80211d=1 ieee80211d=1
EOF EOF
fi fi
if [[ $FREQ_BAND == 2.4 ]]; then if [[ $FREQ_BAND == 2.4 ]]; then
echo "hw_mode=g" >> $CONFDIR/hostapd.conf echo "hw_mode=g" >> "$CONFDIR/hostapd.conf"
else else
echo "hw_mode=a" >> $CONFDIR/hostapd.conf echo "hw_mode=a" >> "$CONFDIR/hostapd.conf"
fi fi
if [[ $MAC_FILTER -eq 1 ]]; then if [[ $MAC_FILTER -eq 1 ]]; then
cat <<- EOF >> $CONFDIR/hostapd.conf cat <<- EOF >> "$CONFDIR/hostapd.conf"
macaddr_acl=${MAC_FILTER} macaddr_acl=${MAC_FILTER}
accept_mac_file=${MAC_FILTER_ACCEPT} accept_mac_file=${MAC_FILTER_ACCEPT}
EOF EOF
fi fi
if [[ $IEEE80211N -eq 1 ]]; then if [[ $IEEE80211N -eq 1 ]]; then
cat <<- EOF >> $CONFDIR/hostapd.conf cat <<- EOF >> "$CONFDIR/hostapd.conf"
ieee80211n=1 ieee80211n=1
ht_capab=${HT_CAPAB} ht_capab=${HT_CAPAB}
EOF EOF
fi fi
if [[ $IEEE80211AC -eq 1 ]]; then if [[ $IEEE80211AC -eq 1 ]]; then
echo "ieee80211ac=1" >> $CONFDIR/hostapd.conf echo "ieee80211ac=1" >> "$CONFDIR/hostapd.conf"
fi fi
if [[ -n "$VHT_CAPAB" ]]; then if [[ -n "$VHT_CAPAB" ]]; then
echo "vht_capab=${VHT_CAPAB}" >> $CONFDIR/hostapd.conf echo "vht_capab=${VHT_CAPAB}" >> "$CONFDIR/hostapd.conf"
fi fi
if [[ $IEEE80211N -eq 1 ]] || [[ $IEEE80211AC -eq 1 ]]; then if [[ $IEEE80211N -eq 1 ]] || [[ $IEEE80211AC -eq 1 ]]; then
echo "wmm_enabled=1" >> $CONFDIR/hostapd.conf echo "wmm_enabled=1" >> "$CONFDIR/hostapd.conf"
fi fi
if [[ -n "$PASSPHRASE" ]]; then if [[ -n "$PASSPHRASE" ]]; then
@ -1573,7 +1569,7 @@ if [[ $WIFI_IFACE ]]; then
else else
WPA_KEY_TYPE=psk WPA_KEY_TYPE=psk
fi fi
cat <<- EOF >> $CONFDIR/hostapd.conf cat <<- EOF >> "$CONFDIR/hostapd.conf"
wpa=${WPA_VERSION} wpa=${WPA_VERSION}
wpa_${WPA_KEY_TYPE}=${PASSPHRASE} wpa_${WPA_KEY_TYPE}=${PASSPHRASE}
wpa_key_mgmt=WPA-PSK wpa_key_mgmt=WPA-PSK
@ -1583,23 +1579,18 @@ if [[ $WIFI_IFACE ]]; then
else else
echo "WARN: Wifi is not protected by password" >&2 echo "WARN: Wifi is not protected by password" >&2
fi fi
chmod 600 $CONFDIR/hostapd.conf chmod 600 "$CONFDIR/hostapd.conf"
fi
#===================================================
#===================================================
if [[ $NM_RUNNING -eq 1 ]] && nm_knows $TARGET_IFACE ; then
nm_set_unmanaged ${SUBNET_IFACE}
fi fi
}
write_dnsmasq_conf() {
if [[ $NO_DNSMASQ -eq 0 ]]; then if [[ $NO_DNSMASQ -eq 0 ]]; then
if grep "^nobody:" /etc/group >/dev/null 2>&1 ; then if grep "^nobody:" /etc/group >/dev/null 2>&1 ; then
NOBODY_GROUP="nobody" NOBODY_GROUP="nobody"
else else
NOBODY_GROUP="nogroup" NOBODY_GROUP="nogroup"
fi fi
cat <<- EOF > $CONFDIR/dnsmasq.conf cat <<- EOF > "$CONFDIR/dnsmasq.conf"
user=nobody user=nobody
group=$NOBODY_GROUP group=$NOBODY_GROUP
bind-dynamic bind-dynamic
@ -1617,8 +1608,8 @@ if [[ $NO_DNSMASQ -eq 0 ]]; then
# 'log-dhcp'(Extra logging for DHCP) shows too much logs. # 'log-dhcp'(Extra logging for DHCP) shows too much logs.
# if use '-d', 'log-facility' should = /dev/null # if use '-d', 'log-facility' should = /dev/null
if [[ $SHARE_METHOD == "none" ]]; then if [[ $SHARE_METHOD == "none" ]]; then
echo "no-resolv" >> $CONFDIR/dnsmasq.conf echo "no-resolv" >> "$CONFDIR/dnsmasq.conf"
echo "no-poll" >> $CONFDIR/dnsmasq.conf echo "no-poll" >> "$CONFDIR/dnsmasq.conf"
fi fi
if [[ "$DHCP_DNS" != "no" ]]; then if [[ "$DHCP_DNS" != "no" ]]; then
if [[ "$DHCP_DNS" == "gateway" ]]; then if [[ "$DHCP_DNS" == "gateway" ]]; then
@ -1626,22 +1617,22 @@ if [[ $NO_DNSMASQ -eq 0 ]]; then
else else
dns_offer="$DHCP_DNS" dns_offer="$DHCP_DNS"
fi 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 fi
if [[ ! "$dnsmasq_NO_DNS" -eq 0 ]]; then if [[ ! "$dnsmasq_NO_DNS" -eq 0 ]]; then
echo "port=0" >> $CONFDIR/dnsmasq.conf echo "port=0" >> "$CONFDIR/dnsmasq.conf"
fi fi
[[ -n "$MTU" ]] && echo "dhcp-option-force=option:mtu,${MTU}" >> $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 [[ $ETC_HOSTS -eq 0 ]] && echo no-hosts >> "$CONFDIR/dnsmasq.conf"
[[ -n "$ADDN_HOSTS" ]] && echo "addn-hosts=${ADDN_HOSTS}" >> $CONFDIR/dnsmasq.conf [[ -n "$ADDN_HOSTS" ]] && echo "addn-hosts=${ADDN_HOSTS}" >> "$CONFDIR/dnsmasq.conf"
if [[ "$THISHOSTNAME" ]]; then if [[ "$THISHOSTNAME" ]]; then
[[ "$THISHOSTNAME" == "-" ]] && THISHOSTNAME="$(cat /etc/hostname)" [[ "$THISHOSTNAME" == "-" ]] && THISHOSTNAME="$(cat /etc/hostname)"
echo "interface-name=$THISHOSTNAME,$SUBNET_IFACE" >> $CONFDIR/dnsmasq.conf echo "interface-name=$THISHOSTNAME,$SUBNET_IFACE" >> "$CONFDIR/dnsmasq.conf"
fi fi
if [[ ! "$SHOW_DNS_QUERY" -eq 0 ]]; then if [[ ! "$SHOW_DNS_QUERY" -eq 0 ]]; then
echo log-queries=extra >> $CONFDIR/dnsmasq.conf echo log-queries=extra >> "$CONFDIR/dnsmasq.conf"
fi fi
if [[ $DNS ]]; then if [[ $DNS ]]; then
@ -1649,16 +1640,16 @@ if [[ $NO_DNSMASQ -eq 0 ]]; then
for (( i=1;i<=DNS_count;i++ )); do for (( i=1;i<=DNS_count;i++ )); do
sep_ip_port "$(echo $DNS | cut -d, -f$i)" DNS_IP DNS_PORT sep_ip_port "$(echo $DNS | cut -d, -f$i)" DNS_IP DNS_PORT
[[ "$DNS_PORT" ]] && DNS_PORT_D="#$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 done
cat <<- EOF >> $CONFDIR/dnsmasq.conf cat <<- EOF >> "$CONFDIR/dnsmasq.conf"
no-resolv no-resolv
no-poll no-poll
EOF EOF
fi fi
if [[ $IPV6 -eq 1 ]];then if [[ $IPV6 -eq 1 ]];then
cat <<- EOF >> $CONFDIR/dnsmasq.conf cat <<- EOF >> "$CONFDIR/dnsmasq.conf"
listen-address=${GATEWAY6} listen-address=${GATEWAY6}
enable-ra enable-ra
#quiet-ra #quiet-ra
@ -1670,37 +1661,19 @@ if [[ $NO_DNSMASQ -eq 0 ]]; then
else else
dns_offer6="$DHCP_DNS6" dns_offer6="$DHCP_DNS6"
fi 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 fi
fi fi
}
#=========================== run_wifi_ap_processes() {
# 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 if [[ $WIFI_IFACE ]]; then
if [[ $NO_HAVEGED -eq 0 ]]; then if [[ $NO_HAVEGED -eq 0 ]]; then
haveged_watchdog & haveged_watchdog &
HAVEGED_WATCHDOG_PID=$! 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" echo "haveged_watchdog PID: $HAVEGED_WATCHDOG_PID"
fi fi
@ -1714,9 +1687,9 @@ if [[ $WIFI_IFACE ]]; then
echo echo
echo "Starting hostapd" echo "Starting hostapd"
# hostapd '-P' works only when use '-B' (run in background) # 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=$! HOSTAPD_PID=$!
echo "$HOSTAPD_PID" > $CONFDIR/hostapd.pid echo "$HOSTAPD_PID" > "$CONFDIR/hostapd.pid"
echo "hostapd PID: $HOSTAPD_PID" echo "hostapd PID: $HOSTAPD_PID"
#while [[ ! -f $CONFDIR/hostapd.pid ]]; do #while [[ ! -f $CONFDIR/hostapd.pid ]]; do
# sleep 1 # sleep 1
@ -1726,27 +1699,170 @@ if [[ $WIFI_IFACE ]]; then
sleep 3 sleep 3
fi fi
}
ip addr add ${GATEWAY}/24 broadcast ${GATEWAY%.*}.255 dev ${SUBNET_IFACE} || die "Failed setting ${SUBNET_IFACE} IP" backup_interface_ipv6_status() {
mkdir "$CONFDIR/sys_6_conf_iface"
mkdir $CONFDIR/sys_6_conf_iface
if [[ $IPV6 -eq 1 ]]; then if [[ $IPV6 -eq 1 ]]; then
cp /proc/sys/net/ipv6/conf/$SUBNET_IFACE/accept_ra \ 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/use_tempaddr" \
/proc/sys/net/ipv6/conf/$SUBNET_IFACE/addr_gen_mode \ "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/addr_gen_mode" \
$CONFDIR/sys_6_conf_iface/ "$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/accept_ra"
echo 0 > /proc/sys/net/ipv6/conf/$SUBNET_IFACE/use_tempaddr echo 0 > "/proc/sys/net/ipv6/conf/$SUBNET_IFACE/use_tempaddr"
echo 0 > /proc/sys/net/ipv6/conf/$SUBNET_IFACE/addr_gen_mode 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" ip -6 addr add ${GATEWAY6}/64 dev ${SUBNET_IFACE} || die "Failed setting ${SUBNET_IFACE} IPv6"
else else
cp /proc/sys/net/ipv6/conf/$SUBNET_IFACE/disable_ipv6 $CONFDIR/sys_6_conf_iface/ 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 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 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"
backup_interface_ipv6_status
# enable Internet sharing # enable Internet sharing
if [[ "$SHARE_METHOD" == "none" ]]; then 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 [[ "$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 start_nat
[[ "$BANLAN" -eq 1 ]] && start_ban_lan [[ "$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 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 fi
# to enable clients to establish PPTP connections we must # to enable clients to establish PPTP connections we must
# load nf_nat_pptp module # load nf_nat_pptp module
modprobe nf_nat_pptp > /dev/null 2>&1 modprobe nf_nat_pptp > /dev/null 2>&1
elif [[ "$SHARE_METHOD" == "redsocks" ]]; then elif [[ "$SHARE_METHOD" == "redsocks" ]]; then
if [[ $IPV6 -eq 1 ]]; 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 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 [[ "$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 [[ "$CATCH_DNS" -eq 1 ]] && start_catch_dns
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
echo "Starting dnsmasq" echo "== Setting up completed, now linux-router is working =="
# 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() { show_qr() {
local T S P H 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 " 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 [[ "$QR" -eq 1 ]] && show_qr
# need loop to keep this script running # need loop to keep this script running
bash -c "while :; do sleep 8000 ; done " & bash -c "while :; do sleep 8000 ; done " &
KEEP_RUNNING_PID=$! KEEP_RUNNING_PID=$!
echo "$KEEP_RUNNING_PID" > $CONFDIR/keep_running.pid echo "$KEEP_RUNNING_PID" > "$CONFDIR/keep_running.pid"
wait $KEEP_RUNNING_PID wait $KEEP_RUNNING_PID
clean_exit clean_exit