asn_ipfire.sh 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  1. #!/usr/bin/env bash
  2. #######################################################################
  3. # IPFire network object creator for IPv4 addresses based on ASN information
  4. # Creates 'customnetworks' objects in /var/ipfire/fwhosts/customnetworks
  5. # Creates 'customgroups' objects in /var/ipfire/fwhosts/customgroups
  6. #######################################################################
  7. #######################################################################
  8. revision="asn_ipfire.sh v0.7.8" # do not comment out
  9. # Last updated: May 10 2019 by maloe
  10. # Author: Mike Kuketz, maloe
  11. # Visit: www.kuketz-blog.de
  12. # Source: notabug.org/maloe/ASN_IPFire_Script
  13. # License: GNU GPL v3
  14. # Copyright 2017-2019 Mike Kuketz, maloe
  15. #######################################################################
  16. #######################################################################
  17. # Constants, Filenames, Enable/Disable Sources
  18. # Use download tool wget (default) or curl (if existent)
  19. downloadtool=wget
  20. #downloadtool=curl
  21. # Path to IPFire customnetworks|customgroups
  22. customnetworks=/var/ipfire/fwhosts/customnetworks
  23. customgroups=/var/ipfire/fwhosts/customgroups
  24. # Remark for IPFire customnetworks|customgroups. This is used to identify entries made by asn_ipfire.sh.
  25. auto_remark="entry by asn_ipfire.sh"
  26. # Define iptables path for iptable/afwall output file
  27. iptable_path="/sbin/iptables"
  28. afwall_path="/system/bin/iptables"
  29. # Output files
  30. file_network="network_list.txt" # output file for network consolidated
  31. file_network_raw="$file_network" # output file for network not consolidated
  32. file_iptable="iptable_rules.txt" # output file in iptable format
  33. file_afwall="afwall_rules.txt" # output file in afwall format
  34. file_asn="asn_list.txt" # output file for ASNs only
  35. temppath="." # path to store temporary source file (default: ".")
  36. temp1="asn_cidrreport.tmp" # Define temp file
  37. temp2="asn_bglooking.tmp" # Define temp file
  38. # Local files can be used as ASN and/or network sources. To be activated by enabling "gather_ASN0" and/or "gather_NET0" into following arrays.
  39. local_asn_file="local_asn.list" # Note: Each ASN must be in the same line as the corresponding company, e.g. 'AS1234 CompanyA' or 'CompanyA AS1234'
  40. local_net_file="local_net.list" # Note: Each network must be in the same line as the corresponding ASN, e.g. '1.2.3.4/24 AS5678' or 'AS5678 1.2.3.4/24'
  41. # Enable/disable ASN sources: Remove leading hashes (#) to enable ASN_sources.
  42. getASNfromCOMPANY=( \
  43. ASN_local \ # local source (local_asn_file)
  44. ASN_cidrreport \ # cidr-report.org
  45. # ASN_ultratools \ # ultratools.com
  46. # ASN_bglookingglass \ # bgplookingglass.com
  47. )
  48. # Enable/disable network sources: Remove leading hash (#) to enable NET_sources.
  49. getNETfromASN=( \
  50. NET_local \ # local source (local_net_file)
  51. NET_ripe \ # stat.ripe.net
  52. # NET_ipinfo \ # ipinfo.io
  53. # NET_radb \ # whois.radb.net # use only if you know what you are doing. query results may be wrong!
  54. )
  55. #######################################################################
  56. # Gather-Functions: add further sources here and activate them in above arrays getASNfromCOMPANY() and getNETfromASN()
  57. # ASN sources: function must return a list of ASNs
  58. ASN_local() # Get ASN from local file
  59. {
  60. if [[ -f $local_asn_file ]]; then
  61. echo "---[Using local ASN Source file ($local_asn_file)]---"
  62. cname=`echo $1 | sed 's/~/ /g; s/*/.*/g'` # Replace ~ with space
  63. asn_array=`cat $local_asn_file | grep -i "$cname" | grep -Eo 'AS[0-9]+'`
  64. fi;
  65. }
  66. ASN_cidrreport() # Get ASN from cidr-report.org
  67. {
  68. if [[ $dl != "local" ]]; then # wget or curl available?
  69. if [[ ! -f $temp1 ]] && [[ ${#company_array[@]} -gt 1 || $keeptemp ]]; then # Temp file not exist and more than one company names or option keeptemp is enabled
  70. touch $temp1 2> /dev/null # Temp file writable?
  71. if [[ -w $temp1 ]]; then # Write temp file
  72. echo "---[Downloading ASN Source List from www.cidr-report.org]---"
  73. $dl "https://www.cidr-report.org/as2.0/autnums.html" | grep -Eo '>AS[0-9]+.*' | sed 's/^>//; s/[ ]*<\/a>[ ]*/ /' >> $temp1
  74. fi
  75. fi
  76. cname=`echo $1 | sed 's/~/ /g; s/*/.*/g'` # Replace ~ with space and * with expression .*
  77. if [[ -f $temp1 ]]; then # Read from temp file
  78. if [[ $verbose ]]; then echo "---[Using local (temporary) ASN Source List ($temp1)]---"; fi
  79. asn_array=`cat $temp1 | grep -i "$cname" | grep -Eo '^AS[0-9]+'`
  80. else # Read from source
  81. echo "---[Downloading ASN Source List from www.cidr-report.org]---"
  82. asn_array=`$dl "https://www.cidr-report.org/as2.0/autnums.html" | grep -i "$cname" | grep -Eo '>AS[0-9]+' | grep -Eo 'AS[0-9]+'`
  83. fi;
  84. fi
  85. }
  86. ASN_ultratools() # Get ASN from ultratools.org
  87. {
  88. if [[ $dl != "local" ]]; then # wget or curl available?
  89. cname=`echo $1 | sed 's/~/ /g; s/+/%2B/g'` # Replace ~ with space and "+" with %2B
  90. asn_array=(`$dl "https://www.ultratools.com/tools/asnInfoResult?domainName=$cname" | grep -Eo 'AS[0-9]+' | uniq`)
  91. fi
  92. }
  93. ASN_bglookingglass() # Get ASN from bgplookingglass.com
  94. {
  95. if [[ $dl != "local" ]]; then # wget or curl available?
  96. if [[ ! -f $temp2 ]] && [[ ${#company_array[@]} -gt 1 || $keeptemp ]]; then # Temp file not exist and more than one company names or option keeptemp is enabled
  97. touch $temp2 2> /dev/null # Check if writable?
  98. if [[ -w $temp2 ]]; then
  99. echo "---[Downloading ASN Source List from www.bgplookingglass.com]---"
  100. $dl "http://www.bgplookingglass.com/list-of-autonomous-system-numbers" | sed -n '/AS[0-9]/ p' | sed 's/<br \/>/\'$'\n/g; s/^[[:space:]]*<pre>//; s/[ ]\+/ /g' >> $temp2
  101. $dl "http://www.bgplookingglass.com/list-of-autonomous-system-numbers-2" | sed -n '/AS[0-9]/ p' | sed 's/<br \/>/\'$'\n/g; s/^[[:space:]]*<pre>//; s/[ ]\+/ /g' >> $temp2
  102. $dl "http://www.bgplookingglass.com/4-byte-asn-names-list" | sed -n '/AS[0-9]/ p' | sed 's/<br \/>/\'$'\n/g; s/^[[:space:]]*<pre>//; s/[ ]\+/ /g' >> $temp2
  103. fi
  104. fi
  105. cname=`echo $1 | sed 's/~/ /g; s/*/.*/g'` # Replace ~ with space and * with expression .*
  106. if [[ -f $temp2 ]]; then # Read from temp file
  107. if [[ $verbose ]]; then echo "---[Using local (temporary) ASN Source List ($temp2)]---"; fi
  108. asn_array=`cat $temp2 | grep -i "$cname" | grep -Eo '^AS[0-9]+'`
  109. else # Temp file not writable
  110. echo "---[Downloading ASN Source List from www.bgplookingglass.com]---"
  111. asn_array=(`$dl "http://www.bgplookingglass.com/list-of-autonomous-system-numbers" | sed -n '/AS[0-9]/ p' | sed 's/<br \/>/\'$'\n/g' | grep -i "$cname" | sed 's/^[[:space:]]*<pre>//' | grep -Eo '^AS[0-9]+'`)
  112. asn_array=(${asn_array[@]} `$dl "http://www.bgplookingglass.com/list-of-autonomous-system-numbers-2" | sed -n '/AS[0-9]/ p' | sed 's/<br \/>/\'$'\n/g' | grep -i "$cname" | sed 's/^[[:space:]]*<pre>//' | grep -Eo '^AS[0-9]+'`)
  113. asn_array=(${asn_array[@]} `$dl "http://www.bgplookingglass.com/4-byte-asn-names-list" | sed -n '/AS[0-9]/ p' | sed 's/<br \/>/\'$'\n/g' | grep -i "$cname" | sed 's/^[[:space:]]*<pre>//' | grep -Eo '^AS[0-9]+'`)
  114. fi
  115. fi
  116. }
  117. # Network sources: function must return a list of CIDR networks
  118. NET_local() # Get networks from local file, sorting
  119. {
  120. if [[ -f $local_net_file ]]; then
  121. cat $local_net_file | grep -i "$1" | grep -Eo '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/)(3[0-2]|[1-2][0-9]|0?[1-2]?[1-9])' | sed -E 's/^[0]{0,2}([0-9])/\1/g; s/\.[0]{0,2}([0-9])/.\1/g; s/\/[0]?/\//g' | sort -Vu
  122. fi
  123. }
  124. NET_ripe() # Get networks from stat.ripe.net, sorting
  125. {
  126. if [[ $dl != "local" ]]; then # wget or curl available?
  127. $dl "https://stat.ripe.net/data/announced-prefixes/data.json?preferred_version=1.1&resource=$1" | grep -Eo '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/)(3[0-2]|[1-2][0-9]|0?[1-2]?[1-9])' | sed -E 's/^[0]{0,2}([0-9])/\1/g; s/\.[0]{0,2}([0-9])/.\1/g; s/\/[0]?/\//g' | sort -Vu
  128. fi
  129. }
  130. NET_ipinfo() # Get networks from ipinfo.io, sorting
  131. {
  132. if [[ $dl != "local" ]]; then # wget or curl available?
  133. $dl "https://ipinfo.io/$1" | grep -Eo '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/)(3[0-2]|[1-2][0-9]|0?[1-2]?[1-9])' | sed -E 's/^[0]{0,2}([0-9])/\1/g; s/\.[0]{0,2}([0-9])/.\1/g; s/\/[0]?/\//g' | sort -Vu
  134. fi
  135. }
  136. NET_radb() # Get networks from whois, sorting
  137. {
  138. if [[ -x `which whois 2>/dev/null` ]]; then # whois available?
  139. whois -h whois.radb.net -i origin $1 | grep -w "route:" | grep -Eo '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/)(3[0-2]|[1-2][0-9]|0?[1-2]?[1-9])' | sed -E 's/^[0]{0,2}([0-9])/\1/g; s/\.[0]{0,2}([0-9])/.\1/g; s/\/[0]?/\//g' | sort -Vu
  140. fi
  141. }
  142. #######################################################################
  143. # NO NEED TO EDIT ANYTHING BELOW
  144. #######################################################################
  145. # Functions
  146. # Function: check existence of wget or curl
  147. chkSystem()
  148. {
  149. if [[ -d /var/ipfire ]] && [[ -f /etc/init.d/firewall ]]; then # Running on ipfire system?
  150. is_ipfire=1
  151. else
  152. is_ipfire=""
  153. fi
  154. dl=local
  155. if [[ -x `which wget 2>/dev/null` ]]; then
  156. dl="wget --quiet -O -" # Use wget if existent
  157. fi
  158. if [[ -x `which curl 2>/dev/null` ]]; then
  159. if [[ $dl == "local" ]] || [[ "$downloadtool" == "curl" ]]; then
  160. dl="curl --silent" # Use curl if existent and wget is missing
  161. fi
  162. fi
  163. if [[ $dl == "local" ]]; then
  164. echo "Warning: did not found wget nor curl. Only local sources usable." # Neither wget nor curl was found
  165. fi
  166. }
  167. # Function: get network mask
  168. cdr2mask()
  169. {
  170. # Number of args to shift, 255..255, first non-255 byte, zeroes
  171. set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
  172. [ $1 -gt 1 ] && shift $1 || shift
  173. echo ${1-0}.${2-0}.${3-0}.${4-0}
  174. }
  175. # Functions: get decimal IP values
  176. get_firstIP() { echo ${1/\//.} | awk -F"." '{ printf "%.0f", $1*2^24+$2*2^16+$3*2^8+$4 }'; } # First IP of network
  177. get_IPrange() { echo $1 | awk -F"/" '{ printf "%.0f", 2^(32-$2)}'; } # IP range of network
  178. get_lastIP() { echo ${1/\//.} | awk -F"." '{ printf "%.0f", $1*2^24+$2*2^16+$3*2^8+$4+2^(32-$5)}'; } # Last IP +1 of network
  179. # Function: transform decimal IP into dot noted IP
  180. dec2ip() { echo $1 | awk '{ printf "%i.%i.%i.%i", $1/(2^24), $1%(2^24)/(2^16), $1%(2^24)%(2^16)/(2^8), $1%(2^24)%(2^16)%(2^8)}'; }
  181. # Function: remove redundant networks
  182. rm_redundantIP() {
  183. declare -a array1=("${!1}") # Put $1 into new array
  184. declare -a array2=() # Create second array
  185. declare maxIP=0 # Initial IP for comparison
  186. declare n=0 # Counter for array
  187. for net in ${array1[@]}; do
  188. lastIP=`get_lastIP $net` # Get last IP(+1) of actual network
  189. if [[ `echo $lastIP $maxIP | awk '$1>$2 {printf 1}'` ]]; then # Comparing big integer. Only keep network if last IP is not covered by previous network
  190. array2[$n]=$net # Write actual network into second array
  191. maxIP=$lastIP # Update maximum IP(+1)
  192. n=$[n+1]
  193. fi
  194. done
  195. for net in ${array2[@]}; do # Return result
  196. if [ $net ]; then echo ${net}; fi # Skip empty lines
  197. done
  198. }
  199. # Function: consolidate adjacent networks
  200. rm_adjacentIP() {
  201. declare -a array1=("${!1}") # Put $1 into new array1
  202. declare -a array2=() # Create working array2
  203. declare n=0 # Counter for array2
  204. declare d=0 # Initial counter for adjacents
  205. declare range=0 # IP range
  206. declare prefirstIP=0 # Get decimal first IP from actual network
  207. declare prenetmask=0 # Get decimal IP range from actual network
  208. declare prelastIP=-1 # Get decimal last IP(+1) from actual network
  209. for net in ${array1[@]}; do # Loop through network list
  210. firstIP=`get_firstIP $net` # Get decimal first IP from actual network
  211. netmask=`get_IPrange $net` # Get decimal IP range from actual network
  212. lastIP=`get_lastIP $net` # Get decimal last IP(+1) from actual network
  213. range=`echo $prenetmask $netmask | awk '{printf "%d", $1+$2;}'`
  214. # If all adjecent consolidation requirements are given
  215. if [[ `echo $firstIP $prelastIP $range $prefirstIP | awk '($1==$2) && (log($3)/log(2)==int(log($3)/log(2))) && ($4%$3==0) {printf 1}'` ]]; then
  216. suffix=`echo $range | awk '{printf "%i", 32-log($1)/log(2);}'`
  217. array2[$[n-1]]=`dec2ip $prefirstIP`"/"$suffix
  218. prelastIP=$lastIP
  219. prenetmask=$range
  220. d=1
  221. else # No changes
  222. array2[$n]=$net
  223. prelastIP=$lastIP
  224. prefirstIP=$firstIP
  225. prenetmask=$netmask
  226. n=$[n+1]
  227. fi
  228. done
  229. if [[ d -eq 1 ]]; then # If changes done, then...
  230. d=0
  231. rm_adjacentIP array2[@] # ... next Iteration
  232. else
  233. for net in ${array2[@]} ; do # Return result
  234. if [ $net ]; then echo ${net}; fi # Skip empty lines
  235. done
  236. fi
  237. }
  238. # Function: print statistics
  239. show_stats() { # Requires arguments: asn_array net_array, company
  240. declare -a asn_array=("${!1}") # Put $1 (asn_list) into new array
  241. declare -a net_array=("${!2}") # Put $2 (net_list) into new array
  242. declare countIP=0 # Counter for IP
  243. for net in ${net_array[@]}; do
  244. netmask=`get_IPrange $net` # Get decimal IP range from actual network
  245. countIP=`echo $countIP $netmask | awk '{printf "%.0f", $1+$2}'` # Count IP
  246. done
  247. countIP=`printf "%'i\n" $countIP` # Point separated format
  248. echo "${#net_array[@]} networks with $countIP IPs found in ${#asn_array[@]} ASNs for $3"
  249. }
  250. #######################################################################
  251. # Main procedures
  252. collectNetworks() {
  253. for company in ${company_array[@]}; do
  254. # Get all company ASNs
  255. declare asn_array=()
  256. declare asn_list=()
  257. prnt_company=`echo $company | sed 's/~/ /g; s/,//g'` # Printable company name with space (and no commas)
  258. echo "---[Get all $prnt_company ASNs]---"
  259. for asn_gather in ${getASNfromCOMPANY[@]}; do # Loop through ASN sources
  260. $asn_gather $company
  261. asn_list=(`echo ${asn_list[@]} ${asn_array[@]}`) # Append to list
  262. done
  263. output=`echo "### Company: ${prnt_company} ###" | sed 's/ /_/g'`" "
  264. if [ ! $asn_list ]; then
  265. echo "---[No ASN found for $prnt_company]---"
  266. elif [ "$1" == "--asn" ]; then
  267. for asn in ${asn_list[@]}; do
  268. output+="$asn " # Create output text
  269. done
  270. result_array=(`echo ${result_array[@]} ${output}`)
  271. else
  272. asn_list=(`echo ${asn_list[@]} | sed 's/ /\'$'\n/g' | sort -Vu`) # Linebreaking and Sorting # Adjusted for FreeBSD
  273. declare net_array=()
  274. declare net_list=()
  275. for asn in ${asn_list[@]}; do
  276. # Store networks from ASN in file
  277. echo "---[Get $prnt_company networks for $asn]---"
  278. for net_gather in ${getNETfromASN[@]}; do # Loop through NET webservices
  279. net_array=(`$net_gather $asn`)
  280. net_list=(`echo ${net_list[@]} ${net_array[@]} | sed 's/ /\'$'\n/g' | sort -Vu`) # Append to list, sorting # Adjusted for FreeBSD
  281. done
  282. done
  283. if [ ! $net_list ]; then
  284. echo "---[No networks found for $prnt_company]---"
  285. else
  286. # Consolidate adjacent and overlapping netblocks
  287. before=${#net_list[@]} # Number of network entries before consolidate
  288. if [[ $verbose ]]; then echo " $(show_stats asn_list[@] net_list[@] $company)"; fi
  289. if [ "$1" != "--network_raw" ]; then
  290. echo "---[Remove adjacent and overlapping netblocks]---"
  291. net_list=(`rm_redundantIP net_list[@]`) # Remove redundant networks
  292. net_list=(`rm_adjacentIP net_list[@]`) # Consolidate adjacent networks
  293. fi
  294. after=${#net_list[@]} # Number of network entries after consolidate
  295. if [[ $verbose ]]; then echo " $[$before - $after] of $before networks removed"; fi
  296. # Write objects to result array
  297. echo "---[Creating objects for $prnt_company networks]---"
  298. if [[ $verbose ]] && [[ "$1" == "--network" || "$1" == "--network_raw" ]]; then
  299. output+=`echo "### $(show_stats asn_list[@] net_list[@] $company) ###" | sed 's/ /_/g'`" "
  300. fi
  301. for net in ${net_list[@]}; do
  302. output+="$net " # Create output text
  303. done
  304. result_array=(`echo ${result_array[@]} ${output}`)
  305. if [[ $verbose ]]; then echo " $(show_stats asn_list[@] net_list[@] $company)"; fi
  306. fi
  307. fi
  308. done
  309. # remove temp files
  310. if [[ ! $keeptemp ]]; then
  311. echo "---[Removing temporary source files]---"
  312. if [[ -f $temp1 ]]; then rm $temp1; fi
  313. if [[ -f $temp2 ]]; then rm $temp2; fi
  314. fi
  315. }
  316. addNetworks() { # Write result to ipfire files
  317. # Get highest number from existing objects in [customnetworks|customgroups]
  318. if [[ -w $customnetworks ]]; then
  319. network_object_number=$(cat $customnetworks | cut -f1 -d',' | awk '{for(i=1;i<=NF;i++) if($i>maxval) maxval=$i;}; END { print maxval;}')
  320. else
  321. echo -e "File $customnetworks not found or write protected.\nCheck your IPFire installation."
  322. exit 0
  323. fi
  324. if [[ -w $customgroups ]]; then
  325. group_object_number=$(cat $customgroups | cut -f1 -d',' | awk '{for(i=1;i<=NF;i++) if($i>maxval) maxval=$i;}; END { print maxval;}')
  326. else
  327. echo -e "File $customgroups not found or write protected.\nCheck your IPFire installation."
  328. exit 0
  329. fi
  330. # Increase counter
  331. network_object_number=$[network_object_number +1]
  332. group_object_number=$[group_object_number +1]
  333. counter=1
  334. for net in ${result_array[@]}; do
  335. if [[ ${net:0:1} == "#" ]]; then
  336. prnt_company=`echo $net | sed 's/###_Company:_\(.*\)_###/\1/' | sed 's/_/ /g'` # Get company name
  337. company=$prnt_company
  338. else
  339. # Separate IP and netmask
  340. ip=${net%/*}
  341. if [ "$ip" != "0.0.0.0" ]; then # Double check for invalid entry
  342. netmask=${net#*/}
  343. if [ "$netmask" == "32" ]; then echo "WARNING: Found single IP. This may cause an invalid entry in ipfire!"; fi # Double check for invalid entry
  344. # Write new objects to files [customnetworks|customgroups]
  345. ipf_company=`echo $prnt_company | sed 's/\(.*\)/\U\1/'` # Uppercase company name
  346. printf "$network_object_number,$company-Network Nr.$counter,$ip,$(cdr2mask $netmask),$auto_remark\n" >> $customnetworks
  347. printf "$group_object_number,$ipf_company,$auto_remark,$company-Network Nr.$counter,Custom Network\n" >> $customgroups
  348. # Increase counter
  349. network_object_number=$[$network_object_number +1]
  350. group_object_number=$[$group_object_number +1]
  351. counter=$[$counter +1]
  352. fi
  353. fi
  354. done
  355. echo "---[Results written to $output_file]---" # Resultfile info
  356. }
  357. outResults() {
  358. case "$1" in # Output result to file
  359. --asn) {
  360. for asn in ${result_array[@]} ; do
  361. echo ${asn} | sed 's/_/ /g' >> $output_file
  362. done
  363. };;
  364. --network|--network_raw) {
  365. for net in ${result_array[@]}; do
  366. echo ${net} | sed 's/_/ /g' >> $output_file
  367. done
  368. };;
  369. --iptable) {
  370. for net in ${result_array[@]}; do
  371. if [[ ${net:0:1} == "#" ]]; then
  372. echo "$net" | sed 's/_/ /g' >> $output_file
  373. else
  374. echo "$iptable_path -A OUTPUT -d $net -j REJECT" >> $output_file
  375. fi
  376. done
  377. };;
  378. --afwall) {
  379. for net in ${result_array[@]}; do
  380. if [[ ${net:0:1} == "#" ]]; then
  381. echo "$net" | sed 's/_/ /g' >> $output_file
  382. else
  383. echo "$afwall_path -A \"afwall\" -d $net -j REJECT" >> $output_file
  384. fi
  385. done
  386. };;
  387. *) { # Default ipfire mode
  388. echo "WARNING: unknown mode. Nothing done."
  389. };;
  390. esac
  391. }
  392. cleanupNetworks() { # Remove entries from ipfire files
  393. for ipfire_file in $customnetworks $customgroups; do
  394. if [[ -w $ipfire_file ]]; then
  395. if [[ $backup ]]; then
  396. if [[ $verbose ]]; then echo "---[Backing up $ipfire_file.bak ]---"; fi
  397. cp -f $ipfire_file $ipfire_file.bak # Create ipfire backup files
  398. fi
  399. if [[ ${company_array[0]} == "ALL" ]]; then # Remove all entries made by asn_ipfire.sh
  400. echo "---[Removing all objects from $ipfire_file ]---"
  401. sed -i "/,$auto_remark/Id" $ipfire_file;
  402. else
  403. for company in ${company_array[@]}; do
  404. prnt_company=`echo $company | sed 's/~/ /g; s/,//g; s/\(.*\)/\U\1/'` # Company name with space and "+"
  405. echo "---[Removing $prnt_company objects from $ipfire_file ]---"
  406. sed -i "/$prnt_company.*$auto_remark/Id" $ipfire_file; # Remove company entries made by asn_ipfire.sh
  407. done
  408. fi
  409. elif [[ -f $ipfire_file ]]; then
  410. echo -e "File $ipfire_file write protected.\nCheck your IPFire installation."
  411. fi
  412. done
  413. }
  414. removeBackup() { # Remove ipfire backup files
  415. for ipfire_file in $customnetworks $customgroups; do
  416. if [[ -w $ipfire_file.bak ]]; then
  417. if [[ $verbose ]]; then echo "---[Removing backup $ipfire_file.bak ]---"; fi
  418. rm -f $ipfire_file.bak
  419. fi
  420. done
  421. }
  422. renumberIpfireFiles() { # Renumber entries of ipfire files
  423. for ipfire_file in $customnetworks $customgroups; do
  424. if [[ -w $ipfire_file ]]; then
  425. if [[ $verbose ]]; then echo "---[Renumbering $ipfire_file ]---"; fi
  426. sed -i '/^$/d;=' $ipfire_file # Delete empty lines and add numbered lines
  427. sed -i 'N;s/\n[0-9]\+//' $ipfire_file # Renumber lines by consolidation
  428. else
  429. echo -e "File $ipfire_file not found or write protected.\nCheck your IPFire installation."
  430. fi
  431. done
  432. }
  433. sortIpfireFiles() { # Sort entries of ipfire files
  434. for ipfire_file in $customnetworks $customgroups; do
  435. if [[ -w $ipfire_file ]]; then
  436. if [[ $verbose ]]; then echo "---[Re-sorting $ipfire_file ]---"; fi
  437. cat $ipfire_file | sort -t, -k2,2V -o $ipfire_file # Sort lines by name
  438. sed -i '/^$/d;=' $ipfire_file # Delete empty lines and add numbered lines
  439. sed -i 'N;s/\n[0-9]\+//' $ipfire_file # Renumber lines by consolidation
  440. else
  441. echo -e "File $ipfire_file not found or write protected.\nCheck your IPFire installation."
  442. fi
  443. done
  444. }
  445. restoreIpfireFiles() { # Restore ipfire file
  446. for ipfire_file in $customnetworks $customgroups; do
  447. if [[ -w $ipfire_file ]]; then
  448. if [[ -f "$ipfire_file.bak" ]]; then
  449. cp -f $ipfire_file.bak $ipfire_file
  450. echo "File $ipfire_file restored."
  451. else
  452. echo "No backup file $ipfire_file.bak found."
  453. fi
  454. else
  455. echo -e "File $ipfire_file not found or write protected.\nCheck your IPFire installation."
  456. fi
  457. done
  458. }
  459. listIpfireFiles () { # Show companies from ipfire files
  460. for ipfire_file in $customnetworks $customgroups; do
  461. if [[ -f $ipfire_file ]]; then
  462. echo "Company names in "$ipfire_file":"
  463. cat $ipfire_file | grep "$auto_remark" | grep -Eo ',.*-Network Nr' | sort -u | cut -d, -f2 | sed 's/-Network Nr//'
  464. else
  465. echo -e "File $ipfire_file not found.\nCheck your IPFire installation."
  466. fi
  467. done
  468. }
  469. print_help() { # Help info
  470. echo "Usage: asn_ipfire.sh [OPTION] [COMPANYs | -f FILE]"
  471. echo "Add or remove networks to IPFire firewall Groups: Networks & Host Groups"
  472. echo
  473. echo "Options:"
  474. echo " -a, --add Add new company networks"
  475. echo " -r, --remove Remove company networks from customnetworks & customgroups"
  476. echo " -f, --file FILE Get company list from FILE"
  477. echo " -l, --list List of companies already added by this script"
  478. echo " -k, --keep Keep temporary source files after finish"
  479. echo " --renumber Renumber lines of customnetworks & customgroups"
  480. echo " --sort Re-sort lines of customnetworks & customgroups"
  481. echo " --backup Backup customnetworks & customgroups before change"
  482. echo " --rmbackup Remove backup files of customnetworks & customgroups"
  483. echo " --restore Restore customnetworks & customgroups from backup"
  484. echo " -v, --verbose Verbose mode"
  485. echo " -V, --version Show this script version and exit"
  486. echo " -h, --help Show this help and exit"
  487. echo
  488. echo "Create special output files (Non-IPFire-Mode):"
  489. echo " --network Create FILE '$file_network' with networks"
  490. echo " --network_raw dito, but networks not consolidated"
  491. echo " --asn Create FILE '$file_asn' with ASNs only"
  492. echo " --iptable Create FILE '$file_iptable' with iptable rules"
  493. echo " --afwall Create FILE '$file_afwall' with afwall rules"
  494. echo
  495. echo "COMPANY to be one or more company names, put into double quotes (\"...\")"
  496. echo " Multi company names must be comma separated"
  497. echo " Substitute spaces with tilde (~)"
  498. echo " Restrict to exact matches with tilde (~) before and after the name"
  499. echo " Company names are handled case insensitive."
  500. echo " example: asn_ipfire.sh --add \"CompanyA,Company~NameB,~CompanyC~\" "
  501. echo
  502. echo "FILE to be a name of a file, containing one or more company names."
  503. echo " Company names to be separated by comma or line feed."
  504. echo " examples: asn_ipfire.sh -a -f company.list "
  505. echo " asn_ipfire.sh --network -f company.list "
  506. echo
  507. echo "Option --remove only affects entries made by asn_ipfire.sh itself."
  508. echo " These entries are recognized by the 'Remark'-column in IPFire."
  509. echo " To remove all entries done by this script, use COMPANY='ALL' "
  510. echo " examples: asn_ipfire.sh -r \"CompanyA, CompanyB\" "
  511. echo " asn_ipfire.sh -r ALL "
  512. echo
  513. }
  514. #######################################################################
  515. # Main program
  516. company_array=() # Create empty company array
  517. result_array=() # Create empty result array
  518. mode="" # Initial mode
  519. verbose="" # Default verbose = OFF
  520. backup="" # Default backup of ipfire files = OFF
  521. keeptemp="" # Default Keep source temp file after finish = OFF
  522. temp1="$temppath/$temp1" # Source temp file
  523. temp2="$temppath/$temp2" # Source temp file
  524. helptext="Usage: asn_ipfire.sh [OPTION] [COMPANYs | -f FILE] \nTry 'asn_ipfire.sh --help' for more information."
  525. chkSystem # ipfire system? wget or curl available?
  526. # Check arguments and get company array
  527. if [[ $# -eq 0 ]]; then echo -e $helptext; exit 0; fi # No arguments --> exit
  528. if [[ $# -gt 6 ]]; then echo -e "Too many arguments.\n"$helptext; exit 0; fi # Too many arguments --> exit
  529. while [[ $# > 0 ]] ; do
  530. case $1 in
  531. -f | --file) {
  532. if [[ -f $2 ]]; then # File exist
  533. company_array_from_file=(`sed 's/[ ]*//g; s/,\+/ /g; s/\[//g; s/\]//g; s/[.\]*//g' <<< cat $2`) # Substitute space,comma,slash
  534. shift
  535. else # File not exist --> exit
  536. echo "Company file not found."
  537. echo -e $helptext
  538. exit 0
  539. fi
  540. };;
  541. -a|--add | -r|--remove | --asn | --network | --network_raw | --iptable | --afwall) {
  542. if [[ $mode ]]; then # Mode already set
  543. echo -e "Too many arguments.\n"$helptext
  544. exit 0
  545. else
  546. mode=$1
  547. if [[ ! $2 ]]; then
  548. echo -e "No COMPANY names given.\n"$helptext
  549. exit 0
  550. elif [[ ${2:0:1} == "-" ]]; then # followed by argument instead of company names
  551. if [[ "$2" != "-f" && "$2" != "--file" ]]; then # followed by argument instead of company names
  552. echo -e "Wrong order of arguments.\n"$helptext # Wrong order of arguments --> exit
  553. exit 0
  554. fi
  555. else
  556. company_array_from_arg=(`sed -E 's/[ ]*//g; s/[,]+/ /g; s/\[//g; s/\]//g; s/[.\]*//g' <<< $2`) # Trim empty entries
  557. shift
  558. fi
  559. fi
  560. };;
  561. -l|--list | --renumber | --sort | --restore | --rmbackup | -h|--help | -V|--version) {
  562. if [[ $mode ]] || [[ $2 ]]; then # No more arguments allowed for this option
  563. echo -e "Too many arguments.\n"$helptext # Too many parameter --> exit
  564. exit 0
  565. else
  566. mode=$1
  567. fi
  568. };;
  569. --backup ) { # Don't write backup Ipfire files
  570. if [[ ! $mode ]] && [[ ! $2 ]]; then
  571. echo -e "Missing arguments.\n"$helptext
  572. exit 0
  573. else
  574. backup=1
  575. fi
  576. };;
  577. -k|--keep ) { # Keep temporary source files
  578. if [[ ! $mode ]] && [[ ! $2 ]]; then
  579. echo -e "Missing arguments.\n"$helptext
  580. exit 0
  581. else
  582. keeptemp=1
  583. fi
  584. };;
  585. -v|--verbose ) { # Verbose mode shows stats
  586. if [[ ! $mode ]] && [[ ! $2 ]]; then
  587. echo -e "Missing arguments.\n"$helptext
  588. exit 0
  589. else
  590. verbose=1
  591. fi
  592. };;
  593. *) {
  594. echo -e "Unknown argument.\n"$helptext # Unknown arguments --> exit
  595. exit 0
  596. };;
  597. esac
  598. shift
  599. done
  600. company_array=(`echo ${company_array_from_file[@]} ${company_array_from_arg[@]} | sort -uf`)
  601. case $mode in
  602. -a|--add) { # Add objects to ipfire files
  603. if [[ $is_ipfire ]]; then
  604. output_file="customnetworks & customgroups"
  605. if [ ! $company_array ]; then
  606. echo "No company names found. Nothing done!"
  607. echo "Try 'asn_ipfire.sh --help' for more information."
  608. exit 0
  609. fi
  610. collectNetworks # Get networks and write to file
  611. cleanupNetworks # Remove existing entries
  612. renumberIpfireFiles # Renumbering
  613. addNetworks # Get networks and write to file
  614. echo "---[Restarting firewall]---"
  615. /etc/init.d/firewall restart 1> /dev/null # Restart firewall
  616. echo "---[All done!]---"
  617. else
  618. echo -e "IPFire not found.\nCheck your IPFire installation."
  619. fi
  620. };;
  621. -r|--remove) { # Add objects to ipfire files
  622. if [[ $is_ipfire ]]; then
  623. output_file="customnetworks & customgroups"
  624. if [ ! $company_array ]; then
  625. echo "No company names found. Nothing done!"
  626. echo "Try 'asn_ipfire.sh --help' for more information."
  627. exit 0
  628. fi
  629. cleanupNetworks # Remove existing entries
  630. renumberIpfireFiles # Renumbering
  631. echo "---[Restarting firewall]---"
  632. /etc/init.d/firewall restart 1> /dev/null # Restart firewall
  633. echo "---[All done!]---"
  634. else
  635. echo -e "IPFire not found.\nCheck your IPFire installation."
  636. fi
  637. };;
  638. -l|--list) { # Function: List all company names already there by asn_ipfire
  639. if [[ $is_ipfire ]]; then
  640. listIpfireFiles
  641. else
  642. echo -e "IPFire not found.\nCheck your IPFire installation."
  643. fi
  644. };;
  645. --renumber) {
  646. if [[ $is_ipfire ]]; then
  647. verbose=1
  648. renumberIpfireFiles
  649. else
  650. echo -e "IPFire not found.\nCheck your IPFire installation."
  651. fi
  652. };;
  653. --sort) {
  654. if [[ $is_ipfire ]]; then
  655. verbose=1
  656. sortIpfireFiles
  657. else
  658. echo -e "IPFire not found.\nCheck your IPFire installation."
  659. fi
  660. };;
  661. --rmbackup) {
  662. if [[ $is_ipfire ]]; then
  663. verbose=1
  664. removeBackup
  665. else
  666. echo -e "IPFire not found.\nCheck your IPFire installation."
  667. fi
  668. };;
  669. --restore) {
  670. if [[ $is_ipfire ]]; then
  671. restoreIpfireFiles
  672. else
  673. echo -e "IPFire not found.\nCheck your IPFire installation."
  674. fi
  675. };;
  676. --asn | --network | --network_raw | --iptable | --afwall ) { # Create special output files
  677. output_file="file_"${mode:2} # Get output file
  678. output_file="${!output_file}"
  679. if [ $company_array ]; then
  680. touch $output_file > $output_file
  681. collectNetworks $mode # Get and add new networks
  682. outResults $mode
  683. echo "---[All done!]---"
  684. else
  685. echo "No company names found. Nothing done!"
  686. echo "Try 'asn_ipfire.sh --help' for more information."
  687. fi
  688. };;
  689. -V|--version ) { # Show version and quit
  690. echo $revision;
  691. };;
  692. -h|--help) {
  693. print_help # Show help and quit
  694. };;
  695. *) echo -e $helptext;; # Wrong or unknown parameter
  696. esac
  697. exit 0