【参考】 http://onlamp.com/pub/a/onlamp/2008/03/04/step-by-step-configuring-ssl-under-apache.html
p.s. 删减部分内容,并修正原文的一些小错误
1. 生成ssl证书:
1) 如果没有安装openssl,sudo apt-get install openssl装一个
2) 生成自签名证书将HOSTNAME替换成需要的域名;更详细说明(各参数/CA签名方法)参见原文。这一步执行完后会有server.crt和server.key两个文件,server.crt是公钥,需要让运行apache的用户可读的;server.key是私钥应当chmod为600。
3). 将server.cst和server.key拷贝到/etc/apache2/ssl/下。这个路径可以更改,但相应的配置文件中的路径也需要更改。
2. 配置apache
1) 启用mod_ssl: $ sudo a2enmod ssl
2) cd到/etc/apache2/sites-available,新建一个配置文件"ssl",内容如下:3). 创建链接:
$ cd /etc/apache2/sites-enabled
$ sudo ln -s ../sites-available/ssl
4). 重启apache2
$ sudo /etc/init.d/apache2 restart
3. 访问网站 https://HOSTNAME
p.s. 删减部分内容,并修正原文的一些小错误
1. 生成ssl证书:
1) 如果没有安装openssl,sudo apt-get install openssl装一个
2) 生成自签名证书
引用
$ openssl req -new -x509 -days 365 -sha1 -newkey rsa:1024 -nodes -keyout server.key -out server.crt -subj '/O=Company/OU=Department/CN=HOSTNAME'
3). 将server.cst和server.key拷贝到/etc/apache2/ssl/下。这个路径可以更改,但相应的配置文件中的路径也需要更改。
2. 配置apache
1) 启用mod_ssl: $ sudo a2enmod ssl
2) cd到/etc/apache2/sites-available,新建一个配置文件"ssl",内容如下:
引用
<IfModule mod_ssl.c>
#注意,下面这四行应当放在VirtualHost标签之外(原文的apache1.3可能支持放在里头,但2.2不行)
SSLRandomSeed startup file:/dev/urandom 1024
SSLRandomSeed connect file:/dev/urandom 1024
SSLSessionCache shm:/usr/local/apache2/logs/ssl_cache_shm
SSLSessionCacheTimeout 600
<VirtualHost *:443>
ServerAdmin webmaster@localhost
DocumentRoot /var/www
<Directory />
SSLRequireSSL
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
SSLProtocol -all +TLSv1 +SSLv3
SSLCipherSuite HIGH:MEDIUM:!aNULL:+SHA1:+MD5:+HIGH:+MEDIUM
#注意.crt和.key文件的路径必须一致
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
SSLVerifyClient none
SSLProxyEngine off
<IfModule mime.c>
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl
</IfModule>
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
# MSIE 7 and newer should be able to use keepalive
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog /var/log/apache2/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/ssl_access.log combined
Alias /doc/ "/usr/share/doc/"
<Directory "/usr/share/doc/">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
Allow from 127.0.0.0/255.0.0.0 ::1/128
</Directory>
</VirtualHost>
</IfModule>
#注意,下面这四行应当放在VirtualHost标签之外(原文的apache1.3可能支持放在里头,但2.2不行)
SSLRandomSeed startup file:/dev/urandom 1024
SSLRandomSeed connect file:/dev/urandom 1024
SSLSessionCache shm:/usr/local/apache2/logs/ssl_cache_shm
SSLSessionCacheTimeout 600
<VirtualHost *:443>
ServerAdmin webmaster@localhost
DocumentRoot /var/www
<Directory />
SSLRequireSSL
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
SSLProtocol -all +TLSv1 +SSLv3
SSLCipherSuite HIGH:MEDIUM:!aNULL:+SHA1:+MD5:+HIGH:+MEDIUM
#注意.crt和.key文件的路径必须一致
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
SSLVerifyClient none
SSLProxyEngine off
<IfModule mime.c>
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl
</IfModule>
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
# MSIE 7 and newer should be able to use keepalive
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog /var/log/apache2/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/ssl_access.log combined
Alias /doc/ "/usr/share/doc/"
<Directory "/usr/share/doc/">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
Allow from 127.0.0.0/255.0.0.0 ::1/128
</Directory>
</VirtualHost>
</IfModule>
$ cd /etc/apache2/sites-enabled
$ sudo ln -s ../sites-available/ssl
4). 重启apache2
$ sudo /etc/init.d/apache2 restart
3. 访问网站 https://HOSTNAME
上一次的方法虽然达到了基本要求,但是还是有很多不爽的地方,尤其是
1. 当需要直接操作该虚拟机,或者修改运行时参数(比如增加共享文件夹、修改网卡的模式、分配光驱)时,需要将虚拟机关闭或者休眠,然后再重新用vbox打开,很麻烦,更重要的是当前ssh会话环境全都要关闭,再次建立很麻烦。
2. 由于虚拟机是后台运行的,在关机的时候可能会被忽略,影响数据的安全性,甚至会导致虚拟机挂掉——我遇到的情况是apt包管理器的缓存文件出错,无法安装或卸载现有程序。于是干脆重装了下(把alternate版换成了server版)。
于是上网搜了一下,找到一款很不错的绿色软件——RBTray,可以强制将软件放入托盘(Systray)中,隐藏它在任务栏占用的位置。
这款软件可以在这里下载:http://rbtray.sourceforge.net/
把它下载,解压,运行,然后右键单击窗口的最小化图标,绝大部分窗口就会最小化到托盘中去。
然后在桌面上额外创建两个bat文件:
start.bat
stop.bat
完美:D
1. 当需要直接操作该虚拟机,或者修改运行时参数(比如增加共享文件夹、修改网卡的模式、分配光驱)时,需要将虚拟机关闭或者休眠,然后再重新用vbox打开,很麻烦,更重要的是当前ssh会话环境全都要关闭,再次建立很麻烦。
2. 由于虚拟机是后台运行的,在关机的时候可能会被忽略,影响数据的安全性,甚至会导致虚拟机挂掉——我遇到的情况是apt包管理器的缓存文件出错,无法安装或卸载现有程序。于是干脆重装了下(把alternate版换成了server版)。
于是上网搜了一下,找到一款很不错的绿色软件——RBTray,可以强制将软件放入托盘(Systray)中,隐藏它在任务栏占用的位置。
这款软件可以在这里下载:http://rbtray.sourceforge.net/
把它下载,解压,运行,然后右键单击窗口的最小化图标,绝大部分窗口就会最小化到托盘中去。
然后在桌面上额外创建两个bat文件:
start.bat
VBOX安装路径\VBoxManage startvm Ubuntu
stop.bat
VBOX安装路径\VBoxManage controlvm Ubuntu savestate
完美:D
作者:pumpkinsm@Pumpkin's
地址:http://ppksm.com/blog/read.php?147
南瓜同学原创的一首RAP(?),挺不错的,share一下。
Windows Media Player文件
大学两年
词曲编:pumpkin
有些时候有些感觉真不知该怎么讲
说出来又很矫情又忍不住又一直想
其实老实说 现在也没什么不爽
也有夏天也有吉他也有一大堆梦想
每天起床然后上他一整天的网
说话写字开心难过都习惯说干你娘
有时候有风 吹上睡懒觉的床
夹杂着的阳光 就像躺在那年的操场
现在学校当然也有大很多的操场
但是我都忘了多久没有再去逛逛
没了那份期望 没了那个姑娘
没了那种少年心情再去发热发光
那年火车毫不犹豫开向了这远方
随后的生活一如那天轰鸣而动荡
看起来生活平静 偶尔稍显匆忙
只有陌生的自己记着那些跌跌撞撞
以前看小说那可是充满奇遇充满美女
真到了江湖才发现生存不比冒险容易
少年时心气大 总说要闯天下
哪想到混到最后几千工资几万房价
说到美女我想大家一定都感兴趣
可是除了幻想咱们穷B肯定没戏
睡不着的夜里 也会觉得好奇
为什么以前追女孩只需一点勇气
歌词写得消极 生活却要继续
梦想和自己为敌 只好将它忘记
命运扑朔迷离 没有资格逃避
只能由着自己越来越不像我自己
两年时间过去 确实有些受益
但我失去的是 单纯的梦和自己
相隔千里说过的话已经不太清晰
热血少年终要变成街上的路人乙
地址:http://ppksm.com/blog/read.php?147
南瓜同学原创的一首RAP(?),挺不错的,share一下。
Windows Media Player文件大学两年
词曲编:pumpkin
有些时候有些感觉真不知该怎么讲
说出来又很矫情又忍不住又一直想
其实老实说 现在也没什么不爽
也有夏天也有吉他也有一大堆梦想
每天起床然后上他一整天的网
说话写字开心难过都习惯说干你娘
有时候有风 吹上睡懒觉的床
夹杂着的阳光 就像躺在那年的操场
现在学校当然也有大很多的操场
但是我都忘了多久没有再去逛逛
没了那份期望 没了那个姑娘
没了那种少年心情再去发热发光
那年火车毫不犹豫开向了这远方
随后的生活一如那天轰鸣而动荡
看起来生活平静 偶尔稍显匆忙
只有陌生的自己记着那些跌跌撞撞
以前看小说那可是充满奇遇充满美女
真到了江湖才发现生存不比冒险容易
少年时心气大 总说要闯天下
哪想到混到最后几千工资几万房价
说到美女我想大家一定都感兴趣
可是除了幻想咱们穷B肯定没戏
睡不着的夜里 也会觉得好奇
为什么以前追女孩只需一点勇气
歌词写得消极 生活却要继续
梦想和自己为敌 只好将它忘记
命运扑朔迷离 没有资格逃避
只能由着自己越来越不像我自己
两年时间过去 确实有些受益
但我失去的是 单纯的梦和自己
相隔千里说过的话已经不太清晰
热血少年终要变成街上的路人乙
一个简单的程序:
编译运行:
搞怪:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
int fd = open(argv[1], O_CREAT | O_WRONLY);
if (fd < 0)
{
printf("err open");
return 1;
}
u_int64_t sz = lseek64(fd, (1ull << 40) - 1, SEEK_SET);
if (sz < 0)
{
printf("err lseek64");
return 2;
}
int nWrite = write(fd, &fd, 1);
printf("nWrite = %d\n", nWrite);
close(fd);
return 0;
}
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
int fd = open(argv[1], O_CREAT | O_WRONLY);
if (fd < 0)
{
printf("err open");
return 1;
}
u_int64_t sz = lseek64(fd, (1ull << 40) - 1, SEEK_SET);
if (sz < 0)
{
printf("err lseek64");
return 2;
}
int nWrite = write(fd, &fd, 1);
printf("nWrite = %d\n", nWrite);
close(fd);
return 0;
}
编译运行:
引用
$ gcc -o hole hole.c -D_FILE_OFFSET_BITS=64
$ ./hole disk
$ ls -lh disk
-rwxr-S--- 1 felix021 felix021 1.0T 2010-08-20 14:36 disk
$ ./hole disk
$ ls -lh disk
-rwxr-S--- 1 felix021 felix021 1.0T 2010-08-20 14:36 disk
搞怪:
引用
felix021@ubuntu-vbox:~/code$ mkdir mnt
felix021@ubuntu-vbox:~/code$ sudo mkfs.vfat disk
mkfs.vfat 3.0.7 (24 Dec 2009)
felix021@ubuntu-vbox:~/code$ sudo mount -oloop disk mnt
felix021@ubuntu-vbox:~/code$ df -lh
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 5.2G 1.5G 3.5G 30% /
...
/dev/sda1 2.3G 957M 1.3G 43% /home
/dev/loop0 1.0T 16K 1.0T 1% /home/felix021/code/mnt
felix021@ubuntu-vbox:~/code$ sudo mkfs.vfat disk
mkfs.vfat 3.0.7 (24 Dec 2009)
felix021@ubuntu-vbox:~/code$ sudo mount -oloop disk mnt
felix021@ubuntu-vbox:~/code$ df -lh
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 5.2G 1.5G 3.5G 30% /
...
/dev/sda1 2.3G 957M 1.3G 43% /home
/dev/loop0 1.0T 16K 1.0T 1% /home/felix021/code/mnt
昨天到今天对这个博客做了一些修正。
首先是给博客加了个背景。其实本来是倾向于不改动的,毕竟我比较缺乏艺术细胞,搞出来的东西通常都很难看。但是在TNT同学的一再催促之下,还是去找了张简单的图片作为总体背景;博客内容等放了文本的地方,加了个alpha=60%的白色背景,效果还算不错。页首的图片也修改了一下,把纯白的地方抠掉变成透明的。
另外一个修正,是改好了feed.php。Google Reader订阅我博客的同学应该都知道,这个博客的rss,总是不能输出最新的一篇日志。这个问题我头疼了很久。曾经把这个博客的rss和wordpress的rss对比了一下,格式调来调去都不行,一度认为是Google Reader的BUG。今天再一次仔细观察了那个xml,发现rss输出的第一篇博客的地址总是 http://www.felix021.com/blog/read.php?0 。由于Google Reader会在服务器端做缓存和日志link->content的匹配,所以最新的一篇总是被忽略了(认为是以前的)。于是去翻了下feed.php的代码,发现里头莫名其妙多了一行,导致第一篇的blogid总是变成0。注释掉那一行,一切都恢复正常了。只是比较诡异的是,那一行代码看起来应该是我自己加进去的,我却完全没有印象是什么时候加进去的那么ooxx的代码……
嗯。总的来说博客变得更好了。
首先是给博客加了个背景。其实本来是倾向于不改动的,毕竟我比较缺乏艺术细胞,搞出来的东西通常都很难看。但是在TNT同学的一再催促之下,还是去找了张简单的图片作为总体背景;博客内容等放了文本的地方,加了个alpha=60%的白色背景,效果还算不错。页首的图片也修改了一下,把纯白的地方抠掉变成透明的。
另外一个修正,是改好了feed.php。Google Reader订阅我博客的同学应该都知道,这个博客的rss,总是不能输出最新的一篇日志。这个问题我头疼了很久。曾经把这个博客的rss和wordpress的rss对比了一下,格式调来调去都不行,一度认为是Google Reader的BUG。今天再一次仔细观察了那个xml,发现rss输出的第一篇博客的地址总是 http://www.felix021.com/blog/read.php?0 。由于Google Reader会在服务器端做缓存和日志link->content的匹配,所以最新的一篇总是被忽略了(认为是以前的)。于是去翻了下feed.php的代码,发现里头莫名其妙多了一行,导致第一篇的blogid总是变成0。注释掉那一行,一切都恢复正常了。只是比较诡异的是,那一行代码看起来应该是我自己加进去的,我却完全没有印象是什么时候加进去的那么ooxx的代码……
嗯。总的来说博客变得更好了。
上一篇提到了,使用sdbmhash来生成64bit摘要。这个算法,是需要用在PHP里头的,但是PHP在设计的时候有点囧,用于表示任意变量的 zval 这个struct里头,有一个union是用于存放不同数据类型的,而该union中用于表示整型的变量,就只有一个long。于是很杯具地:
1. 32bit OS下面的php只支持32bit整数
2. 不支持无符号整型
那个抑郁啊,于是只好用php的bcmath这个大整数库来实现上一篇的sdbmhash算法:
大整数库是用字符串来模拟的,没有对位移的直接支持。于是刚开始的时候用 bcmul($hash, 1<<6) 之类来替代C实现中的位移;然后果断发现自己SB了,直接乘65599更合适。
当然了,由于是用字符串来模拟的,可以想象这段代码效率是很低的。但是有多低呢?在我的Ubuntu虚拟机上测试了一下,1w次对18个字符的hash需要大约2.4s,也就是说一次调用大约需要0.2~0.3ms。宿主机是windows(AMD M320, 2.1GHz),php的效率更低,大约花了3~4s。在同样的时间里,纯C实现,可以进行相同的运算10,000,000+次,效率比大约是PHP:C = 1:1000。
由于0.2~0.3ms这个数量级比较大了,于是决定把它写成一个PHP扩展。参照百度文库的这篇教程 http://wenku.baidu.com/view/044da6f8941ea76e58fa04b1.html 比较快就上手了。
最终实现的效率比是大约1:100。看来PHP的扩展开销还是很大啊。
记得前年曾经和@Sandy讨论过ASP、PHP、JSP的效率,他认为ASP和PHP在同一个数量级,和JSP差距很大(而我当初则认为PHP和JSP差距不大)。这个数据很好地证明了这一点。
最后,附上这个PHP扩展。
下载文件 (已下载 13 次)
1. 32bit OS下面的php只支持32bit整数
2. 不支持无符号整型
那个抑郁啊,于是只好用php的bcmath这个大整数库来实现上一篇的sdbmhash算法:
function sdbmhash($str)
{
$mul = "65599"; // (1 << 6) + (1 << 16) - 1
$mod = "18446744073709551616"; // 1 << 64
$hash = "0";
for ($i = 0; $i < strlen($str); ++$i)
{
$hash = bcmod(bcmul($hash, $mul), $mod);
$hash = bcmod(bcadd($hash, ord($str{$i})), $mod);
}
return $hash;
}
{
$mul = "65599"; // (1 << 6) + (1 << 16) - 1
$mod = "18446744073709551616"; // 1 << 64
$hash = "0";
for ($i = 0; $i < strlen($str); ++$i)
{
$hash = bcmod(bcmul($hash, $mul), $mod);
$hash = bcmod(bcadd($hash, ord($str{$i})), $mod);
}
return $hash;
}
大整数库是用字符串来模拟的,没有对位移的直接支持。于是刚开始的时候用 bcmul($hash, 1<<6) 之类来替代C实现中的位移;然后果断发现自己SB了,直接乘65599更合适。
当然了,由于是用字符串来模拟的,可以想象这段代码效率是很低的。但是有多低呢?在我的Ubuntu虚拟机上测试了一下,1w次对18个字符的hash需要大约2.4s,也就是说一次调用大约需要0.2~0.3ms。宿主机是windows(AMD M320, 2.1GHz),php的效率更低,大约花了3~4s。在同样的时间里,纯C实现,可以进行相同的运算10,000,000+次,效率比大约是PHP:C = 1:1000。
由于0.2~0.3ms这个数量级比较大了,于是决定把它写成一个PHP扩展。参照百度文库的这篇教程 http://wenku.baidu.com/view/044da6f8941ea76e58fa04b1.html 比较快就上手了。
最终实现的效率比是大约1:100。看来PHP的扩展开销还是很大啊。
记得前年曾经和@Sandy讨论过ASP、PHP、JSP的效率,他认为ASP和PHP在同一个数量级,和JSP差距很大(而我当初则认为PHP和JSP差距不大)。这个数据很好地证明了这一点。
最后,附上这个PHP扩展。
下载文件 (已下载 13 次)
前两天在找个摘要算法,要求很简单,冲突少,生成64bit摘要;安全性可以忽略。MD5/SHA-1是好算法,但是它们生成的摘要是128/160bit的。Qining最初提出了个算法,将MD5的128bit分成4个32bit,d[0..3],然后通过以下公式获得64bit摘要:看起来挺有模有样的,但是用0..100,000去测试,发现了3个碰撞,毕竟没有数学理论的支持,胡搞还是不行的。另外再尝试了下,把MD5的前64bit拿出来,效果倒是好,前100,000没有碰撞。只是这种做法毕竟不让人放心,于是到网上搜了一下,发现不少人有此需求,但是没有现成的算法,挺无奈的。还好,有个人一语道破天机:用个字符串hash算法就行了。
于是翻出以前的一篇日志字符串的Hash,从里头把sdbm哈希函数搞出来,测试了一下(跑了好几分钟呢),效果很赞,一亿以内的整数都没有问题,代码如下:
引用
concat(d[0] XOR d[2], d[1] XOR d[3])
于是翻出以前的一篇日志字符串的Hash,从里头把sdbm哈希函数搞出来,测试了一下(跑了好几分钟呢),效果很赞,一亿以内的整数都没有问题,代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <assert.h>
using namespace std;
typedef unsigned long long ull;
ull sdbmhash(const char *s){
ull hash = 0;
while (*s){
hash = (hash << 6) + (hash << 16) - hash + *s++;
}
return hash;
}
int main()
{
const unsigned N = 100000000;
ull *all = new(nothrow) ull[N];
assert(all != NULL);
unsigned i = 0;
char tmp[100];
for (i = 1; i <= N; ++i)
{
snprintf(tmp, 100, "%09u", i);
all[i] = sdbmhash(tmp);
if (i % (N / 20) == 0) printf("i = %u\n", i);
}
sort(all, all + N);
ull * end = unique(all, all + N);
printf("%u\n", all + N - end);
delete[] all;
return 0;
}
#include <cstdio>
#include <algorithm>
#include <assert.h>
using namespace std;
typedef unsigned long long ull;
ull sdbmhash(const char *s){
ull hash = 0;
while (*s){
hash = (hash << 6) + (hash << 16) - hash + *s++;
}
return hash;
}
int main()
{
const unsigned N = 100000000;
ull *all = new(nothrow) ull[N];
assert(all != NULL);
unsigned i = 0;
char tmp[100];
for (i = 1; i <= N; ++i)
{
snprintf(tmp, 100, "%09u", i);
all[i] = sdbmhash(tmp);
if (i % (N / 20) == 0) printf("i = %u\n", i);
}
sort(all, all + N);
ull * end = unique(all, all + N);
printf("%u\n", all + N - end);
delete[] all;
return 0;
}






类别:
