All posts by dotte

如何生成每秒百万级别的 HTTP 请求?

  • 第一篇:《如何生成每秒百万级别的 HTTP 请求?》
  • 第二篇:《为最佳性能调优 Nginx》
  • 第三篇:《用 LVS 搭建一个负载均衡集群》

 


本文是构建能够每秒处理 3 百万请求的高性能 Web 集群系列文章的第一篇。它记录了我使用负载生成器工具的一些经历,希望它能帮助每一个像我一样不得不使用这些工具的人节省时间。

负载生成器是一些生成用于测试的流量的程序。它们可以向你展示服务器在高负载的情况下的性能,以及让你能够找出服务器可能存在的问题。通过负载测试了解服务器的缺点,是测试服务器弹性以及未雨绸缪的好方法。

负载生成工具(Load-Generating Tools)

在进行负责测试时要牢记一件重要的事:你能在 Linux 上建立多少个 socket 连接。这个限制是硬编码在内核里的,最典型的就是临时 W 端口的限制。(在某种程度上)你可以在 /etc/sysctl.conf 里扩展它。但是基本上,一台 Linux 机器只能同时打开大约 64,000 个 socket 。因此在负载测试时,我们不得不通过在单一的连接上尽可能多地发出请求来充分利用 socket 。 除此之外,我们还需要不止一台的机器来产生负载。否则,负载生成器会把可用的 socket 占用导致不能产生足够的负载。

我一开始用的是‘ab’,Apache Bench 。它是我所知道的 http 基准测试工具中最简单、最通用的。并且它是 Apache 附带的产品,因此它可能已经存在于你的系统中。不幸的是,我在使用它的时候每秒大约只能生成 900 个请求。虽然我见过其他人使用它每秒能达到 2,000 个请求,但我可以立即告诉你,‘ab’并不适合我们的基准测试。

Httperf

接着,我尝试了 ‘httperf’。这个工具更强大,但是它依然相对简单并且功能有限。要算出每秒生产了多少个请求并不是仅传递参数那么简单。经过我的多次尝试,获取了每秒超过几百请求的结果。例如:

它以每秒 1,000 个的速率创建了 100,000 个会话(session)。每次会话发起 5 次请求,时间间隔为 2 秒。

httperf --hog --server=192.168.122.10 --wsess=100000,5,2 --rate 1000 --timeout 5
Total: connections 117557 requests 219121 replies 116697 test-duration 111.423 s

Connection rate: 1055.0 conn/s (0.9 ms/conn, <=1022 concurrent connections)
Connection time [ms]: min 0.3 avg 865.9 max 7912.5 median 459.5 stddev 993.1
Connection time [ms]: connect 31.1
Connection length [replies/conn]: 1.000

Request rate: 1966.6 req/s (0.5 ms/req)
Request size [B]: 91.0

Reply rate [replies/s]: min 59.4 avg 1060.3 max 1639.7 stddev 475.2 (22 samples)
Reply time [ms]: response 56.3 transfer 0.0
Reply size [B]: header 267.0 content 18.0 footer 0.0 (total 285.0)
Reply status: 1xx=0 2xx=116697 3xx=0 4xx=0 5xx=0

CPU time [s]: user 9.68 system 101.72 (user 8.7% system 91.3% total 100.0%)
Net I/O: 467.5 KB/s (3.8*10^6 bps)

最终,我使用这些设置达到了每秒 6,622 个连接:

httperf --hog --server 192.168.122.10 --num-conn 100000 --ra 20000 --timeout 5

(总共创建了 100,000 个连接,并且以每秒 20,000 个连接的固定速率创建)

它还有一些潜在的优势,并且拥有比‘ab‘更多的特性。但它不是我要用在这个项目里的重量级工具。我需要的是能够支持分布式多负载测试节点的工具。因此,我的下一个尝试是:Jmeter。

Apache Jmeter

这是一个功能齐全的 web 应用测试套件,它可以模拟真实用户的所有行为。你可以使用 Jmeter 的代理去访问你的网站,进行点击、登陆、模仿用户可以做的所有行为。Jemeter 会把这些行为记录下来作为测试用例。然后 Jmeter 会反复执行这些动作来模拟你想要的用户数量。尽管配置 Jmeter 比 ‘ab‘ 和 ’httperf‘ 复杂得多,但它是一个很有趣的工具!

根据我的测试,它每秒可以产生 14,000 个请求!这绝对是一个好的进展。

我使用了 Googlle Code project 上的一些插件,并且使用它们的“Stepping Threads”和“HTTP RAW”请求,最终每秒大约可以产生 30,000 个请求!但这已经达到极限了,所以还要寻找另一个工具。这里有一个我之前的 Jmeter 配置,希望可以帮助到其他人。虽然这个配置离完美相差甚远,但有时它可以满足你的要求。

Tsung: 重型的(heavy-duty)、分布式的、多协议测试工具

它每秒基本可以产生 40,000 个请求,这绝对是我们想要的工具。类似于 Jmeter,你可以把一些行为记录下来在测试时运行,并且可以测试大多数的协议。比如 SSL、HHTP、WebDAV、SOAP、PostgreSQL、MySQL、LDAP 和 Jabber/XMPP。与 Jmeter 不同的是,它没有让人感到迷茫的 GUI 设置,它仅有一个 XML 配置文件,和一些你选择的分布式节点的 SSH 密钥。它的简洁和效率对我的吸引力,完全不亚于它的健壮性和可扩展性。我发现它是一个很强大的工具,在正确的配置下它可以每秒产生百万级的 HTTP 请求。

除此之外,Tsung 还可以在 html 上产生图表以及输入你的测试的详细报告。测试的结果通俗易懂,并且你甚至可以把这些图片展示给你的 boss 看!

在这个系列文章的剩余部分,我还会讲解这个工具。现在你可以继续浏览下面的配置说明,或者直接跳到下一页。

在 CentOS 6.2 上安装 Tsung

首先,你要安装(Erlang 需要的) EPEL 源。因此,在进行下一步之前要把它安装好。安装完后,继续安装你用来产生负载的每个节点需要的包。如果你还没有在节点之间建立无密码 SSH 密钥(passwordless SSH key),那么请建立之。

 yum -y install erlang perl perl-RRD-Simple.noarch perl-Log-Log4perl-RRDs.noarch gnuplot perl-Template-Toolkit firefox

从 Github 或者 Tsung 的官网上下载最新的 Tsung。

 wget http://tsung.erlang-projects.org/dist/tsung-1.4.2.tar.gz

解压并且编译。

tar zxfv  tsung-1.4.2.tar.gz
cd tsung-1.4.2
./configure && make && make install

把示例配置复制到 ~/.tsung 目录里。这是 Tsung 的配置文件和日志文件的存放地方。

cp  /usr/share/doc/tsung/examples/http_simple.xml /root/.tsung/tsung.xml

你可以根据你的需求去编辑这个配置文件,或者使用我的配置文件。经过大量的尝试以及失败后,我目前的配置文件在使用 7 个分布式节点时可以每秒产生 5 百万个 HTTP 请求。

<?xml version="1.0"?>
<!DOCTYPE tsung SYSTEM "/usr/share/tsung/tsung-1.0.dtd">
<tsung loglevel="notice" version="1.0">

<clients>
<client host="localhost" weight="1" cpu="10" maxusers="40000">
<ip value="192.168.122.2"/>
</client>
<client host="loadnode1" weight="1" cpu="9" maxusers="40000">
<ip value="192.168.122.2"/>
</client>
<client host="loadnode2" weight="1" maxusers="40000" cpu="8">
<ip value="192.168.122.3"/>
</client>
<client host="loadnode3" weight="1" maxusers="40000" cpu="9">
<ip value="192.168.122.21"/>
</client>
<client host="loadnode4" weight="1" maxusers="40000" cpu="9">
<ip value="192.168.122.11"/>
</client>
<client host="loadnode5" weight="1" maxusers="40000" cpu="9">
<ip value="192.168.122.12"/>
</client>
<client host="loadnode6" weight="1" maxusers="40000" cpu="9">
<ip value="192.168.122.13"/>
</client>
<client host="loadnode7" weight="1" maxusers="40000" cpu="9">
<ip value="192.168.122.14"/>
</client>
</clients>

<servers>
<server host="192.168.122.10" port="80" type="tcp"/>
</servers>

<load>
<arrivalphase phase="1" duration="10" unit="minute">
<users maxnumber="15000" arrivalrate="8" unit="second"/>
</arrivalphase>

<arrivalphase phase="2" duration="10" unit="minute">
<users maxnumber="15000" arrivalrate="8" unit="second"/>
</arrivalphase>

<arrivalphase phase="3" duration="30" unit="minute">
<users maxnumber="20000" arrivalrate="3" unit="second"/>
</arrivalphase>

</load>

<sessions>
<session probability="100" name="ab" type="ts_http">
<for from="1" to="10000000" var="i">
<request> <http url="/test.txt" method="GET" version="1.1"/> </request>
</for>
</session>
</sessions>
</tsung>

刚开始的时候有很多东西要理解,但你一旦理解了它们后就会变得很简单。

  • <client> 只是简单地指定了运行 Tsung 的主机。你可以指定 Tsung 使用的 IP 和 CPU 的最大数。你可以使用 maxusers 设置节点能够模拟的用户数量上限。每一个用户都会执行我们之后定义的操作。
  • <servers> 指定了你要测试的 HTTP 服务器。我们可以使用这个选项去测试一个 IP 集群,或者一个单一的服务器。
  • <load> 定义了我们的模拟用户将会在什么时候“到达”我们的网站。以及它们达到的有多快。
    •  <arrivalphase> 在持续了 10 分钟的第一个阶段里,以 每秒 8 个用户的速率到达了 15,000 个用户。
    • <arrivalphase phase=”1″ duration=”10″ unit=”minute”>
    • <users maxnumber=”15000″ arrivalrate=”8″ unit=”second”/>
    •  这里还有两个 arrivalphases,它们的用户都以同样的方式达到。
    •  这些 arrivalphases 一起组成了一个 <load>,它控制了我们可以每秒产生多少个请求。
  • <session> 这部分定义了一旦这些用户达到了你的网站,它们将会执行什么动作。
  • probability 允许你定义用户可能会做的随机事件。有时他们可能点击这里,有时他们可能点击那里。所有的Probability 加起来一定要等于 100% 。
  • 在上面的配置里,用户只做一件事,所以它的 probability 等于 100% 。
  • <for from=”1″ to=”10000000″ var=”i”> 这就是用户在 100% 的时间里做的事情。它们循环遍历 10,000,000 次并且 <request> 一个网页:/test.txt 。
  • 这个循环结构允许我们使用少量的用户连接去获取比较大的每秒请求数量。

一旦你已经很好地理解了它们,你就可以创建一个便利的别名,去快速观察 Tsung 报告。

vim ~/.bashrc
alias treport="/usr/lib/tsung/bin/tsung_stats.pl; firefox report.html"
source ~/.bashrc

然后启动 Tsung

[root@loadnode1 ~] tsung start
Starting Tsung
"Log directory is: /root/.tsung/log/20120421-1004"

结束后观察报告

cd /root/.tsung/log/20120421-1004
treport

使用 Tsung 去规划你的集群构造

现在我们拥有了一个足够强大的负载测试工具,我们可以规划余下的集群构造了:

1. 使用 Tsung 去测试一个单一的 HTTP 服务器。获取一个基本的基准。

2. 对 web 服务器进行调优,定期使用 Tsung 进行测试提高性能。

3. 对这些系统的 TCP 套接字进行调优,获取最佳的网络性能。再来一次,测试,测试,不停地测试。

4. 构造 LVS 集群,它包含了这些充分调优过的 web 服务器。

5. 使用 Tsung IP 集群对 LVS 进行压力测试。

在之后的两篇文章里,我将会向你展示如何使你的 web 服务器获取最高性能,以及怎样用 LVS 集群软件把它们整合起来。

from:http://www.techug.com/http-rank

压力测试工具Tsung安装和使用 http://blog.csdn.net/jimesum1/article/details/7847924

Java Spring open source project

1、spring-projects
https://github.com/spring-projects

2、PetClinic
https://github.com/spring-projects/spring-petclinic
http://docs.spring.io/docs/petclinic.html

3、spring mvc示例代码
https://github.com/spring-projects/spring-mvc-showcase

4、Spring Security Reference
http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/

5、JeeSite

https://github.com/thinkgem/jeesite

JeeSite 是一个企业信息化开发基础平台,Java企业应用开源框架,Java EE(J2EE)快速开发框架,使用经典技术组合(Spring、Spring MVC、Apache Shiro、MyBatis、Bootstrap UI),包括核心模块如:组织机构、角色用户、权限授权、数据权限、内容管理、工作流等。 http://jeesite.com

技术栈:

1、后端

  • 核心框架:Spring Framework 4.0
  • 安全框架:Apache Shiro 1.2
  • 视图框架:Spring MVC 4.0
  • 服务端验证:Hibernate Validator 5.1
  • 布局框架:SiteMesh 2.4
  • 工作流引擎:Activiti 5.15、FoxBPM 6
  • 任务调度:Spring Task 4.0
  • 持久层框架:MyBatis 3.2
  • 数据库连接池:Alibaba Druid 1.0
  • 缓存框架:Ehcache 2.6、Redis
  • 日志管理:SLF4J 1.7、Log4j
  • 工具类:Apache Commons、Jackson 2.2、Xstream 1.4、Dozer 5.3、POI 3.9

2、前端

  • JS框架:jQuery 1.9。
  • CSS框架:Twitter Bootstrap 2.3.1。
  • 客户端验证:JQuery Validation Plugin 1.11。
  • 富文本:CKEcitor
  • 文件管理:CKFinder
  • 动态页签:Jerichotab
  • 手机端框架:Jingle
  • 数据表格:jqGrid
  • 对话框:jQuery jBox
  • 下拉选择框:jQuery Select2
  • 树结构控件:jQuery zTree
  • 日期控件: My97DatePicker

4、平台

  • 服务器中间件:在Java EE 5规范(Servlet 2.5、JSP 2.1)下开发,支持应用服务器中间件 有Tomcat 6、Jboss 7、WebLogic 10、WebSphere 8。
  • 数据库支持:目前仅提供MySql和Oracle数据库的支持,但不限于数据库,平台留有其它数据库支持接口, 可方便更改为其它数据库,如:SqlServer 2008、MySql 5.5、H2等
  • 开发环境:Java EE、Eclipse、Maven、Git

6、SpringBlog
https://github.com/Raysmond/SpringBlog
•Spring Boot and many of Spring familiy (e.g. Spring MVC, Spring JPA, Spring Secruity and etc)
•Hibernate + MySQL
•HikariCP – A solid high-performance JDBC connection pool
•Bootstrap – A very popular and responsive front-end framework
•Pegdown – A pure-java markdown processor
•ACE Editor – A high performance code editor which I use to write posts and code.
•Pygments – A python library for highlighting code syntax
•Jade4j – Jade is an elegant template language.
•Webjars – A client-side web libraries packaged into JAR files. A easy way to manage JavaScript and CSS vendors in Gradle.
•Redis – A very powerful in-memory data cache server.

7、expper
https://github.com/Raysmond/expper
•Java 8+
•Spring Boot 1.3.0.RELEASE
•PostgreSQL 9.4+
•Jhipster 2.24.0
•Redis 3.0+
•RabbitMQ 3.5.6+
•ElasticSearch
•Node.js

 

 

Refer:http://stackoverflow.com/questions/2604655/any-open-source-spring-sample-project-thats-bigger-than-petclinic

http://www.programcreek.com/2012/08/open-source-projects-that-use-spring-framework/

SSL/TLS协议运行机制的概述

互联网的通信安全,建立在SSL/TLS协议之上。

本文简要介绍SSL/TLS协议的运行机制。文章的重点是设计思想和运行过程,不涉及具体的实现细节。如果想了解这方面的内容,请参阅RFC文档

bg2014020501

一、作用

不使用SSL/TLS的HTTP通信,就是不加密的通信。所有信息明文传播,带来了三大风险。

(1) 窃听风险(eavesdropping):第三方可以获知通信内容。

(2) 篡改风险(tampering):第三方可以修改通信内容。

(3) 冒充风险(pretending):第三方可以冒充他人身份参与通信。

SSL/TLS协议是为了解决这三大风险而设计的,希望达到:

(1) 所有信息都是加密传播,第三方无法窃听。

(2) 具有校验机制,一旦被篡改,通信双方会立刻发现。

(3) 配备身份证书,防止身份被冒充。

互联网是开放环境,通信双方都是未知身份,这为协议的设计带来了很大的难度。而且,协议还必须能够经受所有匪夷所思的攻击,这使得SSL/TLS协议变得异常复杂。

二、历史

互联网加密通信协议的历史,几乎与互联网一样长。

1994年,NetScape公司设计了SSL协议(Secure Sockets Layer)的1.0版,但是未发布。

1995年,NetScape公司发布SSL 2.0版,很快发现有严重漏洞。

1996年,SSL 3.0版问世,得到大规模应用。

1999年,互联网标准化组织ISOC接替NetScape公司,发布了SSL的升级版TLS 1.0版。

2006年和2008年,TLS进行了两次升级,分别为TLS 1.1版和TLS 1.2版。最新的变动是2011年TLS 1.2的修订版

目前,应用最广泛的是TLS 1.0,接下来是SSL 3.0。但是,主流浏览器都已经实现了TLS 1.2的支持。

TLS 1.0通常被标示为SSL 3.1,TLS 1.1为SSL 3.2,TLS 1.2为SSL 3.3。

三、基本的运行过程

SSL/TLS协议的基本思路是采用公钥加密法,也就是说,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。

但是,这里有两个问题。

(1)如何保证公钥不被篡改?

解决方法:将公钥放在数字证书中。只要证书是可信的,公钥就是可信的。

(2)公钥加密计算量太大,如何减少耗用的时间?

解决方法:每一次对话(session),客户端和服务器端都生成一个”对话密钥”(session key),用它来加密信息。由于”对话密钥”是对称加密,所以运算速度非常快,而服务器公钥只用于加密”对话密钥”本身,这样就减少了加密运算的消耗时间。

因此,SSL/TLS协议的基本过程是这样的:

(1) 客户端向服务器端索要并验证公钥。

(2) 双方协商生成”对话密钥”。

(3) 双方采用”对话密钥”进行加密通信。

上面过程的前两步,又称为”握手阶段”(handshake)。

四、握手阶段的详细过程

bg2014020502

“握手阶段”涉及四次通信,我们一个个来看。需要注意的是,”握手阶段”的所有通信都是明文的。

4.1 客户端发出请求(ClientHello)

首先,客户端(通常是浏览器)先向服务器发出加密通信的请求,这被叫做ClientHello请求。

在这一步,客户端主要向服务器提供以下信息。

(1) 支持的协议版本,比如TLS 1.0版。

(2) 一个客户端生成的随机数,稍后用于生成”对话密钥”。

(3) 支持的加密方法,比如RSA公钥加密。

(4) 支持的压缩方法。

这里需要注意的是,客户端发送的信息之中不包括服务器的域名。也就是说,理论上服务器只能包含一个网站,否则会分不清应该向客户端提供哪一个网站的数字证书。这就是为什么通常一台服务器只能有一张数字证书的原因。

对于虚拟主机的用户来说,这当然很不方便。2006年,TLS协议加入了一个Server Name Indication扩展,允许客户端向服务器提供它所请求的域名。

4.2 服务器回应(SeverHello)

服务器收到客户端请求后,向客户端发出回应,这叫做SeverHello。服务器的回应包含以下内容。

(1) 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。

(2) 一个服务器生成的随机数,稍后用于生成”对话密钥”。

(3) 确认使用的加密方法,比如RSA公钥加密。

(4) 服务器证书。

除了上面这些信息,如果服务器需要确认客户端的身份,就会再包含一项请求,要求客户端提供”客户端证书”。比如,金融机构往往只允许认证客户连入自己的网络,就会向正式客户提供USB密钥,里面就包含了一张客户端证书。

4.3 客户端回应

客户端收到服务器回应以后,首先验证服务器证书。如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。

如果证书没有问题,客户端就会从证书中取出服务器的公钥。然后,向服务器发送下面三项信息。

(1) 一个随机数。该随机数用服务器公钥加密,防止被窃听。

(2) 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。

(3) 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验。

上面第一项的随机数,是整个握手阶段出现的第三个随机数,又称”pre-master key”。有了它以后,客户端和服务器就同时有了三个随机数,接着双方就用事先商定的加密方法,各自生成本次会话所用的同一把”会话密钥”。

至于为什么一定要用三个随机数,来生成”会话密钥”,dog250解释得很好:

“不管是客户端还是服务器,都需要随机数,这样生成的密钥才不会每次都一样。由于SSL协议中证书是静态的,因此十分有必要引入一种随机因素来保证协商出来的密钥的随机性。

对于RSA密钥交换算法来说,pre-master-key本身就是一个随机数,再加上hello消息中的随机,三个随机数通过一个密钥导出器最终导出一个对称密钥。

pre master的存在在于SSL协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么pre master secret就有可能被猜出来,那么仅适用pre master secret作为密钥就不合适了,因此必须引入新的随机因素,那么客户端和服务器加上pre master secret三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能完全不随机,可是是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的 可不是一。”

此外,如果前一步,服务器要求客户端证书,客户端会在这一步发送证书及相关信息。

4.4 服务器的最后回应

服务器收到客户端的第三个随机数pre-master key之后,计算生成本次会话所用的”会话密钥”。然后,向客户端最后发送下面信息。

(1)编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。

(2)服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。

至此,整个握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的HTTP协议,只不过用”会话密钥”加密内容。

bg2014020503

五、参考链接

from:http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html

密钥数字签名和证书

原文网址:http://www.youdzone.com/signature.html

1.

鲍勃有两把钥匙,一把是公钥,另一把是私钥。

2.

鲍勃把公钥送给他的朋友们—-帕蒂、道格、苏珊—-每人一把。

3.

苏珊要给鲍勃写一封保密的信。她写完后用鲍勃的公钥加密,就可以达到保密的效果。

4.

鲍勃收信后,用私钥解密,就看到了信件内容。这里要强调的是,只要鲍勃的私钥不泄露,这封信就是安全的,即使落在别人手里,也无法解密。

5.

鲍勃给苏珊回信,决定采用”数字签名”。他写完后先用Hash函数,生成信件的摘要(digest)。

6.

然后,鲍勃使用私钥,对这个摘要加密,生成”数字签名”(signature)。

7.

鲍勃将这个签名,附在信件下面,一起发给苏珊。

8.

苏珊收信后,取下数字签名,用鲍勃的公钥解密,得到信件的摘要。由此证明,这封信确实是鲍勃发出的。

9.

苏珊再对信件本身使用Hash函数,将得到的结果,与上一步得到的摘要进行对比。如果两者一致,就证明这封信未被修改过。

10.

复杂的情况出现了。道格想欺骗苏珊,他偷偷使用了苏珊的电脑,用自己的公钥换走了鲍勃的公钥。此时,苏珊实际拥有的是道格的公钥,但是还以为这是鲍勃的公钥。因此,道格就可以冒充鲍勃,用自己的私钥做成”数字签名”,写信给苏珊,让苏珊用假的鲍勃公钥进行解密。

11.

后来,苏珊感觉不对劲,发现自己无法确定公钥是否真的属于鲍勃。她想到了一个办法,要求鲍勃去找”证书中心”(certificate authority,简称CA),为公钥做认证。证书中心用自己的私钥,对鲍勃的公钥和一些相关信息一起加密,生成”数字证书”(Digital Certificate)。

12.

鲍勃拿到数字证书以后,就可以放心了。以后再给苏珊写信,只要在签名的同时,再附上数字证书就行了。

13.

苏珊收信后,用CA的公钥解开数字证书,就可以拿到鲍勃真实的公钥了,然后就能证明”数字签名”是否真的是鲍勃签的。

14.

下面,我们看一个应用”数字证书”的实例:https协议。这个协议主要用于网页加密。

15.

首先,客户端向服务器发出加密请求。

16.

服务器用自己的私钥加密网页以后,连同本身的数字证书,一起发送给客户端。

17.

客户端(浏览器)的”证书管理器”,有”受信任的根证书颁发机构”列表。客户端会根据这张列表,查看解开数字证书的公钥是否在列表之内。

18.

如果数字证书记载的网址,与你正在浏览的网址不一致,就说明这张证书可能被冒用,浏览器会发出警告。

19.

如果这张数字证书不是由受信任的机构颁发的,浏览器会发出另一种警告。

20.

如果数字证书是可靠的,客户端就可以使用证书中的服务器公钥,对信息进行加密,然后与服务器交换加密信息。

from:http://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_signature.html

putty使用密钥登陆OpenSSH

在Windows管理Linux服务器时,常使用putty登陆ssh进行远程管理。默认登陆验证方式为密码认证,该方式虽然简单,但每次登陆都要输入一长串的密码,相当麻烦。而且,如果万一把root允许登陆打开,还有可能被强力破解,导致严重的后果。
所以,通常建议用密钥登陆验证代替密码方式,即简单,又可靠。
一、为什么建议使用密钥登陆
通常现在的Linux发行版都使用OpenSSH代替telnet、rsh等明文传输的终端服务。
以红旗 DC Server 5.0为例:

引用
# rpm -qa|grep -E -w ‘openssh’
openssh-clients-4.0p1-1.2AX
openssh-server-4.0p1-1.2AX
openssh-4.0p1-1.2AX

而OpenSSH默认是同时支持密码和密钥两种认证方式的。转一个说明:

为什么要使用公钥认证
通常,通过ssh登录远程服务器时,使用密码认证,分别输入用户名和密码,两者满足一定规则就可以登录。但是密码认证有以下的缺点:

引用
a)用户无法设置空密码(即使系统允许空密码,也会十分危险)
b)密码容易被人偷窥或猜到
c)服务器上的一个帐户若要给多人使用,则必须让所有使用者都知道密码,导致密码容易泄露,而且修改密码时必须通知所有人

而使用公钥认证则可以解决上述问题。

引用
a)公钥认证允许使用空密码,省去每次登录都需要输入密码的麻烦
b)多个使用者可以通过各自的密钥登录到系统上的同一个用户
c)即使修改了对应用户的密码,也不会影响登陆
d)若同时禁用密码认证,则只要保证私钥的安全,不会受到暴力破解的威胁

二、使用putty生成密钥和登陆
根据公钥认证的原理(见后面说明),认证双方任何一方都可制作该钥匙对,并且只要认证方有被认证方的公钥信息,即可匹配成功。
这里,我们先以Windows上的putty登陆Linux服务器为例说明。所以,该密钥对由putty制作。
继续前,请确保您已经把整个putty包都下载完:
官方网站:点击
最新版本:0.60,我截图的版本是0.55的。
本地下载:

其中包括:PuTTY、Puttygen、PSCP、Plink、Pagent 等工具。
1、使用puttygen制作密钥
启动puttygen工具,为兼容OpenSSH密钥,选择“SSH2 RSA”:
点击在新窗口中浏览此图片
单击 Generate 按钮,并使用鼠标在“key”框内移动,以获得足够的随机数据供生成密钥使用:
点击在新窗口中浏览此图片
※期间,你会看到进度条上面有个提示“Please generate some radomness by moving the mouse over the blank area.”,意思就是让你用鼠标在空白区域随机移动。随着鼠标在空白区域的移动,进度条会一直走下去。停止移动鼠标,进度条也就停止了。所以,那我们要移动鼠标,直到进度条走满为止。
完成后的窗口如下:
点击在新窗口中浏览此图片
其中:

引用
Key comment:是注释,不会影响密钥的有效性,但可作为自己用于区别其他密钥的参考;
Key passphrase 和 Confirm passphrase :用于保护私钥,如果不输入该信息,那么任何人只要拿到该私钥,即可无密码登陆系统,非常危险;通常情况下,我是建议大家输入的,但这里为了方便说明,暂时留空,请看后面使用的说明。

随后,点击“Save private key”保留私钥。
如果没有输入Key passphrase信息,会有警告:
点击在新窗口中浏览此图片
输入私钥的文件名:
点击在新窗口中浏览此图片
※公钥信息可以不用保留在本地的,puttygen可以从私钥得到它,验证时也不会用到。

2、修改openssh配置
修改/etc/ssh/sshd_config:

引用
ChallengeResponseAuthentication no  #关闭挑战应答方式
UsePAM no  #不使用PAM认证

然后重启sshd服务,原因见:这里

3、拷贝公钥信息
上面密钥信息窗口的“Key”框最后生成的就是公钥信息:
点击在新窗口中浏览此图片
需要把该信息拷贝到Linux服务器的特定文件中:~/.ssh/authorized_keys
其中,“~”表示对应用户的主目录,以root为例。
若.ssh目录不存在,请创建它,并把公钥信息写入文件中:

# mkdir ~/.ssh
# chmod 700 ~/.ssh
# vi ~/.ssh/authorized_keys
# chmod 644 ~/.ssh/authorized_keys

※请务必留意:文件和目录的权限问题,用户必须是将要进行认证的用户,而权限必须是0644,也就是禁止其他人对该文件写入信息。(否则,某些有心人把自己的公钥写入这里,他也可以无密码进来了)
因为,通常umask是0022或0002的,所以请使用chown和chmod修改为对应的权限咯。

4、使用putty使用密钥登陆
对putty进行一些简单配置,即可使用密钥登陆Linux服务器。
选择Connection-SSH-Auth,在“Private key file for authentication”输入密钥的路径:
点击在新窗口中浏览此图片
然后在Connection的“Auth-login username”输入登陆的用户名,例如root:
点击在新窗口中浏览此图片
◎Putty 0.60 版本在Connection-Data页内。
然后点击Open即可:
点击在新窗口中浏览此图片
若一切正常,则可以在session中Save保存配置。

三、使用OpenSSH生成密钥
密钥既可使用putty生成,也可用OpenSSH生成。
1、Linux下生成密钥
运行:

引用
# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):  <-密钥路径
Enter passphrase (empty for no passphrase): <-密钥保护密码
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa. <-私钥
Your public key has been saved in /root/.ssh/id_rsa.pub. <-公钥
The key fingerprint is:
17:28:4c:c3:e4:18:d4:c2:31:bd:be:a7:a9:d4:a8:48 root@mail.linuxfly.org

2、把公钥信息写入authorized_keys文件中
运行:

# cd ~/.ssh
# cat id_rsa.pub >> authorized_keys

3、生成putty的私钥
由于SSH的标准中,并没有固定密钥文件的格式。而Putty使用的私钥格式和OpenSSH生成的有点不同,需要转换一下。
a)把id_rsa传到Windows机器上
b)使用puttygen的“Load”读取id_rsa文件
点击在新窗口中浏览此图片
这里也可以从图中的公钥信息,与id_rsa.pub对比一下,应该是一致的。
c)点击“Save private key”保留私钥。
d)putty使用该新的私钥登陆服务器即可。
四、注意事项
1、检查OpenSSH服务端的配置

引用
OpenSSH的配置通常保存在:/etc/ssh/sshd_config
PermitRootLogin no  # 禁止root用户登陆
StrictModes yes  # 检查密钥的用户和权限是否正确,默认打开的
RSAAuthentication yes        # 启用 RSA 认证
AuthorizedKeysFile     .ssh/authorized_keys   # 验证公钥的存放路径
PubkeyAuthentication yes     # 启用公钥认证
PasswordAuthentication no    # 禁止密码认证,默认是打开的。

说明:
a)如果StrictModes为yes,而authorized_keys的权限为664等的情况,则验证密钥的时候,会报错:

引用
bad ownership or modes for file /home/linuxing/.ssh/authorized_keys

b)若PasswordAuthentication设置为no,则禁用密码认证,配合启动公钥认证,是更安全的方式。

2、公钥存放的路径
Putty作为客户端是不需要使用公钥的,而Linux服务端的公钥是存放在:~/.ssh/authorized_keys中。
也就是讲,如果登陆用户的主目录不同,存放的路径是不相同的。
例如某用户:

引用
$ echo ~
/home/linuxing
则密钥在:
/home/linuxing/.ssh/authorized_keys

若你想使用同一私钥,但不同用户登陆服务器,则请保证公钥信息已经写入每个用户的验证文件中咯。并且一定要注意验证文件的用户和权限不能搞错哦。

3、Key passphrase密码
如果你在保存私钥的时候,输入了Key passphrase密码。其就会使用该信息对私钥加密。这会带来一个好处:就是万一您的私钥给盗走了,但如果小偷不知道该密码,他也无法使用该私钥登陆服务器的。简单来说,就是加强了安全性。
a)在putty使用这种私钥登陆服务器的时候,就会有提示:
点击在新窗口中浏览此图片
只有输入正确的密码才能通过认证。
※这里看上去和使用密码认证方式登陆OpenSSH有点类似。但实际上是完全不同的。该
Key passphrase密码是用于管理私钥,避免私钥被盗用的;而OpenSSH的密码认证方式使用的密码,指的是Linux服务器端的用户密码,即PAM信息。也就是说,即使你修改了PAM的密码,但只要Key passphrase信息正确,你还是可以登陆到服务器上的。(因为使用它解压出来的私钥是没变的)

b)若每次登陆都要输入Key passphrase,明显达不到我们简化登陆步骤的目的。在既要保证安全,又要简便的情况下,我们可以使用PAGEANT。
PAGEANT的作用很简单,就是在我们输入一次私钥密码后,把解密后的私钥保存在PAGEANT中。
再次使用putty登陆的时候,PAGEANT就会自动的把解密后私钥用于认证,这样就不用我们多次输入密码了。而
当我们退出PAGEANT的时候,会自动删除私钥,重新登陆的时候需要再次检验。实现“一次验证,多次使用”的目的。
打开PAGEANT,其会自动放入Windows右下角的任务栏中:点击在新窗口中浏览此图片
右键点击后,选择“View Keys”:点击在新窗口中浏览此图片
在弹出框中,选择“Add Key”,输入Putty的私钥(.PPK),并会提示输入Key passphrase:
点击在新窗口中浏览此图片
结果:
点击在新窗口中浏览此图片
直接选择菜单的“Add Key”也可以。
这时候,使用putty再次登陆服务器就不需要Key passphrase啦。
点击在新窗口中浏览此图片
◎其实,即使没有Key passphrase的私钥也可以导入PAGEANT中的,这时候就可以不用在Putty的配置文件中指定私钥的路径咯。也可以达到一定的安全目的的。

c)若要修改Key passphrase,可以使用puttygen重新Load私钥,其会咨询Key passphrase信息:
点击在新窗口中浏览此图片
输入正确密码后,即可修改,并保存新私钥即可。是否存在或修改Key passphrase是不会改变公钥信息的。

4、保存putty的配置信息
putty的配置信息是保存在Windows注册表的,需使用下面的命令导出:

regedit /e PuTTY.config.reg “HKEY_CURRENT_USER\Software\SimonTatham\PuTTY”

5、使用DSA密钥
默认配置下,OpenSSH就同时支持RSA和DSA两种编码的密钥。只要在生成密钥的时候选择“DSA”即可。例如:

# ssh-keygen -t dsa

使用上和RSA是没有区别的,把公钥信息拷贝到验证文件中即可使用。

五、公钥认证的原理
所谓的公钥认证,实际上是使用一对加密字符串,一个称为公钥(public key),任何人都可以看到其内容,用于加密;另一个称为密钥(private key),只有拥有者才能看到,用于解密。通过公钥加密过的密文使用密钥可以轻松解密,但根据公钥来猜测密钥却十分困难。
ssh 的公钥认证就是使用了这一特性。服务器和客户端都各自拥有自己的公钥和密钥。为了说明方便,以下将使用这些符号。

引用
Ac 客户端公钥
Bc 客户端密钥
As 服务器公钥
Bs 服务器密钥

在认证之前,客户端需要通过某种安全的方法将公钥 Ac 登录到服务器上。
认证过程分为两个步骤:
1、会话密钥(session key)生成
客户端请求连接服务器,服务器将 As 发送给客户端。
服务器生成会话ID(session id),设为 p,发送给客户端。
客户端生成会话密钥(session key),设为 q,并计算 r = p xor q。
客户端将 r 用 As 进行加密,结果发送给服务器。
服务器用 Bs 进行解密,获得 r。
服务器进行 r xor p 的运算,获得 q。
至此服务器和客户端都知道了会话密钥q,以后的传输都将被 q 加密。
2、认证
服务器生成随机数 x,并用 Ac 加密后生成结果 S(x),发送给客户端
客户端使用 Bc 解密 S(x) 得到 x
客户端计算 q + x 的 md5 值 n(q+x),q为上一步得到的会话密钥
服务器计算 q + x 的 md5 值 m(q+x)
客户端将 n(q+x) 发送给服务器
服务器比较 m(q+x) 和 n(q+x),两者相同则认证成功

六、参考资料
一份非常详细的putty使用说明:http://docs.google.com/View?docid=ajbgz6fp3pjh_2dwwwwt
源地址打开很慢,我保存了一份:

http://blog.3gcomet.com/article.asp?id=215
http://blog.chinaunix.net/u/25686/showart_200821.html
http://tech.idv2.com/2006/10/21/ssh-rsa-auth/

原编辑文件备份:

下载文件
from:http://www.linuxfly.org/post/175/1/1/