开发者社区> 问答> 正文

基于阿里云ECS API实现操作简单 功能强大的初级SDN功能

*.文章中提到的SDN实现或许与其它网络资料的创建vxnet的方式略有不同,但实现的功能大致一样,都是将一群实例用各自方式来做成子网隔离,实现更多业务需求。


SDN即“Software-Defined-Networking(软件定义网络)”的简称,SDN是一种网络虚拟化(network virtualization)技术,利用OpenFlow协定,将路由功能从硬件、数据面上分离出来,将由软件层面使用;让本来需要在网关交换机上配置才能实现的功能直接用软件来实现,以实现网络管理的智能化。


也许你还有一些抽象,像下面这样解释你就会大义顿悟了:


通过SDN,你可以轻松给同一数据中心的云服务器群搭建子网,彼此之间内网互通,也可以用规则实现特定主机不互通;[1]
通过SDN,你可以轻松屏蔽掉某一段IP的访问;[2]
通过SDN,你可以更方便地禁PING。[3]
*.
[1].阿里云默认默认申请的主机会放到分别每个机房的安全组内,也可能是多个安全组,但同机房安全组之间已经配置成互通。以此实现同一机房、同账户的实例之间内网的互通。
[2],[3].使用iptables命令也可实现这些功能,但运行效率受到云主机本身资源影响。有维护防御DDOS/CC攻击的朋友就知道,有时候iptables执行起来效率超级慢。




上面讲的只是概念,下面来进行一些实践。在继续阅读下面文章前,请确认您已经有一定开发基础,并已经熟悉阿里云ECS API文档。




本处用作者自己写的一个ECS SDK来做功能演示,项目地址是 https://github.com/hexdata/AliECS_PHP_SDK


PHP程序的老规矩:
<?php加载SDK
require_once "ecs.sdk.class.php";进行参数配置
$ecs=new ECS("你的ACCESS KEY ID","你的ACCESS KEY SECRET");

需求1  创建 “安全组 1” 和 “安全组 2” 两个安全组,加入相应实例并彼此内网隔离。

调用SDK方法createSecurityGroup:
$ret = $ecs->createSecurityGroup( array(
    'RegionId' => 'cn-hangzhou-dg-a01', //目前数据中心有 cn-hangzhou-dg-a01 和 cn-qingdao-cm5-a01
    'Description'=>'安全组 1'
) );
print_r($ret);


如果执行顺利,程序将会输出类似:
Array
(
    [SecurityGroupId] => G2646694a-5bc0-46cf-830e-45572f19d10a
    [RequestId] => 4F79414D-E407-43CB-A53F-4ECAEF8E4354
)
其中的$ret['SecurityGroupId']就是安全组的ID;在后面,给这个安全组授权规则、加主机进这个安全组及删除安全组,都需要用到这个ID。

所以,我们需要将这个ID记下,如果要做一整套工具、系统,最好将这个安全组ID与名称绑定进数据库里。
而另外一个返回的值RequestId是ECS API的公共返回值,除调试外无其它用途。


然后我们需要将相应的主机加入到这个安全组内。这里给大家讲几处注意的:
1.当前1个实例只能加入一个安全组,如果已经加入过安全组,新加入另一安全组后,此实例就脱离旧的安全组加入新的安全组,旧的安全组的规则不再对此实例有效,而新的安全组规则对此实例有效
2.一个安全组内最多能包含100个实例,如果尝试加入超过100个实例将会报错

加入安全组的代码:ECS API安全组方面的接口并不提供加入安全组的,而是在ECS API的更改主机属性的modifyInstanceAttribute接口。


$ret = $ecs->modifyInstanceAttribute( array(
    'instanceId'=>'AY1208220944470574343',
    'SecurityGroupId'=>'G2646694a-5bc0-46cf-830e-45572f19d10a'
) );
print_r($ret);


如果顺利,服务器将返回类似下面的数据:
Array
(
[RequestId] => 4F817A4D-BC07-43CB-A93F-4ECAE772BC01
)
这样就成功将相应实例加入进了安全组内。如果需要批量加入,重复执行上述代码即可。
后面的 再新建一个安全组、添加其它实例的步骤就省略了。
默认新创建的两个安全组之间内网是不互通的,所以已经满足需求了。




需求2  给一个安全组授权访问规则:


安全组创建好后,默认的规则就是对内网的限制,在没有任何手工添加的规则的时候,同一组内的实例之间内网互通,不同组内实例之间内网不互通。
使用安全组规则,可以实现更加复杂的功能,如 丢弃(drop)/拒绝(reject)[1]/接受(accept) 指定协议 指定端口 指定IP段/指定安全组 的数据包
*. [1] 丢弃相当于忽略,拒绝相当于say "no",前者是直接将数据扔进路由黑洞,后者是返回拒绝数据。



添加新的安全组规则需要调用SDK中的authorizeSecurityGroup方法来实现。
例如我们添加 图上第一条规则“禁止公网所有流量”:
$ret = $ecs-authorizeSecurityGroup( array(
'SecurityGroupId'=>'G2646694a-5bc0-46cf-830e-45572f19d10a',
'RegionId'=>'cn-hangzhou-dg-a01',
'IpProtocol'=>'all',
'PortRange'=>'-1/-1',
'SourceCidrIp'=>'0.0.0.0/0',
'Policy'=>'drop',
'NicType'=>'internet'
) );
print_r($ret);

同上面代码运行返回数据类似,本代码也将返回仅有一个RequestId的值


再例如我们添加 “允许公网任意IP来源的SSH连接”:
$ret = $ecs-authorizeSecurityGroup( array(
'SecurityGroupId'=>'G2646694a-5bc0-46cf-830e-45572f19d10a',
'RegionId'=>'cn-hangzhou-dg-a01',
'IpProtocol'=>'tcp', // 取值:tcp|udp|icmp|gre|all
'PortRange'=>'22/22', // 协议为icmp,gre,all 时端口号范围值为-1/-1,若为1/200表示从1~200所有端口 此处22/22是因为SSH端口是22号
'SourceCidrIp'=>'0.0.0.0/0', // CIDR格式的IP搭配法
'Policy'=>'accept', //  丢弃drop/拒绝reject/接受accept
'NicType'=>'internet' // 公网internet/内网intranet
) );
print_r($ret);

如果执行成功,此操作也只将返回一个RequestId值。


其它规则的添加希望读者自行完成。


此处补充一点注意事项:添加规则,越后添加的,优先级越高。也就是说规则之间若存在冲突,以最后添加的规则为准。






需求3  创建“安全组 1”、“安全组 2”、“安全组 3”...,加入相应实例后,授权不同安全组之间的实例的访问规则为依次链式互通,1和2、2和3、3和4...互通,否则不互通


依次创建“安全组 1/2/3/4”的教学此处不再重复描述,读者按照需求1中的创建安全组的代码即可实现。
此处提一下安全组之间授权连通的规则:
“安全组 1” 与 “安全组 2” 之间连通,可以给“安全组 1”添加 【允许来自安全组 2 的ALL协议】,也可以给“安全组 2”添加【允许来自安全组 1 的ALL协议】。但需要注意的是,若在安全中1中授权,列出安全组1的授权规则时会列出此处规则,列出对方规则时不会列出此规则。
授权安全组之间的规则也是用authorizeSecurityGroup方法来实现,与上面需求2代码略有差异的是有一个参数需要变动,此时不再需要SourceCidrIp 参数,而需要在SourceGroupId这个的参数附带上目标安全组的ID。


下面是代码片段:
$ret = $ecs-authorizeSecurityGroup( array(
'SecurityGroupId'=>'G2646694a-5bc0-46cf-830e-45572f19d10a',  // 此安全组
'RegionId'=>'cn-hangzhou-dg-a01',
'IpProtocol'=>'all',
'PortRange'=>'-1/-1',
'SourceGroupId'=>'Gf8957146-4c52-47dc-828e-ceeea060790e',  // 另一安全组
'Policy'=>'accept',
'NicType'=>'internet'
) );
print_r($ret);
执行结果返回数据类似上面需求2。


同学们可以自行将上面代码片段修改相应参数,多次执行实现多个安全组之间的链式互通。


后记   笔者enj0y参加阿里云2013开发者大赛的作品是hexpanel,定位是做阿里云的ECS代理业务的同时,把这模式的解决方案开源免费分享给对这模式感兴趣的朋友。作品编号是11号,如果您觉得文章对您有帮助,或者您试用hexpanel过后感觉不错,请为我投上您宝贝的一票。 地址: http://dasai.aliyun.com/signup/works2013/?search=11






展开
收起
enj0y 2013-09-21 23:06:30 22955 0
6 条回答
写回答
取消 提交回答
  • Re基于阿里云ECSAPI实现操作简单功能强大的初级SDN功能
    这个和SDN有关系还是太牵强了。

    等阿里云支持VPC后再说吧
    2014-07-25 22:39:19
    赞同 展开评论 打赏
  • Re基于阿里云ECSAPI实现操作简单功能强大的初级SDN功能
    加入群【阿里云ECS API群】:59727016
    2014-06-08 00:52:37
    赞同 展开评论 打赏
  • 支持楼主的大作
    2013-09-23 21:01:17
    赞同 展开评论 打赏
  • 回3楼enj0y的帖子
    如果有这类操作,我觉得提交工单客服处理更好

    -------------------------

    回5楼enj0y的帖子
    那也是,能自己做的就自己做。
    2013-09-23 15:14:05
    赞同 展开评论 打赏
  • 回 1楼(leehon) 的帖子
    文章主要讲解下关于安全组接口的操作及进行一些特殊需求的实现。

    我开发的作品是一个代理平台,阿里云的趋势是要走向开放,根据可靠消息阿里云的8个资源创建管理接口将于10月初~月中 开放。即使现在使用价值不大,以后开放了只要这版API没撤销,以后也可以用的。

    代理商更关心的应该是用户渠道,代理折扣啥的一签了合同就吃准了。

    -------------------------

    回 4楼(leehon) 的帖子
    有些需求,不是客服理解得了的。像下面较为复杂的情况,2台专门做VPN跳板(登录SSH、3389用),其余15台分成了3个子网,若要客服处理,你光解释就得需要一天左右时间。当然,这只是一个小创业应用,若做得更大让客服来处理安全组那情况更不乐观了。

    2013-09-23 10:37:29
    赞同 展开评论 打赏
  • Re基于阿里云ECSAPI实现操作简单功能强大的初级SDN功能
    楼主好人,正在考虑如何调用云盾来加强安全性,发现没有接口
    看到你写的关于SDN的介绍,非常棒~~~ 可以借鉴,谢谢楼主
    2013-09-23 01:05:36
    赞同 展开评论 打赏
滑动查看更多
问答排行榜
最热
最新

相关电子书

更多
CUDA MATH API 立即下载
API PLAYBOOK 立即下载
传统企业的“+互联网”-API服务在京东方的实践 立即下载