linux服务器上openvpn服务器性能加速计划[2012] 回首页
目标:在千M网卡上,openvpn服务器使用aes-256-cbc算法,优化其性能至900M/秒。
PS:这样标的的一台专业加密通讯的网关设备通常30万一台。
选择一台服务器主板加若干Intel千兆网卡来做这件事,成本仅1~2万
尝试开发进展:
1.硬件环境准备
我的MAC air的CPU型号是i5-2557m,带有intel AES-Ni指令集。
具体验证如下:
在linux虚拟机中
通过cat /proc/cpuinfo | grep aes
发现处理器支持aes,而且这个指令集被带入到linux虚拟机中。
如果要买新的服务器做开发用,mac mini(2013)是个不错的选择:支持到16G内存,耗能平均11W,Ivy Bridge处理器,两颗1T硬盘,OS X lion服务版。
http://www.apple.com.cn/mac-mini/server/
http://www.apple.com/mac-mini/server/
2.linux内核
检查模块是否加载:
$ /sbin/modinfo aesni_intel
filename: /lib/modules/3.2.11-merry/kernel/arch/x86/crypto/aesni-intel.ko
alias: aes
license: GPL
description: Rijndael (AES) Cipher Algorithm, Intel AES-NI instructions optimized
depends: cryptd,aes-x86_64
vermagic: 3.2.11-merry SMP mod_unload modversions
检查加密方法是否支持:
$ grep module /proc/crypto | sort -u
module : aesni_intel
module : aes_x86_64
module : arc4
module : kernel
3.openssl
检查openssl是否支持该方法:
$ openssl engine
(aesni) Intel AES-NI engine
(dynamic) Dynamic engine loading support
---------------------------------------------------------------------------------
方法讨论:
一、openvpn官方以及网上,对openvpn加速和性能调优的方法有下面几种:
====
1.调整NIC的MTU
2.openssl和Intel® AES-NI相结合。
3.SSL硬件加速
二、基于openvpn的局限性:
====
1.openvpn只能用到CPU单核,其它CPU核心空闲
2.openvpn是单进程,受载能力有限
有人在源码上做了二次开发:
1.改进tun设备驱动,使多个openvpn服务/进程捆绑于一个tun设备上。
2.使用openvpn的tap方式,并将多个tap和一个ethernet桥接
3.将多个openvpn服务绑在不同的CPU核心,并为之做一个负载均衡前端。
三、我的方案:
====
1.建立单核CPU的虚拟机,在其中将openvpn服务调至最优,并统计资源。
2.建立多个上述虚拟机,基于同一个只读盘启动,加载不同的网络配置,并分配不同的CPU,共享宿主机上证书和客户端配置。
(但是这个方案似乎用不上硬件加速卡和一些CPU指令集)
---------------------------------------------------------------------------------
参考文献和引用地址:
(1).修改openvpn相关:
====
摘要>>><<<隐藏
1.动手写一个OpenVPN的wrapper来优化OpenVPN性能
http://blog.csdn.net/dog250/article/details/7294234
简单的多进程OpenVPN前端控制程序
http://blog.csdn.net/dog250/article/details/8045209
桥接多进程OpenVPN虚拟网卡解决多处理问题
http://blog.csdn.net/dog250/article/details/8045217
2.OpenVPN性能-多OpenVPN共享一个虚拟网卡
http://blog.csdn.net/dog250/article/details/6938412
3.OpenVPN性能-OpenVPN的第一个瓶颈在tun驱动
http://blog.csdn.net/dog250/article/details/6300347
4.OpenVPN性能-OpenVPN的第二个瓶颈在ssl加解密
http://blog.csdn.net/dog250/article/details/6300348
5.返璞归真的OpenVPN的p2p模式
http://blog.csdn.net/dog250/article/details/7484119
6.关于OpenVPN文章的目录
http://blog.csdn.net/dog250/article/details/6990814
(2).SSL加速相关:
====
1.
Intel® AES New Instructions (Intel® AES-NI)
http://www.intel.com/content/www/us/en/architecture-and-technology/advanced-encryption-standard--aes-/data-protection-aes-general-technology.html
Intel® AES-NI Performance Testing on Linux/Java Stack
http://software.intel.com/en-us/articles/intel-aes-ni-performance-testing-on-linuxjava-stack/
2.
Optimizing performance on gigabit networks
https://community.openvpn.net/openvpn/wiki/Gigabit_Networks_Linux
OpenVPNのスループットと最適化
http://yamatamemo.blogspot.com/2012/01/openvpn-1.html
Intel® Advanced Encryption Standard Instructions (AES-NI)
http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-instructions-aes-ni/
Intel AES-NI For Ubuntu Home Encryption
http://www.phoronix.com/scan.php?page=article&item=ubuntu_aesni_intel&num=1
摘要:
The performance improvement expected with the use of AES-NI would depend on the applications and how much of the application time is spent in encryption and decryption. At the algorithm level, using AES-NI can provide significant speedup of AES. For non-parallel modes of AES operation such as CBC-encrypt AES-NI can provide a 2-3 fold gain in performance over a completely software approach. For parallelizable modes such as CBC-decrypt and CTR, AES-NI can provide a 10x improvement over software solutions.
3.
OpenVPNのスループット
http://yamatamemo.blogspot.com/2011/05/openvpn.html 摘要>>><<<隐藏
詳細は上記サイトを参照していただくとして、要は「いい性能のPCを使ってGigabit上でOpenVPNをつないでみて、どこまでスループットを上げられるか実験してみよう!」ということです。OSはサーバー、クライアントともLinuxです。以下、結果を簡単にまとめるとこんな感じ(すべて計測値はiperfによるもので、プロトコルはUDPを使用しています)。
標準設定(MTUやFragmentなどをいじらない&CipherはBlowfish)のOpenVPNスループットで156Mbps。Cipherをaes-256-cbcに変更すると 126Mbps。今回のPCのスペックでは標準のままで100Mbpsは超えます。この速度で十分というケースもありそうですね。
OpenVPNでMTUの設定値を大きくし、フラグメントを無効にするとスループットが上昇する。たとえばMTUを9000にすると 370Mbps、24000では 466Mbps、48000では 510Mbps。この値が最大で、これ以上MTUを増やすと速度は低下していく。 Cipherをaes-256にすると、MTUとスループットの相関性は低くなる(MTUを上げてもちょっとしかスループットが上がらない)。こんな大きいMTU設定したことない…。
AES-NIを使用すると速度がかなり向上する(当然、CipherをAESにしないと効果はありません)。たとえば、AES256でAES-NIを使用すると、MTUが9000なら 249Mbps→410Mbps に、24000なら 259Mbps→540Mbps に、48000では 247Mbps→585Mbps に上がります。これは相当なパワーアップですね。
OpenVPNの暗号化と署名を無効にした場合、 930Mbps というスループットに。Gigabitの範囲であればユーザー空間とカーネル空間の分離はパフォーマンスにそれほど影響せず(この結果によれば7%程度)、やはりOpenSSLによる暗号化と署名の処理がスループットに大きく影響することがわかる。
結論として、MTUサイズを大きくして、フラグメントを無効にすればスループットは大きく向上する、とのこと。ただし、当たり前ですが、MTUの設定値にネットワークの品質は密接に関わっていますので、ネットワーク構成に応じて設定する必要がありますね。
4.程序中如何启用openssl的AES-NI ?
http://www.udpwork.com/item/7855.html 摘要>>><<<隐藏
昨天我贴了一个测试报告,openssl在启用了AES-NI后,做AES加解密的时候,效率有8-9倍的提升。但是当我自己写了一个程序去测试的时候,结果却并非如此。
首先,openssl有两套接口,一套EVP的(与具体算法无关),一套较低level的,针对特定算法的。
EVP的例子如下:
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
ENGINE_load_builtin_engines();
ENGINE* engine=ENGINE_by_id("aesni");
if(engine==NULL){
printf("aesni not found\n");
}
EVP_EncryptInit_ex(&ctx,EVP_aes_128_cbc(),engine,test_key_128,test_init_vector);
int out;
EVP_CipherUpdate(&ctx,output,&out, test_plain_text, inputlen);
需要特别说明的是:在openssl 1.0.0中,新添了一个叫做aesni的engine,只有当你指定了使用这个engine的时候,才会使用CPU的AES指令。但是到了openssl 1.0.1
之后,这个engine被去除掉了,变成运行期自动监测是否使用AESNI。1.0.1版本中EVP_aes_128_cbc()这个函数的实现如下:
extern unsigned int OPENSSL_ia32cap_P[2];
#define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32)))
const EVP_CIPHER *EVP_aes_128_cbc(void) { return AESNI_CAPABLE?&aesni_128_cbc:&aes_128_cbc; }
除了EVP,还有一套低级接口如下:
int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, const int enc);
这些函数都是没有文档没有注释的。与这3个函数类似的,还有一套aesni_set_encrypt_key、aesni_set_decrypt_key、aesni_cbc_encrypt函数。但是这几个函数并
不在安装后的头文件中。但是没有关系,可以自己声明一下然后用:
extern "C"{
int aesni_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
int aesni_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, const int enc);
}
然后我这还有一个函数,用来监测CPU是否支持AES-Ni:
#ifndef __linux__
#include
#else
static void __cpuid(unsigned int where[4], unsigned int leaf) {
asm volatile("cpuid":"=a"(*where),"=b"(*(where+1)), "=c"(*(where+2)),"=d"(*(where+3)):"a"(leaf));
return;
}
#endif
#define AES_INSTRCTIONS_CPUID_BIT (1<<25)
bool check_for_aes_instructions()
{
#ifdef __linux__
unsigned int cpuid_results[4];
#else
int cpuid_results[4];
#endif
__cpuid(cpuid_results,0);
if (cpuid_results[0] < 1)
return false;
/*
* MSB LSB
* EBX = 'u' 'n' 'e' 'G'
* EDX = 'I' 'e' 'n' 'i'
* ECX = 'l' 'e' 't' 'n'
*/
if (memcmp((unsigned char *)&cpuid_results[1], "Genu", 4) != 0 ||
memcmp((unsigned char *)&cpuid_results[3], "ineI", 4) != 0 ||
memcmp((unsigned char *)&cpuid_results[2], "ntel", 4) != 0)
return false;
__cpuid(cpuid_results,1);
if (cpuid_results[2] & AES_INSTRCTIONS_CPUID_BIT)
return true;
return false;
}
6.nCipher SSL 卸载卡 (nCipher nfast ultra BN1200 ssl offload card)
http://net.yesky.com/193/2455193.shtml
http://baike.baidu.com/link?url=BgJa2GPcTqwV4woXnlyoXIpXE0K5m2BRvKS_dmrew9BPhys9zNyT3IwxEwV3fQVEqfBJ-4yXkOXsJX_D2hAP_a
7.在PowerEdge 服务器上使用SSL加速适配器
http://www1.ap.dell.com/content/topics/topic.aspx/ap/topics/power/zhcn/ps4q01_broadcom?c=cn&l=zh&cs=cnlca1
8.深信服应用交付助服务器实现SSL压力卸载
http://news.zol.com.cn/303/3034868.html
(3).其它参考:
====
openssl速度测试
openssl speed -evp aes-128-cbc
openssl speed -evp aes-256-cbc