Compare commits

...

6 Commits

Author SHA1 Message Date
garywill 60d4b53236 version 0.8.1 2025-09-13 10:33:03 +08:00
garywill bef65d4b2b add some quotes 2025-09-13 10:33:03 +08:00
garywill 1158b8b337 use approach better than '-gt 0' for writing hostapd.conf 2025-09-13 10:33:03 +08:00
garywill 8b3ebd8f67 text 2025-09-13 10:33:03 +08:00
garywill 73aac55c34 refractor hostapd.conf wifi4-6 part 2025-09-13 10:33:03 +08:00
garywill 317de635d2 readme 2025-09-13 10:33:03 +08:00
2 changed files with 93 additions and 109 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` (or even by closing terminal window).
[Linux-Router News & Developer Notes 📰](https://github.com/garywill/linux-router/issues/28) | [More tools and projects 🛠️](https://garywill.github.io) | [🍻 Buy me a coffee ❤️](https://github.com/garywill/receiving/blob/master/receiving_methods.md)
[More tools and projects 🛠️](https://garywill.github.io) | [🍻 Buy me a coffee ❤️](https://github.com/garywill/receiving/blob/master/receiving_methods.md)
## Features
@ -19,17 +19,17 @@ Basic features:
- Specify upstream DNS (kind of a plain DNS proxy)
- IPv6 (behind NATed LAN, like IPv4)
- Creating WiFi hotspot:
- Wifi 4/5/6
- Wifi 3/4/5/6
- 2.4GHz, 5GHz
- Channel selecting
- Choose encryptions: WPA2/WPA, WPA2, WPA, No encryption
- Create AP on the same interface you are getting Internet (usually require same channel)
- Create AP on the same interface you are getting Internet (Need hardware support. Usually require same channel)
- Transparent proxy (redsocks)
- Transparent DNS proxy (hijack port 53 packets)
- Detect and prevent interference from following Linux system daemons:
- NetworkManager (handle interface (un)managed status)
- firewalld (use temporary `trusted` zone)
- You can run many instances, to create many different networks. Has instances managing feature.
- Instances managing. You can run multiple instances, to create different sub-networks.
**For many other features, see below [CLI usage](#cli-usage-and-other-features)**
@ -388,13 +388,13 @@ Options:
--no-haveged Do not run haveged automatically when needed
--hs20 Enable Hotspot 2.0
WiFi 4 (802.11n) configs:
WiFi 4 (802.11n) configs (2.4G/5GHz): (default: not enable)
--wifi4 Enable IEEE 802.11n (HT, High Throughput)
--ht-capab <HT caps> HT capabilities (example: '[HT40+][HT40-]')
--ht-capab <HT caps> HT capabilities (example: '[HT40+][DSSS_CCK-40]')
(default: '[HT40+]')
--req-wifi4 Only support Wifi>=4 clients
WiFi 5 (802.11ac) configs:
WiFi 5 (802.11ac) configs (5GHz): (default: not enable)
--wifi5 Enable IEEE 802.11ac (VHT, Very High Thoughtput)
--vht-capab <VHT caps> VHT capabilities (example: '[VHT160][RXLDPC]')
--vht-ch-width <index> Index of VHT channel width:
@ -408,7 +408,7 @@ Options:
(second 80MHz) segment. Use with '--vht-ch-width 3'
--req-wifi5 Only support Wifi>=5 clients
WiFi 6 (802.11ax) configs:
WiFi 6 (802.11ax) configs (2.4G/5GHz): (default: not enable)
--wifi6 Enable IEEE 802.11ax (HE, High Efficiency)
--he-ch-width <index> Index of HE channel width:
0 for 20MHz or 40MHz (default)
@ -463,7 +463,7 @@ Visit [**my homepage** 🏡](https://garywill.github.io) to see **more tools and
>
> 🥂 ( ^\_^) o自自o (^_^ ) 🍻
🤝 Bisides, thank [create_ap](https://github.com/oblique/create_ap) by [oblique](https://github.com/oblique). This script was forked from create\_ap. Now they are quite different. (See `history` branch for how I modified create_ap). 🤝 Also thank those who contributed to that project.
🤝 Bisides, thank [create_ap](https://github.com/oblique/create_ap) by [oblique](https://github.com/oblique). This script was forked from create\_ap. Now they are quite different. 🤝 Also thank those people who contributed to that project.
👨‍💻 You can be contributor, too!

184
lnxrouter
View File

@ -1,6 +1,6 @@
#!/bin/bash
VERSION=0.8.0
VERSION=0.8.1
PROGNAME="$(basename "$0")"
export LC_ALL=C
@ -105,13 +105,13 @@ Options:
--no-haveged Do not run haveged automatically when needed
--hs20 Enable Hotspot 2.0
WiFi 4 (802.11n) configs:
WiFi 4 (802.11n) configs (2.4G/5GHz): (default: not enable)
--wifi4 Enable IEEE 802.11n (HT, High Throughput)
--ht-capab <HT caps> HT capabilities (example: '[HT40+][HT40-]')
--ht-capab <HT caps> HT capabilities (example: '[HT40+][DSSS_CCK-40]')
(default: '[HT40+]')
--req-wifi4 Only support Wifi>=4 clients
WiFi 5 (802.11ac) configs:
WiFi 5 (802.11ac) configs (5GHz): (default: not enable)
--wifi5 Enable IEEE 802.11ac (VHT, Very High Thoughtput)
--vht-capab <VHT caps> VHT capabilities (example: '[VHT160][RXLDPC]')
--vht-ch-width <index> Index of VHT channel width:
@ -125,7 +125,7 @@ Options:
(second 80MHz) segment. Use with '--vht-ch-width 3'
--req-wifi5 Only support Wifi>=5 clients
WiFi 6 (802.11ax) configs:
WiFi 6 (802.11ax) configs (2.4G/5GHz): (default: not enable)
--wifi6 Enable IEEE 802.11ax (HE, High Efficiency)
--he-ch-width <index> Index of HE channel width:
0 for 20MHz or 40MHz (default)
@ -236,14 +236,14 @@ define_global_variables(){
REQUIREVHT=0
VHT_CAPAB=
VHTCHANNELWIDTH=0
VHTSEG0CHINDEX=0
VHTSEG1CHINDEX=0
VHTSEG0CHINDEX=
VHTSEG1CHINDEX=
#wifi6
IEEE80211AX=0
REQUIREHE=0
HECHANNELWIDTH=0
HESEG0CHINDEX=0
HESEG1CHINDEX=0
HESEG0CHINDEX=
HESEG1CHINDEX=
HESUBFE=0
HESUBFR=0
HEMUBFR=0
@ -720,7 +720,7 @@ can_transmit_to_channel() {
[[ "${CHANNEL_INFO}" == *disabled* ]] && return 3
return 0
else
CHANNEL_NUM=$(printf '%02d' ${CHANNEL_NUM})
CHANNEL_NUM="$(printf '%02d' "${CHANNEL_NUM}")"
CHANNEL_INFO=$(iwlist "${IFACE}" channel | grep -E "Channel[[:blank:]]${CHANNEL_NUM}[[:blank:]]?:")
[[ -z "${CHANNEL_INFO}" ]] && return 1
return 0
@ -766,7 +766,7 @@ is_unicast_macaddr() {
local x
x=$(echo "$1" | cut -d: -f1)
x=$(printf '%d' "0x${x}")
[[ $(expr $x % 2) -eq 0 ]]
[[ $(expr "$x" % 2) -eq 0 ]]
}
get_interface_mac() {
@ -874,15 +874,15 @@ generate_random_mac() {
is_ip4_lan_range_available() { # checks 192.168.x.x
( ip -4 address | grep "inet 192\.168\.$1\." > /dev/null 2>&1 ) && return 1
( ip -4 route | grep "^192\.168\.$1\." > /dev/null 2>&1 ) && return 1
( ip -4 route get 192.168.$1.0 2>&1 | grep -E "\bvia\b|\bunreachable\b" > /dev/null 2>&1 ) && \
( ip -4 route get 192.168.$1.255 2>&1 | grep -E "\bvia\b|\bunreachable\b" > /dev/null 2>&1 ) && return 0
( ip -4 route get "192.168.$1.0" 2>&1 | grep -E "\bvia\b|\bunreachable\b" > /dev/null 2>&1 ) && \
( ip -4 route get "192.168.$1.255" 2>&1 | grep -E "\bvia\b|\bunreachable\b" > /dev/null 2>&1 ) && return 0
return 1
}
is_ip6_lan_range_available() { # checks fdxx::
( ip -6 address | grep -i "inet6 fd$1:$2$3:$4$5:$6$7:" > /dev/null 2>&1 ) && return 1
( ip -6 route | grep -i "^fd$1:$2$3:$4$5:$6$7:" > /dev/null 2>&1 ) && return 1
( ip -6 route get fd$1:$2$3:$4$5:$6$7:: 2>&1 | grep -E "\bvia\b|\bunreachable\b" > /dev/null 2>&1 ) && \
( ip -6 route get fd$1:$2$3:$4$5:$6$7:ffff:ffff:ffff:ffff 2>&1 | grep -E "\bvia\b|\bunreachable\b" > /dev/null 2>&1 ) && return 0
( ip -6 route get "fd$1:$2$3:$4$5:$6$7::" 2>&1 | grep -E "\bvia\b|\bunreachable\b" > /dev/null 2>&1 ) && \
( ip -6 route get "fd$1:$2$3:$4$5:$6$7:ffff:ffff:ffff:ffff" 2>&1 | grep -E "\bvia\b|\bunreachable\b" > /dev/null 2>&1 ) && return 0
return 1
}
@ -924,7 +924,7 @@ haveged_watchdog() {
elif ! pidof haveged > /dev/null 2>&1; then # TODO judge zombie ?
echo "Low entropy detected, starting haveged" 1>&2
# boost low-entropy
haveged -w 1024 -p $COMMON_CONFDIR/haveged.pid
haveged -w 1024 -p "$COMMON_CONFDIR/haveged.pid"
fi
fi
sleep 2
@ -965,8 +965,8 @@ is_same_netns() {
local pid2="$1"
local my_netns his_netns
[[ ! -f /proc/$$/ns/net ]] && return 0 # no netns feature. treat as same
my_netns="$(readlink /proc/$$/ns/net)"
his_netns="$(readlink /proc/$pid2/ns/net)"
my_netns="$(readlink "/proc/$$/ns/net")"
his_netns="$(readlink "/proc/$pid2/ns/net")"
[[ ! -n "$his_netns" ]] && return 1 # can't find his pid or netns (maybe different pidns), treat as not same
[[ "$my_netns" == "$his_netns" ]] && return 0
return 1
@ -1015,7 +1015,7 @@ nm_set_managed() {
NM_UNM_LIST=
}
nm_restore_manage() {
if [[ $NM_UNM_LIST ]]; then
if [[ -n "$NM_UNM_LIST" ]]; then
echo "Restore $NM_UNM_LIST managed by NetworkManager"
nm_set_managed "$NM_UNM_LIST"
sleep 0.5
@ -1185,7 +1185,7 @@ start_nat() {
# forward subnet -> internet
iptb "$iv" v filter I FORWARD -i "$SUBNET_IFACE" -s "$SUBNET_NET" \
-o $INTERNET_IFACE \
-o "$INTERNET_IFACE" \
-j ACCEPT || die
# forward any -> subnet
@ -1291,8 +1291,8 @@ allow_dhcp() {
echo
echo "iptables: allow dhcp"
iptb 4 v filter I INPUT -i ${SUBNET_IFACE} -p udp -m udp --dport 67 -j ACCEPT || die
iptb 6 v filter I INPUT -i ${SUBNET_IFACE} -p udp -m udp --dport 547 -j ACCEPT || die
iptb 4 v filter I INPUT -i "${SUBNET_IFACE}" -p udp -m udp --dport 67 -j ACCEPT || die
iptb 6 v filter I INPUT -i "${SUBNET_IFACE}" -p udp -m udp --dport 547 -j ACCEPT || die
}
# TODO: use 'DNAT' instead of '--to-ports' to support other IP
@ -1329,8 +1329,8 @@ start_redsocks() {
iptb "$iv" v nat I PREROUTING -i "$SUBNET_IFACE" -s "$SUBNET_NET" -j lrt${$}${SUBNET_IFACE}-TP || die
iptb "$iv" v filter I INPUT -i "$SUBNET_IFACE" -s "$SUBNET_NET" -p tcp -m tcp --dport ${TP_PORT} -j ACCEPT || die
iptb "$iv" v filter I INPUT -i "$SUBNET_IFACE" -s "$SUBNET_NET" -p udp -m udp --dport ${TP_PORT} -j ACCEPT || die
iptb "$iv" v filter I INPUT -i "$SUBNET_IFACE" -s "$SUBNET_NET" -p tcp -m tcp --dport "${TP_PORT}" -j ACCEPT || die
iptb "$iv" v filter I INPUT -i "$SUBNET_IFACE" -s "$SUBNET_NET" -p udp -m udp --dport "${TP_PORT}" -j ACCEPT || die
done
}
@ -1437,7 +1437,7 @@ _cleanup() {
firewalld_restoreoldzone
if [[ $VWIFI_IFACE ]]; then # the subnet interface (virtual wifi interface) will be removed
if [[ -n "$VWIFI_IFACE" ]]; then # the subnet interface (virtual wifi interface) will be removed
iw dev "${VWIFI_IFACE}" del
dealloc_vface_name "$VWIFI_IFACE"
fi
@ -2050,94 +2050,78 @@ write_hostapd_conf() {
echo "ap_max_inactivity=${STATIMEOUT}" >> "$CONFDIR/hostapd.conf"
fi
# wifi4 -----------------
if [[ $IEEE80211N -eq 1 ]]; then
if [[ $IEEE80211N -eq 1 ]]; then # wifi4
echo "ieee80211n=1" >> "$CONFDIR/hostapd.conf"
if [[ -n "$HT_CAPAB" ]]; then
echo "ht_capab=${HT_CAPAB}" >> "$CONFDIR/hostapd.conf"
fi
if [[ $REQUIREHT -eq 1 ]]; then
echo "require_ht=1" >> "$CONFDIR/hostapd.conf"
fi
fi
if [[ -n "$HT_CAPAB" ]]; then
echo "ht_capab=${HT_CAPAB}" >> "$CONFDIR/hostapd.conf"
fi
if [[ $REQUIREHT -eq 1 ]]; then
echo "require_ht=1" >> "$CONFDIR/hostapd.conf"
fi
# wifi5 -----------------
if [[ $IEEE80211AC -eq 1 ]]; then
if [[ $IEEE80211AC -eq 1 ]]; then # wifi5
echo "ieee80211ac=1" >> "$CONFDIR/hostapd.conf"
if [[ -n "$VHT_CAPAB" ]]; then
echo "vht_capab=${VHT_CAPAB}" >> "$CONFDIR/hostapd.conf"
fi
if [[ -n "$VHTCHANNELWIDTH" ]]; then
echo "vht_oper_chwidth=${VHTCHANNELWIDTH}" >> "$CONFDIR/hostapd.conf"
fi
if [[ -n "$VHTSEG0CHINDEX" ]]; then
echo "vht_oper_centr_freq_seg0_idx=${VHTSEG0CHINDEX}" >> "$CONFDIR/hostapd.conf"
fi
if [[ -n "$VHTSEG1CHINDEX" ]]; then
echo "vht_oper_centr_freq_seg1_idx=${VHTSEG1CHINDEX}" >> "$CONFDIR/hostapd.conf"
fi
if [[ $REQUIREVHT -eq 1 ]]; then
echo "require_vht=1" >> "$CONFDIR/hostapd.conf"
fi
fi
if [[ $REQUIREVHT -eq 1 ]]; then
echo "require_vht=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ -n "$VHT_CAPAB" ]]; then
echo "vht_capab=${VHT_CAPAB}" >> "$CONFDIR/hostapd.conf"
fi
if [[ $VHTCHANNELWIDTH -gt 0 ]]; then
cat <<- EOF >> "$CONFDIR/hostapd.conf"
vht_oper_chwidth=${VHTCHANNELWIDTH}
EOF
fi
if [[ $VHTSEG0CHINDEX -gt 0 ]]; then
cat <<- EOF >> "$CONFDIR/hostapd.conf"
vht_oper_centr_freq_seg0_idx=${VHTSEG0CHINDEX}
EOF
fi
if [[ $VHTSEG1CHINDEX -gt 0 ]]; then
cat <<- EOF >> "$CONFDIR/hostapd.conf"
vht_oper_centr_freq_seg1_idx=${VHTSEG1CHINDEX}
EOF
fi
# wifi6 -----------------
if [[ $IEEE80211AX -eq 1 ]]; then
if [[ $IEEE80211AX -eq 1 ]]; then # wifi6
echo "ieee80211ax=1" >> "$CONFDIR/hostapd.conf"
if [[ $REQUIREHE -eq 1 ]]; then
echo "require_he=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ $HESUBFE -eq 1 ]]; then
echo "he_su_beamformee=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ $HESUBFR -eq 1 ]]; then
echo "he_su_beamformer=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ $HEMUBFR -eq 1 ]]; then
echo "he_mu_beamformer=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ -n "$HECHANNELWIDTH" ]]; then
echo "he_oper_chwidth=${HECHANNELWIDTH}" >> "$CONFDIR/hostapd.conf"
fi
if [[ -n "$HESEG0CHINDEX" ]]; then
echo "he_oper_centr_freq_seg0_idx=${HESEG0CHINDEX}" >> "$CONFDIR/hostapd.conf"
fi
if [[ -n "$HESEG1CHINDEX" ]]; then
echo "he_oper_centr_freq_seg1_idx=${HESEG1CHINDEX}" >> "$CONFDIR/hostapd.conf"
fi
fi
if [[ $REQUIREHE -eq 1 ]]; then
echo "require_he=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ $HESUBFE -eq 1 ]]; then
echo "he_su_beamformee=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ $HESUBFR -eq 1 ]]; then
echo "he_su_beamformer=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ $HEMUBFR -eq 1 ]]; then
echo "he_mu_beamformer=1" >> "$CONFDIR/hostapd.conf"
fi
if [[ $HECHANNELWIDTH -gt 0 ]]; then
cat <<- EOF >> "$CONFDIR/hostapd.conf"
he_oper_chwidth=${HECHANNELWIDTH}
EOF
fi
if [[ $HESEG0CHINDEX -gt 0 ]]; then
cat <<- EOF >> "$CONFDIR/hostapd.conf"
he_oper_centr_freq_seg0_idx=${HESEG0CHINDEX}
EOF
fi
if [[ $HESEG1CHINDEX -gt 0 ]]; then
cat <<- EOF >> "$CONFDIR/hostapd.conf"
he_oper_centr_freq_seg1_idx=${HESEG1CHINDEX}
EOF
fi
if [[ $P2PTWT -eq 1 ]]; then
echo "peer_to_peer_twt=1" >> "$CONFDIR/hostapd.conf"
fi
# -----------------
if [[ $IEEE80211N -eq 1 ]] || [[ $IEEE80211AC -eq 1 ]] || [[ $IEEE80211AX -eq 1 ]]; then
echo "wmm_enabled=1" >> "$CONFDIR/hostapd.conf"
fi