ip.sh 13 KB

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