Pluto实现总结

Pluto实现总结

1. ike默认使用的udp端口为500,如果激活了NAT-Traversal功能,就需要pluto监听udp4500端口

2. pluto支持在不同的操作系统使用不同的ip协议栈,默认使用--use-netkey,或者使用--use-klips, --use-mast,--use-bsdkame, --use-win2k or --use-nostack

3. pluto通过--nat_travesal来激活nat穿越,在nat路由器后的网段通过—virtual_private来进行设置

4. --force-keepalive将激活发送keep-alive包,防止ipsec-链路间存在nat路由器,但没有ipsec流量后就关闭端口。--keep-alive设置发keep-alive包的间隔

5. pluto支持X.509证书的使用,如果需要就可以发送证书来使用。通过NSS来发送x.509相关的数据,包括CAcerts, certs, CRLs and private keys。所有认证相关的处理通过利用NSS数据库来完成,所有的认证材料都存储在NSS数据库,存储在/etc/ipsec.d 或者通过—ipsecdir来指定。

6. pluto可以利用helper children来卸载加密操作,利用—nhelpers来实现。底层加密优化可另行查看如何卸载加密操作。

7. pluto配置—perpeerlog来输出每个连接的日志,--perpeerlogbase配置日志目录

8. 如果需要调查pluto存在的内存泄漏,就可以运行携带--leak-detective选项

9. 状态对象对应一个连接,有状态对象对应ISAKMP SA,有状态对象对应ipsec SA

whack总结

1.whack被用来控制运行的pluto进程,来对pluto进行执行各种操作,他通过UNIX domain socket来与pluto通信,属于pluto上层的管理程序。

2. The listen form tells pluto to start orstop listening on the public interfaces for IKE requests from peers

3. The initiate form tells pluto tonegotiate an SA corresponding to a connection

4. The terminate form tells pluto to removeall SAs corresponding to a connection, including those being negotiated

5. The status form displays the pluto'sinternal state

6. The shutdown form tells pluto to shutdown, deleting all SAs.

以上对应whact 的相关命令:--listen, --initiate,--terminate ,–status, --shutdown

--ctlbase path:the UNIX domain socket for talkingto pluto

--label string:adds the string to all errormessages generated by whack

--name connection-name:sets the name of the connection 代码用ipsec-con-site的id作为连接name

--debug-all来激活输出所有的调试信息。

具体见https://review.openstack.org/#/c/496991/

pluto &&whack命令使用

底层openswan创建ipsec 连接过程

openstack代码neutron_aas/services//device_drivers/ipsec.py中的主要方法:

def start(self):
    """Start the process.

    Note: if there is not namespace yet,
    just do nothing, and wait next event.
    """
    if not self.namespace:
        return
    if not self._process_running():
        self._cleanup_control_files()

    virtual_private = self._virtual_privates()
    #start pluto IKE keying daemon
    cmd = [self.binary,
           'pluto',
           '--ctlbase', self.pid_path,
           '--ipsecdir', self.etc_dir,
           '--use-netkey',
           '--uniqueids',
           '--nat_traversal',
           '--secretsfile', self.secrets_file,
           '--virtual_private', virtual_private]

    if self.conf.ipsec.enable_detailed_logging:
        cmd += ['--perpeerlog', '--perpeerlogbase', self.log_dir]
        if self.conf.ipsec.enable_debug:
            for debug_key in self.conf.ipsec.debug_level:
                cmd += ['--' + debug_key]
    self._execute(cmd)
    #add connections
    for ipsec_site_conn in self.service['ipsec_site_connections']:
        # Don't add a connection if its admin state is down
        if not ipsec_site_conn['admin_state_up']:
            continue
        nexthop = self._get_nexthop(ipsec_site_conn['peer_address'],
                                    ipsec_site_conn['id'])
        self._execute([self.binary,
                       'addconn',
                       '--ctlbase', '%s.ctl' % self.pid_path,
                       '--defaultroutenexthop', nexthop,
                       '--config', self.config_file,
                       ipsec_site_conn['id']
                       ])
    #TODO(nati) fix this when openswan is fixed
    #Due to openswan bug, this command always exit with 3
    #start whack ipsec keying daemon
    self._execute([self.binary,
                   'whack',
                   '--ctlbase', self.pid_path,
                   '--listen',
                   ], check_exit_code=False)

    for ipsec_site_conn in self.service['ipsec_site_connections']:
        if (not ipsec_site_conn['initiator'] == 'start' or
                not ipsec_site_conn['admin_state_up']):
            continue
        #initiate ipsec connection
        self._execute([self.binary,
                       'whack',
                       '--ctlbase', self.pid_path,
                       '--name', ipsec_site_conn['id'],
                       '--asynchronous',
                       '--initiate'
                       ])
    self._copy_configs()

 

def disconnect(self):
    if not self.namespace:
        return
    if not self.service:
        return

    connections = self.get_established_connections()
    for conn_name in connections:
        self._execute([self.binary,
                       'whack',
                       '--ctlbase', self.pid_path,
                       '--name', '%s' % conn_name,
                       '--terminate'
                       ])

def stop(self):
    #Stop process using whack
    #Note this will also stop pluto
    self.disconnect()
    self._execute([self.binary,
                   'whack',
                   '--ctlbase', self.pid_path,
                   '--shutdown',
                   ])
    self.connection_status = {}

 

通过调用上面的方法对ipsec连接进行创建,删除操作。

下面试验用手动下发命令方式来创建ipsec-连接,并对已经存在的连接进行修改。

 

目前存在ipsec连接信息如下

gateway_ip = 192.168.30.29   subnet-1: 192.168.10.0/24

gateway_ip= 192.168.30.30    subnet-2:192.168.20.0/24

现创建192.168.100.0/24,绑定到router-1,创建192.168.200.0/24,绑定到router-2,将ipsec-连接修改为192.168.100.0/24à192.168.200.0/24间建立隧道,信息如下:

gateway_ip = 192.168.30.29   subnet-1: 192.168.100.0/24

gateway_ip= 192.168.30.30    subnet-2: 192.168.200.0/24

1.    查看已经有的ipsec进程状态,rouer_id: 05bf6a27-5901-4c67-bfef-89bde3d2bc67

ip netns exec qrouter-05bf6a27-5901-4c67-bfef-89bde3d2bc67 ipsec whack --ctlbase /opt/stack/data/neutron/ipsec/05bf6a27-5901-4c67-bfef-89bde3d2bc67/var/run/pluto --status




2. 删除跟connection相关联的SA,其中ipsec_site_conn id为42d65a23-ee51-466b-95f6-f99a0b70df59

ip netns exec qrouter-05bf6a27-5901-4c67-bfef-89bde3d2bc67 ipsec whack --ctlbase /opt/stack/data/neutron/ipsec/05bf6a27-5901-4c67-bfef-89bde3d2bc67/var/run/pluto --name 42d65a23-ee51-466b-95f6-f99a0b70df59/0x1 --terminate

 



3.停止与router相关的pluto进程

ip netns exec qrouter-05bf6a27-5901-4c67-bfef-89bde3d2bc67 ipsec whack --ctlbase /opt/stack/data/neutron/ipsec/05bf6a27-5901-4c67-bfef-89bde3d2bc67/var/run/pluto --shutdown




4.重新启动pluto进程,在此之前修改ipssec.conf的配置,left/right子网修改为192.168.100.0/24,192.168.200.0/24,其他不变。这里本端网络为192.168.100.0/24,对端网络为192.168.200.0/24,通过—debug-all打开调试信息,在/var/log/auth.log可以查看进程创建日志。

ip netns exec qrouter-05bf6a27-5901-4c67-bfef-89bde3d2bc67 /usr/lib/ipsec/pluto --ctlbase /opt/stack/data/neutron/ipsec/05bf6a27-5901-4c67-bfef-89bde3d2bc67/var/run/pluto --ipsecdir /opt/stack/data/neutron/ipsec/05bf6a27-5901-4c67-bfef-89bde3d2bc67/etc --use-netkey --uniqueids --nat_traversal --secretsfile /opt/stack/data/neutron/ipsec/05bf6a27-5901-4c67-bfef-89bde3d2bc67/etc/ipsec.secrets --virtual_private %v4:192.168.100.0/24,%v4:192.168.200.0/24 --perpeerlog --perpeerlogbase /opt/stack/data/neutron/ipsec/05bf6a27-5901-4c67-bfef-89bde3d2bc67/log --debug-all








5.添加connection,这里192.168.30.30为默认下一条,因为vrouter在同一个网络节点上。

ip netns exec qrouter-05bf6a27-5901-4c67-bfef-89bde3d2bc67 ipsec addconn --ctlbase /opt/stack/data/neutron/ipsec/05bf6a27-5901-4c67-bfef-89bde3d2bc67/var/run/pluto.ctl --defaultroutenexthop 192.168.30.30 --config /opt/stack/data/neutron/ipsec/05bf6a27-5901-4c67-bfef-89bde3d2bc67/etc/ipsec.conf 42d65a23-ee51-466b-95f6-f99a0b70df59





6. 发现公共的端口,并开始接收对端发来的消息,通过UDP:500监听消息

ip netns exec qrouter-05bf6a27-5901-4c67-bfef-89bde3d2bc67 ipsec whack --ctlbase /opt/stack/data/neutron/ipsec/05bf6a27-5901-4c67-bfef-89bde3d2bc67/var/run/pluto --listen




7.最后利用pluto开始ISAKMP SA,IPSEC SA的协商过程

ip netns exec qrouter-05bf6a27-5901-4c67-bfef-89bde3d2bc67 ipsec whack --ctlbase /opt/stack/data/neutron/ipsec/05bf6a27-5901-4c67-bfef-89bde3d2bc67/var/run/pluto --name 42d65a23-ee51-466b-95f6-f99a0b70df59 --asynchronous --initiate




8. 相同操作重建反方向的ipsec-连接,汇总后的命令如下

此时isakmp sa/ipsec sa创建成功,ipsec-双向连接也创建成功,但还不能正常通信,

需要在每个router命名中设置Iptable规则将特定网段流量引入ipsec-隧道

最后验证修正成功, 192.168.100.0/24 192.168.200.0/24可以通过ipsec-隧道实现l3-。并且对应192.168.10/24 192.168.20/24的ipsec-链接状态也是active


参考:

http://lingxiankong.github.io/2017-04-01-aas-openswan.html

 


你可能感兴趣的:(openstack)