linux系统gateway的配置

几个vps(虚拟主机),只有一个拥有公网ip地址,所有的vps都拥有内网ip地址。其它的vps需要通过拥有公网ip的这个vps进行公网访问,以方便yum安装软件等需求。

在没有公网ip的vps上需要进行的设置:

/etc/sysconfig/network-scripts/ifcfg-eth0 文件中: GATEWAY=10.x.x.x

service network restart

到此完成。

 

接下来是拥有公网ip的那台vps上进行设置:

echo “1” > /proc/sys/net/ipv4/ip_forward

注意,这条命令是临时开启系统的转发功能,系统重启后会恢复为默认设置。 可以通过在/etc/rc.d/rc.local中加入上述命令,使之在系统启动时被执行。

打开iptables的nat功能:

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

到此设置完成。

 

其它vps应该可以访问公网了。

(全文完)

HTTP协议学习笔记(二)性能考量

Http协议是基于TCP协议的,因此TCP协议的性能将直接影响HTTP通信的性能。 服务器端用于处理请求的时间不在我们讨论的范围之内,那么性能问题聚焦在以下方面:

  • 建立TCP连接的三次握手
  • TCP慢启动拥塞控制
  • Nagle算法
  • delayed-ack (延迟确认)
  • TIME-WAIT时延和端口耗尽。

建立tcp连接的三次握手

这个应该比较容易理解了。 TCP连接的建立需要经过3个网络传输的过程。详见这篇

TCP慢启动

TCP连接刚刚建立的时候,会限制数据发送的最大速度。如果数据发送成功,会逐渐提高数据传输速率。这一特性称之为TCP满启动,用于防止互联网上出现突然的过载和拥塞现象。如果某个HTTP事务有大量的数据要发送,那么在TCP连接刚刚建立的时候,是不能立即将所有的分组发送出去的。必须按照慢启动策略,先发一定数量的分组,得到ack响应之后才能继续发送。 在TCP慢启动的作用下,可以发送的分组的数量是逐渐调节增大的。这就导致了新建立的TCP连接的传输速度,比已经建立的,传输过一定数据的连接要慢一些。所以HTTP协议中存在重用现有连接的机制。

继续阅读“HTTP协议学习笔记(二)性能考量”

HTTP协议学习笔记(一)简介

最近在阅读《HTTP权威指南》这本书。 本文中的绝大部分内容均出自此书。
HTTP协议是基于TCP之上的。 HTTP报文分为请求报文和响应报文两种。 这两种报文格式相同,都由以下三部分组成:
起始行(start line)
首部(header)
正文(body)
其中start line是必须要有的,header部分通常也一定会有,但body部分是可以没有的。
HTTP协议的报文是以文本方式组织的(虽然body部分可以有二进制数据)。 每一行以回车换行两个字符作为行结束标志。start line只有一行,它和header部分很容易区分,第一个回车换行之后,就开始了header部分。 header部分由若干键值对组成,每个键值对独占一行。 header部分和body部分之间以一个空行作为分隔标志。下面是一个请求和一个响应的示例:

请求报文:

GET /static/test.jpg HTTP/1.1
Host: www.domain.com
OtherHeader: OtherValue

请求响应:

HTTP/1.0 200 OKrn
Content-type: image/gifrn
Content-Length: 8572rn
rn
xxxxxxxxxxxxxxxxxxx

继续阅读“HTTP协议学习笔记(一)简介”

java的ssl的一点问题,没搞定

服务端是一个基于mina开发的socket server, 连接采用ssl加密。 在服务端即配置了mina的SSLFilter.

客户端的c程序访问的时候,是一切正常的。 而使用java作为客户端,不论是用mina还是直接自己写SSlContext获得socketFactory,结果都一样,有2个怪异的现象。
1. tcp的3次握手完成之后,应该开始进行ssl握手,但是客户端发出的clientHello包却经过了明显的延迟(170ms左右)才发出来。
2. 最后的结束,不是正确的tcp 4次挥手 fin/ack/fin/ack。 而是最后以rst结束。 (猜测是ssl的 close_notify包处理的不正确?)
尽管有这2个现象的存在,但数据的交互却完全是正常的。 如果不是用tcpdump去抓包的话,甚至不会知道底下出现了这样怪异的现象。google也找不到有用的信息。

tcpdump抓包结果如下:

20:12:31.895990 IP 10.18.65.39.47552 > 10.108.90.237.8080: S 1674804305:1674804305(0) win 29200 <mss 1460,sackOK,timestamp 7589134 0,nop,wscale 7>
20:12:31.896079 IP 10.108.90.237.8080 > 10.18.65.39.47552: S 1592612872:1592612872(0) ack 1674804306 win 14480 <mss 1460,sackOK,timestamp 1355739116 7589134,nop,wscale 7>
20:12:31.896521 IP 10.18.65.39.47552 > 10.108.90.237.8080: . ack 1 win 229 <nop,nop,timestamp 7589134 1355739116>
20:12:32.066097 IP 10.18.65.39.47552 > 10.108.90.237.8080: P 1:155(154) ack 1 win 229 <nop,nop,timestamp 7589177 1355739116>
20:12:32.066192 IP 10.108.90.237.8080 > 10.18.65.39.47552: . ack 155 win 122 <nop,nop,timestamp 1355739287 7589177>
20:12:32.095820 IP 10.108.90.237.8080 > 10.18.65.39.47552: P 1:1192(1191) ack 155 win 122 <nop,nop,timestamp 1355739316 7589177>
20:12:32.096437 IP 10.18.65.39.47552 > 10.108.90.237.8080: . ack 1192 win 251 <nop,nop,timestamp 7589184 1355739316>
20:12:32.114039 IP 10.18.65.39.47552 > 10.108.90.237.8080: P 155:230(75) ack 1192 win 251 <nop,nop,timestamp 7589189 1355739316>
20:12:32.114100 IP 10.18.65.39.47552 > 10.108.90.237.8080: P 230:236(6) ack 1192 win 251 <nop,nop,timestamp 7589189 1355739316>
20:12:32.114124 IP 10.18.65.39.47552 > 10.108.90.237.8080: P 236:289(53) ack 1192 win 251 <nop,nop,timestamp 7589189 1355739316>
20:12:32.114572 IP 10.108.90.237.8080 > 10.18.65.39.47552: . ack 289 win 122 <nop,nop,timestamp 1355739335 7589189>
20:12:32.124198 IP 10.108.90.237.8080 > 10.18.65.39.47552: P 1192:1198(6) ack 289 win 122 <nop,nop,timestamp 1355739345 7589189>
20:12:32.161404 IP 10.18.65.39.47552 > 10.108.90.237.8080: . ack 1198 win 251 <nop,nop,timestamp 7589201 1355739345>
20:12:32.161459 IP 10.108.90.237.8080 > 10.18.65.39.47552: P 1198:1251(53) ack 289 win 122 <nop,nop,timestamp 1355739382 7589201>
20:12:32.161926 IP 10.18.65.39.47552 > 10.108.90.237.8080: . ack 1251 win 251 <nop,nop,timestamp 7589201 1355739382>
20:12:32.163208 IP 10.18.65.39.47552 > 10.108.90.237.8080: P 289:406(117) ack 1251 win 251 <nop,nop,timestamp 7589201 1355739382>
20:12:32.171213 IP 10.108.90.237.8080 > 10.18.65.39.47552: P 1251:1336(85) ack 406 win 122 <nop,nop,timestamp 1355739392 7589201>
20:12:32.186214 IP 10.18.65.39.47552 > 10.108.90.237.8080: P 406:752(346) ack 1336 win 251 <nop,nop,timestamp 7589207 1355739392>
20:12:32.226172 IP 10.108.90.237.8080 > 10.18.65.39.47552: . ack 752 win 130 <nop,nop,timestamp 1355739447 7589207>
20:12:32.228869 IP 10.108.90.237.8080 > 10.18.65.39.47552: P 1336:1554(218) ack 752 win 130 <nop,nop,timestamp 1355739449 7589207>
20:12:32.232552 IP 10.18.65.39.47552 > 10.108.90.237.8080: P 752:789(37) ack 1554 win 270 <nop,nop,timestamp 7589218 1355739449>
20:12:32.232613 IP 10.108.90.237.8080 > 10.18.65.39.47552: . ack 789 win 130 <nop,nop,timestamp 1355739453 7589218>
20:12:32.232795 IP 10.18.65.39.47552 > 10.108.90.237.8080: F 789:789(0) ack 1554 win 270 <nop,nop,timestamp 7589218 1355739449>
20:12:32.233915 IP 10.108.90.237.8080 > 10.18.65.39.47552: P 1554:1591(37) ack 790 win 130 <nop,nop,timestamp 1355739454 7589218>
20:12:32.234091 IP 10.108.90.237.8080 > 10.18.65.39.47552: F 1591:1591(0) ack 790 win 130 <nop,nop,timestamp 1355739454 7589218>
20:12:32.234515 IP 10.18.65.39.47552 > 10.108.90.237.8080: R 1674805095:1674805095(0) win 0
20:12:32.234594 IP 10.18.65.39.47552 > 10.108.90.237.8080: R 1674805095:1674805095(0) win 0

怪事。 如果客户端不调用socket.close(),在客户端java进程结束的时候, 却是以正常的fin/ack结束连接。

(全文完)

记一次压力测试和对nginx/tomcat配置的调整

是一个web系统,前端使用nginx做为反向代理,处理https,并将请求转发给后端的tomcat服务。
压力测试工具选择了jmeter。 首先简单介绍一下jmeter。 它是apache的一个开源项目,基于java swing开发的GUI界面。
jmeter提供了许多高级的功能,但我们仅仅使用了jmeter最简单的功能。在简单的jmeter使用中,我们涉及到这么几个概念:测试计划,线程组,测试任务,和Listener。看下面的图:
jmeter

在一个名为“测试”的测试计划下, 我们建立了一个线程组。 这个线程组可以设置线程数,创建时间(在多长时间内创建出这么多个线程),每个线程任务循环执行次数。 然后为这个线程组指派了一个http请求任务。 这个任务可以指定协议(http或https),服务器, url,参数等。

接下来为这个http请求任务添加了一个aggregate graph类型的listener。 我们需要看最终的测试结果, 这个listener就是为我们记录并展示结果的。

一切设置就绪之后,点击主界面上边的“启动”按钮,就可以在aggregate graph中观看测试结果了。
继续阅读“记一次压力测试和对nginx/tomcat配置的调整”

用openssl命令行进行aes加密

openssl的文档中说,-K参数已经被更加“优越”的-pass取代。
但其实,-pass才是真正的evil。 因为你不知道-pass之后,它会用你输入的pass如何生成key(密钥),IV。
openssl推荐的实现是不标准的。
如果你希望和其它语言合作,那么采用标准的做法是十分必要的。

对于openssl,就不能采用它默认的形式。

以下是一个和java互相加解密的例子。 加密方式采用的是 AES 128, ecb模式。
openssl enc -aes-128-ecb -K 95B8724B0763DF53469EE78B367F4588 -nosalt -in /tmp/shadowfiend.tmp -out /tmp/shadowfiend.enc

-K参数是大写的K, 小写的k的话会被当作password,而不是key。 nosalt是必须的。 否则在输出的文件中,会以一个特定的magic number开头,表示这是一个加salt的加密文件。且其salt信息会保存在文件中。 这不是一个标准的加密做法,其它语言解密就会很麻烦。

(全文完)

yum安装apache php

yum install httpd

yum -y install httpd-manual mod_ssl mod_perl mod_auth_mysql

service httpd restart

yum install php php-common php-gd php-mcrypt php-pear php-pecl-memcache php-mhash php-mysql php-xml php-mbstring

yum install php-*

vi /etc/httpd/conf/httpd.conf

增加两行:
AddType application/x-httpd-php .php .php3 .phtml .inc
AddType application/x-httpd-php-source .phps

openssl生成RSA格式,并转为pkcs8格式

openssl默认使用的是PEM格式,经过base64。

生成pem格式的私钥:
openssl genrsa -out private_key.pem 1024

生成公钥:
openssl rsa -in private_key.pem -pubout -out public_key.pem

产生的密钥如下:

[wind@localhost key]$ cat private_key.pem
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCd3V5+GjpOwqNks9ProDGaZT2qURAAuAodHcUM3P1mnhOh4l4u
VdvkXunUI7K6XDg6Xu9eL1WDQc6qKXs/OD91LS+RpkIAb2gMU8hGrNfR34izZh36
KdfWnEQpniAiFsHsg2ddAaPtGZZ8/jpjuPq32IVZJkgyKcWqnz5aL3FMXQIDAQAB
AoGAJFdkvGTvTVhTYwhe3dxn7uIlmwLES1YSxfcneLmbADedz2OcSNBtKZqL+9Eo
AOzf6NgYBLei2O+aUuPvwnMBcGyijFmRoZGVEj70UP0mngyAkvY/juA60QDe5kY5
rsqj4raHUf4iDK85nNwzXu7hIlPAn+ZmH+e2Eekwo1rmgQUCQQDJerucfBKk3qrV
xS5NRW99lKMomIsMH55Si+rbrnk8aU3SSRSD6uil3Dytv0erLZbc9d0Nr6SmBZgO
0qzOjXDDAkEAyJVGgHMNuMbpHnim93HAP7wcejmMx7rP4zutw4OCiHrWv3kN8WUC
u826taRFtOuiXhQ3X8+tb0l4ifae+vJ8XwJAEcmuKqChnMCz4G+qKNRKhZHL3dep
3wYjmjIUKBT9SyIY5sng78ybgZkyGjza/Pfna9ahD4ZESQwRYq2i6BGAtQJBAJyD
bmnYXQKro0e1mYNHbV3OKOJueZ139bM35BTFT1uzjlIF4Y1U5lco5uHJduL/YsjK
OZM3d/t4duggWlkyUT0CQBdsjc7eQ9roxphrW4Q/6Zwi0EQ4xxM4SgxPY1RvkKFu
i0HdYBj5KRdIbrAbisUyQeKzB7+6oTJH5+kZAU/pxao=
-----END RSA PRIVATE KEY-----
[wind@localhost key]$
[wind@localhost key]$
[wind@localhost key]$ openssl rsa -in private_key.pem -pubout -out public_key.pem
writing RSA key
[wind@localhost key]$ cat public_key.pem
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCd3V5+GjpOwqNks9ProDGaZT2q
URAAuAodHcUM3P1mnhOh4l4uVdvkXunUI7K6XDg6Xu9eL1WDQc6qKXs/OD91LS+R
pkIAb2gMU8hGrNfR34izZh36KdfWnEQpniAiFsHsg2ddAaPtGZZ8/jpjuPq32IVZ
JkgyKcWqnz5aL3FMXQIDAQAB
-----END PUBLIC KEY-----

某些语言需要pkcs8格式的公钥。 (php就不需要了)
使用openssl将刚才生成的公钥转为pkcs#8格式:
openssl pkcs8 -topk8 -inform PEM -in private_key.pem -outform PEM -nocrypt -out private_key_pkcs8.pem

继续阅读“openssl生成RSA格式,并转为pkcs8格式”