├── README.md └── CF.sh /README.md: -------------------------------------------------------------------------------- 1 | # cloudflare-private-ip-sanner 2 | 3 | cloudflare 私有/中转 ip扫描工具 4 | 路由器上扫CF的脚本 5 | 运行目录下创建一个cfip.txt定义扫描范围 6 | 每行定义一个网段,例如1.0.0.0/24 7 | 0.0.0.0/0则全网扫描 8 | 扫描结果:查看log.txt 9 | 本次测速结果:查看speedlog.txt 10 | 历史测速结果:查看hspeedlog.txt 11 | 12 | 支持输入参数: 13 | 14 | ``` 15 | -n 表示并发任务数量,默认100。路由运行如果内存不足挂死,可适当调小。手机termux下建议400。 16 | -k 表示跳过扫描,仅测速。 17 | -s 表示跳过测速,仅扫描。 18 | -m 表示扫描模式,0表示https,1表示http 19 | -c 表示清除断点文件从头扫描,不会清除log.txt、speedlog.txt和hspeedlog.txt文件 20 | -a 表示以ASN作为扫描范围,例如AS54994则输入-a 54994 21 | -r 当ftp服务器或worker备份服务器参数已配置时,携带-r参数从服务器上最近一次备份恢复运行环境(断点、log等),当worker和ftp都配置时,从worker恢复。 22 | -e 表示仅结束脚本时通过ftp或worker备份环境,中途不备份 23 | -i 表示断点模式测速,保留speedlog.txt并跳过其中已有测速记录的IP 24 | ``` 25 | -------------------------------------------------------------------------------- /CF.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #路由器上扫CF的脚本 3 | #运行目录下创建一个cfip.txt定义扫描范围 4 | #每行定义一个网段,例如1.0.0.0/24 5 | #0.0.0.0/0则全网扫描 6 | #扫描结果:查看log.txt 7 | #本次测速结果:查看speedlog.txt 8 | #历史测速结果:查看hspeedlog.txt 9 | 10 | #支持输入参数: 11 | #-n 表示并发任务数量,默认100。路由运行如果内存不足挂死,可适当调小。手机termux下建议400。 12 | #-k 表示跳过扫描,仅测速。 13 | #-s 表示跳过测速,仅扫描。 14 | #-m 表示扫描模式,0表示https,1表示http 15 | #-c 表示清除断点文件从头扫描,不会清除log.txt、speedlog.txt和hspeedlog.txt文件 16 | #-a 表示以ASN作为扫描范围,例如AS54994则输入-a 54994 17 | #-r 当ftp服务器或worker备份服务器参数已配置时,携带-r参数从服务器上最近一次备份恢复运行环境(断点、log等),当worker和ftp都配置时,从worker恢复。 18 | #-e 表示仅结束脚本时通过ftp或worker备份环境,中途不备份 19 | #-i 表示断点模式测速,保留speedlog.txt并跳过其中已有测速记录的IP 20 | 21 | #版本号,请勿修改 22 | ver=20211222-00 23 | 24 | ######START###### 25 | ###以下为脚本默认命令行参数,如果不想运行脚本时输入参数,可以直接修改这里 26 | p_default_para="-m 0 -n 880" 27 | 28 | ######以下为内置参数###### 29 | ###自定义扫描参数设置### 30 | p_to=2; 31 | #单个ip扫描超时时间,默认5秒 32 | p_max_load=1000; 33 | #负载控制,高于该负载暂停启新任务,规避老毛子概率性跑死问题,老毛子建议20,没有跑死问题调到1000,相当于没有限制。 34 | ###自定义扫描参数设置结束### 35 | 36 | ###自定义测速设置### 37 | p_st=1; 38 | #测速次数,可多次测速,取最大值输出 39 | p_delay_mode=0 40 | #时延测试模式,1为ping时延,0为http时延,即测速url的http/https响应时间 41 | p_st_to=10 42 | #每个IP测速时间,默认10秒 43 | p_st_https_url="https://speed.cloudflare.com/__down?measId=6891185455449098&bytes=500000000" 44 | #https测速地址 45 | p_st_http_url="http://speed.cloudflare.com/__down?measId=6891185455449098&bytes=500000000" 46 | #http测速地址 47 | p_speed_filter='| grep HKG' 48 | #定义从log.txt中筛选测速IP的规则。例如不测洛杉矶的p_speed_filter='| grep -v LAX' 49 | ###自定义测速设置结束### 50 | 51 | ###以下为ftp备份和恢复参数,周期上传到ftp服务器,技能要求高,不懂不要用。 52 | p_bk_ftp_srv=""; 53 | #备份服务器地址,例如p_bk_ftp_srv="ftp://user:password@valid.scan.cf:21";,留空表示不备份 54 | p_bk_ftp_dir=/scancf/openwrt/; 55 | #ftp服务器上的备份目录 56 | p_bk_ftp_mode=0; 57 | #ftp模式,1表示被动模式,0主动模式 58 | p_bk_ftp_period=30; 59 | #备份周期,默认30分钟 60 | p_ftp_rslt_file="cf_speed_result.txt" 61 | #把speedlog.txt重命名后上传到一个命名不带时间的固定目录,方便通过固定URL分享,留空表示不重命名上传。 62 | ###ftp备份参数定义区域结束 63 | 64 | ###以下为worker备份和恢复设置,需要搭建CF worker 65 | p_wk_env_srv="" 66 | #worker备份运行环境的地址,例如"scancfupate.doremi.workers.dev" 67 | p_bk_wk_period=30 68 | #worker备份周期 69 | ############ 70 | 71 | ###以下为公共TG推送设置 72 | api_host="" 73 | nickname="神仙" 74 | ipflag="🚀🚀🚀" 75 | msgemoji="🔥" 76 | chat_id="-1001549398293" 77 | ###公共TG推送设置结束 78 | 79 | ###以下为私有TG推送设置(定制功能,不考虑通用性) 80 | p_priv_api_url="" 81 | p_priv_chat_id="" 82 | ###私有TG推送设置结束 83 | ######内置参数定义区域结束###### 84 | ######END###### 85 | 86 | #解析脚本输入参数 87 | parse_para() 88 | { 89 | for i in $(seq $(($#+1))) 90 | do 91 | eval "arg=\${$i}" 92 | key=$(echo "~$arg" | sed 's/^.//' | grep "^-" | tr '-' '_') 93 | if [ "$key"x = x ];then 94 | continue 95 | fi 96 | j=$((i+1)) 97 | eval "value=\${$j}" 98 | value=$(echo "~$value" | sed 's/^.//' | grep -v "^-") 99 | if [ "$value"x = x ];then 100 | eval "p$key=1" 101 | else 102 | eval "p$key='$value'" 103 | fi 104 | done 105 | } 106 | 107 | #根据参数注释生成全0的参数默认值 108 | parse_para $(cat $0 | grep -Eo "^#-([A-Z]|[a-z]|[_])* " | tr -d "#" | tr -d "\n" | sed 's/ / 0 /g') 109 | #生成用户自定义参数默认值 110 | parse_para $p_default_para 111 | #解析脚本输入参数 112 | parse_para "$@" 113 | 114 | #TG推送 115 | push_msg() 116 | { 117 | if [ ! "$api_host"x = x ];then 118 | api_url="https://$api_host/" 119 | post_url="https://$api_host/put" 120 | #推送到服务器 121 | { 122 | touch log.txt 123 | isrunning=x 124 | oldlog=$(cat log.txt) 125 | while [ ! "$isrunning"x = x ] 126 | do 127 | sleep 10 128 | #规避免费域名概率性不解析,每10秒ping,触发解析 129 | ping -c1 -W 1 $api_host &> /dev/null 130 | newlog=$(cat log.txt) 131 | rawtxt=$(echo -e "$newlog\n$oldlog" | sort | uniq -u) 132 | if [ ! "$rawtxt"x = x ];then 133 | pushtxt="" 134 | rawtxt=$(echo "$rawtxt" | tr " " "~") 135 | for line in $rawtxt 136 | do 137 | ip=$(echo "$line" | tr -d "ip=colh" | awk -F~ "{print \$1}") 138 | colo=$(echo "$line" | tr -d "ip=colh" | awk -F~ "{print \$3}") 139 | pushtxt=$pushtxt,$(echo -e "{\"user\":\"$nickname\",\"ip\":\"$ip\",\"colo\":\"$colo\",\"flag\":\"$ipflag\"}") 140 | done 141 | pushtxt=$(echo $pushtxt | sed "s/^,/\[/" | sed "s/\$/\]/") 142 | curl -s -X POST "$post_url" -d "$pushtxt" &> /dev/null 143 | #定制推送 144 | if [ ! "$p_priv_api_url"x = x ];then 145 | pushtxt=$(echo -e "$ipflag $nickname 新中转 \n$rawtxt" | tr "~" " ") 146 | curl -s -X POST -d "chat_id=$p_priv_chat_id&text=$pushtxt" "$p_priv_api_url/sendMessage" &> /dev/null 147 | fi 148 | fi 149 | oldlog=$newlog 150 | isrunning=`ps | sed "s/^/ /" | grep " $$ " | grep -v grep` 151 | done 152 | subfix=$(TZ=UTC-8 date +_%Y%m%d%H%M%S) 153 | prefix=$(echo $nickname"_" | tr " " "-") 154 | logfile="log$subfix.txt" 155 | speedfile="speedlog$subfix.txt" 156 | cp log.txt $logfile &> /dev/null 157 | cp speedlog.txt $speedfile &> /dev/null 158 | mv $logfile $prefix$logfile &> /dev/null 159 | if [ $? -eq 0 ];then 160 | logfile=$prefix$logfile 161 | fi 162 | mv $speedfile $prefix$speedfile &> /dev/null 163 | if [ $? -eq 0 ];then 164 | speedfile=$prefix$speedfile 165 | fi 166 | curl -v -F "chat_id=$chat_id" -F document=@./$logfile "$api_url/sendDocument" &> /dev/null 167 | curl -v -F "chat_id=$chat_id" -F document=@./$speedfile "$api_url/sendDocument" &> /dev/null 168 | 169 | #定制推送 170 | if [ ! "$p_priv_api_url"x = x ];then 171 | curl -v -F "chat_id=$p_priv_chat_id" -F document=@./$logfile "$p_priv_api_url/sendDocument" &> /dev/null 172 | curl -v -F "chat_id=$p_priv_chat_id" -F document=@./$speedfile "$p_priv_api_url/sendDocument" &> /dev/null 173 | fi 174 | 175 | rm -rf $logfile $speedfile &> /dev/null 176 | }& 177 | 178 | #推送进度到TG,1小时一次 179 | { 180 | start=$(TZ=UTC-8 date +%Y-%m-%d" "%H:%M:%S) 181 | isrunning=x 182 | loop=0 183 | while [ ! "$isrunning"x = x ] 184 | do 185 | sleep 10 186 | isrunning=`ps | sed "s/^/ /" | grep " $$ " | grep -v grep` 187 | loop=$((loop+1)) 188 | if [ ! $loop -eq 360 ];then 189 | continue 190 | fi 191 | loop=0 192 | if [ ! -f tmpip.txt ];then 193 | continue 194 | fi 195 | total=$(cat tmpip.txt | wc -l) 196 | now=$(TZ=UTC-8 date +%Y-%m-%d" "%H:%M:%S) 197 | span=$((($(date +%s -d "$now") - $(date +%s -d "$start"))/60)) 198 | finish=0 199 | if [ -f finiship.txt ];then 200 | finish=$(cat finiship.txt | wc -l) 201 | fi 202 | pushtxt=$(echo -e "$msgemoji$nickname$msgemoji\n版本:$ver\n进度:$finish/$total,$(echo | awk "{print $finish/$total*100}" | tr -d "\n")%\n用时:$span"分钟) 203 | curl -s -X POST "$api_url/sendMessage" -d "chat_id=$chat_id&text=$pushtxt" &> /dev/null 204 | #定制推送 205 | if [ ! "$p_priv_api_url"x = x ];then 206 | curl -s -X POST -d "chat_id=$p_priv_chat_id&text=$pushtxt" "$p_priv_api_url/sendMessage" &> /dev/null 207 | fi 208 | done 209 | }& 210 | fi 211 | } 212 | 213 | scan_single_ip(){ 214 | read -u6; 215 | ./$scancmdfile $1 216 | } 217 | 218 | scan_subnet(){ 219 | raw=`echo $1.32 | tr '/' '.' | grep -Eo "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,2}"`; 220 | 221 | if [ "$raw"x = x ];then 222 | return; 223 | fi 224 | 225 | mask=`echo $raw | awk -F. '{print $5}'`; 226 | 227 | if [ "$mask"x = x ];then 228 | return; 229 | fi 230 | 231 | i=`echo $raw | awk -F. '{print $1}'`; 232 | j=`echo $raw | awk -F. '{print $2}'`; 233 | k=`echo $raw | awk -F. '{print $3}'`; 234 | l=`echo $raw | awk -F. '{print $4}'`; 235 | 236 | if [ $i -le 0 ];then 237 | i=1; 238 | fi 239 | 240 | echo scanning:$i.$j.$k.$l/$mask 241 | 242 | ipstart=$(((i<<24)|(j<<16)|(k<<8)|l)); 243 | hostend=$((2**(32-mask)-1)); 244 | loop=0; 245 | while [ $loop -le $hostend ] 246 | do 247 | ip=$((ipstart|loop)); 248 | i=$(((ip>>24)&255)); 249 | j=$(((ip>>16)&255)); 250 | k=$(((ip>>8)&255)); 251 | l=$(((ip>>0)&255)); 252 | loop=$((loop+1)); 253 | scan_single_ip $i.$j.$k.$l; 254 | done 255 | } 256 | 257 | #测速 258 | speedtest(){ 259 | ip=`echo $1 | tr '/' '.' | grep -Eo "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"`; 260 | if [ "$ip"x = x ];then 261 | return; 262 | fi 263 | 264 | if [ $p_m -eq 0 ];then 265 | st_url="$p_st_https_url" 266 | st_host=$(echo "$st_url" | awk -F/ '{print $3":443"}') 267 | else 268 | st_url="$p_st_http_url" 269 | st_host=$(echo "$st_url" | awk -F/ '{print $3":80"}') 270 | fi 271 | 272 | bw_delay=$(for i in $(seq $p_st);do curl -s --resolve "$st_host:$ip" -o /dev/null --connect-timeout 1 --max-time $p_st_to -w %{time_namelookup}-%{time_connect}-%{time_starttransfer}-%{time_total}-%{speed_download}"\n" "$st_url" | awk -F- '{print $5,$3}'; done | awk 'BEGIN {bw=0;dl=10} {if($1+0>bw+0)bw=$1;if(($2+0>0.000000001)&&($2+0/dev/null | grep -Eo '[0-9]{4}-[0-9]{2}-[0-9]{2}' | tail -n 1` 298 | last=$(TZ=UTC-8 date +%Y-%m-%d) 299 | if [ "$first"x = x ]; then 300 | first=$last; 301 | fi 302 | basespan=$(cat hspeedlog.txt | awk "{print \$0}END{print \"$ip 1ms 1days\"}" | grep "^$ip " | head -n 1 | tr -d ' ' | grep -Eo '[0-9]{1,9}days' | awk '{print $0-1}') 303 | span=$((($(date +%s -d $last) - $(date +%s -d $first))/86400+1)); 304 | span=$((span+basespan)); 305 | fi 306 | 307 | if [ $max -eq 0 ]; then 308 | span='*'; 309 | fi 310 | 311 | colo=`cat log.txt | grep "ip=$ip " | awk '{print $3}' | awk -F= '{print $2}' | tail -n 1` 312 | 313 | max=`echo $max | awk '{printf ("%.2f\n",$1/1024)}'`; 314 | echo $ip "$max"MB/s "$delay"ms "$span"days $colo; 315 | echo $ip "$max"MB/s "$delay"ms "$span"days $colo >> speedlog.txt 316 | } 317 | 318 | #把比较大的网段拆小,提升断点执行效率 319 | divsubnet(){ 320 | mask=$5;i=$1;j=$2;k=$3;l=$4; 321 | echo "拆分子网:$i.$j.$k.$l/$mask"; 322 | 323 | if [ $mask -ge 8 ] && [ $mask -le 23 ];then 324 | ipstart=$(((i<<24)|(j<<16)|(k<<8)|l)); 325 | hostend=$((2**(32-mask)-1)); 326 | loop=0; 327 | while [ $loop -le $hostend ] 328 | do 329 | subnet=$((ipstart|loop)); 330 | i=$(((subnet>>24)&255)); 331 | j=$(((subnet>>16)&255)); 332 | k=$(((subnet>>8)&255)); 333 | l=$(((subnet>>0)&255)); 334 | loop=$((loop+256)); 335 | echo $i.$j.$k.$l/24 >> tmpip.txt; 336 | done 337 | else 338 | echo $i.$j.$k.$l/$mask >> tmpip.txt; 339 | fi 340 | } 341 | 342 | #ftp备份和恢复处理 343 | safe_curl='#!/bin/bash 344 | CURL(){ 345 | ret=0 346 | for i in $(seq 10) 347 | do 348 | curl "$@" 349 | ret=$? 350 | if [ $ret -eq 0 ];then 351 | break 352 | fi 353 | done 354 | return $ret 355 | } 356 | 357 | ftp_upload() 358 | { 359 | eval file=\$$# 360 | cmd="CURL" 361 | for i in $(seq $(($#-2))) 362 | do 363 | eval arg=\$$i 364 | cmd="$cmd \"$arg\"" 365 | done 366 | filebak="$file.bak" 367 | rm -rf "$filebak" &>/dev/null 368 | cp "$file" "$filebak" &>/dev/null 369 | eval "$cmd -T \"$filebak\"" 370 | if [ $? -eq 0 ];then 371 | eval "$cmd -Q \"-RNFR $filebak\" -Q \"-RNTO $file\"" 372 | fi 373 | rm -rf "$filebak" &>/dev/null 374 | } 375 | 376 | ftpupload=$(echo "$*" | grep "\-T") 377 | if [ ! "$ftpupload"x = x ];then 378 | ftp_upload "$@" 379 | else 380 | CURL "$@" 381 | fi 382 | ' 383 | echo "$safe_curl" > CURL.sh 384 | chmod 777 CURL.sh 385 | 386 | worker_restore_env() 387 | { 388 | if [ ! "$p_wk_env_srv"x = x ] && [ $p_r -eq 1 ];then 389 | 390 | workerfilename=$(echo $nickname | md5sum | awk "{print \$1}" | sed "s/$/.txt/") 391 | curl -o $workerfilename -s -H "authorization: Basic YWRtaW46anM=" "https://$p_wk_env_srv/get?key=$workerfilename" 392 | total=$(cat $workerfilename | wc -l) 393 | file="" 394 | begin=1 395 | end=1 396 | for line in $(cat $workerfilename | grep -n "FILE:") 397 | do 398 | end=$(echo $line | awk -F: '{print $1}') 399 | if [ ! "$file"x = x ] && [ $((end-begin-1)) -gt 0 ];then 400 | eval cat $workerfilename | head -n $((end-1)) | tail -n $((end-begin-1)) > $file 401 | fi 402 | file=$(echo $line | awk -F: '{print $3}') 403 | begin=$end 404 | done 405 | end=$(cat $workerfilename | wc -l) 406 | end=$((end+1)) 407 | if [ ! "$file"x = x ] && [ $((end-begin-1)) -gt 0 ];then 408 | eval cat $workerfilename | head -n $((end-1)) | tail -n $((end-begin-1)) > $file 409 | fi 410 | rm -rf $workerfilename 2>/dev/null 411 | fi 412 | } 413 | 414 | ftp_restore_env() 415 | { 416 | if [ ! "$p_bk_ftp_srv"x = x ] && [ $p_r -eq 1 ] && [ "$p_wk_env_srv"x = x ] ;then 417 | p_bk_cmd="./CURL.sh --ftp-create-dirs --retry 5" 418 | if [ $p_bk_ftp_mode -eq 0 ];then 419 | p_bk_cmd="$p_bk_cmd -P -"; 420 | fi 421 | p_bk_cmd="$p_bk_cmd $p_bk_ftp_srv$p_bk_ftp_dir"; 422 | latestbkdir=`$p_bk_cmd 2>/dev/null | grep ^d | grep -v "\." | grep -Eo "[0-9]{8}" | sort -nr | tr '\n' ' ' | awk '{print $1}'`; 423 | if [ ! "$latestbkdir"x = x ];then 424 | $p_bk_cmd$latestbkdir/log.txt -o log.txt; 425 | $p_bk_cmd$latestbkdir/speedlog.txt -o speedlog.txt; 426 | $p_bk_cmd$latestbkdir/hspeedlog.txt -o hspeedlog.txt; 427 | $p_bk_cmd$latestbkdir/tmpip.txt -o tmpip.txt; 428 | $p_bk_cmd$latestbkdir/finiship.txt -o finiship.txt; 429 | $p_bk_cmd"task/cfip.txt" -o cfip.txt; 430 | fi 431 | fi 432 | } 433 | 434 | worker_backup_env() 435 | { 436 | if [ ! "$p_wk_env_srv"x = x ];then 437 | wkbkcmdfile="wkbkcf.sh" 438 | wkbkcf='#!/bin/bash 439 | { 440 | nickname=$1 441 | p_bk_wk_period=$2 442 | p_wk_env_srv=$3 443 | p_e=$4 444 | workerfilename=$(echo $nickname | md5sum | awk "{print \$1}" | sed "s/$/.txt/") 445 | p="x" 446 | loop=0; 447 | while [ ! "$p"x = x ]; 448 | do 449 | sleep 60 450 | p=`ps | sed "s/^/ /" | grep " $$ " | grep -v grep`; 451 | if [ ! $p_e -eq 0 ];then 452 | continue 453 | fi 454 | if [ $loop -eq $p_bk_wk_period ];then 455 | loop=0; 456 | if [ -f tmpip.txt ];then 457 | echo "FILE:tmpip.txt" > $workerfilename 458 | cat tmpip.txt >> $workerfilename 459 | fi 460 | if [ -f finiship.txt ];then 461 | echo "FILE:finiship.txt" >> $workerfilename 462 | cat finiship.txt >> $workerfilename 463 | fi 464 | if [ -f log.txt ];then 465 | echo "FILE:log.txt" >> $workerfilename 466 | cat log.txt >> $workerfilename 467 | fi 468 | if [ -f speedlog.txt ];then 469 | echo "FILE:speedlog.txt" >> $workerfilename 470 | cat speedlog.txt >> $workerfilename 471 | fi 472 | if [ -f hspeedlog.txt ];then 473 | echo "FILE:hspeedlog.txt" >> $workerfilename 474 | cat hspeedlog.txt >> $workerfilename 475 | fi 476 | if [ -f cfip.txt ];then 477 | echo "FILE:cfip.txt" >> $workerfilename 478 | cat cfip.txt >> $workerfilename 479 | fi 480 | ./CURL.sh -H "authorization: Basic YWRtaW46anM=" -X POST --data-binary @./$workerfilename "https://$p_wk_env_srv/put?key=$workerfilename" 2> /dev/null 481 | rm -rf $workerfilename 2> /dev/null 482 | fi 483 | loop=$((loop+1)) 484 | done 485 | if [ -f tmpip.txt ];then 486 | echo "FILE:tmpip.txt" > $workerfilename 487 | cat tmpip.txt >> $workerfilename 488 | fi 489 | if [ -f finiship.txt ];then 490 | echo "FILE:finiship.txt" >> $workerfilename 491 | cat finiship.txt >> $workerfilename 492 | fi 493 | if [ -f log.txt ];then 494 | echo "FILE:log.txt" >> $workerfilename 495 | cat log.txt >> $workerfilename 496 | fi 497 | if [ -f speedlog.txt ];then 498 | echo "FILE:speedlog.txt" >> $workerfilename 499 | cat speedlog.txt >> $workerfilename 500 | fi 501 | if [ -f hspeedlog.txt ];then 502 | echo "FILE:hspeedlog.txt" >> $workerfilename 503 | cat hspeedlog.txt >> $workerfilename 504 | fi 505 | if [ -f cfip.txt ];then 506 | echo "FILE:cfip.txt" >> $workerfilename 507 | cat cfip.txt >> $workerfilename 508 | fi 509 | ./CURL.sh -H "authorization: Basic YWRtaW46anM=" -X POST --data-binary @./$workerfilename "https://$p_wk_env_srv/put?key=$workerfilename" 2> /dev/null 510 | rm -rf $workerfilename 2> /dev/null 511 | }& 512 | ' 513 | echo "$wkbkcf" | sed "s/\\\$\\\$/$$/g" > $wkbkcmdfile 514 | chmod 777 $wkbkcmdfile 515 | ./$wkbkcmdfile "$nickname" "$p_bk_wk_period" "$p_wk_env_srv" "$p_e" 516 | fi 517 | } 518 | 519 | ftp_backup_env() 520 | { 521 | if [ ! "$p_bk_ftp_srv"x = x ];then 522 | bkcmdfile="bkcf.sh" 523 | p_bk_cmd="./CURL.sh --ftp-create-dirs --retry 5" 524 | if [ $p_bk_ftp_mode -eq 0 ];then 525 | p_bk_cmd="$p_bk_cmd -P -"; 526 | fi 527 | p_bk_cmd="$p_bk_cmd $p_bk_ftp_srv$p_bk_ftp_dir"; 528 | bkcf='#!/bin/bash 529 | { 530 | p_bk_cmd="$1" 531 | bk_period="$2" 532 | rslt_file="$3" 533 | p_e=$4 534 | p="run"; 535 | loop=0; 536 | while [ ! "$p"x = x ]; 537 | do 538 | sleep 60 539 | p=`ps | sed "s/^/ /" | grep " $$ " | grep -v grep` 540 | if [ ! $p_e -eq 0 ];then 541 | continue 542 | fi 543 | bktime=$(TZ=UTC-8 date +%Y%m%d); 544 | if [ $loop -eq $bk_period ];then 545 | $p_bk_cmd$bktime/ -T tmpip.txt 546 | $p_bk_cmd$bktime/ -T finiship.txt 547 | $p_bk_cmd$bktime/ -T log.txt 548 | $p_bk_cmd$bktime/ -T speedlog.txt 549 | $p_bk_cmd$bktime/ -T hspeedlog.txt 550 | if [ ! -f tmpip.txt ];then 551 | $p_bk_cmd$bktime/ -X "DELE tmpip.txt" 552 | $p_bk_cmd$bktime/ -X "DELE finiship.txt" 553 | fi 554 | loop=0; 555 | fi 556 | loop=$((loop+1)) 557 | done 558 | echo done 559 | bktime=$(TZ=UTC-8 date +%Y%m%d); 560 | $p_bk_cmd$bktime/ -T tmpip.txt 561 | $p_bk_cmd$bktime/ -T finiship.txt 562 | $p_bk_cmd$bktime/ -T log.txt 563 | $p_bk_cmd$bktime/ -T speedlog.txt 564 | $p_bk_cmd$bktime/ -T hspeedlog.txt 565 | rm -rf $rslt_file &>/dev/null 566 | cp speedlog.txt $rslt_file &>/dev/null 567 | $p_bk_cmd -T $rslt_file 568 | rm -rf $rslt_file &>/dev/null 569 | 570 | if [ ! -f tmpip.txt ];then 571 | $p_bk_cmd$bktime/ -X "DELE tmpip.txt" 572 | $p_bk_cmd$bktime/ -X "DELE finiship.txt" 573 | fi 574 | }& 575 | ' 576 | echo "$bkcf" | sed "s/\\\$\\\$/$$/g" > $bkcmdfile 577 | chmod 777 $bkcmdfile 578 | ./$bkcmdfile "$p_bk_cmd" "$p_bk_ftp_period" "$p_ftp_rslt_file" "$p_e" 579 | fi 580 | } 581 | 582 | worker_restore_env 583 | ftp_restore_env 584 | worker_backup_env 585 | ftp_backup_env 586 | 587 | ##推送TG和服务器 588 | push_msg 589 | 590 | ##创建FIFO控制并发进程数 591 | tmp_fifofile="./$$.fifo" 592 | mkfifo $tmp_fifofile &> /dev/null 593 | #有些linux系统不支持mkfifo 594 | if [ ! $? -eq 0 ];then 595 | mknod $tmp_fifofile p 596 | fi 597 | exec 6<>$tmp_fifofile 598 | rm -f $tmp_fifofile 599 | for i in `seq $p_n`; 600 | do 601 | echo >&6 602 | done 603 | 604 | #创建一个新sh文件扫描,避免各种怪异内存泄露 605 | scancmdfile=scancfcmdfile.sh 606 | if [ $p_k -eq 0 ];then 607 | cat >$scancmdfile</dev/null | grep 'h=\|colo=' | tr '\n' ' ' | sed "s/^/ip=\$1 &/g" | grep 'speedtest.galgamer.eu.org' | grep 'colo=' | sed "s/speedtest.galgamer.eu.org/valid.scan.cf/g" >> log.txt 612 | else 613 | curl --resolve valid.scan.cf:80:\$1 http://valid.scan.cf/cdn-cgi/trace --connect-timeout $p_to -m $p_to 2>/dev/null | grep 'h=\|colo=' | tr '\n' ' ' | sed "s/^/ip=\$1 &/g" | grep 'valid' | grep 'colo=' >> log.txt 614 | fi 615 | echo >&6 ; 616 | }& 617 | EOF 618 | chmod 777 $scancmdfile 619 | fi 620 | 621 | if [ $p_c -eq 1 ];then 622 | rm tmpip.txt &> /dev/null; 623 | rm finiship.txt &> /dev/null; 624 | fi 625 | 626 | if [ ! -f cfip.txt ];then 627 | echo "2.0.0.0/24" >> cfip.txt 628 | fi 629 | 630 | #生成断点文件 631 | if [ $p_k -eq 0 ];then 632 | if [ ! -f tmpip.txt ];then 633 | echo "生成断点文件时间较长,请耐心等待!"; 634 | rm finiship.txt &> /dev/null 635 | if [ $p_a -eq 0 ];then 636 | cat cfip.txt | sed 's/<\/a>//g' | grep -Eo "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(/[0-9]{1,2})*?" | awk '{print $0"/32"}' | awk -F/ '{print $1"/"$2}' > cfip1.txt 637 | cat cfip1.txt | awk -F/ '$2 >=24' > tmpip.txt; 638 | cat cfip1.txt | awk -F/ '$2 <24' > tmpip1.txt; 639 | rm cfip1.txt; 640 | cat tmpip1.txt | awk -F/ '{print $2}' > mask.txt 641 | cat tmpip1.txt | awk -F. '{print $1}' > i.txt 642 | cat tmpip1.txt | awk -F. '{print $2}' > j.txt 643 | cat tmpip1.txt | awk -F. '{print $3}' > k.txt 644 | cat tmpip1.txt | awk -F. '{print $4}' | awk -F/ '{print $1}' > l.txt 645 | rm tmpip1.txt; 646 | while read -u3 i && read -u4 j && read -u5 k && read -u7 l && read -u8 mask 647 | do 648 | divsubnet $i $j $k $l $mask 649 | done 3//g' | grep -Eo "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(/[0-9]{1,2})*?" | awk '{print $0"/32"}' | awk -F/ '{print $1"/"$2}' > cfip1.txt 653 | cat cfip1.txt | awk -F/ '$2 >=24' > tmpip.txt; 654 | cat cfip1.txt | awk -F/ '$2 <24' > tmpip1.txt; 655 | rm cfip1.txt; 656 | cat tmpip1.txt | awk -F/ '{print $2}' > mask.txt 657 | cat tmpip1.txt | awk -F. '{print $1}' > i.txt 658 | cat tmpip1.txt | awk -F. '{print $2}' > j.txt 659 | cat tmpip1.txt | awk -F. '{print $3}' > k.txt 660 | cat tmpip1.txt | awk -F. '{print $4}' | awk -F/ '{print $1}' > l.txt 661 | rm tmpip1.txt; 662 | while read -u3 i && read -u4 j && read -u5 k && read -u7 l && read -u8 mask 663 | do 664 | divsubnet $i $j $k $l $mask 665 | done 3 tmp.txt;cat tmp.txt > tmpip.txt;rm tmp.txt; 669 | rm finiship.txt &> /dev/null; 670 | fi 671 | fi 672 | 673 | #扫描流程 674 | if [ $p_k -eq 0 ];then 675 | echo "开始扫描" 676 | touch tmpip.txt 677 | if [ -f finiship.txt ];then 678 | finishline=$(cat tmpip.txt | grep -n "^" | grep "$(cat finiship.txt | grep -n "^" | tail -n 1)" | awk -F: "{print \$1}") 679 | #如果不为空,可认为tmpip.txt和finiship.txt都没有被修改过,直接按行取效率高 680 | if [ ! "$finishline"x = x ];then 681 | totalline=$(cat tmpip.txt | wc -l) 682 | newlinenum=$((totalline-finishline)) 683 | cat tmpip.txt | tail -n $newlinenum > tmp.txt;cat tmp.txt > tmpip.txt;rm tmp.txt; 684 | else 685 | cat finiship.txt tmpip.txt | tr '/' '.' | awk -F. '{printf "%.6f %s\n",sqrt(($1*(2^24))+($2*(2^16))+($3*(2^8))+$4),$1"."$2"."$3"."$4"/"$5}' | sort -n | awk '{print $2}' | uniq > tmp.txt;cat tmp.txt > tmpip.txt;rm tmp.txt; 686 | fi 687 | fi 688 | rm finiship.txt &> /dev/null; 689 | scanresult=`cat tmpip.txt | sed '/^\s*$/d' | wc -l` 690 | if [ $scanresult -eq 0 ];then 691 | echo "错误:cfip.txt或网络ASN数据库中没有符合格式的子网地址或IP地址。" 692 | fi 693 | for line in ` awk '{print $1}' tmpip.txt ` 694 | do 695 | load=`uptime | awk -F 'load average: ' '{print $2}' | awk -F. '{print $1}'` 696 | while [ $load -ge $p_max_load ]; 697 | do 698 | sleep 1 699 | load=`uptime | awk -F 'load average: ' '{print $2}' | awk -F. '{print $1}'` 700 | done 701 | if [ ! "$line"x = x ];then 702 | scan_subnet $line 703 | fi 704 | #sed -i '1d' tmpip.txt; 705 | #sed用一个备份文件实现编辑,太费flash,换一种实现 706 | echo $line >> finiship.txt 707 | done 708 | rm tmpip.txt; 709 | rm $scancmdfile; 710 | sleep 10 711 | fi 712 | 713 | #等待扫描任务结束 714 | #for i in `seq $p_n`; 715 | #do 716 | # read -u6; 717 | #done 718 | 719 | exec 6>&- 720 | 721 | #测速流程 722 | if [ $p_s -eq 0 ];then 723 | echo "开始测速"; 724 | touch log.txt; 725 | touch speedlog.txt 726 | #去除log.txt中重复ip 727 | awk ' !x[$1]++ ' log.txt > tmp.txt;cat tmp.txt > log.txt;rm tmp.txt; 728 | sed -i '/^\s*$/d' log.txt 729 | ghasspeedtest=0; 730 | cat speedlog.txt 2&>/dev/null >> hspeedlog.txt 731 | speedtime=$(TZ=UTC-8 date +%Y-%m-%d" "%H:%M:%S); 732 | 733 | if [ $p_i -eq 0 ];then 734 | echo "[$speedtime]" > speedlog.txt 735 | fi 736 | 737 | for line in $(eval "cat speedlog.txt log.txt | sed \"s/^ip=//g\" | awk ' ! x[\$1]++ ' | grep valid $p_speed_filter" | tr ' ' '~') 738 | do 739 | line=`echo $line | tr '~' ' '`; 740 | ip=`echo $line | awk '{print $1}' | tr -d 'ip='`; 741 | if [ "$ip"x = x ];then 742 | continue; 743 | fi 744 | ghasspeedtest=1; 745 | speedtest $ip; 746 | cat speedlog.txt | grep -v '\[' | awk '{print $2,$1,$3,$4,$5}' | sort -nr | awk '{print $2,$1,$3,$4,$5}' | sed "1s/^/[$speedtime]\n/" > tmp.txt;rm -rf speedlog.txt;mv tmp.txt speedlog.txt 747 | done 748 | 749 | if [ $ghasspeedtest -eq 0 ];then 750 | echo "错误:没有待测速的结果,即log.txt中没有合法的记录或断点模式测速时所有IP都已完成测速" 751 | fi 752 | fi 753 | 754 | exit 0 755 | --------------------------------------------------------------------------------