分类目录归档:Server

CentOS 7 编译安装nginx并启用TLS1.3

更新日志

20180207 修正部分错误。
如果TLSv1.3如期发布,OpenSSL 1.1.1 将于2018年4月17日面向公众发布。截至2018年1月27日,OpenSSL开发至TLSv1.3 draft 23,暂时不推荐用于生产环境。对于服务器来说,我还是喜欢CentOS,支持周期很长,折腾一次可以用很长世间,因此以下记录一下在基于LNMP的CentOS 7 系统上启用TLSv1.3的过程。

1 升级系统

yum update

升级后的系统版本为:

cat /etc/centos-release
CentOS Linux release 7.4.1708 (Core)

2 安装官方mainline版的nginx

通过官方源安装nginx的目的是:
自动生成nginx的配置文件,减少大量的工作;
获取nginx的编译参数。

配置源:

vi /etc/yum.repos.d/nginx.repo

写入如下内容:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1

安装nginx:

yum install nginx -y

查看nginx版本:

nginx -v
nginx version: nginx/1.13.8

获取编译参数:

nginx -V
nginx version: nginx/1.13.8
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'

修改nginx源,将enabled=1改为enabled=0,防止yum update时nginx被更新掉

vi /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=0

3 编译nginx

安装可能用到的依赖:

yum install -y git gcc gcc-c clang automake make autoconf libtool zlib-devel libatomic_ops-devel pcre-devel openssl-devel libxml2-devel libxslt-devel gd-devel GeoIP-devel gperftools-devel  perl-devel perl-ExtUtils-Embed

获取源码:

git clone https://github.com/nginx/nginx.git
git clone https://github.com/openssl/openssl.git
git clone https://github.com/grahamedgecombe/nginx-ct.git

nginx-ct是启用证书透明度(Certificate Transparency)策略的模块。为了启用Certificate Transparency和TLSv1.3,需要额外加入如下编译参数:

--add-module=../nginx-ct/ --with-openssl=../openssl/ --with-openssl-opt=enable-tls1_3

加在官方编译参数后面,简单修改形成完整的编译参数:

auto/configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --add-module=../nginx-ct/ --with-openssl=../openssl/ --with-openssl-opt=enable-tls1_3

进入nginx源码目录,并输入如上完整的编译参数。如果直接编译(make),会遇到“pthread_atfork”相关错误:

-Wl,-z,relro -Wl,-z,now -pie -ldl -lpthread -lpthread -lcrypt -lpcre ../openssl//.openssl/lib/libssl.a ../openssl//.openssl/lib/libcrypto.a -ldl -lz \
-Wl,-E
../openssl//.openssl/lib/libcrypto.a(threads_pthread.o): In function `fork_once_func':
threads_pthread.c:(.text+0x16): undefined reference to `pthread_atfork'
collect2: error: ld returned 1 exit status
make[1]: *** [objs/nginx] Error 1

因此config之后,先不要编译,而是先修改nginx目录下objs内的Makefile:

vi ./objs/Makefile

找到这行:

-Wl,-z,relro -Wl,-z,now -pie -ldl -lpthread -lpthread -lcrypt -lpcre ../openssl//.openssl/lib/libssl.a ../openssl//.openssl/lib/libcrypto.a -ldl -lz \

将第一个“-lpthread”删除,将第二个“-lpthread”移至行末“\”之前,看起来是这样:

-Wl,-z,relro -Wl,-z,now -pie -ldl -lcrypt -lpcre ../openssl//.openssl/lib/libssl.a ../openssl//.openssl/lib/libcrypto.a -ldl -lz -lpthread \

然后顺利编译:

make

查看编译好的nginx信息:

./objs/nginx -v
nginx version: nginx/1.13.9

备份已经安装好的官方mainline版,安装编译版:

mv /usr/sbin/nginx /usr/sbin/nginx.1.13.8.20180127.official.mainline
cp ./objs/nginx /usr/sbin/

4 修改nginx配置文件内的ssl_protocolsssl_ciphers,启用TLSv1.3

...
ssl_protocols          TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers            TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:ECDHE+aECDSA+CHACHA20:ECDHE+aRSA+CHACHA20:ECDHE+aECDSA+AESGCM:ECDHE+aRSA+AESGCM:ECDHE+aECDSA+AES256+SHA384:ECDHE+aRSA+AES256+SHA384:ECDHE+aECDSA+AES256+SHA:ECDHE+aRSA+AES256+SHA;
...

重启nginx服务以使修改生效:

systemctl restart nginx

5 测试TLSv1.3是否生效

5.1 使用testssl工具
git clone --depth 1 https://github.com/drwetter/testssl.sh.git
cd testssl.sh
./testssl.sh --help

命令为(coldawn.com需要换成自己的域名):

./testssl.sh -p coldawn.com
...
 Testing protocols via sockets except SPDY+HTTP2

 SSLv2      not offered (OK)
 SSLv3      not offered (OK)
 TLS 1      offered
 TLS 1.1    offered
 TLS 1.2    offered (OK)
 TLS 1.3    offered (OK): draft 23
 SPDY/NPN   http/1.1 (advertised)
 HTTP2/ALPN http/1.1 (offered)
...

详细的情况,用大写的P作为参数:

./testssl.sh -P coldawn.com

 Testing server preferences

 Has server cipher order?     yes (OK)
 Negotiated protocol          TLSv1.3
 Negotiated cipher            TLS13-AES-256-GCM-SHA384, 253 bit ECDH (X25519)
 Cipher order
    TLSv1:     ECDHE-ECDSA-AES256-SHA ECDHE-RSA-AES256-SHA
    TLSv1.1:   ECDHE-ECDSA-AES256-SHA ECDHE-RSA-AES256-SHA
    TLSv1.2:   ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-SHA384
               ECDHE-RSA-AES256-SHA384 ECDHE-ECDSA-AES256-SHA ECDHE-RSA-AES256-SHA
    TLSv1.3:   TLS13-AES-256-GCM-SHA384 TLS13-CHACHA20-POLY1305-SHA256 TLS13-AES-128-GCM-SHA256 TLS13-AES-128-CCM-8-SHA256 TLS13-AES-128-CCM-SHA256
5.2 使用现代浏览器

Chrome正式版 64.0.3282.119(2018年1月27日)仅支持半年前就不再更新的draft 18,不支持TLS 1.3 draft 23。推荐使用Canary 金丝雀版66.0.3332.0(2018年1月27日):

http://www.google.com/chrome/browser/canary.html?platform=win64

安装后,地址栏输入:

chrome://flags/#tls13-variant

下拉右侧列表,选中“Enableed(Draft 23)”,重启浏览器,查看https://tls13.crypto.mozilla.org/看是否能正常访问来确定浏览器自身是否支持Draft 23。
然后访问域名,查看证书相关信息:

 Connection - secure (strong TLS 1.3)
The connection to this site is encrypted and authenticated using TLS 1.3 (a strong protocol), X25519 (a strong key exchange), and AES_256_GCM (a strong cipher).

为Debian 9 stretch的SSH登录安装并启用谷歌两步验证(google authenticator)

以密钥方式登录vps提供了更高的安全性,但以用户名密码登录vps的方式比用密钥方式更适用于经常多个地方登录的情况,此时需要加用两步验证防止用户名密码泄漏的情况。目前网上搜索到的教程多半已经过时,稍有不慎,容易配置失误导致自己无法登录vps。本文就如何在Debian 9上正确的设置谷歌两步验证做个介绍。

开始之前需要先有个Debian 9;
下文出现的命令都是一行一条,虽然有时可以全部复制一起执行,但不建议这么做,还是老老实实一行一行执行吧。无特殊说明均以root用户执行。

1 更新系统

apt-get update
apt-get upgrade -y
apt-get dist-upgrade -y

2 安装所需的软件包

apt-get install wget make gcc libpam0g-dev git autotools-dev autoconf libtool qrencode -y

3 下载并安装两步验证源码

假设打算将源码放到/usr/local/src目录下:

cd /usr/local/src
git clone https://github.com/google/google-authenticator-libpam.git
cd google-authenticator-libpam/
./bootstrap.sh
./configure
make
make install

在安装信息中可以看到有这样一行:
libtool: install: /usr/bin/install -c .libs/pam_google_authenticator.so /usr/local/lib/security/pam_google_authenticator.so
这个信息提供了开启两步验证所需的最重要的文件的安装路径,很多教程无法成功启用两步验证就在于此。

4 修改ssh相关配置文件

4.1 修改sshd_config

将ChallengeResponseAuthentication的no改为yes:

vi /etc/ssh/sshd_config

...
ChallengeResponseAuthentication yes
...
4.2 修改sshd

在/etc/pam.d/sshd第一行后加入auth required /usr/local/lib/security/pam_google_authenticator.so。

vi /etc/pam.d/sshd

# PAM configuration for the Secure Shell service
auth       required     /usr/local/lib/security/pam_google_authenticator.so

# Standard Un*x authentication.
...

5 开启两步验证

当以root用户安装完两步验证后,需要针对某个用户启用两步验证,需要切换为该用户时才能正确启用。假设为名为jackson的用户开启两步验证,需要切换为该用户:

su jackson

然后运行如下命令配置两步验证:

google-authenticator

依次输入5个“y”并回车确认安装即可。
注意备份好密钥(secret key)和备用验证码(emergency scratch codes)。
重启sshd来使两步验证即时生效:

sudo service sshd restart

注意此时不要关闭ssh登录窗口。因为如果启用失败,而又关闭了这个已登录的窗口会把自己挡在外面的。

6 验证是否开启成功

用app扫描二维码或者手动输入密钥启用两步验证,然后打开一个新的ssh窗口尝试登录vps,以查看是否成功启用两步验证。

CentOS 7 搭建LNMP服务器环境

CentOS漫长的支持周期使得对系统更新的需求不是那么迫切,只要用得顺手。不过,新安装的话,就应该直接安装最新版,这样就可以用很久了。Centos 7 搭建LNMP(nginx, MariaDB, PHP)服务器和在CentOS 6 搭建LNMP服务器环境大同小异,整体过程和方法都是一样的,只需将NMP的源由CentOS 6 改成CentOS 7 的,修改几条命令就可以了。

1 更新系统:

yum update -y

查看系统版本:

cat /etc/centos-release

CentOS Linux release 7.3.1611 (Core)

2 配置源:

2.1 配置MariaDB官方源
首先需要定制MariaDB的官方源
选择合适的系统,系统版本,及MariaDB版本(最新是10.2, 目前处于RC阶段),获得CentOS 7 64位系统MariaDB 10.2 RC版本的源地址。

CentOS > CentOS 7 (x86_64) > 10.2 [Release Candidate]

配置源方法

vi /etc/yum.repos.d/MariaDB.repo

填入如下内容

# MariaDB 10.2 CentOS repository list - created 2017-02-25 08:07 UTC
# http://downloads.mariadb.org/mariadb/repositories/
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.2/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

保存退出(按ESC键,输入:wq)。

2.2 配置PHP源
webtatic源更新较快,且其命名有自己的特色方式,可以避免与其他源的某些冲突:

rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm

2.3 配置nginx官方源
官方nginx有两个版本,mainline和stable,即开发板和稳定版,区别是前者引入新特性但可能有新bug,后者足够稳定。事实上,两者均比较稳定,nginx的网站总是运行在mainline版上。
以下提供两个版本供选择,请选择其一,推荐使用mainline版。

2.3.1 mainline 版
nginx的mainline版

vi /etc/yum.repos.d/nginx.repo

系统是CentOS 7,故写入如下内容

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1

保存退出。

2.3.2 stable 版

vi /etc/yum.repos.d/nginx.repo

系统是CentOS 7,故写入如下内容


[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1

保存退出。

3 安装、启动服务及设置开机启动

3.1.1 安装MariaDB

yum install MariaDB-server -y

3.1.2 安装PHP

yum install php71w-fpm -y

安装扩展

yum install php71w-gd php71w-mysqlnd php71w-pdo php71w-mcrypt php71w-mbstring php71w-xmlrpc -y

3.1.3 安装nginx

yum install nginx -y

3.2 启动服务并设置开机启动

systemctl start nginx

systemctl start mariadb

systemctl start php-fpm

systemctl enable nginx

systemctl enable mariadb

systemctl enable php-fpm

4 配置

4.1 设置MariaDB

MariaDB对MySQL的命令具有良好的兼容性。
此步主要是MariaDB的安全设置:

mysql_secure_installation
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none): 

因为是初次设置MariaDB,所以root密码是空的,此处直接回车

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] y

设置数据库的密码

New password: 

设置密码,设置一个你自己知道的密码。

Re-enter new password: 

再次输入密码

By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

4.2 配置PHP

vi /etc/php.ini

找到

;cgi.fix_pathinfo=1

去掉注释,并将1改成0

cgi.fix_pathinfo=0

保存退出。

4.3 配置nginx

4.3.1 默认配置

直接用浏览器打开你的主机空间的IP地址或者域名(假设IP地址为1.2.3.4,域名为www.urwp.com,后面也会用到),就可以看到nginx的欢迎页面,说明nginx已经在工作了。

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

4.3.2 配置nginx,以支持PHP

vi /etc/nginx/conf.d/default.conf

修改前的默认配置是这样的:

server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

修改如下区块,取消注释,并修改部分内容:

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        root           /usr/share/nginx/html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

4.3.3 测试PHP是否正常运行

vi /usr/share/nginx/html/phpinfo.php

写入如下代码,并保存

<?php
phpinfo();
?>

重启nginx和PHP

systemctl restart nginx
systemctl restart php-fpm

再次访问你的主机地址或域名:

http://1.2.3.4/phpinfo.php

或者

http://www.urwp.com/phpinfo.php

可见到php相关信息,说明PHP和nginx已经配合工作了。
此时LNMP网络服务环境就已初步搭建了。

接下来,可以部署自己的网站,或者开个简单的博客,比如WordPress
部署好LNMP后,不管是CentOS 6,还是CentOS 7,安装WordPress步骤都是一样的:CentOS 6系统LNMP环境下安装WordPress

在CentOS 6 上用谷歌身份验证器Google authenticator开启两步验证保护VPS的SSH登陆安全

通过Google Authenticator开启VPS在SSH登陆时的两步验证,可以有效对抗暴力破解。本文是在CentOS 6 64位系统的VPS上开启SSH登陆的两步验证。首先需要先在手机上安装好Google authenticator,常见的Android和IOS手机都是支持的。
主要参考:
Secure SSH with Google Authenticator Two-Factor Authentication on CentOS 7

详细步骤:

1 首先安装EPLE源:
Google authenticator位于EPLE源中,可以不用再去编译安装了。

yum install epel-release

2.安装Google authenticator

2.1 使用yum安装法:

yum install google-authenticator

同意导入GPG key即可:

Importing GPG key 0x0608B895:
Userid : EPEL (6) <epel@fedoraproject.org>
Package: epel-release-6-8.noarch (@extras)
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
Is this ok [y/N]:y

2.2 使用rpm安装法:
有些小内存(比如64M)的VPS,会因为内存不足使得yum命令中途被killed。那么可以使用rpm 命令来手动安装Google authenticator。
下载:

wget http://dl.fedoraproject.org/pub/epel/6/x86_64/google-authenticator-0-0.3.20110830.hgd525a9bab875.el6.x86_64.rpm

安装:

rpm -ivh google-authenticator-0-0.3.20110830.hgd525a9bab875.el6.x86_64.rpm

3 配置Google authenticator

在VPS上运行如下命令:

google-authenticator

出现

https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/root@localhost.localdomain%3Fsecret%3DDUO5MSLICSFHYCMV
Your new secret key is: DUO5MSLICSFHYCMV
Your verification code is 036197
Your emergency scratch codes are:
22188647
15985270
10493468
55754566
92756123

Do you want me to update your "~/.google_authenticator" file (y/n)

在浏览器中打开网址:

https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/root@localhost.localdomain%3Fsecret%3DDUO5MSLICSFHYCMV

可以见到二维码,用手机的Google authenticator(身份验证器)程序扫描条形码,即会自动配置好。

如果扫描后手机未自动配置,则需要手动输入验证码(IOS)或输入提供的密钥(Android),在接下来的界面中,给账户起个名字,输入上面出现的密钥,如本例中的DUO5MSLICSFHYCMV,并默认基于时间的选项,确认即可。

secret key(DUO5MSLICSFHYCMV)和5个应急码(emergency scratch codes)保存到安全的地方,备用。

接下来四个选项,全部选择y即可,有兴趣的自己去研究。

Do you want me to update your "~/.google_authenticator" file (y/n) y

Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y

By default, tokens are good for 30 seconds and in order to compensate for
possible time-skew between the client and the server, we allow an extra
token before and after the current time. If you experience problems with poor
time synchronization, you can increase the window from its default
size of 1:30min to about 4min. Do you want to do so (y/n) y

If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting (y/n) y

4 修改pam设置

vi /etc/pam.d/sshd

顶部加入一行:

auth required pam_google_authenticator.so

最后看起来是这样的:

#%PAM-1.0
auth required pam_google_authenticator.so
auth required pam_sepermit.so
auth include password-auth
account required pam_nologin.so
...

这里有个坑,原文是将这一行加在最后一行之下(Add the following line to the bottom of line),结果登陆的时候不出现验证码的输入框。但是加在第二行就可以了,可能的原因是原作者用的是CentOS 7 系统。

5 修改ssh设置

vi /etc/ssh/sshd_config

定位到:

# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no

将no改成yes,改完后是这样的:

# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication yes

6 重启ssh服务

service sshd restart

Stopping sshd: [ OK ]
Starting sshd: [ OK ]

7 退出SSH客户端,重新登陆进行验证,如下则成功:

login as: (此处输入登陆的用户名)
Using keyboard-interactive authentication.
Verification code:(这里输入手机端生成的验证码)
Using keyboard-interactive authentication.
Password:(这里输入登录的密码)

使用Let’s Encrypt的Certbot为ngxin生成ECDSA证书

更新

20170312 本文是以CentOS 6.8系统为基础的,而对于CentOS 7系统,certbot则包含在了EPEL源中,可以启用EPEL后直接安装,且命令也由certbot-auto改为了certbot,但是两者的命令参数是通用的。
256位的ECDSA密钥提供的安全性和3072位的RSA密钥相当,而对于大多数网站来说,2048位RSA密钥提供的安全性已经足够。ECDSA证书在算法和密钥长度上的优势可以提供更快的HTTPS访问速度,但浏览器和平台的支持度不如后者广泛。Nginx 1.11.0版本即开始支持ECDSA和RSA双证书配置,可以通过同时配置RSA证书来解决ECDSA证书的兼容性问题。以下内容主要是记录一下如何用Let's Encrypt官方推荐的Certbot生成ECDSA证书,亦为ECC证书。取得Certbot环境、全自动生成和更新RSA证书和注意事项,不再赘述。
主要参考:
Status of and instructions for EC certification generation using CertBot?

详细步骤:
1 进入Certbot工作目录

cd /etc/certbot/

2 生成ECDSA私钥
使用secp384r1曲线算法

openssl ecparam -genkey -name secp384r1 > ec.key

3 生成支持多域名的证书请求文件CSR
certbot目前只能以–csr的方式加载证书请求文件来生成ECDSA的证书,并且要求csr为der格式csr已支持der和pem格式
使用–csr时,要将需要申请证书的域名全部包含在csr中,如co1dawn.com和www.co1dawn.com,即需要生成多域名的CSR。
3.1 方法一(推荐直接使用方法二)

cp /usr/local/ssl/openssl.cnf /etc/certbot/
vi openssl.cnf

在[ req ]区块找到并去掉注释“#”:

req_extensions = v3_req # The extensions to add to a certificate request

在[ v3_req ] 加入如下内容:

subjectAltName = @alt_names
[ alt_names ]
DNS.1 = co1dawn.com
DNS.2 = www.co1dawn.com

修改后的样子:

[ v3_req ]

# Extensions to add to a certificate request

basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = co1dawn.com
DNS.2 = www.co1dawn.com

通过openssl使用-config参数生成多域名证书请求文件:

openssl req -new -sha384 -key ec.key -out ec-der.csr -outform der -config /etc/certbot/openssl.cnf

只需填入Common Name (e.g. server FQDN or YOUR name) []:co1dawn.com即可。前几项输入“.”,即为空;最后后两项留空即可。

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:.
State or Province Name (full name) [Some-State]:.
Locality Name (eg, city) []:.
Organization Name (eg, company) [Internet Widgits Pty Ltd]:.
Organizational Unit Name (eg, section) []:.
Common Name (e.g. server FQDN or YOUR name) []:co1dawn.com
Email Address []:.

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

3.2 方法二,更为简单,为推荐使用的方法

按需要做相应更改:

openssl req -new -sha384 -key ec.key -subj "/CN=co1dawn.com" -reqexts SAN -config <(cat /usr/local/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:co1dawn.com,DNS:www.co1dawn.com")) -outform der -out ec-der.csr

/usr/local/ssl/openssl.cnf为openssl编译安装时所在位置,根据实际情况更改,考虑到安全性和兼容性,请编译升级到最新版的openssl 1.0.2
3.3查看csr是否正确

openssl req -inform der -in ec-der.csr -noout -text
        ...
        Subject: CN=co1dawn.com
        ...
            X509v3 Subject Alternative Name:
                DNS:co1dawn.com, DNS:www.co1dawn.com
        ...

4 使用certbot生成ECDSA证书

./certbot-auto certonly --webroot -w /var/www/html/ -d co1dawn.com -d www.co1dawn.com --email "youremail@youremail.com" --csr "/etc/certbot/ec-der.csr"

具体命令的意义可参照之前的部分

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/certbot/0001_chain.pem. Your cert will expire on
   2016-11-29. To obtain a new or tweaked version of this certificate
   in the future, simply run certbot-auto again. To non-interactively
   renew *all* of your certificates, run "certbot-auto renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

如不指定获取的证书存放目录时,默认放在cerbot程序所在目录,即/etc/certbot/。
生成三个证书:

0000_cert.pem  0000_chain.pem   0001_chain.pem

与certbot自动化生成并更新的RSA证书的对应关系是:

   0000_cert.pem   = cert.pem
   0000_chain.pem  = chain.pem
   0001_chain.pem  = fullchain.pem

在nginx中用到的是0000_chain.pem和0001_chain.pem,具体使用方法和前面一致

使用cloudflare的chacha20/poly1305补丁编译nginx,在ngxin中配置ECDSA和RSA双证书后,需要提供并提升ECDSA和chacha20/poly1305的优先级,ssl_ciphers可参考该文进行配置:

ssl_ciphers 'ECDHE+aECDSA+CHACHA20:ECDHE+aRSA+CHACHA20:ECDHE+aECDSA+AESGCM:ECDHE+aRSA+AESGCM:ECDHE+aECDSA+AES256+SHA384:ECDHE+aRSA+AES256+SHA384:ECDHE+aECDSA+AES256+SHA:ECDHE+aRSA+AES256+SHA';

5 局限性
5.1 OCSP stapling
目前Let’s encrypt使用的中间证书和RSA证书是同一个,因此如果同时使用certbot生成的ECDSA和RSA双证书时,在nginx的OCSP stapling配置部分的ssl_trusted_certificate用0000_chain.pem或者chain.pem都可以,目前这两个中间证书其实是同一个证书。官方预计在2017年3月31日前使用ECDSA算法的中间证书;
5.2 无法自动更新
现在certbot还不能像RSA证书那样智能化的生成并更新ECDSA证书,只能手动运行,而且再次运行时文件名会递增,需要更改文件名或在nginx中更改证书位置。
6 展望
Certbot的作者们早已在github上讨论直接生成双证书的可行性,那将大大简化配置双证书的复杂度,只是还没有具体的时间表。