ip.sh 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. #!/bin/bash
  2. #===========================================================================#
  3. # #
  4. # Hestia Control Panel - IP/Network Function Library #
  5. # #
  6. #===========================================================================#
  7. # === Global definitions ===
  8. REGEX_IPV4="^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}$"
  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. ip_name=$(grep "NAME=" $HESTIA/data/ips/$local_ip | cut -f 2 -d \')
  77. if [ -n "$ip_name" ]; then
  78. echo "${1//./-}.$ip_name"
  79. fi
  80. }
  81. # Increase ip value
  82. increase_ip_value() {
  83. sip=${1-ip}
  84. USER=${2-$user}
  85. web_key='U_WEB_DOMAINS'
  86. usr_key='U_SYS_USERS'
  87. current_web=$(grep "$web_key=" $HESTIA/data/ips/$sip | cut -f 2 -d \')
  88. current_usr=$(grep "$usr_key=" $HESTIA/data/ips/$sip | cut -f 2 -d \')
  89. if [ -z "$current_web" ]; then
  90. echo "Error: Parsing error"
  91. log_event "$E_PARSING" "$ARGUMENTS"
  92. exit "$E_PARSING"
  93. fi
  94. new_web=$((current_web + 1))
  95. if [ -z "$current_usr" ]; then
  96. new_usr="$USER"
  97. else
  98. check_usr=$(echo -e "${current_usr//,/\\n}" | grep -x "$USER")
  99. if [ -z "$check_usr" ]; then
  100. new_usr="$current_usr,$USER"
  101. else
  102. new_usr="$current_usr"
  103. fi
  104. fi
  105. # Make sure users list does not contain duplicates
  106. new_usr=$(echo "$new_usr" \
  107. | sed "s/,/\n/g" \
  108. | sort -u \
  109. | sed ':a;N;$!ba;s/\n/,/g')
  110. sed -i "s/$web_key='$current_web'/$web_key='$new_web'/g" \
  111. $HESTIA/data/ips/$sip
  112. sed -i "s/$usr_key='$current_usr'/$usr_key='$new_usr'/g" \
  113. $HESTIA/data/ips/$sip
  114. }
  115. # Decrease ip value
  116. decrease_ip_value() {
  117. sip=${1-ip}
  118. local user=${2-$user}
  119. web_key='U_WEB_DOMAINS'
  120. usr_key='U_SYS_USERS'
  121. current_web=$(grep "$web_key=" $HESTIA/data/ips/$sip | cut -f 2 -d \')
  122. current_usr=$(grep "$usr_key=" $HESTIA/data/ips/$sip | cut -f 2 -d \')
  123. if [ -z "$current_web" ]; then
  124. check_result $E_PARSING "Parsing error"
  125. fi
  126. new_web=$((current_web - 1))
  127. check_ip=$(grep $sip $USER_DATA/web.conf | wc -l)
  128. if [[ $check_ip = 0 ]]; then
  129. new_usr=$(echo "$current_usr" \
  130. | sed "s/,/\n/g" \
  131. | sed "s/^$user$//g" \
  132. | sed "/^$/d" \
  133. | sort -u \
  134. | sed ':a;N;$!ba;s/\n/,/g')
  135. else
  136. new_usr="$current_usr"
  137. fi
  138. sed -i "s/$web_key='$current_web'/$web_key='$new_web'/g" \
  139. $HESTIA/data/ips/$sip
  140. sed -i "s/$usr_key='$current_usr'/$usr_key='$new_usr'/g" \
  141. $HESTIA/data/ips/$sip
  142. }
  143. # Get ip address value
  144. get_ip_value() {
  145. key="$1"
  146. string=$(cat $HESTIA/data/ips/$ip)
  147. eval $string
  148. eval value="$key"
  149. echo "$value"
  150. }
  151. # Get real ip address
  152. get_real_ip() {
  153. if [ -e "$HESTIA/data/ips/$1" ]; then
  154. echo "$1"
  155. else
  156. nat=$(grep -H "^NAT='$1'" $HESTIA/data/ips/* | head -n1)
  157. if [ -n "$nat" ]; then
  158. echo "$nat" | cut -f 1 -d : | cut -f 7 -d /
  159. fi
  160. fi
  161. }
  162. # Convert CIDR to netmask
  163. convert_cidr() {
  164. set -- $((5 - ($1 / 8))) 255 255 255 255 \
  165. $(((255 << (8 - ($1 % 8))) & 255)) 0 0 0
  166. if [[ $1 -gt 1 ]]; then
  167. shift $1
  168. else
  169. shift
  170. fi
  171. echo ${1-0}.${2-0}.${3-0}.${4-0}
  172. }
  173. # Convert netmask to CIDR
  174. convert_netmask() {
  175. nbits=0
  176. IFS=.
  177. for dec in $1; do
  178. case $dec in
  179. 255) let nbits+=8 ;;
  180. 254) let nbits+=7 ;;
  181. 252) let nbits+=6 ;;
  182. 248) let nbits+=5 ;;
  183. 240) let nbits+=4 ;;
  184. 224) let nbits+=3 ;;
  185. 192) let nbits+=2 ;;
  186. 128) let nbits+=1 ;;
  187. 0) ;;
  188. esac
  189. done
  190. echo "$nbits"
  191. }
  192. # Calculate broadcast address
  193. get_broadcast() {
  194. OLD_IFS=$IFS
  195. IFS=.
  196. typeset -a I=($1)
  197. typeset -a N=($2)
  198. IFS=$OLD_IFS
  199. echo "$((${I[0]} | (255 ^ ${N[0]}))).$((${I[1]} | (255 ^ ${N[1]}))).$((${I[2]} | (255 ^ ${N[2]}))).$((${I[3]} | (255 ^ ${N[3]})))"
  200. }
  201. # Get user ips
  202. get_user_ips() {
  203. dedicated=$(grep -H "OWNER='$user'" $HESTIA/data/ips/*)
  204. dedicated=$(echo "$dedicated" | cut -f 1 -d : | sed 's=.*/==' | grep -E ${REGEX_IPV4})
  205. shared=$(grep -H -A1 "OWNER='admin'" $HESTIA/data/ips/* | grep shared)
  206. shared=$(echo "$shared" | cut -f 1 -d : | sed 's=.*/==' | cut -f 1 -d \- | grep -E ${REGEX_IPV4})
  207. for dedicated_ip in $dedicated; do
  208. shared=$(echo "$shared" | grep -v $dedicated_ip)
  209. done
  210. echo -e "$dedicated\n$shared" | sed "/^$/d"
  211. }
  212. # Get user ip
  213. get_user_ip() {
  214. ip=$(get_user_ips | head -n1)
  215. if [ -z "$ip" ]; then
  216. check_result $E_NOTEXIST "no IP is available"
  217. fi
  218. local_ip=$ip
  219. nat=$(grep "^NAT" $HESTIA/data/ips/$ip | cut -f 2 -d \')
  220. if [ -n "$nat" ]; then
  221. ip=$nat
  222. fi
  223. }
  224. # Validate ip address
  225. is_ip_valid() {
  226. local_ip="$1"
  227. if [ ! -e "$HESTIA/data/ips/$1" ]; then
  228. nat=$(grep -H "^NAT='$1'" $HESTIA/data/ips/*)
  229. if [ -z "$nat" ]; then
  230. check_result "$E_NOTEXIST" "IP $1 doesn't exist"
  231. else
  232. nat=$(echo "$nat" | cut -f1 -d: | cut -f7 -d/)
  233. local_ip=$nat
  234. fi
  235. fi
  236. if [ -n "$2" ]; then
  237. if [ -z "$nat" ]; then
  238. ip_data=$(cat $HESTIA/data/ips/$1)
  239. else
  240. ip_data=$(cat $HESTIA/data/ips/$nat)
  241. fi
  242. ip_owner=$(echo "$ip_data" | grep OWNER= | cut -f2 -d \')
  243. ip_status=$(echo "$ip_data" | grep STATUS= | cut -f2 -d \')
  244. if [ "$ip_owner" != "$user" ] && [ "$ip_status" = 'dedicated' ]; then
  245. check_result "$E_FORBIDEN" "$user user can't use IP $1"
  246. fi
  247. get_user_owner
  248. if [ "$ip_owner" != "$user" ] && [ "$ip_owner" != "$owner" ]; then
  249. check_result "$E_FORBIDEN" "$user user can't use IP $1"
  250. fi
  251. fi
  252. }
  253. # === IPV6 specific functions ===
  254. # Check ipv6 ownership
  255. is_ipv6_owner() {
  256. owner=$(grep 'OWNER=' $HESTIA/data/ips/$ipv6 |cut -f 2 -d \')
  257. if [ "$owner" != "$user" ]; then
  258. check_result $E_FORBIDEN "$ipv6 is not owned by $user"
  259. fi
  260. }
  261. # Check if ipv6 address is free
  262. is_ipv6_free() {
  263. if [ -e "$HESTIA/data/ips/$ipv6" ]; then
  264. check_result $E_EXISTS "$ipv6 is already exists"
  265. fi
  266. }
  267. # Get full interface name
  268. get_ipv6_iface() {
  269. i=$(/sbin/ip addr |grep -w $interface |\
  270. awk '{print $NF}' |tail -n 1 |cut -f 2 -d :)
  271. if [ "$i" = "$interface" ]; then
  272. n=0
  273. else
  274. n=$((i + 1))
  275. fi
  276. echo "$interface:$n"
  277. }
  278. # Check ipv6 address speciefic value
  279. is_ipv6_key_empty() {
  280. key="$1"
  281. string=$(cat $HESTIA/data/ips/$ipv6)
  282. eval $string
  283. eval value="$key"
  284. if [ ! -z "$value" ] && [ "$value" != '0' ]; then
  285. key="$(echo $key|sed -e "s/\$U_//")"
  286. check_result $E_EXISTS "IP6 is in use / $key = $value"
  287. fi
  288. }
  289. # Update ipv6 address value
  290. update_ipv6_value() {
  291. key="$1"
  292. value="$2"
  293. conf="$HESTIA/data/ips/$ipv6"
  294. str=$(cat $conf)
  295. eval $str
  296. c_key=$(echo "${key//$/}")
  297. eval old="${key}"
  298. old=$(echo "$old" | sed -e 's/\\/\\\\/g' -e 's/&/\\&/g' -e 's/\//\\\//g')
  299. new=$(echo "$value" | sed -e 's/\\/\\\\/g' -e 's/&/\\&/g' -e 's/\//\\\//g')
  300. sed -i "$str_number s/$c_key='${old//\*/\\*}'/$c_key='${new//\*/\\*}'/g"\
  301. $conf
  302. }
  303. # Get ipv6 name
  304. get_ipv6_alias() {
  305. ip_name=$(grep "NAME=" $HESTIA/data/ips/$ipv6 2> /dev/null |cut -f 2 -d \')
  306. if [ ! -z "$ip_name" ]; then
  307. echo "${1//./-}.$ip_name"
  308. fi
  309. }
  310. # Increase ipv6 value
  311. increase_ipv6_value() {
  312. sip=${1-ipv6}
  313. if [ "$sip" != "no" ] && [ ! -z "$sip" ]; then
  314. USER=$user
  315. web_key='U_WEB_DOMAINS'
  316. usr_key='U_SYS_USERS'
  317. current_web=$(grep "$web_key=" $HESTIA/data/ips/$sip |cut -f 2 -d \')
  318. current_usr=$(grep "$usr_key=" $HESTIA/data/ips/$sip |cut -f 2 -d \')
  319. if [ -z "$current_web" ]; then
  320. echo "Error: Parsing error"
  321. log_event "$E_PARSING" "$ARGUMENTS"
  322. exit $E_PARSING
  323. fi
  324. new_web=$((current_web + 1))
  325. if [ -z "$current_usr" ]; then
  326. new_usr="$USER"
  327. else
  328. check_usr=$(echo -e "${current_usr//,/\n}" |grep -w $USER)
  329. if [ -z "$check_usr" ]; then
  330. new_usr="$current_usr,$USER"
  331. else
  332. new_usr="$current_usr"
  333. fi
  334. fi
  335. sed -i "s/$web_key='$current_web'/$web_key='$new_web'/g" \
  336. $HESTIA/data/ips/$sip
  337. sed -i "s/$usr_key='$current_usr'/$usr_key='$new_usr'/g" \
  338. $HESTIA/data/ips/$sip
  339. fi
  340. }
  341. # Decrease ipv6 value
  342. decrease_ipv6_value() {
  343. sip=${1-ipv6}
  344. if [ "$sip" != "no" ] && [ ! -z "$sip" ]; then
  345. USER=$user
  346. web_key='U_WEB_DOMAINS'
  347. usr_key='U_SYS_USERS'
  348. current_web=$(grep "$web_key=" $HESTIA/data/ips/$sip |cut -f 2 -d \')
  349. current_usr=$(grep "$usr_key=" $HESTIA/data/ips/$sip |cut -f 2 -d \')
  350. if [ -z "$current_web" ]; then
  351. check_result $E_PARSING "Parsing error"
  352. fi
  353. new_web=$((current_web - 1))
  354. check_ip=$(grep $sip $USER_DATA/web.conf |wc -l)
  355. if [ "$check_ip" -lt 2 ]; then
  356. new_usr=$(echo "$current_usr" |\
  357. sed "s/,/\n/g"|\
  358. sed "s/^$user$//g"|\
  359. sed "/^$/d"|\
  360. sed ':a;N;$!ba;s/\n/,/g')
  361. else
  362. new_usr="$current_usr"
  363. fi
  364. sed -i "s/$web_key='$current_web'/$web_key='$new_web'/g" \
  365. $HESTIA/data/ips/$sip
  366. sed -i "s/$usr_key='$current_usr'/$usr_key='$new_usr'/g" \
  367. $HESTIA/data/ips/$sip
  368. fi
  369. }
  370. # Get ipv6 address value
  371. get_ipv6_value() {
  372. key="$1"
  373. string=$(cat $HESTIA/data/ips/$ip)
  374. eval $string
  375. eval value="$key"
  376. echo "$value"
  377. }
  378. # Get real ipv6 address
  379. get_real_ipv6() {
  380. if [ -e "$HESTIA/data/ips/$1" ]; then
  381. echo $1
  382. else
  383. nat=$(grep -H "^NAT='$1'" $HESTIA/data/ips/*)
  384. if [ ! -z "$nat" ]; then
  385. echo "$nat" |cut -f 1 -d : |cut -f 7 -d /
  386. fi
  387. fi
  388. }
  389. # Convert ipv6 CIDR to netmask
  390. convert_cidrv6() {
  391. set -- $(( 5 - ($1 / 8) )) 255 255 255 255 \
  392. $(((255 << (8 - ($1 % 8))) & 255 )) 0 0 0
  393. if [[ $1 -gt 1 ]]; then
  394. shift $1
  395. else
  396. shift
  397. fi
  398. echo ${1-0}.${2-0}.${3-0}.${4-0}
  399. }
  400. # Convert ipv6 netmask to CIDR
  401. convert_netmaskv6() {
  402. nbits=0
  403. IFS=.
  404. for dec in $1 ; do
  405. case $dec in
  406. 255) let nbits+=8;;
  407. 254) let nbits+=7;;
  408. 252) let nbits+=6;;
  409. 248) let nbits+=5;;
  410. 240) let nbits+=4;;
  411. 224) let nbits+=3;;
  412. 192) let nbits+=2;;
  413. 128) let nbits+=1;;
  414. 0);;
  415. esac
  416. done
  417. echo "$nbits"
  418. }
  419. # Get user ip6s
  420. get_user_ip6s() {
  421. dedicated=$(grep -H -A10 "OWNER='$user'" $HESTIA/data/ips/* |grep "VERSION='6'")
  422. dedicated=$(echo "$dedicated" |cut -f 1 -d '-' |sed 's=.*/==')
  423. shared=$(grep -H -A10 "OWNER='admin'" $HESTIA/data/ips/* |grep -A10 shared |grep "VERSION='6'")
  424. shared=$(echo "$shared" |cut -f 1 -d '-' |sed 's=.*/==' |cut -f 1 -d \-)
  425. for dedicated_ip in $dedicated; do
  426. shared=$(echo "$shared" |grep -v $dedicated_ip)
  427. done
  428. echo -e "$dedicated\n$shared" |sed "/^$/d"
  429. }
  430. # Get user ipv6
  431. get_user_ipv6() {
  432. ipv6=$(get_user_ip6s |head -n1)
  433. }
  434. # Validate ipv6 address
  435. is_ipv6_valid() {
  436. ipv6="$1"
  437. if [ -z "$ipv6" ]; then
  438. check_result $E_NOTEXIST "IPV6 address is empty"
  439. fi
  440. if [ ! -e "$HESTIA/data/ips/$1" ]; then
  441. check_result $E_NOTEXIST "IPV6 $1 doesn't exist"
  442. fi
  443. if [ ! -z $2 ]; then
  444. ip_data=$(cat $HESTIA/data/ips/$1)
  445. ip_owner=$(echo "$ip_data" |grep OWNER= |cut -f2 -d \')
  446. ip_status=$(echo "$ip_data" |grep STATUS= |cut -f2 -d \')
  447. if [ "$ip_owner" != "$user" ] && [ "$ip_status" = 'dedicated' ]; then
  448. check_result $E_FORBIDEN "$user user can't use IPV6 $1"
  449. fi
  450. get_user_owner
  451. if [ "$ip_owner" != "$user" ] && [ "$ip_owner" != "$owner" ]; then
  452. check_result $E_FORBIDEN "$user user can't use IPV6 $1"
  453. fi
  454. fi
  455. }