ONOS与OVS间设置SSL安全连接

SSL(Secure Sockets Layer)是为网络通信提供安全性的协议,我们可以使用SSL来保证OpenFlow传输通道的安全。本篇文章主要介绍ONOS控制器与OVS(Open vSwitch)交换机之间使用自签名证书进行SSL连接(这是实现SSL的一种较为简便的方式 )的配置过程。这部分内容在ONOS的官方Wiki上有介绍,但是其内容不是很细致,有一些需要特别注意的步骤没有进行强调,有的命令也漏掉了一些选项设置,导致我花了好长时间才配置好。所以写这篇文章,是想让大家照着流程做就一定能成功。如果对这方面有什么问题,欢迎与我交流。

以下步骤中的ONOS端与OVS端可以是两台不同的机器,也可以是相同的机器(为了实验方便),本文以两台不同的虚拟机为例。

一、配置步骤

1. 生成ONOS端的自签名证书

在ONOS端新建一个文件夹(本文称作SSL文件夹)用来存储本实验中的所有相关文件,在SSL文件夹下使用keytool工具生成一个自签名的证书库onos.jks(包含私钥与公钥证书信息):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ keytool -genkey -keyalg RSA -alias onos -keystore onos.jks -storepass 111111 -validity 365 -keysize 2048
What is your first and last name?
[Unknown]: Zeyang Zhang
What is the name of your organizational unit?
[Unknown]: FNLab-BUPT
What is the name of your organization?
[Unknown]: BUPT
What is the name of your City or Locality?
[Unknown]: Beijing
What is the name of your State or Province?
[Unknown]: Beijing
What is the two-letter country code for this unit?
[Unknown]: CN
Is CN=Zeyang Zhang, OU=FNLab-BUPT, O=BUPT, L=Beijing, ST=Beijing, C=CN correct?
[no]: yes

Enter key password for <onos>
(RETURN if same as keystore password): #直接回车!
$ ls
onos.jks

其中storepass(至少6个字符)应该牢记,各种信息随便填。

请注意:在输入<onos>的主密码时一定要直接敲回车(即<onos>的主密码一定要和keystore密码相同,否则在测试时ONOS端会出现”SSL init failed: Cannot recover key”错误)。

将onos.jks经过两步转换为onos.pem文件:onos.jks→onos.p12→onos.pem

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ keytool -importkeystore -srckeystore onos.jks -destkeystore onos.p12 -srcstoretype jks -deststoretype pkcs12
Enter destination keystore password: #为了方便,跟之前一样吧(111111)
Re-enter new password:
Enter source keystore password: #onos.jks的密码(111111)
Entry for alias onos successfully imported.
Import command completed: 1 entries successfully imported, 0 entries failed or cancelled
$ ls
onos.jks onos.p12
$ openssl pkcs12 -in onos.p12 -out onos.pem
Enter Import Password: #111111
MAC verified OK
Enter PEM pass phrase: #随便填,4个字符或以上有效
Verifying - Enter PEM pass phrase:
$ ls
onos.jks onos.p12 onos.pem

onos.pem的内容大概是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ cat onos.pem
Bag Attributes
friendlyName: onos
localKeyID: 54 69 6D 65 20 31 34 37 36 35 38 39 38 36 31 30 33 38
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQITT2bGjZ0m1ICAggA
......
A87aqKt2iIJiSdIraRHjvl93Qo3KhD7OOjFpFb7fRcxjIXxkaW+Jbx7rcMR5ASzo
dWo=
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: onos
localKeyID: 54 69 6D 65 20 31 34 37 36 35 38 39 38 36 31 30 33 38
subject=/C=CN/ST=Beijing/L=Beijing/O=BUPT/OU=FNLab-BUPT/CN=Zeyang Zhang
issuer=/C=CN/ST=Beijing/L=Beijing/O=BUPT/OU=FNLab-BUPT/CN=Zeyang Zhang
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEa++BnjANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQGEwJD
......
HW4tyiJKfrzrhEhRKLIrJz4Y9W3HeC+9FXts3qebCFBsaW52oQwXUBT2X7AngVpr
+X0bz9JYv6uJ7qG2c0T7yyZ+ajCHqTiStAXx
-----END CERTIFICATE-----

接下来我们需要新建一个叫做cacert.pem的文件用来给OVS使用,它的内容是onos.pem的证书部分,即从中间的”Bag Attributes”到最后的部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ cat cacert.pem 
Bag Attributes
friendlyName: onos
localKeyID: 54 69 6D 65 20 31 34 37 36 35 38 39 38 36 31 30 33 38
subject=/C=CN/ST=Beijing/L=Beijing/O=BUPT/OU=FNLab-BUPT/CN=Zeyang Zhang
issuer=/C=CN/ST=Beijing/L=Beijing/O=BUPT/OU=FNLab-BUPT/CN=Zeyang Zhang
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEa++BnjANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQGEwJD
......
HW4tyiJKfrzrhEhRKLIrJz4Y9W3HeC+9FXts3qebCFBsaW52oQwXUBT2X7AngVpr
+X0bz9JYv6uJ7qG2c0T7yyZ+ajCHqTiStAXx
-----END CERTIFICATE-----
$ ls
cacert.pem onos.jks onos.p12 onos.pem

请注意:两个中间文件onos.p12和onos.pem已经没有用了,安全起见应该被删除。

2.将ONOS的证书复制到OVS端

把cacert.pem复制到OVS端的/var/lib/openvswitch/pki/controllerca目录下(该目录中可能已经有了一个名为cacert.pem的文件,可先将其备份一下),此目录用来存放OVS信任的证书授权机构的证书。

3.生成OVS端的自签名证书并配置OVS端的SSL

进入OVS端的/etc/openvswitch目录,使用自己的pki请求和签署一个数字证书,生成OVS的私钥文件sc-privkey.pem和公钥证书sc-cert.pem:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ cd /etc/openvswitch
/etc/openvswitch$ sudo ovs-pki --dir=/var/lib/openvswitch/pki req+sign sc switch
sc-req.pem 20161016日 星期日 12:33:29 CST
fingerprint 36a25f547b875e3fd3d5e53230eee4e0bd79251b
/etc/openvswitch$ ll
total 52
drwxr-xr-x 2 root root 4096 1016 12:33 ./
drwxr-xr-x 137 root root 12288 1016 11:49 ../
......
-rw-r--r-- 1 root root 4053 1016 12:33 sc-cert.pem
-rw------- 1 root root 1675 1016 12:33 sc-privkey.pem
-rw-r--r-- 1 root root 3601 1016 12:33 sc-req.pem
......

开启OVS服务,使用ovs-vsctl set-ssl设置OVS端的SSL(配置OVS的私钥文件、OVS的证书文件和ONOS的证书文件的位置):

1
$ sudo ovs-vsctl set-ssl /etc/openvswitch/sc-privkey.pem /etc/openvswitch/sc-cert.pem /var/lib/openvswitch/pki/controllerca/cacert.pem

4.将OVS的证书复制到ONOS端并配置ONOS端的SSL

把OVS端的sc-cert.pem复制到ONOS端的SSL文件夹中,然后在ONOS端使用keytool -importcert将sc-cert.pem导入到ONOS的证书库onos.jks中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ keytool -importcert -file sc-cert.pem -keystore onos.jks
Enter keystore password: #111111
Owner: CN=sc id:2c950c10-99f5-4887-a3a4-15085e7580b7, OU=Open vSwitch certifier, O=Open vSwitch, ST=CA, C=US
Issuer: CN=OVS switchca CA Certificate (2016 10月 02 19:12:35), OU=switchca, O=Open vSwitch, ST=CA, C=US
Serial number: 2
Valid from: Sun Oct 16 12:33:29 CST 2016 until: Wed Oct 14 12:33:29 CST 2026
Certificate fingerprints:
MD5: 58:DD:8C:9F:1E:DB:EB:BA:8C:A7:D0:19:8F:62:BB:03
SHA1: 4F:88:28:61:65:EA:79:4A:45:DF:B3:75:60:50:0A:A9:CA:CB:CB:2D
SHA256: 05:9A:C1:14:36:00:63:85:90:DB:3B:4A:1A:59:14:13:E4:DB:5A:9C:2E:91:E1:CC:D5:8F:52:80:89:FE:CB:1F
Signature algorithm name: MD5withRSA
Version: 1
Trust this certificate? [no]: yes
Certificate was added to keystore

使用下面的命令查看证书库的内容,可以发现证书库已经包含有了PrivateKeyEntry和trustedCertEntry。

1
2
3
4
5
6
7
8
9
10
11
12
$ keytool -list -keystore onos.jks
Enter keystore password: #111111

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

onos, Oct 16, 2016, PrivateKeyEntry,
Certificate fingerprint (SHA1): 39:D4:55:8D:F4:59:31:08:70:CA:C6:A8:24:D9:96:84:76:39:0C:3C
mykey, Oct 16, 2016, trustedCertEntry,
Certificate fingerprint (SHA1): 4F:88:28:61:65:EA:79:4A:45:DF:B3:75:60:50:0A:A9:CA:CB:CB:2D

下面一步是设置相关的环境变量。ONOS的Wiki上给出的方法是将命令加入$ONOS_HOME/tools/package/bin/onos-service,但是我试了之后发现并没有用。其实直接在终端里export以下就行了,如下(注意写出onos.jks的绝对路径,保证Password正确):

1
$ export EXTRA_JAVA_OPTS="-DenableOFTLS=true -Djavax.net.ssl.keyStore=/home/zzy/SSL/onos.jks -Djavax.net.ssl.keyStorePassword=111111 -Djavax.net.ssl.trustStore=/home/zzy/SSL/onos.jks -Djavax.net.ssl.trustStorePassword=111111"

若要使ONOS每次开启时都进入SSL模式,可以将这个命令写入.profile之类的文件。

这样,ONOS端的SSL就配置完成了。

二、进行测试

使用onos-karaf clean开启ONOS端的ONOS系统,启动后在ONOS的日志里会看到以下记录,说明ONOS已经进入了SSL模式。

1
2016-10-16 13:53:14,926 | INFO  | -message-handler | Controller                       | 162 - org.onosproject.onos-of-ctl - 1.7.0.SNAPSHOT | OpenFlow Security is enabled

在OVS端启动OVS服务,新建一个网桥并使用SSL方式链接到ONOS控制器:

1
2
$ sudo ovs-vsctl add-br b1
$ sudo ovs-vsctl set-controller b1 ssl:192.168.194.133:6653

这时在ONOS端使用devices命令,会发现OVS已经成功连接到了ONOS控制器:

1
2
onos> devices
id=of:00001a633cb35b4f, available=true, role=MASTER, type=SWITCH, mfr=Nicira, Inc., hw=Open vSwitch, sw=2.6.0, serial=None, driver=ovs, channelId=192.168.194.131:51524, managementAddress=192.168.194.131, protocol=OF_13

也可以使用mininet连接控制器,需要注意只有为每个交换机正确打开SSL连接后才能连接成功。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ sudo mn --topo linear,3 --controller remote
*** Creating network
*** Adding controller
Unable to contact the remote controller at 127.0.0.1:6653
Unable to contact the remote controller at 127.0.0.1:6633
Setting remote controller to 127.0.0.1:6653
*** Adding hosts:
h1 h2 h3
*** Adding switches:
s1 s2 s3
*** Adding links:
(h1, s1) (h2, s2) (h3, s3) (s2, s1) (s3, s2)
*** Configuring hosts
h1 h2 h3
*** Starting controller
c0
*** Starting 3 switches
s1 s2 s3 ...
*** Starting CLI:
mininet> sh ovs-vsctl set-controller s1 ssl:192.168.194.133:6653
mininet> sh ovs-vsctl set-controller s2 ssl:192.168.194.133:6653
mininet> sh ovs-vsctl set-controller s3 ssl:192.168.194.133:6653

大家可以在此基础上做一些实验,如试一试在两端证书不匹配的情况下进行连接会发生什么,以此来验证SSL连接的安全性。也可以进行抓包分析,来验证SSL的加密传输特性。

本文链接:http://www.sdnlab.com/17969.html