问题由来

阿里云的VPC与其他基于OpenStack的IaaS不同,他的路由只是作为多网段的路由交换,不提供内到外的路由,因此在VPC内的主机除非绑定EIP,否则是无法连接公网的。通过工单询问客服,得到的结论是通过在路由器上添加一个路由,通过一个绑定EIP的主机做NAT上网,通过设置iptables的方式来实现。

VPC结构图

虚拟路由器配置

添加路由

为了让内网服务器借助EIP访问公网,所以设置所有目标地址0.0.0.0/0下一跳都转发到绑定了公网IP的ECS实例上。这里的下一跳ECS不支持搜索,需要提前记号名称:

绑定EIP的主机配置

iptables添加SNAT规则

iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE

注意: ubuntu 14.04 系统保存iptables设置需要安装iptables-persistent包,然后通过 service iptables-persistent save 的方式保存配置,安装完iptables-persistent后该服务随系统一起启动并会把保存的配置应用

开启IP转发

echo "net.ipv4.ip_forward=1" >>  /etc/sysctl.conf && sysctl -p

数组定义

# 定义一个空数组
Result=()

# 定义并给数组赋值
arr=(a b c d e)

说明:

  • 默认数组中的元素是以空格分隔的,如果元素是包含空格的字符串,最好用双引号括起来

  • shell中的默认分隔符可以通过修改 $IFS变量来设置

数组读取/删除

# 初始化并赋值数组
arr=(a b c d e)

# 计算长度
echo ${#arr[@]} # 结果: 5
# 或
echo ${#arr[*]} # 结果: 5

# 取出所有数据
echo ${arr[@]} # 结果: a b c d e
# 或
echo ${arr[*]} # 结果: a b c d e

# 取出第二个元素的数据
echo ${arr[1]} # 结果: b

# 遍历数组
filelist=(`ls`)
for file in ${filelist[@]};do
echo $file
done

# 删除第二个元素
unset arr[1]
echo ${arr[*]} # 结果: a c d e

切片/元素替换

# 切片

# 初始化并赋值数组
arr=(a b c d e)

arr2=(${arr[@]:0:3})
echo ${arr2[@]} # 结果 a b c


# 替换
# 初始化并赋值数组
arr=(a b c d e)
echo ${arr[@]/a/aaa}
  • 切片(分片): 直接通过 ${数组名[@或*]:起始位置:长度} 切片原先数组,返回是字符串,中间用“空格”分开,因此如果加上”()”,将得到切片数组,上面例子:c 就是一个新数据。
  • 替换: ${数组名[@或*]/查找字符/替换字符} 该操作不会改变原先数组内容,如果需要修改,请重新定义变量并赋值。

实例

在一个多域名的web server环境中,通过分析访问日志,统计最近8小时有用户访问的域名(去重),并显示。

日志格式:X-Forworld-IP User-IP YYYY-MM-DD HH:mm:ss method “URL” HTTP响应码 服务器处理时间 返回大小 “Refer” “浏览器信息” “虚拟主机域名” 真实处理请求的主机

#!/bin/bash

AWKBin="/usr/bin/awk"
EGREPBin="/bin/egrep"
SORTBin="/usr/bin/sort"
SEDBin="/bin/sed"

# 虚拟主机
VSName=$1

# 时间段
TimePeriod=$2

# 过滤字符串
FilterKeys='''DNSPod-Monitor|JianKongBao'''
# 日志目录
LOGPath="/logs/nginx"

# 定义最终输出的数组变量
Result=()

while (( TimePeriod > 0 ))
do
LogTime=`date -d "- ${TimePeriod}hours" +%Y-%m-%d-%H`
LogFile=${VSName}_${LogTime}.log

Result=(${Result[@]} `$AWKBin '{if($5!~/HEAD/ && $5!~/\"\"/ ) print $0}' ${LOGPath}/${LogFile} | \
$EGREPBin -v $FilterKeys | $AWKBin '{print $NF}' | $AWKBin -F '@' '{print $1}' |\
$SORTBin -u`)

echo "第$TimePeriod 个日志:${Result[*]}"


((TimePeriod--))
done

echo "未去重:${Result[*]}"

Result=($(awk -vRS=' ' '!a[$1]++' <<< ${Result[@]}))

echo "去重以后:${Result[*]}"

由于之前的blog内容过于陈旧,很多文档现在来看会给广大朋友带来困扰,因此决定将之前的所有内容都抛弃,从今天开始重新写!

最近5年由于工作原因也没有顾得上更新blog,近期会有一系列文档更新,都是这五年来的一些工作经验。

由于大家共识的原因,本blog于2015-08-02正式迁移到GitHub