11 Commits

Author SHA1 Message Date
garywill
45ad35d29f 0.6.7 2023-01-07 20:55:20 +08:00
garywill
a663d9052b update readme 2023-01-07 09:10:05 +08:00
garywill
e3941c560f text 2023-01-07 09:08:18 +08:00
garywill
7ec589b1c2 add some notice 2023-01-07 09:07:18 +08:00
Cabbache
10ca7249cb Updated --virt-name to make interface name predictable 2023-01-07 01:02:04 +00:00
lukescerri
a414ac035b Added --virt-name option 2022-09-26 21:26:50 +02:00
lukescerri
b51a2d2349 renamed virtual interface 2022-09-24 17:32:28 +02:00
garywill
9e1d985623 move 'qrencode' from readme dependency to cli usage note 2022-04-03 18:05:05 +08:00
garywill
433b3b8d39 add --dns-nocache option 2022-04-03 18:03:51 +08:00
garywill
e8284c5398 add "Install" section in readme 2022-04-03 17:46:48 +08:00
garywill
c2da43250e typo 2022-04-03 17:46:24 +08:00
2 changed files with 89 additions and 99 deletions

View File

@@ -92,7 +92,7 @@ sudo lnxrouter -i eth1 -o isp5 --no-dns --dhcp-dns 1.1.1.1 -6 --dhcp-dns6 [26
> In this case of usage, it's recommended to: > In this case of usage, it's recommended to:
> >
> 1. Stop serving local DNS > 1. Stop serving local DNS
> 2. Tell clients which DNS to use (ISP5's DNS. Or, a safe public DNS, like above example) > 2. Tell clients which DNS to use ISP5's DNS. (Or, a safe public DNS, like above example)
> Also, read *Notice 1* > Also, read *Notice 1*
@@ -138,7 +138,7 @@ sudo lnxrouter -i lxcbr5
### Transparent proxy ### Transparent proxy
All clients' Internet traffic go through, for example, Tor All clients' Internet traffic go through, for example, Tor (notice this example is NOT an anonymity use)
<details> <details>
@@ -155,6 +155,10 @@ TransPort [fd00:5:6:7::1]:9040
DNSPort [fd00:5:6:7::1]:9053 DNSPort [fd00:5:6:7::1]:9053
``` ```
> **Warn**: Tor's anonymity relies on a purpose-made browser. Using Tor like this (sharing Tor's network to LAN clients) will NOT ensure anonymity.
>
> Although we use Tor as example here, Linux-router does NOT ensure nor is NOT aiming at anonymity.
</details> </details>
### Clients-in-sandbox network ### Clients-in-sandbox network
@@ -173,7 +177,7 @@ sudo lnxrouter -i eth1 \
</details> </details>
> This script comes with no warrenty. Use on your own risk > Linux-router comes with no warranty. Use on your own risk
### Use as transparent proxy for LXD ### Use as transparent proxy for LXD
@@ -317,25 +321,27 @@ Options:
-d DNS server will take into account /etc/hosts -d DNS server will take into account /etc/hosts
-e <hosts_file> DNS server will take into account additional -e <hosts_file> DNS server will take into account additional
hosts file hosts file
--dns-nocache DNS server no cache
--mac <MAC> Set MAC address --mac <MAC> Set MAC address
--random-mac Use random MAC address --random-mac Use random MAC address
--tp <port> Transparent proxy, --tp <port> Transparent proxy,
redirect non-LAN TCP and UDP traffic to port. redirect non-LAN TCP and UDP(not tested) traffic to
(usually used with '--dns') port. (usually used with '--dns')
WiFi hotspot options: WiFi hotspot options:
--ap <wifi interface> <SSID> --ap <wifi interface> <SSID>
Create WiFi access point Create WiFi access point
-p, --password <password> -p, --password <password>
WiFi password WiFi password
--qr Show WiFi QR code in terminal --qr Show WiFi QR code in terminal (need qrencode)
--hidden Hide access point (not broadcast SSID) --hidden Hide access point (not broadcast SSID)
--no-virt Do not create virtual interface --no-virt Do not create virtual interface
Using this you can't use same wlan interface Using this you can't use same wlan interface
for both Internet and AP for both Internet and AP
--virt-name <name> Set name of virtual interface
-c <channel> Channel number (default: 1) -c <channel> Channel number (default: 1)
--country <code> Set two-letter country code for regularity --country <code> Set two-letter country code for regularity
(example: US) (example: US)
@@ -397,6 +403,16 @@ On exit of a linux-router instance, script **will do cleanup**, i.e. undo most c
5. The wifi device which is used to create hotspot is `rfkill unblock`ed 5. The wifi device which is used to create hotspot is `rfkill unblock`ed
6. WiFi country code, if user assigns 6. WiFi country code, if user assigns
## Install
1-file-script. Download and run (meet the dependencies).
I'm currently not packaging for any distro. If you do, open a PR and add the link (can be with a version badge) to list here:
| Linux distro | |
| ------------ | ---------------------------------------------------------------------------------------------------------- |
| Any | download [1-file-script](https://raw.githubusercontent.com/garywill/linux-router/master/lnxrouter) and run |
## Dependencies ## Dependencies
- bash - bash
@@ -409,7 +425,6 @@ On exit of a linux-router instance, script **will do cleanup**, i.e. undo most c
- iw - iw
- iwconfig (you only need this if 'iw' can not recognize your adapter) - iwconfig (you only need this if 'iw' can not recognize your adapter)
- haveged (optional) - haveged (optional)
- qrencode (optional)
## TODO ## TODO

139
lnxrouter
View File

@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
VERSION=0.6.6 VERSION=0.6.7
PROGNAME="$(basename $0)" PROGNAME="$(basename $0)"
export LC_ALL=C export LC_ALL=C
@@ -67,25 +67,27 @@ Options:
-d DNS server will take into account /etc/hosts -d DNS server will take into account /etc/hosts
-e <hosts_file> DNS server will take into account additional -e <hosts_file> DNS server will take into account additional
hosts file hosts file
--dns-nocache DNS server no cache
--mac <MAC> Set MAC address --mac <MAC> Set MAC address
--random-mac Use random MAC address --random-mac Use random MAC address
--tp <port> Transparent proxy, --tp <port> Transparent proxy,
redirect non-LAN TCP and UDP traffic to port. redirect non-LAN TCP and UDP(not tested) traffic to
(usually used with '--dns') port. (usually used with '--dns')
WiFi hotspot options: WiFi hotspot options:
--ap <wifi interface> <SSID> --ap <wifi interface> <SSID>
Create WiFi access point Create WiFi access point
-p, --password <password> -p, --password <password>
WiFi password WiFi password
--qr Show WiFi QR code in terminal --qr Show WiFi QR code in terminal (need qrencode)
--hidden Hide access point (not broadcast SSID) --hidden Hide access point (not broadcast SSID)
--no-virt Do not create virtual interface --no-virt Do not create virtual interface
Using this you can't use same wlan interface Using this you can't use same wlan interface
for both Internet and AP for both Internet and AP
--virt-name <name> Set name of virtual interface
-c <channel> Channel number (default: 1) -c <channel> Channel number (default: 1)
--country <code> Set two-letter country code for regularity --country <code> Set two-letter country code for regularity
(example: US) (example: US)
@@ -156,6 +158,7 @@ define_global_variables(){
SHOW_DNS_QUERY=0 # log dns SHOW_DNS_QUERY=0 # log dns
ETC_HOSTS=0 ETC_HOSTS=0
ADDN_HOSTS= ADDN_HOSTS=
DNS_NOCACHE=
CONN_IFACE= # which interface user choose to use to create network CONN_IFACE= # which interface user choose to use to create network
INTERNET_IFACE= # which interface to get Internet from INTERNET_IFACE= # which interface to get Internet from
THISHOSTNAME= # this host's name the DNS tells clients THISHOSTNAME= # this host's name the DNS tells clients
@@ -195,6 +198,7 @@ define_global_variables(){
# script variables # script variables
VWIFI_IFACE= # virtual wifi interface name, if created VWIFI_IFACE= # virtual wifi interface name, if created
VIRT_NAME= # name to use for virtual interface if --virt-name is used
AP_IFACE= # can be VWIFI_IFACE or WIFI_IFACE AP_IFACE= # can be VWIFI_IFACE or WIFI_IFACE
USE_IWCONFIG=0 # some device can't use iw USE_IWCONFIG=0 # some device can't use iw
@@ -322,6 +326,10 @@ parse_user_options(){
ADDN_HOSTS="$1" ADDN_HOSTS="$1"
shift shift
;; ;;
--dns-nocache)
shift
DNS_NOCACHE=1
;;
--isolate-clients) --isolate-clients)
shift shift
@@ -399,6 +407,11 @@ parse_user_options(){
shift shift
NO_VIRT=1 NO_VIRT=1
;; ;;
--virt-name)
shift
VIRT_NAME="$1"
shift
;;
--country) --country)
shift shift
@@ -505,6 +518,10 @@ is_interface() {
[[ -d "/sys/class/net/${1}" ]] [[ -d "/sys/class/net/${1}" ]]
} }
is_vface_name_allocated(){
is_interface "$1" || [[ -f "$COMMON_CONFDIR/vfaces/${1}" ]]
}
get_interface_phy_device() { # only for wifi interface get_interface_phy_device() { # only for wifi interface
local x local x
for x in /sys/class/ieee80211/*; do for x in /sys/class/ieee80211/*; do
@@ -651,20 +668,19 @@ get_interface_pci_info() { # pci id / model / virtual
# TODO current driver # TODO current driver
} }
alloc_new_vface_name() { # only for wifi alloc_new_vface_name() { # only for wifi
local i=0 local i=0
local v_iface_name= local v_iface_name="$VIRT_NAME"
while :; do if [[ -z $VIRT_NAME ]]; then
v_iface_name="x$i${WIFI_IFACE}" while :; do
if ! is_interface ${v_iface_name} && [[ ! -f $COMMON_CONFDIR/vfaces/${v_iface_name} ]]; then v_iface_name="x$i${WIFI_IFACE}"
mkdir -p $COMMON_CONFDIR/vfaces i=$((i + 1))
touch $COMMON_CONFDIR/vfaces/${v_iface_name} is_vface_name_allocated ${v_iface_name} || break
echo "${v_iface_name}" done
return fi
fi mkdir -p $COMMON_CONFDIR/vfaces
i=$((i + 1)) touch $COMMON_CONFDIR/vfaces/${v_iface_name}
done echo "${v_iface_name}"
} }
dealloc_vface_name() { dealloc_vface_name() {
@@ -1021,7 +1037,7 @@ allow_dhcp() {
# TODO: use 'DNAT' instead of '--to-ports' to support other IP # TODO: use 'DNAT' instead of '--to-ports' to support other IP
start_redsocks() { start_redsocks() {
echo echo
echo "iptables: transparent proxy non-LAN TCP/UDP traffic to port ${TP_PORT}" echo "iptables: transparent proxy non-LAN TCP and UDP(not tested) traffic to port ${TP_PORT}"
if [[ $NO4 -eq 0 ]]; then if [[ $NO4 -eq 0 ]]; then
iptb 4 n nat N lrt${$}${SUBNET_IFACE}-TP || die iptb 4 n nat N lrt${$}${SUBNET_IFACE}-TP || die
iptb 4 n nat A lrt${$}${SUBNET_IFACE}-TP -d 0.0.0.0/8 -j RETURN || die iptb 4 n nat A lrt${$}${SUBNET_IFACE}-TP -d 0.0.0.0/8 -j RETURN || die
@@ -1207,7 +1223,7 @@ cleanup() {
#kill -9 -$pgid #kill -9 -$pgid
} }
# NOTE function die() is designed not to be used before init_trap() executed # NOTE function die() is designed NOT to be used before init_trap() executed
die() { # SIGUSR2 die() { # SIGUSR2
echo "Error occured" echo "Error occured"
[[ -n "$1" ]] && echo -e "\nERROR: $1\n" >&2 [[ -n "$1" ]] && echo -e "\nERROR: $1\n" >&2
@@ -1569,6 +1585,18 @@ check_wifi_settings() {
fi fi
echo "WARN: If AP doesn't work, read https://github.com/oblique/create_ap/blob/master/howto/realtek.md" >&2 echo "WARN: If AP doesn't work, read https://github.com/oblique/create_ap/blob/master/howto/realtek.md" >&2
fi fi
if [[ -z $VIRT_NAME ]]; then
if [[ ${#WIFI_IFACE} -gt 13 ]]; then
echo "WARN: $WIFI_IFACE has ${#WIFI_IFACE} characters which might be too long. If AP doesn't work, see --virt-name and https://github.com/garywill/linux-router/issues/44" >&2
fi
elif [[ ${#VIRT_NAME} -gt 15 ]]; then
echo "WARN: option --virt-name $VIRT_NAME has ${#VIRT_NAME} characters which might be too long, consider making it shorter in case of errors" >&2
fi
if [[ ! -z $VIRT_NAME ]] && is_vface_name_allocated $VIRT_NAME; then
echo "WARN: interface $VIRT_NAME aleady exists, this will cause an error"
fi
} }
check_if_new_mac_valid() { check_if_new_mac_valid() {
@@ -1614,10 +1642,6 @@ decide_ip_addresses() {
} }
prepare_wifi_interface() { prepare_wifi_interface() {
sleep 1
echo; echo; echo;
echo "Trying to set power_save off ..."
if [[ $USE_IWCONFIG -eq 0 ]]; then if [[ $USE_IWCONFIG -eq 0 ]]; then
iw dev ${WIFI_IFACE} set power_save off iw dev ${WIFI_IFACE} set power_save off
fi fi
@@ -1641,8 +1665,6 @@ prepare_wifi_interface() {
fi fi
fi fi
sleep 6
echo; echo; echo;
echo "Creating a virtual WiFi interface... " echo "Creating a virtual WiFi interface... "
VWIFI_IFACE=$(alloc_new_vface_name) VWIFI_IFACE=$(alloc_new_vface_name)
if iw dev ${WIFI_IFACE} interface add ${VWIFI_IFACE} type __ap; then if iw dev ${WIFI_IFACE} interface add ${VWIFI_IFACE} type __ap; then
@@ -1652,7 +1674,13 @@ prepare_wifi_interface() {
echo "${VWIFI_IFACE} created" echo "${VWIFI_IFACE} created"
else else
VWIFI_IFACE= VWIFI_IFACE=
die "Failed creating virtual WiFi interface. Maybe your WiFi adapter does not fully support virtual interfaces. Try again with '--no-virt'" if [[ ! -z ${VIRT_NAME} ]] && [[ ${#VIRT_NAME} -gt 15 ]]; then
die "Failed creating virtual WiFi interface. This is likely because you have set a long name for your virtual interface using --virt-name, try making it shorter'"
elif [[ -z ${VIRT_NAME} ]] && [[ ${#WIFI_IFACE} -gt 13 ]]; then
die "Failed creating virtual WiFi interface. This is likely because your interface name is too long. Try using '--virt-name <shorter interface name>'"
else
die "Failed creating virtual WiFi interface. Maybe your WiFi adapter does not fully support virtual interfaces. Try again with '--no-virt'"
fi
fi fi
AP_IFACE=${VWIFI_IFACE} AP_IFACE=${VWIFI_IFACE}
@@ -1828,6 +1856,10 @@ write_dnsmasq_conf() {
no-poll no-poll
EOF EOF
fi fi
if [[ $DNS_NOCACHE -eq 1 ]]; then
echo "cache-size=0" >> "$CONFDIR/dnsmasq.conf"
echo "no-negcache" >> "$CONFDIR/dnsmasq.conf"
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}
@@ -1957,8 +1989,6 @@ phead
phead2 phead2
echo echo
echo " ============ In dev branch for issue #12 ==========="
echo "PID: $$" echo "PID: $$"
TARGET_IFACE="$(decide_target_interface)" || exit 1 # judge wired (-i CONN_IFACE) or wireless hotspot (--ap $WIFI_IFACE) TARGET_IFACE="$(decide_target_interface)" || exit 1 # judge wired (-i CONN_IFACE) or wireless hotspot (--ap $WIFI_IFACE)
@@ -1982,33 +2012,10 @@ init_trap
init_conf_dirs # CONFDIR , COMMON_CONFDIR . make dir init_conf_dirs # CONFDIR , COMMON_CONFDIR . make dir
echo -e "\nDistro:"
cat /etc/os-release
echo -e "\nKernel:"
uname -a
echo
echo "setting NM log level: nmcli general logging level TRACE domains ALL"
nmcli general logging level TRACE domains ALL
echo "Logging journalctl -f"
journalctl -f &
echo $! > $CONFDIR/journalctl.pid
echo "Logging dmesg -W"
dmesg -W &
echo $! > $CONFDIR/dmesg.pid
echo "Logging wpa_supplicant.log"
tail -f /var/log/wpa_supplicant.log &
echo $! > $CONFDIR/wpa_supplicant_log.pid
[[ $WIFI_IFACE ]] && prepare_wifi_interface # this will create virtual ap interface (if needed) and set VWIFI_IFACE and AP_IFACE (if success) [[ $WIFI_IFACE ]] && prepare_wifi_interface # this will create virtual ap interface (if needed) and set VWIFI_IFACE and AP_IFACE (if success)
SUBNET_IFACE="$(decide_subnet_interface)" # SUBNET_IFACE can be TARGET_IFACE (wired) or AP_IFACE (ap) .this is after prepare_wifi_interface() SUBNET_IFACE="$(decide_subnet_interface)" # SUBNET_IFACE can be TARGET_IFACE (wired) or AP_IFACE (ap) .this is after prepare_wifi_interface()
echo "$SUBNET_IFACE" > "$CONFDIR/subn_iface" echo "$SUBNET_IFACE" > "$CONFDIR/subn_iface"
ip addr show dev ${SUBNET_IFACE}
# if virtual wifi interface, will be destroyed, so only need to save status when not # if virtual wifi interface, will be destroyed, so only need to save status when not
[[ -z $VWIFI_IFACE ]] && backup_interface_status [[ -z $VWIFI_IFACE ]] && backup_interface_status
@@ -2028,10 +2035,6 @@ fi
#=================================================== #===================================================
#=================================================== #===================================================
sleep 1
echo; echo; echo;
ip addr show dev ${SUBNET_IFACE}
echo "Trying to set NM unmanage ..."
# set interface unmanaged by networkManager # set interface unmanaged by networkManager
if [[ $NM_RUNNING -eq 1 ]] && nm_knows $TARGET_IFACE; then # if nm knows target iface, should know subnet iface too. but need to wait until nm finds subnet iface (waiting code is in nm_set_unmanaged() if [[ $NM_RUNNING -eq 1 ]] && nm_knows $TARGET_IFACE; then # if nm knows target iface, should know subnet iface too. but need to wait until nm finds subnet iface (waiting code is in nm_set_unmanaged()
nm_set_unmanaged ${SUBNET_IFACE} # will write NM_UNM_LIST nm_set_unmanaged ${SUBNET_IFACE} # will write NM_UNM_LIST
@@ -2040,47 +2043,19 @@ fi
[[ $NO_DNSMASQ -eq 0 ]] && write_dnsmasq_conf [[ $NO_DNSMASQ -eq 0 ]] && write_dnsmasq_conf
#=========================== #===========================
sleep 1
echo; echo; echo;
ip addr show dev ${SUBNET_IFACE}
echo "Trying to set ${SUBNET_IFACE} down ..."
# initialize subnet interface # initialize subnet interface
# take subnet interface down first # take subnet interface down first
ip link set down dev ${SUBNET_IFACE} || die "Failed setting ${SUBNET_IFACE} down" ip link set down dev ${SUBNET_IFACE} || die "Failed setting ${SUBNET_IFACE} down"
sleep 1
echo; echo; echo;
ip addr show dev ${SUBNET_IFACE}
echo "Trying to flush ${SUBNET_IFACE} ..."
# flush old IPs of subnet interface # flush old IPs of subnet interface
ip addr flush ${SUBNET_IFACE} || die "Failed flush ${SUBNET_IFACE} IP" ip addr flush ${SUBNET_IFACE} || die "Failed flush ${SUBNET_IFACE} IP"
sleep 1
echo; echo; echo;
ip addr show dev ${SUBNET_IFACE}
dealwith_mac # setting MAC should be after setting NM unmanaged dealwith_mac # setting MAC should be after setting NM unmanaged
sleep 1
echo; echo; echo;
ip addr show dev ${SUBNET_IFACE}
echo "Trying to check and do rfkill unblock ..."
[[ $WIFI_IFACE ]] && check_rfkill_unblock_wifi [[ $WIFI_IFACE ]] && check_rfkill_unblock_wifi
sleep 1
echo; echo; echo;
ip addr show dev ${SUBNET_IFACE}
echo "Trying to bring interface ${SUBNET_IFACE} up ..."
# bring subnet interface up # bring subnet interface up
ip link set up dev ${SUBNET_IFACE} || die "Failed bringing ${SUBNET_IFACE} up" ip link set up dev ${SUBNET_IFACE} || die "Failed bringing ${SUBNET_IFACE} up"
sleep 1
echo; echo; echo;
echo "Finished test. Exiting ..."
clean_exit
exit
# hostapd , haveged # hostapd , haveged
[[ $WIFI_IFACE ]] && run_wifi_ap_processes [[ $WIFI_IFACE ]] && run_wifi_ap_processes