三月 21

使用 Nginx 构建优化的 https 服务

推荐使用 Nginx 1.6 以上版本,用以支持 spdy 3.0。虽然 http/2 已经推出,但现在浏览器支持度太低,服务器也只有几个小应用,Nginx 和 Apache 都还没有支持 http/2。

所以 spdy 依然是加速 https 的最好方式,但 Chrome 新版已经不支持 spdy 2.0 及以下版本,所以新版 Nginx 对 https 是很有帮助的。

首先监听443端口。

listen       443 ssl spdy;

老版本 Nginx 大家都用 ssl on,新版本(0.7.14以上)就推荐在 listen 加 ssl 关键字,这样最大的好处是在一个 Server 段里可同时支持 http 与 https 服务,像这样:

listen   80;
listen   443 ssl;

配置证书:

ssl_certificate      /etc/nginx/zhigang.net.crt;
ssl_certificate_key  /etc/nginx/zhigang.net.key;

证书现在免费的 StartSSL 挺好的,大部分浏览器都支持,新版 Linux 也都内置了 StartSSL 的 CA 证书。只是 java 目前还没有内置。具体申请与使用回头单写。

启用 ssl session 缓存:

ssl_session_cache shared:SSL:10m;
ssl_session_timeout  10m;

第一条设置一10M大小的缓存池,因为 Nginx 使用本地内存,所以这在分布式系统中作用就不大了。第二条缓存时间,单位分钟。

加密协议与算法:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_prefer_server_ciphers on;

因 SSL3.0 及以下版本已被爆出各种漏洞,现在已极不推荐使用,所以我们只启用 TLS 系列协议。

加密算法部分涉及东西太多,这里先注意需禁用的几个:MD5 RC4 DES 及 NULL。这里列出的算法规则应该是比较优化的。

启用 OCSP

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/startssl_trust_chain.crt;
resolver 8.8.8.8 8.8.4.4;

简单点说,启用 OCSP 可以让浏览器更快的获取证书撤销状态,提高加载速度。ssl_trusted_certificate 是 CA 的证书链,如 StartSSL class 1 证书这样生成:

wget https://www.startssl.com/certs/ca-sha2.pem
wget https://www.startssl.com/certs/class1/sha2/pem/sub.class1.server.sha2.ca.pem
cat sub.class1.server.sha2.ca.pem ca-sha2.pem > startssl_trust_chain.crt

启用 HSTS

add_header Strict-Transport-Security "max-age=31536000";

用于通知浏览器强制使用 https 通信,这样下次用户在直接输入域名访问时,浏览器会自动使用 https 请求,避免一次跳转。

Notes

完成设置后可以使用测试网站:https://www.ssllabs.com/ssltest/ 测下自己的得分,本站经过优化前的 D 提升到了 A+。

三月 21

Ubuntu双线双IP配置

软件环境

Ubuntu 14.04

网络环境

两条网络,电信与移动,测试服务器位于内网,移动IP:192.168.1.8,电信IP:192.168.23.8。

路由器使用端口映射对外暴露部分服务。

设置网络

/etc/network/interfaces

auto em1
#iface em1 inet dhcp
iface em1 inet static
address 192.168.1.8
gateway 192.168.1.1
netmask 255.255.255.0
broadcast 192.168.1.255
network 192.168.1.0

auto em2
iface em2 inet static
address 192.168.23.8
netmask 255.255.255.0

em1 使用移动网络,服务器默认出口。em2 使用电信网络,不设置网关。

设置路由表,实现原路返回数据

修改:/etc/iproute2/rt_tables 文件,增加条记录

252 mobile
251 telecom

执行命令:

ip route flush table telecom
ip route add default via 192.168.23.1 dev em2 src 192.168.23.8 table telecom
ip rule add from 192.168.23.8 table telecom

将以上命令加入 /etc/rc.local 实现重启配置不丢失。

在这个案例中,移动为默认网络,所以不需要特殊配置路由表,否则会导致网络不通。

设置路由表,实现指定网络访问特定内容

route add -host 91.189.95.83 gw 192.168.23.1

91.189.95.83 是 launchpad.net 源的IP地址,移动访问不稳定,这里指定网关使用电信网络访问。

结语

网上很多教程是错误的,主要在实现原路返回数据部分,很多人都说要写两个网络的路由表,但这会直接导致网络不通,我也在这里卡了很久。

Category: Linux | LEAVE A COMMENT
九月 26

OpenStack安装笔记

折腾一个礼拜,终于算把OpenStack搭起来了。

教程:https://github.com/ist0ne/OpenStack-Grizzly-Install-Guide-CN/blob/OVS_Quantum_MutliNode/OpenStack_Grizzly_Install_Guide.rst

安装OpenVSwitch时遇到了点问题,模块编译通不过,后来发现Ubuntu内核版本为3.8,应该是OpenVSwitch还不支持,改用3.2版内核后成功安装。

虚拟机默认CPU是QEMU的虚拟CPU,性能极差,修改 /etc/nova/nova.conf,增加 libvirt_cpu_mode = host-passthrough 可直接使用物理机CPU,达到最大性能。但注意,只有KVM支持host-passthrough。详细说明:https://wiki.openstack.org/wiki/LibvirtXMLCPUModel

几个有用的资源:

陈沙克日志:http://www.chenshake.com/ 国内OpenStack大牛

puppet-openstack: https://github.com/stackforge/puppet-openstack Puppet部署模块,正式环境大规模部署我计划用这个

Ubuntu OpenStack包地址: http://ubuntu-cloud.archive.canonical.com/ubuntu/dists/precise-updates/ 包括最新的Havana测试版也在,回头试试。

八月 24

批量转换文件编码

适用于Linux及 Mac OS 系统,Windows就抱歉了,你们自己想办法吧。

find . -name *.java -exec sh -c "iconv -f GBK -t UTF8 {} > /tmp/iconv.tmp" \; -exec mv /tmp/iconv.tmp '{}' \;

以上命令将所有 .java 文件由GBK编码转换为UTF8编码。

注意,网上有很多文章将 iconv 命令写成这样:

find . -name *.java -exec sh -c "iconv -f GBK -t UTF8 {} > {}" \;

再说一句,上面这种写法是错误的,以上写法相当于 iconv 输出到源文件,但不知是BUG还是别的原因,你只能得到0字节的空文件,所以必须使用第一条命令,先生成到一个临时文件,然后再移动回来。

八月 16

JAVA+jni 包名或方法名中含有下划线(_)的解决方法

jni或NDK定义C函数是用下划线(_)作为命名分隔。但如果JAVA包名或方法名里包含了_ 那么就会发生找不到函数的错误,对此网上的各教程都说不要使用 _,对于新项目,这种情况当然很容易避免,但若对一原有项目开发jni接口就麻烦了,特别是在 Android 平台下,包名决定着应用的唯一识别,轻易改不的。

经过不懈的努力,我终于找到了解决方法,简单来说就是在 _ 后加1,如:

// JAVA
package net.zhigang.ndk_test;

public class NdkTest
{
    static {
        System.loadLibrary(ndktest);
    }
    public native void sayHello();
}

//C
#include <jni.h>

jstring Java_net_zhigang_ndk_1test(JNIEnv* env, jobject thiz)
{
    return env->NewStringUTF("Hello from jni");
}

注意上面C语言部分的 ndk_1test。

八月 12

移植libcurl到Android NDK

测试通过环境:
操作系统:Mac OS
NDK:NDK r8e
libcurl:7.31.0

下载NDK环境: http://developer.android.com/tools/sdk/ndk/index.html ,安装环境不废话了。

在NDK安装目录执行

./build/tools/make-standalone-toolchain.sh

导出编译工具,一般生成压缩如 /tmp/ndk-zhigang/arm-linux-androideabi-4.6.tar.bz2。

解压:

cd /opt/
sudo tar xf /tmp/ndk-zhigang/arm-linux-androideabi-4.6.tar.bz2

下载curl源代码:http://curl.haxx.se/download.html

设置编译环境:

export LDFLAGS="\
-L/usr/local/Cellar/android-ndk/r8e/platforms/android-14/arch-arm/usr/lib"

export CPPFLAGS="\
-I/usr/local/Cellar/android-ndk/r8e/platforms/android-14/arch-arm/usr/include"

将以上路径修改为自己的NDK安装目录。

进入curl目录:

./configure --host=arm-linux-androideabi \
--disable-ftp \
--disable-gopher \
--disable-file \
--disable-imap \
--disable-ldap \
--disable-ldaps \
--disable-pop3 \
--disable-proxy \
--disable-rtsp \
--disable-smtp \
--disable-telnet \
--disable-tftp \
--without-gnutls \
--without-libidn \
--without-librtmp \
--without-ssl \
--disable-dict

mark

生成的静态库文件位于:lib/.libs/libcurl.a 动态库:libcurl.so.5.3.0

一般我们使用静态库文件。

复制 libcurl.a 到项目 jni/ 目录,修改 Android.mk 文件:

# A simple test for the minimal standard C++ library
#

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := curl
LOCAL_SRC_FILES := libcurl.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_CFLAGS = -Wno-psabi
LOCAL_MODULE := curltest
LOCAL_SRC_FILES := curltest.c
LOCAL_STATIC_LIBRARIES := libcurl
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_LDLIBS    += -lz

参考:http://stackoverflow.com/questions/11330180/porting-libcurl-on-android-with-ssl-support

四月 25

终于上了一次电视

年前受《命运60秒》节目组的邀请,去北京录了一期节目,河南卫视每周二21:20播,我录那期在这个月16号播了,悲剧的是我没看到直播…

好在现在都有点播可看,我在大约34分钟左右,刚上台有些紧张,好在上台后问答环节总算没丢人,欲知最后我成功没有?自己看吧,呵呵。

用了 https 视频没办法 iframe 过来了,地址:http://v.youku.com/v_show/id_XNTQzOTI2MDQ0.html

十二月 29

开始使用vim作主要开发工具

经过这么多年,IDE与编辑器用了不少,从开始的EditPlus到ZendStudio再到Eclipse、NetBeans、TextMate、Sublime Text等等。

几年前也曾经尝试过VIM、Emacs,但当时一是年少无知,二是插件没有如今这么丰富与强大,特别是在VIM支持Python、Ruby等脚本语言开发插件后,插件功能日益强大,甚至可以达到IDE标准,还有UltiSnips实现了类似TextMate的tab功能。加上灵活的自定义功能,让经过几年漂泊的我发现这几十年前诞生的编辑器竟如此强大。所以就这样了,选定离手。

下面是一些目前我使用的插件:

  • vundle (最好用的VIM插件管理工具,当年插件安装复杂也是我无法继续的原因之一)
  • UltiSnips (仿TextMate的TAB补全,支持Python写snips)
  • NERDTree (项目目录树)
  • NERTCommenter (代码注释,支持多种语言)
  • TagBar (显示类方法、函数列表、属性等导航)
  • neocomplcache (代码提示)
  • vim-octopress (本博客代码加亮)
  • phpcomplete.vim (PHP代码自动完成)
  • javacomplete (JAVA代码自动完成)
  • zencoding.vim (HTML快速书写)
  • numbers.vim (在命令模式显示与当前行间隔的行数,用于快速定位)
  • powerline (漂亮的状态栏)
  • matchit (快速找到标签的开始或结束位置)
  • AutoClose (自动关闭括号、引号)

我的.vimrc配置已经发布到GitHub: https://github.com/yinzhigang/dotvim

十二月 11

下载themeforest.net的主题

themeforest.net有很多漂亮的主题,但都是收费的而且还不便宜。但幸好很多主题都提供预览功能,这时我们就可以使用wget神器将HTML、CSS、JS、图片等下载下来,当然Wordpress之类的主题就需要自己写程序来实现功能了。

比如这个简洁的后台管理模板,我们点 Live Prefiew 找到真正的预览地址:http://benblogged.com/dev/ninja_admin/

wget -mk http://benblogged.com/dev/ninja_admin/

稍等一会儿,包括CSS图片在内的文件就会被下载到benblogged.com/dev/ninja_admin/,这个页面比较简单,只有一个HTML,其他复杂些也一样。

如果对方服务器有限制,如限制抓取速度,那么:

wget -mk -w 20 http://benblogged.com/dev/ninja_admin/

-w 20 代表每隔20秒下载一个文件。

还有服务器限制User-Agent,这也好办:

wget -mk -U 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11' http://benblogged.com/dev/ninja_admin/

这就模拟成了普通浏览器,怎么样,酷吧。