ip.sh 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. #!/bin/bash
  2. #===========================================================================#
  3. # #
  4. # Hestia Control Panel - IP/Network Function Library #
  5. # #
  6. #===========================================================================#
  7. # === Global definitions ===
  8. REGEX_IPV4="^((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])$"
  9. # === IPV4 specific functions ===
  10. # Check ip ownership
  11. is_ip_owner() {
  12. # ip address (ipv4/ipv6) as first parameter, otherwise $ip (ipv4)
  13. ip_for_test="${1-$ip}"
  14. owner=$(grep 'OWNER=' $HESTIA/data/ips/$ip_for_test | cut -f 2 -d \')
  15. if [ "$owner" != "$user" ]; then
  16. check_result "$E_FORBIDEN" "$ip_for_test is not owned by $user"
  17. fi
  18. }
  19. # Check if ip address is free
  20. is_ip_free() {
  21. # ip address (ipv4/ipv6) as first parameter, otherwise $ip (ipv4)
  22. ip_for_test="${1-$ip}"
  23. if [ -e "$HESTIA/data/ips/$ip_for_test" ]; then
  24. check_result "$E_EXISTS" "$ip_for_test is already exists"
  25. fi
  26. }
  27. # Check ip address specific value
  28. is_ip_key_empty() {
  29. key="$1"
  30. # ip address (ipv4/ipv6) as second parameter, otherwise $ip (ipv4)
  31. ip_for_test="${2-$ip}"
  32. if [ -n "$ip_for_test" ]; then
  33. string=$(cat $HESTIA/data/ips/$ip_for_test)
  34. eval $string
  35. eval value="$key"
  36. if [ -n "$value" ] && [ "$value" != '0' ]; then
  37. key="$(echo $key | sed -e "s/\$U_//")"
  38. check_result "$E_EXISTS" "IP is in use / $key = $value"
  39. fi
  40. else
  41. check_result 1 "is_ip_key_empty(): IP address is empty!"
  42. fi
  43. }
  44. is_ip_rdns_valid() {
  45. local ip="$1"
  46. local network_ip=$(echo $ip | cut -d"." -f1-3)
  47. local awk_ip=$(echo $network_ip | sed 's|\.|/\&\&/|g')
  48. local rev_awk_ip=$(echo $awk_ip | rev)
  49. if [ -z "$rdns" ]; then
  50. local rdns=$(dig +short -x "$ip" | head -n 1 | sed 's/.$//') || unset rdns
  51. fi
  52. if [ -n "$rdns" ] && [ ! $(echo $rdns | awk "/$awk_ip/ || /$rev_awk_ip/") ]; then
  53. echo $rdns
  54. return 0 # True
  55. fi
  56. return 1 # False
  57. }
  58. # Update ip address value
  59. update_ip_value() {
  60. key="$1"
  61. value="$2"
  62. conf="$HESTIA/data/ips/$ip"
  63. str=$(cat $conf)
  64. eval $str
  65. c_key=$(echo "${key//$/}")
  66. eval old="${key}"
  67. old=$(echo "$old" | sed -e 's/\\/\\\\/g' -e 's/&/\\&/g' -e 's/\//\\\//g')
  68. new=$(echo "$value" | sed -e 's/\\/\\\\/g' -e 's/&/\\&/g' -e 's/\//\\\//g')
  69. sed -i "$str_number s/$c_key='${old//\*/\\*}'/$c_key='${new//\*/\\*}'/g" \
  70. $conf
  71. }
  72. # New method that is improved on a later date we need to check if we can improve it for other locations
  73. update_ip_value_new() {
  74. key="$1"
  75. value="$2"
  76. conf="$HESTIA/data/ips/$ip"
  77. check_ckey=$(grep "^$key='" $conf)
  78. if [ -z "$check_ckey" ]; then
  79. echo "$key='$value'" >> $conf
  80. else
  81. sed -i "s|^$key=.*|$key='$value'|g" $conf
  82. fi
  83. }
  84. # Get ip name
  85. get_ip_alias() {
  86. if [ -n "$local_ip"]; then
  87. ip_name=$(grep "NAME=" $HESTIA/data/ips/$local_ip | cut -f 2 -d \')
  88. if [ -n "$ip_name" ]; then
  89. echo "${1//./-}.$ip_name"
  90. fi
  91. else
  92. ip_name=""
  93. fi
  94. }
  95. # Increase ip value
  96. increase_ip_value() {
  97. sip=${1-ip}
  98. USER=${2-$user}
  99. web_key='U_WEB_DOMAINS'
  100. usr_key='U_SYS_USERS'
  101. current_web=$(grep "$web_key=" $HESTIA/data/ips/$sip | cut -f 2 -d \')
  102. current_usr=$(grep "$usr_key=" $HESTIA/data/ips/$sip | cut -f 2 -d \')
  103. if [ -z "$current_web" ]; then
  104. echo "Error: Parsing error"
  105. log_event "$E_PARSING" "$ARGUMENTS"
  106. exit "$E_PARSING"
  107. fi
  108. new_web=$((current_web + 1))
  109. if [ -z "$current_usr" ]; then
  110. new_usr="$USER"
  111. else
  112. check_usr=$(echo -e "${current_usr//,/\\n}" | grep -x "$USER")
  113. if [ -z "$check_usr" ]; then
  114. new_usr="$current_usr,$USER"
  115. else
  116. new_usr="$current_usr"
  117. fi
  118. fi
  119. # Make sure users list does not contain duplicates
  120. new_usr=$(echo "$new_usr" \
  121. | sed "s/,/\n/g" \
  122. | sort -u \
  123. | sed ':a;N;$!ba;s/\n/,/g')
  124. sed -i "s/$web_key='$current_web'/$web_key='$new_web'/g" \
  125. $HESTIA/data/ips/$sip
  126. sed -i "s/$usr_key='$current_usr'/$usr_key='$new_usr'/g" \
  127. $HESTIA/data/ips/$sip
  128. }
  129. # Decrease ip value
  130. decrease_ip_value() {
  131. sip=${1-ip}
  132. local user=${2-$user}
  133. web_key='U_WEB_DOMAINS'
  134. usr_key='U_SYS_USERS'
  135. current_web=$(grep "$web_key=" $HESTIA/data/ips/$sip | cut -f 2 -d \')
  136. current_usr=$(grep "$usr_key=" $HESTIA/data/ips/$sip | cut -f 2 -d \')
  137. if [ -z "$current_web" ]; then
  138. check_result $E_PARSING "Parsing error"
  139. fi
  140. new_web=$((current_web - 1))
  141. check_ip=$(grep $sip $USER_DATA/web.conf | wc -l)
  142. if [[ $check_ip = 0 ]]; then
  143. new_usr=$(echo "$current_usr" \
  144. | sed "s/,/\n/g" \
  145. | sed "s/^$user$//g" \
  146. | sed "/^$/d" \
  147. | sort -u \
  148. | sed ':a;N;$!ba;s/\n/,/g')
  149. else
  150. new_usr="$current_usr"
  151. fi
  152. sed -i "s/$web_key='$current_web'/$web_key='$new_web'/g" \
  153. $HESTIA/data/ips/$sip
  154. sed -i "s/$usr_key='$current_usr'/$usr_key='$new_usr'/g" \
  155. $HESTIA/data/ips/$sip
  156. }
  157. # Get ip address value
  158. get_ip_value() {
  159. key="$1"
  160. string=$(cat $HESTIA/data/ips/$ip)
  161. eval $string
  162. eval value="$key"
  163. echo "$value"
  164. }
  165. # Get real ip address
  166. get_real_ip() {
  167. if [ -e "$HESTIA/data/ips/$1" ]; then
  168. echo "$1"
  169. else
  170. nat=$(grep -H "^NAT='$1'" $HESTIA/data/ips/* | head -n1)
  171. if [ -n "$nat" ]; then
  172. echo "$nat" | cut -f 1 -d : | cut -f 7 -d /
  173. fi
  174. fi
  175. }
  176. # Convert CIDR to netmask
  177. convert_cidr() {
  178. # CIDR can be defined as /32 (with leading /) or as 32 (number without leading /)
  179. # please check the value range of cidr before converting!
  180. set ${1#/} # allow to use cidr format with leading /
  181. set -- $((5 - ($1 / 8))) 255 255 255 255 \
  182. $(((255 << (8 - ($1 % 8))) & 255)) 0 0 0
  183. if [[ $1 -gt 1 ]]; then
  184. shift $1
  185. else
  186. shift
  187. fi
  188. echo ${1-0}.${2-0}.${3-0}.${4-0}
  189. }
  190. # Convert netmask to CIDR
  191. convert_netmask() {
  192. nbits=0
  193. IFS=.
  194. for dec in $1; do
  195. case $dec in
  196. 255) let nbits+=8 ;;
  197. 254) let nbits+=7 ;;
  198. 252) let nbits+=6 ;;
  199. 248) let nbits+=5 ;;
  200. 240) let nbits+=4 ;;
  201. 224) let nbits+=3 ;;
  202. 192) let nbits+=2 ;;
  203. 128) let nbits+=1 ;;
  204. 0) ;;
  205. esac
  206. done
  207. echo "/$nbits"
  208. }
  209. # Calculate broadcast address
  210. get_broadcast() {
  211. OLD_IFS=$IFS
  212. IFS=.
  213. typeset -a I=($1)
  214. typeset -a N=($2)
  215. IFS=$OLD_IFS
  216. echo "$((${I[0]} | (255 ^ ${N[0]}))).$((${I[1]} | (255 ^ ${N[1]}))).$((${I[2]} | (255 ^ ${N[2]}))).$((${I[3]} | (255 ^ ${N[3]})))"
  217. }
  218. # Get user ips
  219. get_user_ips() {
  220. dedicated=$(grep -H "OWNER='$user'" $HESTIA/data/ips/*)
  221. dedicated=$(echo "$dedicated" | cut -f 1 -d : | sed 's=.*/==' | grep -E ${REGEX_IPV4})
  222. shared=$(grep -H -A1 "OWNER='admin'" $HESTIA/data/ips/* | grep shared)
  223. shared=$(echo "$shared" | cut -f 1 -d : | sed 's=.*/==' | cut -f 1 -d \- | grep -E ${REGEX_IPV4})
  224. for dedicated_ip in $dedicated; do
  225. shared=$(echo "$shared" | grep -v $dedicated_ip)
  226. done
  227. echo -e "$dedicated\n$shared" | sed "/^$/d"
  228. }
  229. # Get user ip
  230. get_user_ip() {
  231. ip=$(get_user_ips | head -n1)
  232. if [ -z "$ip" ]; then
  233. check_result $E_NOTEXIST "no IP is available"
  234. fi
  235. local_ip=$ip
  236. nat=$(grep "^NAT" $HESTIA/data/ips/$ip | cut -f 2 -d \')
  237. if [ -n "$nat" ]; then
  238. ip=$nat
  239. fi
  240. }
  241. # Validate ip address
  242. is_ip_valid() {
  243. local_ip="$1"
  244. if [ ! -e "$HESTIA/data/ips/$1" ]; then
  245. nat=$(grep -H "^NAT='$1'" $HESTIA/data/ips/*)
  246. if [ -z "$nat" ]; then
  247. check_result "$E_NOTEXIST" "IP $1 doesn't exist"
  248. else
  249. nat=$(echo "$nat" | cut -f1 -d: | cut -f7 -d/)
  250. local_ip=$nat
  251. fi
  252. fi
  253. if [ -n "$2" ]; then
  254. if [ -z "$nat" ]; then
  255. ip_data=$(cat $HESTIA/data/ips/$1)
  256. else
  257. ip_data=$(cat $HESTIA/data/ips/$nat)
  258. fi
  259. ip_owner=$(echo "$ip_data" | grep OWNER= | cut -f2 -d \')
  260. ip_status=$(echo "$ip_data" | grep STATUS= | cut -f2 -d \')
  261. if [ "$ip_owner" != "$user" ] && [ "$ip_status" = 'dedicated' ]; then
  262. check_result "$E_FORBIDEN" "$user user can't use IP $1"
  263. fi
  264. get_user_owner
  265. if [ "$ip_owner" != "$user" ] && [ "$ip_owner" != "$owner" ]; then
  266. check_result "$E_FORBIDEN" "$user user can't use IP $1"
  267. fi
  268. fi
  269. }
  270. # === IPV6 specific functions ===
  271. # Get full interface name
  272. get_ipv6_iface() {
  273. i=$(/sbin/ip addr |grep -w $interface |\
  274. awk '{print $NF}' |tail -n 1 |cut -f 2 -d :)
  275. if [ "$i" = "$interface" ]; then
  276. n=0
  277. else
  278. n=$((i + 1))
  279. fi
  280. echo "$interface:$n"
  281. }
  282. # Update ipv6 address value
  283. update_ipv6_value() {
  284. key="$1"
  285. value="$2"
  286. conf="$HESTIA/data/ips/$ipv6"
  287. str=$(cat $conf)
  288. eval $str
  289. c_key=$(echo "${key//$/}")
  290. eval old="${key}"
  291. old=$(echo "$old" | sed -e 's/\\/\\\\/g' -e 's/&/\\&/g' -e 's/\//\\\//g')
  292. new=$(echo "$value" | sed -e 's/\\/\\\\/g' -e 's/&/\\&/g' -e 's/\//\\\//g')
  293. sed -i "$str_number s/$c_key='${old//\*/\\*}'/$c_key='${new//\*/\\*}'/g"\
  294. $conf
  295. }
  296. # Get ipv6 name
  297. get_ipv6_alias() {
  298. if [ -n "$local_ipv6" ]; then
  299. ipv6_name=$(grep "NAME=" $HESTIA/data/ips/$local_ipv6 2> /dev/null |cut -f 2 -d \')
  300. if [ -n "$ipv6_name" ]; then
  301. echo "${1//./-}.$ipv6_name"
  302. fi
  303. else
  304. ipv6_name=""
  305. fi
  306. }
  307. # Increase ipv6 value
  308. increase_ipv6_value() {
  309. sip=${1-ipv6}
  310. if [ "$sip" != "no" ] && [ ! -z "$sip" ]; then
  311. USER=$user
  312. web_key='U_WEB_DOMAINS'
  313. usr_key='U_SYS_USERS'
  314. current_web=$(grep "$web_key=" $HESTIA/data/ips/$sip |cut -f 2 -d \')
  315. current_usr=$(grep "$usr_key=" $HESTIA/data/ips/$sip |cut -f 2 -d \')
  316. if [ -z "$current_web" ]; then
  317. echo "Error: Parsing error"
  318. log_event "$E_PARSING" "$ARGUMENTS"
  319. exit $E_PARSING
  320. fi
  321. new_web=$((current_web + 1))
  322. if [ -z "$current_usr" ]; then
  323. new_usr="$USER"
  324. else
  325. check_usr=$(echo -e "${current_usr//,/\n}" |grep -w $USER)
  326. if [ -z "$check_usr" ]; then
  327. new_usr="$current_usr,$USER"
  328. else
  329. new_usr="$current_usr"
  330. fi
  331. fi
  332. sed -i "s/$web_key='$current_web'/$web_key='$new_web'/g" \
  333. $HESTIA/data/ips/$sip
  334. sed -i "s/$usr_key='$current_usr'/$usr_key='$new_usr'/g" \
  335. $HESTIA/data/ips/$sip
  336. fi
  337. }
  338. # Decrease ipv6 value
  339. decrease_ipv6_value() {
  340. sip=${1-ipv6}
  341. if [ "$sip" != "no" ] && [ ! -z "$sip" ]; then
  342. USER=$user
  343. web_key='U_WEB_DOMAINS'
  344. usr_key='U_SYS_USERS'
  345. current_web=$(grep "$web_key=" $HESTIA/data/ips/$sip |cut -f 2 -d \')
  346. current_usr=$(grep "$usr_key=" $HESTIA/data/ips/$sip |cut -f 2 -d \')
  347. if [ -z "$current_web" ]; then
  348. check_result $E_PARSING "Parsing error"
  349. fi
  350. new_web=$((current_web - 1))
  351. check_ip=$(grep $sip $USER_DATA/web.conf |wc -l)
  352. if [ "$check_ip" -lt 2 ]; then
  353. new_usr=$(echo "$current_usr" |\
  354. sed "s/,/\n/g"|\
  355. sed "s/^$user$//g"|\
  356. sed "/^$/d"|\
  357. sed ':a;N;$!ba;s/\n/,/g')
  358. else
  359. new_usr="$current_usr"
  360. fi
  361. sed -i "s/$web_key='$current_web'/$web_key='$new_web'/g" \
  362. $HESTIA/data/ips/$sip
  363. sed -i "s/$usr_key='$current_usr'/$usr_key='$new_usr'/g" \
  364. $HESTIA/data/ips/$sip
  365. fi
  366. }
  367. # Get ipv6 address value
  368. get_ipv6_value() {
  369. key="$1"
  370. string=$(cat $HESTIA/data/ips/$ipv6)
  371. eval $string
  372. eval value="$key"
  373. echo "$value"
  374. }
  375. # Get real ipv6 address
  376. get_real_ipv6() {
  377. if [ -e "$HESTIA/data/ips/$1" ]; then
  378. echo $1
  379. else
  380. check_result $E_NOTEXIST "IPV6 $1 doesn't exist"
  381. fi
  382. }
  383. # Get user ip6s
  384. get_user_ip6s() {
  385. dedicated=$(grep -H -A10 "OWNER='$user'" $HESTIA/data/ips/* |grep "VERSION='6'")
  386. dedicated=$(echo "$dedicated" |cut -f 1 -d '-' |sed 's=.*/==')
  387. shared=$(grep -H -A10 "OWNER='admin'" $HESTIA/data/ips/* |grep -A10 shared |grep "VERSION='6'")
  388. shared=$(echo "$shared" |cut -f 1 -d '-' |sed 's=.*/==' |cut -f 1 -d \-)
  389. for dedicated_ip in $dedicated; do
  390. shared=$(echo "$shared" |grep -v $dedicated_ip)
  391. done
  392. echo -e "$dedicated\n$shared" |sed "/^$/d"
  393. }
  394. # Get user ipv6
  395. get_user_ipv6() {
  396. ipv6=$(get_user_ip6s |head -n1)
  397. local_ipv6="$ipv6"
  398. }
  399. # Validate ipv6 address
  400. is_ipv6_valid() {
  401. local_ipv6="$1"
  402. if [ -z "$local_ipv6" ]; then
  403. check_result $E_NOTEXIST "IPV6 address is empty"
  404. fi
  405. if [ ! -e "$HESTIA/data/ips/$1" ]; then
  406. check_result $E_NOTEXIST "IPV6 $1 doesn't exist"
  407. fi
  408. if [ ! -z $2 ]; then
  409. ip_data=$(cat $HESTIA/data/ips/$1)
  410. ip_owner=$(echo "$ip_data" |grep OWNER= |cut -f2 -d \')
  411. ip_status=$(echo "$ip_data" |grep STATUS= |cut -f2 -d \')
  412. if [ "$ip_owner" != "$user" ] && [ "$ip_status" = 'dedicated' ]; then
  413. check_result $E_FORBIDEN "$user user can't use IPV6 $1"
  414. fi
  415. get_user_owner
  416. if [ "$ip_owner" != "$user" ] && [ "$ip_owner" != "$owner" ]; then
  417. check_result $E_FORBIDEN "$user user can't use IPV6 $1"
  418. fi
  419. fi
  420. }