开始使用 ECC 证书

之前经常有听说 ECC 证书,它体积小,速度快,但是不兼容旧的浏览器,所以我也一直只使用 RSA 证书。
但从 Nginx 1.11.0 开始提供了对 RSA/ECC 双证书的支持。它的实现原理是:分析在 TLS 握手中双方协商得到的 Cipher Suite,如果支持 ECDSA 就返回 ECC 证书,否则返回 RSA 证书。也就是说,配合最新的 Nginx,我们可以使用 ECC 证书为现代浏览器提供更好的体验,同时老旧浏览器依然会得到 RSA 证书,从而保证了兼容性。这一次,鱼与熊掌可以兼得。

下面介绍一下如何使用 ECC 证书:

1.申请

如果你的 CA 支持签发 ECC 证书,使用以下命令生成 CSR(Certificate Signing Request,证书签名请求)文件并提交给提供商,就可以获得 ECC 证书:

openssl ecparam -genkey -name secp256r1 | openssl ec -out ecc.key
openssl req -new -key ecc.key -out ecc.csr

以上命令中可供选择的算法有 secp256r1 和 secp384r1,secp521r1 已被 Chrome 和 Firefox 废弃,而且 escp256p1 已经足够健壮。
目前很火的 Let’s Encrypt,也支持签发 ECC 证书。我们可以使用 acme.sh 这个小巧的工具来签发证书,指定 -k ec-256 就可以将证书类型改为 ECC:

/PATH/TO/.acme.sh/acme.sh --issue --dns dns_cx -d imququ.com -d www.imququ.com -k ec-256

2.配合 Nginx 使用

有了 RSA/ECC 双证书之后,需要安装 Nginx 1.11.x。
一切准备妥当后,将证书配置改为双份即可:

ssl_certificate     example.com.rsa.crt;
ssl_certificate_key example.com.rsa.key;

ssl_certificate     example.com.ecdsa.crt;
ssl_certificate_key example.com.ecdsa.key;

修改 Cipher Suites 配置如下,供参考:

ssl_ciphers                EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;

参考:https://imququ.com/post/ecc-certificate.html

折腾 HTTP/2

之前看到 ningx 1.9.5 版发布了,把 spdy 换成了 http2,安装主要参考了 这里

  1. nginx 官网上下载最新的 1.9.5 源代码,因为 HTTP/2 module 需要用到 “ALPN” OpenSSL_1.0.2 以上提供与 “NPN” OpenSSL_1.0.1 以上提供, 所以还要去 OpenSSLLibreSSL(建议用 LibreSSL 有一些新的特性)官网下载最新的 SSL 源码包并分别解压。

  2. 预编译的时候需要启用 http_v2_modulehttp_ssl_module 这两个模块:

    $ ./configure --with-openssl=/PATH/TO/LibreSSL --with-http_v2_module --with-http_ssl_module --with-ld-opt=-lrt #使用 LibreSSL
    $ ./configure --with-openssl=/PATH/TO/OpenSSL --with-http_v2_module --with-http_ssl_module  #使用 OpenSSL
  3. 然后 makemake install

  4. 在 Nginx 配置中启用站点对 HTTP/2 的支持也很方便,只需要在 listen 时加上 http2 就可以了:

    listen 443 ssl http2;

  5. 其它配置就跟 https 的配置是一样的,可以参考以前的

nginx 中 https 优化配置

https 网站比 http 网站慢一些,原因很多,诸如握手次数、缓存限制等。

那么进行一定的配置优化可以加快一些 https 的加载速度,下面是一个配置示例:

ssl on spdy;
ssl_certificate ssl/ssl.crt;
ssl_certificate_key ssl.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate ssl/trustchain.crt;
resolver 223.5.5.5 223.6.6.6;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000";
error_page 497  https://$host$request_uri;

其中ssl_certificate对应单张证书,ssl_certificate_key对应私钥,ssl_trusted_certificate对应信任链,即需要附加到单张证书后面的那两张证书链,这里可以把他们剥离出来。

参考:
Optimizing HTTPS on Nginx – {bjørn:johansen}
Nginx Performance Tuning for SSL – Tech Samurais

另外,当配置好SSL之后,可以去这个站点进行测试,看看还有没有什么的地方可以优化的 SSL 配置检查工具

Nginx 使用 openssl 的自签名证书

一、准备证书

0. 前期准备工作

cd ~/
mkdir ssl
cd ssl
mkdir demoCA
cd demoCA
mkdir newcerts
mkdir private
touch index.txt
echo '01' > serial

1. 制件 CA 证书

生成 CA 私钥: ca.key

openssl genrsa -des3 -out ca.key 2048

这样是生成 rsa 私钥,`des3` 算法,openssl 格式,2048 位强度。`ca.key` 是密钥文件名。为了生成这样的密钥,需要一个至少四位的密码。另外可以通过以下方法生成没有密码的key:

openssl rsa -in ca.key -out ca_decrypted.key

生成 CA 根证书的公钥 ca.crt:

openssl req -new -x509 -days 3650 -key ca.key -out ca.crt

2. 制作网站的 https 证书,并用 CA 签名认证

假设我们需要为 abc.com 域名制作证书

先生成 abc.com 的证书私钥 abc.com.pem

openssl genrsa -des3 -out abc.com.pem 1024

无密码的私钥

openssl rsa -in abc.com.pem -out abc.com.key

生成 csr 签名请求

openssl req -new -key abc.com.pem -out abc.com.csr

这里需要输入国家,地区,组织,email等。最重要的是 **common name**,可以写你的名字或者域名。如果为了 https 申请,这个必须和域名一样,即,这里要写 abc.com,否则会引发浏览器警报,这里可以用 *.abc.com 来做泛域名证书。

最后,需要用 CA 证书进行签名:

openssl ca -policy policy_anything -days 1460 -cert ./demoCA/ca.crt -keyfile ./demoCA/ca.key -in abc.com.csr -out abc.com.crt

这样网站的 https 证书就做完了。

还有一步就是把 ca.crt 的内容追加到 abc.com.crt 后面,因为有些浏览似乎不支持。

cat demoCA/ca.crt >> abc.com.crt

nginx 配置

加入配置内容:

server {
        listen 443;
        server_name abc.com www.abc.com;

        root html;
        index index.html index.htm;

        ssl on; 
        ssl_certificate /PATH/TO/abc.com.crt;
        ssl_certificate_key /PATH/TO/abc.com.key;

        ssl_session_timeout 5m;

        ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
        ssl_prefer_server_ciphers on;

        location / {
                try_files $uri $uri/ =404;
        }       
}

其它

其实很多时候,并不需要加密的 key,所以像这面这么做就好了。

cd ~/
mkdir ssl
cd ssl
mkdir demoCA
cd demoCA
mkdir newcerts
mkdir private
touch index.txt
echo '01' > serial
openssl genrsa -out ca.key 2048
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
cd ..
openssl genrsa -out abc.com.key 2048
openssl req -new -key abc.com.key -out abc.com.csr
openssl ca  -policy policy_anything  -days 1460 -in abc.com.csr -out abc.com.crt -cert ./demoCA/ca.crt -keyfile ./demoCA/ca.key

使用 .htaccess 封禁某 User-Agent 访问网站

有时候想要禁掉一些 user agent 访问网站,可以直接在 .htaccess 中设置就可以 deny 掉来自这些 user agent 的访问:

SetEnvIfNoCase User-Agent "^GbPlugin" bad_user
SetEnvIfNoCase User-Agent "^Wget" bad_user
SetEnvIfNoCase User-Agent "^EmailSiphon" bad_user
SetEnvIfNoCase User-Agent "^EmailWolf" bad_user
SetEnvIfNoCase User-Agent "^libwww-perl" bad_user
Deny from env=bad_user

这样符合上述User-Agent头的访问都将直接返回 403。

正确的nginx重定向

之前给nginx做301重定向的时候经常会这样写:

server {
    listen       80;
    server_name  www.nginx.org  nginx.org;
    if ($http_host = nginx.org) {
        rewrite  (.*)  http://www.nginx.org$1;
    }
    ...
}

而今天在 nginx docs 上看到这是不正确的。。。。

正确的写法应该是这样的:

server {
    listen       80;
    server_name  nginx.org;
    return       301 http://www.nginx.org$request_uri;
}

server {
    listen       80;
    server_name  www.nginx.org;
    ...
}

这好像只能在较新版本的 nginx 中才有用,在0.9.1版本(含)以前,可以这样实现重定向:

rewrite ^ http://www.nginx.org$request_uri?;

EOF

淘宝 Web 服务器 Tengine 正式开源

真是个令人振奋的消息。

Tengine是由淘宝核心系统部基于Nginx开发的Web服务器,它在Nginx的基础上,针对大访问量网站的需求,添加了很多功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网,淘宝商城等得到了很好的验证。它的最终目标是打造一个高效、稳定、安全、易用的 Web 平台。Tengine现已开源。

—以下摘自其官方网站—

官方网站:http://tengine.taobao.org/

Tengine基于最新的Nginx稳定版(Nginx-1.0.10),在它的基础上开发了一些功能和做了一些bug修复,比如:

  • 组合多个CSS、JavaScript文件的访问请求变成一个请求;
  • 支持管道和syslog形式的日志和抽样;
  • 自动根据CPU数目设置亲缘性;
  • 监控系统的负载和资源占用从而对系统进行保护;
  • 显示对运维人员更友好的出错信息,便于定位出错机器;
  • 更强大的访问速度限制模块;
  • backtrace模块,程序崩溃的时候可以显示出错的调用栈;
  • 根据文件类型设置过期时间;

基本上,Tengine可以被看作一个更好的Nginx,或者是Nginx的超集。

open_basedir restriction in effect: eAccelerator与open_basedir

今天在查阅apache的错误日志时发现有很多的warning,都跟open_basedir有关,如:

2011/09/25 21:27:54 [error] 3927#0: *146 FastCGI sent in stderr: “PHP Warning: require(): open_basedir restriction in effect. File() is not within the allowed path(s): (/srv/http/:/home/:/tmp/:/usr/share/pear/) in /srv/http/xxx.php on line 913” while reading upstream, client: x.x.x.x, server: example.com, request: “GET / HTTP/1.1”, upstream: “fastcgi://unix:/var/run/php-fpm/php-fpm-kelltan.sock:”, host: “example.com”, referrer: “http://example.com/”

检查php.ini的配置也没发现什么问题,google一番也没有有用的信息,只好自己动手找原因。重新查看了日志,发现这个警告出现在我安装eAccelerator之后,所以觉得这个错误应该跟eAccelerator有关。

在阅读了eAccelerator的wiki,然后又做了一番研究后发现,默认的eAccelerator编译选项跟open_basedir是不相容的,根据wiki上介绍,只要在编译的时候加上参数“ –without-eaccelerator-use-inode”,便可解决这个问题:

$ cd /PATH/TO/eaccelerator-0.9.6.1
$ make clean
$ ./configure --without-eaccelerator-use-inode
$ make
# make install

好了,重新编译完后,记得删掉eAccelerator之前产生的文件,然后重新启动apache:

# rm -rf /var/cache/eaccelerator/*
# /etc/rc.d/httpd restart

好了,一切重归宁静。

PHP运行于fcgid模式时,上传大文件抛500错误

我在pma上试图导入一个SQL文件时,pma抛给我一个500错误,看日志后发现错误日志为:

mod_fcgid: HTTP request length 135225 (so far) exceeds MaxRequestLen (131072)

我的php是运行在mod_fcgid模式下的,看上去是因为HTTP的请求长度太长,大于现有的131072最大请求长度。看了fcgid的配置文件后,发现并没有配置过MaxRequestLen的参数。看来这个131072的配置是默认的了。于是在fcgid的配置文件里加入这个配置,15728640是15M,因为我的php.ini中设置的最大POST长度是15M,所以把它们设置长一样的:

  MaxRequestLen 15728640

重启APACHE后,上传,导入,OK~

apache2上配置php-fastcgi


一直以来配置LAMP都会让php以apache handler的方式运行,虽然这样的运行模式会非常高效,但一直觉得它很占我VPS的资源,可怜的128M内存。所以尝试将php以fastcgi的模式运行。

安装

首先安装apache的fastcgi模块,apache下的fastcgi模式有两个:fastcgi_module与fcgid_module,比较后发现fcgid_module比较有优势,所以我选择了fcgid的模块,可以从源安装,也可以从官方下载然后自己编译。图方便,我直接从源安装:

apt-get install libapache2-mod-fcgid

接下去安装php-cgi

apt-get install php5-cgi

如果自己编译的话,记得去掉–with-apxs2,并加上–enable-cgi编译选项。
继续阅读apache2上配置php-fastcgi