Bubble android client. Fork of https://git.zx2c4.com/wireguard-android/
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

wg-quick.bash 5.2 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #!/system/xbin/bash
  2. #
  3. # Copyright (C) 2016-2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
  4. #
  5. set -e -o pipefail
  6. shopt -s extglob
  7. export LC_ALL=C
  8. SELF="$(readlink -f "${BASH_SOURCE[0]}")"
  9. export PATH="${SELF%/*}:$PATH"
  10. WG_CONFIG=""
  11. INTERFACE=""
  12. NETID=0
  13. ADDRESSES=( )
  14. MTU=""
  15. DNS=( )
  16. CONFIG_FILE=""
  17. PROGRAM="${0##*/}"
  18. ARGS=( "$@" )
  19. parse_options() {
  20. local interface_section=0 line key value
  21. CONFIG_FILE="$1"
  22. [[ $CONFIG_FILE =~ ^[a-zA-Z0-9_=+.-]{1,16}$ ]] && CONFIG_FILE="/data/misc/wireguard/$CONFIG_FILE.conf"
  23. [[ -e $CONFIG_FILE ]] || die "\`$CONFIG_FILE' does not exist"
  24. [[ $CONFIG_FILE =~ /?([a-zA-Z0-9_=+.-]{1,16})\.conf$ ]] || die "The config file must be a valid interface name, followed by .conf"
  25. ((($(stat -c '%#a' "$CONFIG_FILE") & 0007) == 0)) || echo "Warning: \`$CONFIG_FILE' is world accessible" >&2
  26. INTERFACE="${BASH_REMATCH[1]}"
  27. shopt -s nocasematch
  28. while read -r line || [[ -n $line ]]; do
  29. key="${line%%=*}"; key="${key##*( )}"; key="${key%%*( )}"
  30. value="${line#*=}"; value="${value##*( )}"; value="${value%%*( )}"
  31. [[ $key == "["* ]] && interface_section=0
  32. [[ $key == "[Interface]" ]] && interface_section=1
  33. if [[ $interface_section -eq 1 ]]; then
  34. case "$key" in
  35. Address) ADDRESSES+=( ${value//,/ } ); continue ;;
  36. MTU) MTU="$value"; continue ;;
  37. DNS) DNS+=( ${value//,/ } ); continue ;;
  38. esac
  39. fi
  40. WG_CONFIG+="$line"$'\n'
  41. done < "$CONFIG_FILE"
  42. shopt -u nocasematch
  43. }
  44. cmd() {
  45. echo "[#] $*" >&2
  46. "$@"
  47. }
  48. cndc() {
  49. local out="$(cmd ndc "$@")"
  50. [[ $out == *200\ 0* ]] || { echo "$out"; return 1; }
  51. }
  52. die() {
  53. echo "$PROGRAM: $*" >&2
  54. exit 1
  55. }
  56. auto_su() {
  57. [[ $UID == 0 ]] || exec su -p -c "'$SELF' ${ARGS[*]}"
  58. }
  59. add_if() {
  60. cmd ip link add "$INTERFACE" type wireguard
  61. }
  62. del_if() {
  63. cmd ip link del "$INTERFACE"
  64. [[ $(ip rule show) =~ 0xc([0-9a-f]+)/0xcffff\ lookup\ $INTERFACE ]] && cndc network destroy $(( 0x${BASH_REMATCH[1]} ));
  65. }
  66. up_if() {
  67. while [[ $NETID -lt 4096 ]]; do
  68. NETID="$RANDOM"
  69. done
  70. cmd wg set "$INTERFACE" fwmark 0x20000
  71. cndc interface setcfg "$INTERFACE" up
  72. cndc network create "$NETID" vpn 1 1
  73. cndc network interface add "$NETID" "$INTERFACE"
  74. cndc network users add "$NETID" 0-99999
  75. }
  76. set_dns() {
  77. [[ ${#DNS[@]} -eq 0 ]] || cndc resolver setnetdns "$NETID" "" "${DNS[@]}"
  78. }
  79. add_addr() {
  80. if [[ $1 == *:* ]]; then
  81. cndc interface ipv6 "$INTERFACE" enable
  82. cmd ip -6 addr add "$1" dev "$INTERFACE"
  83. else
  84. local ip="${1%%/*}" mask=32
  85. [[ $1 == */* ]] && mask="${1##*/}"
  86. cndc interface setcfg "$INTERFACE" "$ip" "$mask"
  87. fi
  88. }
  89. set_mtu() {
  90. local mtu=0 endpoint output
  91. if [[ -n $MTU ]]; then
  92. cndc interface setmtu "$INTERFACE" "$MTU"
  93. return
  94. fi
  95. while read -r _ endpoint; do
  96. [[ $endpoint =~ ^\[?([a-z0-9:.]+)\]?:[0-9]+$ ]] || continue
  97. output="$(ip route get "${BASH_REMATCH[1]}" || true)"
  98. [[ ( $output =~ mtu\ ([0-9]+) || ( $output =~ dev\ ([^ ]+) && $(ip link show dev "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) ) ) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}"
  99. done < <(wg show "$INTERFACE" endpoints)
  100. if [[ $mtu -eq 0 ]]; then
  101. read -r output < <(ip route show default || true) || true
  102. [[ ( $output =~ mtu\ ([0-9]+) || ( $output =~ dev\ ([^ ]+) && $(ip link show dev "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) ) ) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}"
  103. fi
  104. [[ $mtu -gt 0 ]] || mtu=1500
  105. cndc interface setmtu "$INTERFACE" $(( mtu - 80 ))
  106. }
  107. add_route() {
  108. cndc network route add "$NETID" "$INTERFACE" "$1"
  109. }
  110. set_config() {
  111. cmd wg setconf "$INTERFACE" <(echo "$WG_CONFIG")
  112. }
  113. cmd_usage() {
  114. cat >&2 <<-_EOF
  115. Usage: $PROGRAM [ up | down ] [ CONFIG_FILE | INTERFACE ]
  116. CONFIG_FILE is a configuration file, whose filename is the interface name
  117. followed by \`.conf'. Otherwise, INTERFACE is an interface name, with
  118. configuration found at /data/misc/wireguard/INTERFACE.conf. It is to be readable
  119. by wg(8)'s \`setconf' sub-command, with the exception of the following additions
  120. to the [Interface] section, which are handled by $PROGRAM:
  121. - Address: may be specified one or more times and contains one or more
  122. IP addresses (with an optional CIDR mask) to be set for the interface.
  123. - MTU: an optional MTU for the interface; if unspecified, auto-calculated.
  124. - DNS: an optional DNS server to use while the device is up.
  125. See wg-quick(8) for more info and examples.
  126. _EOF
  127. }
  128. cmd_up() {
  129. local i
  130. [[ -z $(ip link show dev "$INTERFACE" 2>/dev/null) ]] || die "\`$INTERFACE' already exists"
  131. trap 'del_if; exit' INT TERM EXIT
  132. add_if
  133. set_config
  134. set_mtu
  135. for i in "${ADDRESSES[@]}"; do
  136. add_addr "$i"
  137. done
  138. up_if
  139. set_dns
  140. for i in $(while read -r _ i; do for i in $i; do [[ $i =~ ^[0-9a-z:.]+/[0-9]+$ ]] && echo "$i"; done; done < <(wg show "$INTERFACE" allowed-ips) | sort -nr -k 2 -t /); do
  141. [[ $(ip route get "$i" 2>/dev/null) == *dev\ $INTERFACE\ * ]] || add_route "$i"
  142. done
  143. trap - INT TERM EXIT
  144. }
  145. cmd_down() {
  146. [[ -n $(ip link show dev "$INTERFACE" type wireguard 2>/dev/null) ]] || die "\`$INTERFACE' is not a WireGuard interface"
  147. del_if
  148. }
  149. if [[ $# -eq 1 && ( $1 == --help || $1 == -h || $1 == help ) ]]; then
  150. cmd_usage
  151. elif [[ $# -eq 2 && $1 == up ]]; then
  152. auto_su
  153. parse_options "$2"
  154. cmd_up
  155. elif [[ $# -eq 2 && $1 == down ]]; then
  156. auto_su
  157. parse_options "$2"
  158. cmd_down
  159. else
  160. cmd_usage
  161. exit 1
  162. fi
  163. exit 0