标签归档:CentOS 7

在Oracle Cloud免费VPS CentOS 7 系统上开启SELinux和防火墙(firewalld和iptables)情况下安装Web服务器Caddy

参考:

https://src.fedoraproject.org/rpms/caddy/blob/master/f/caddy.spec
https://github.com/caddyserver/caddy/tree/master/dist/init/linux-systemd

本文的亮点在于开启SELinux、防火墙(Firewalld和iptables)情况下,配置caddy。 本文不限于Oracle Cloud云服务,同样适用于其他类似的情况下。

按照以上教程,默认路径为:

  • /usr/local/bin/caddy #caddy程序所在目录
  • /etc/caddy/Caddyfile #caddy配置文件所作目录
  • /etc/ssl/caddy #ssl证书所在目录
  • /var/www/ #网页所在目录

建立www-data用户

caddy服务默认使用www-data用户运行,因此需要建立该用户。教程中为建立用户组为33,但Oracle CentOS 7系统中GID 33被tape占用:

grep '33' /etc/group

使用GID 36建立www-data用户

sudo groupadd -g 36 www-data
sudo useradd \
  -g www-data --no-user-group \
  --home-dir /var/www --no-create-home \
  --shell /usr/sbin/nologin \
  --system --uid 36 www-data

下载并安装caddy

sudo mkdir ~/caddy && cd ~/caddy
sudo wget https://github.com/caddyserver/caddy/releases/download/v1.0.3/caddy_v1.0.3_linux_amd64.tar.gz
sudo tar xvf caddy_v1.0.3_linux_amd64.tar.gz
sudo cp caddy /usr/local/bin

sudo chown root:root /usr/local/bin/caddy

sudo chmod 755 /usr/local/bin/caddy

使caddy能监听443,80端口

sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/caddy

安装systemd服务

sudo cp init/linux-systemd/caddy.service /etc/systemd/system/

sudo chown root:root /etc/systemd/system/caddy.service

sudo chmod 644 /etc/systemd/system/caddy.service

修改servicen内容

sudo vi /etc/systemd/system/caddy.service

需要修改为以下三行:

  1. ExecStart=/usr/local/bin/caddy -quic -log stdout -agree=true -conf=/etc/caddy/Caddyfile -root=/var/tmp
  2. ReadWriteDirectories=/etc/ssl/caddy
  3. AmbientCapabilities=CAP_NET_BIND_SERVICE

说明:

第一行,加入-quic,使caddy开启QUIC协议;

第二行,默认为ReadWritePaths=/etc/ssl/caddy,此时启动caddy服务,会出现如下错误:[ERROR] Making new certificate manager: could not save user: mkdir /etc/ssl/caddy/acme: read-only file system。

第三行,注释掉AmbientCapabilities=CAP_NET_BIND_SERVICE前的#,不用注释应该页没问题。因前面已经setcap过了。

建立caddy配置文件和ssl相关文件夹

sudo mkdir /etc/caddy
sudo touch /etc/caddy/Caddyfile
sudo chown -R www-data:www-data /etc/caddy
sudo chmod 644 /etc/caddy/Caddyfile
sudo mkdir /etc/ssl/caddy
sudo chown www-data:www-data /etc/ssl/caddy
sudo chown -R root:www-data /etc/ssl/caddy
sudo chmod 0770 /etc/ssl/caddy

修改VPS系统内SELinux和防火墙相关设置

将caddy定义为httpd服务

sudo semanage fcontext -a -t httpd_exec_t /usr/local/bin/caddy
sudo restorecon /usr/local/bin/caddy

设置caddy配置文件和ssl相关文件夹SELinux权限

sudo semanage fcontext -a -t httpd_config_t /etc/caddy
sudo semanage fcontext -a -t httpd_config_t /etc/caddy/Caddyfile
sudo semanage fcontext -a -t httpd_sys_rw_content_t /etc/ssl/caddy
sudo restorecon -r /etc/caddy
sudo restorecon -r /etc/ssl/caddy

开启http和https服务,即开启80和443端口,默认为tcp

sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-service=https

允许ACME进行连接以获取证书

sudo setsebool -P httpd_can_network_connect 1

HTTP challenge 端口的SELinux权限

sudo semanage port -a -t http_port_t -p tcp 5033

开启QUIC,需开放udp端口

sudo semanage port --add --type http_port_t --proto udp 80
sudo semanage port --add --type http_port_t --proto udp 443

QUIC-firewalld设置

sudo firewall-cmd --zone=public --add-port=80/udp --permanent
sudo firewall-cmd --zone=public --add-port=443/udp --permanent

保存设置,重启防火墙,以使配置生效

sudo firewall-cmd --reload

在Oracle Cloud后台网页开放端口

进入“实例”,点击“实例信息”下的“虚拟云网络”右侧类似“VirtualCloudNetwork-2019****-****”的按钮并进入;

在“(根)区间中的子网”下,如果存在多个类似“公共子网 pbOp:***-**-1 ”的项目列表,就随便点进去一个

在“安全列表”下,点击并进入“Default Security List for VirtualCloudNetwork-2019****-****”。

编辑“入站规则”下“目的地端口范围”为22那条规则,或者参照这条规则新建也可以。
将“目的地端口范围”下的“22”改为“22,80,443,5033”,然后“保存更改”即可。 系统会自动根据添加的IP生成新的三条规则。

注意:每个端口或范围间隔需要英文逗号。

开启QUIC,需要开放80和443的UDP端口,参照刚才设置的80和433端口新建规则即可,注意在“IP 协议 ”下选择“UDP”。

web站点文件相关设置

建立web站点文件夹

sudo mkdir /var/www
sudo chown -R www-data:www-data /var/www
sudo chmod 555 /var/www
sudo mkdir -p /var/www/example.com

sudo chown -R www-data:www-data /var/www/example.com

sudo chmod -R 555 /var/www/example.com

设置网站文件夹SELinux权限

sudo restorecon -r /var/www

建立web测试页

sudo vi /var/www/example.com/index.html

写入如下内容

<h1>Hello world!</h1>

测试web页

修改Caddyfile,添加站点

sudo vi /etc/caddy/Caddyfile

添加如下内容:

example.com {
     root /var/www/example.com
}

启动caddy服务

sudo systemctl daemon-reload
sudo systemctl start caddy.service
systemctl status caddy

访问example.com,看是否能见到网站页面

如能成功访问,设置开机启动

sudo systemctl enable caddy.service

完毕。

Oracle Cloud免费VPS CentOS 7 系统防火墙(firewalld和iptables)的正确配置方法

不少人不会配置Oracle的防火墙,导致无法访问80或443端口。本文记录为Oracle Cloud的VPS CentOS 7系统正确配置防火墙的步骤,理论上适用于其他系统,如Debian等。

VPS系统的SELinux为开启状态

sestatus

Firewalld为开启状态

sudo firewall-cmd --state

Iptables为开启状态,查看iptables规则

sudo iptables -L -n

一些人的做法是彻底停用防火墙(firewalld),并清除iptables规则,如:

sudo systemctl stop firewalld

sudo systemctl disable firewalld
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -F

但是端口仍然可能不能正常访问,同时我们都知道这肯定不是正确的解决方式。那正确的做法是什么呢?

正确的配置方法为:

  1. 登陆VPS的CentOS 7 系统,配置防火墙(firewalld),开放相关服务和端口;
  2. 登陆Oracle Cloud网页后台,进入实例,在“安全列表”中,修改“入站规则”;
  3. 不要手动修改iptables。

例,要建立一个小网站,需要开放80和443端口,步骤为:

第一步,登陆VPS的CentOS 7系统,修改防火墙设置,增加http和https服务,即开启80和443端口

sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-service=https

重启防火墙以生效

sudo firewall-cmd --reload

第二步,登陆Oracle Cloud网页后台,进行设置

进入“实例”,点击“实例信息”下的“虚拟云网络”右侧类似“VirtualCloudNetwork-2019****-****”的按钮并进入;

在“(根)区间中的子网”下,如果存在多个类似“公共子网 pbOp:***-**-1 ”的项目列表,就随便点进去一个

在“安全列表”下,点击并进入“Default Security List for VirtualCloudNetwork-2019****-****”。

编辑“入站规则”下“目的地端口范围”为22那条规则,或者参照这条规则新建也可以。
将“目的地端口范围”下的“22”改为“22,80,443”,然后“保存更改”即可。 系统会自动根据添加的IP生成新的两条规则。

注意:每个端口或范围间隔需要英文逗号;如果需要增加UDP端口,就在“IP 协议 ”下选择“UDP”。

至此设置完毕,赶紧访问下你的网页吧。

为Oracle Cloud申请的免费VPS CentOS 7 系统升级内核并开启官方原版BBR加速

Oracle 云申请的CentOS 7 系统,自带3.1内核,且为EFI引导,并默认开启SELinux,升级内核开启BBR易出现错误导致无法开机。开启原版BBR需要4.9以上内核,以下内容记录升级内核并开启BBR的过程。

更新系统

sudo yum update -y

查看内核

uname -r

3.10.0-1062.1.1.el7.x86_64

改SELinux为permissive模式

查看SELinux状态,默认开启:

sestatus

将enforcing改为permissive,如下:

sudo vi /etc/sysconfig/selinux

SELINUX=permissive

重启vps:

sudo reboot

开启elrepo源

sudo rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org

sudo yum install https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm

查看可安装内核

yum --disablerepo="*" --enablerepo="elrepo-kernel" list available

安装内核

sudo yum --enablerepo=elrepo-kernel install kernel-ml

查看新内核是否安装成功

rpm -qa | grep kernel

更新引导

这是一个容易出错的地方,以前碰到的启动配置文件,大多是在/boot/grub2/grub.cfg,而该系统为EFI引导,配置文件位置不同。

sudo grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg

列出系统开机的所有启动项

sudo awk -F\' '$1=="menuentry " {print i++ " : " $2}' /boot/efi/EFI/centos/grub.cfg

设置默认启动项

sudo grub2-set-default 0

重启VPS

sudo reboot

查看内核

uname -r
5.3.1-1.el7.elrepo.x86_64

开启bbr(直接抄袭大佬的全部内容)

执行 lsmod | grep bbr,如果结果中没有 tcp_bbr 的话就先执行:

sudo modprobe tcp_bbr
echo "tcp_bbr" | sudo tee --append /etc/modules-load.d/modules.conf

执行

echo "net.core.default_qdisc=fq" | sudo tee --append /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" | sudo tee --append /etc/sysctl.conf

保存生效

sudo sysctl -p

执行

sysctl net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_congestion_control

如果结果都有 bbr,则证明你的内核已开启 BBR。

执行 lsmod | grep bbr,看到有 tcp_bbr 模块即说明 BBR 已启动。

重新开启SELinux

检查有无SELinux相关错误:

sudo cat /var/log/messages | grep "SELinux is preventing"

确保无错误后,再启用SELinux Enforcing 模式

sudo vi /etc/sysconfig/selinux

将permissive改回enforcing,如下修改:

SELINUX=enforcing

重启VPS

sudo reboot

解决CentOS 7 上yum update时出现的Error: Multilib version problems found.

现象描述

CentOS 7.5 系统,sudo yum update,出现如下错误:

Error:  Multilib version problems found. This often means that the root cause is something else and multilib version checking is just pointing out that there is a problem. Eg.:
       
 1. You have an upgrade for audit-libs which is missing some dependency that another package requires. Yum is trying to solve this by installing an older version of audit-libs of the different architecture. If you exclude the bad architecture yum will tell you what the root cause is (which package requires what). You can try redoing the upgrade with --exclude audit-libs.otherarch ... this should give you an error message showing the root cause of the problem.
       
 2. You have multiple architectures of audit-libs installed, but yum can only see an upgrade for one of those architectures.
 If you don't want/need both architectures anymore then you can remove the one with the missing update and everything will work.
       
 3. You have duplicate versions of audit-libs installed already. You can use "yum check" to get yum show these errors. ...you can also use --setopt=protected_multilib=false to remove this checking, however this is almost never the correct thing to do as something else is very likely to go wrong (often causing much more problems).
       
 Protected multilib versions: -2.8.1-3.el7_5.1.i686 != audit-libs-2.8.1-3.el7.x86_64
Error: Protected multilib versions: systemd-libs-219-57.el7_5.1.i686 != systemd-libs-219-57.el7.x86_64

尝试单独更新相关软件包

单独更新audit-libs,失败

sudo yum update audit-libs

Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.usc.edu
 * elrepo-kernel: repos.lax-noc.com
 * epel: mirrors.develooper.com
 * extras: mirrors.xtom.com
 * updates: mirror.hostduplex.com
 * webtatic: us-east.repo.webtatic.com
Resolving Dependencies
--> Running transaction check
---> Package audit-libs.i686 0:2.8.1-3.el7 will be updated
---> Package audit-libs.x86_64 0:2.8.1-3.el7 will be updated
--> Processing Dependency: audit-libs(x86-64) = 2.8.1-3.el7 for package: audit-libs-python-2.8.1-3.el7.x86_64
--> Processing Dependency: audit-libs(x86-64) = 2.8.1-3.el7 for package: audit-2.8.1-3.el7.x86_64
---> Package audit-libs.i686 0:2.8.1-3.el7_5.1 will be an update
---> Package audit-libs.x86_64 0:2.8.1-3.el7_5.1 will be an update
--> Running transaction check
---> Package audit.x86_64 0:2.8.1-3.el7 will be updated
---> Package audit.x86_64 0:2.8.1-3.el7_5.1 will be an update
---> Package audit-libs-python.x86_64 0:2.8.1-3.el7 will be updated
---> Package audit-libs-python.x86_64 0:2.8.1-3.el7_5.1 will be an update
--> Finished Dependency Resolution

Dependencies Resolved
=======================================================================================================================================================
 Package                                  Arch                          Version                                   Repository                      Size
=======================================================================================================================================================
Updating:
 audit-libs                               i686                          2.8.1-3.el7_5.1                           updates                        100 k
 audit-libs                               x86_64                        2.8.1-3.el7_5.1                           updates                         99 k
Updating for dependencies:
 audit                                    x86_64                        2.8.1-3.el7_5.1                           updates                        247 k
 audit-libs-python                        x86_64                        2.8.1-3.el7_5.1                           updates                         75 k

Transaction Summary
=======================================================================================================================================================
Upgrade  2 Packages (+2 Dependent packages)

Total size: 521 k
Is this ok [y/d/N]: y
Downloading packages:
Running transaction check
Running transaction test


Transaction check error:
  package audit-libs-2.8.1-3.el7_5.1.x86_64 is already installed

Error Summary
-------------

单独更新systemd-libs,失败

sudo yum update systemd-libs

Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.usc.edu
 * elrepo-kernel: repos.lax-noc.com
 * epel: mirrors.develooper.com
 * extras: mirrors.xtom.com
 * updates: mirror.hostduplex.com
 * webtatic: us-east.repo.webtatic.com
Resolving Dependencies
--> Running transaction check
---> Package systemd-libs.i686 0:219-57.el7 will be updated
--> Processing Dependency: systemd-libs = 219-57.el7 for package: systemd-219-57.el7.x86_64
--> Processing Dependency: systemd-libs = 219-57.el7 for package: libgudev1-219-57.el7.x86_64
---> Package systemd-libs.x86_64 0:219-57.el7 will be updated
--> Processing Dependency: systemd-libs = 219-57.el7 for package: systemd-219-57.el7.x86_64
---> Package systemd-libs.i686 0:219-57.el7_5.1 will be an update
---> Package systemd-libs.x86_64 0:219-57.el7_5.1 will be an update
--> Running transaction check
---> Package libgudev1.x86_64 0:219-57.el7 will be updated
---> Package libgudev1.x86_64 0:219-57.el7_5.1 will be an update
---> Package systemd-libs.i686 0:219-57.el7 will be updated
--> Processing Dependency: systemd-libs = 219-57.el7 for package: systemd-219-57.el7.x86_64
---> Package systemd-libs.x86_64 0:219-57.el7 will be updated
--> Processing Dependency: systemd-libs = 219-57.el7 for package: systemd-219-57.el7.x86_64
--> Finished Dependency Resolution
Error: Package: systemd-219-57.el7.x86_64 (@base)
           Requires: systemd-libs = 219-57.el7
           Removing: systemd-libs-219-57.el7.i686 (@base)
               systemd-libs = 219-57.el7
           Updated By: systemd-libs-219-57.el7_5.1.i686 (updates)
               systemd-libs = 219-57.el7_5.1
 You could try using --skip-broken to work around the problem
** Found 18 pre-existing rpmdb problem(s), 'yum check' output follows:
....

解决办法

系统是64位的,我们在上一步发现了两个不符合x86_64构架的包全名:

audit-libs.i686 0:2.8.1-3.el7

systemd-libs-219-57.el7.i686


需要做的就是移除它们:

sudo yum remove audit-libs.i686 0:2.8.1-3.el7

sudo yum remove systemd-libs-219-57.el7.i686

然后更新系统即可:
sudo yum update

CentOS 7 上使用Certbot申请通配符证书(ACMEv2 Wildcard Certificates)

通配符证书(泛域名证书)对于小博客来说,毫无用处,但是要赶个时髦。本文记录下申请RSA和ECDSA通配符证书的过程。

1 安装Certbot

签署通配符证书需要Certbot 0.22以上。如果以前安装过certbot,一般是直接yum update即可。如果是全新安装,则如下:
先升级:

yum update -y

查看系统版本:

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

安装epel源:

yum install epel-release -y

安装certbot:

yum install certbot -y

查看certbot版本:

certbot --version certbot 0.22.0

2 申请RSA通配符证书的过程

2.1 用如下命令申请证书

co1dawn.com和*.co1dawn.com换成自己的域名;执行该命令时不依赖nginx。

certbot -d co1dawn.com -d *.co1dawn.com --manual --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory certonly --agree-tos

输入应急邮箱,证书到期前会有邮件提示:

Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel):

如果想跳过输入邮箱的步骤,可在申请命令后面加上:

--register-unsafely-without-email

之后出现如下提示:要公开记录申请该证书的IP地址,是否同意?不同意就无法继续。

-------------------------------------------------------------------------------
NOTE: The IP of this machine will be publicly logged as having requested this
certificate. If you're running certbot in manual mode on a machine that is not
your server, please ensure you're okay with that.

Are you OK with your IP being logged?
-------------------------------------------------------------------------------
(Y)es/(N)o: y

同意之后,出现如下提示,第一个“Press Enter to Continue”处直接回车,第二个“Press Enter to Continue”不要按回车:

-------------------------------------------------------------------------------
Please deploy a DNS TXT record under the name
_acme-challenge.co1dawn.com with the following value:

iLS0NjcdP3RR1KphB6xbbVnKS_NS2uMW-xdDRzz85OM

Before continuing, verify the record is deployed.
-------------------------------------------------------------------------------
Press Enter to Continue             #此处直接回车

-------------------------------------------------------------------------------
Please deploy a DNS TXT record under the name
_acme-challenge.co1dawn.com with the following value:

f3V7aw5GPm5yzNsJFanQQaUFMyVQcqriUe3UjIDUHn0

Before continuing, verify the record is deployed.
-------------------------------------------------------------------------------
Press Enter to Continue             #此处不要按回车
2.2 为DNS解析增加TXT记录

进入自己域名的DNS记录管理页面,增加两条TXT记录,多数情况下,仅需在域名(Name)处填入_acme-challenge,在内容(Target)处填入上一步Certbot生成的内容即可,不同DNS提供商处可能会略有不同,根据实际情况修改:

    Name                                     Target
_acme-challenge             iLS0NjcdP3RR1KphB6xbbVnKS_NS2uMW-xdDRzz85OM
_acme-challenge             f3V7aw5GPm5yzNsJFanQQaUFMyVQcqriUe3UjIDUHn0

稍等片刻,等TXT记录解析生效。查看是否生效的命令和生效后的查询结果如下:

host -t txt _acme-challenge.co1dawn.com
_acme-challenge.co1dawn.com descriptive text "iLS0NjcdP3RR1KphB6xbbVnKS_NS2uMW-xdDRzz85OM" 
_acme-challenge.co1dawn.com descriptive text "f3V7aw5GPm5yzNsJFanQQaUFMyVQcqriUe3UjIDUHn0"
2.3 继续申请证书

当第2.2步查看TXT记录解析成功后,回到申请证书的第2.1步处,直接回车,等待:

Waiting for verification...
Resetting dropped connection: acme-v02.api.letsencrypt.org
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/co1dawn.com-0001/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/co1dawn.com-0001/privkey.pem
   Your cert will expire on 2018-06-14. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot 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

这表示已成功生成新的证书和密钥,修改nginx的配置文件定位新证书和密钥的位置后重启nginx即可。

3 申请ECDSA通配符证书

3.1 首先是生成支持通配符证书的请求文件

步骤请参考这篇文章:使用Let’s Encrypt的Certbot为ngxin生成ECDSA证书,以下内容中的文件名基本和这篇文章相同。
生成ECDSA私钥:

openssl ecparam -genkey -name secp384r1 > ec.key

生成通配符证书的请求文件的命令需要改为:

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:*.co1dawn.com")) -outform der -out ec-der.csr

ec.key 是自己生成的私钥
co1dawn.com 改成自己的域名
ec-der.csr 支持通配符证书的请求文件,假设放到/usr/local/src下,下面会用到

3.2 申请通配符证书

步骤和申请默认的RSA通配符证书基本一致,而且TXT记录相同,无需再次添加了。

certbot -d co1dawn.com -d *.co1dawn.com --manual --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory certonly --csr "/usr/local/src/ec-der.csr"

之后一路回车即可。

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

暂时转向caddy,caddy已经可以支持tls v1.3

更新日志

20180708
OpenSSL于2018年6月8日更新了关于tls 1.3的说明,见此wiki,本文按新wiki修改更新;
主要变化有:OpenSSL目前同时支持“draft-26”, "draft-27" and "draft-28"草案;简化流程,编译时默认开启tls 1.3,无需enable参数;加密算法表达的更新;
Chrome canary 69.0.3484.0 和 Firefox Nightly 63.0a1支持tls1.3 Draft 28。
20180411
Firefox Nightly 61.0a1支持tls1.3 Draft 26。
20180404
IESG批准将TLS 1.3 Draft 28作为TLS version 1.3 的建议标准;
至20180404,Openssl支持的标准为Draft 26。
20180312
Chrome 65正式版已经发布,支持tls1.3 Draft 23。
20180207
修正部分错误。
如果TLSv1.3如期发布,OpenSSL 1.1.1 将于2018年4月17日面向公众发布。对于服务器来说,我还是喜欢CentOS,支持周期很长,折腾一次可以用很长世间,因此以下记录一下在基于LNMP的CentOS 7 系统上启用TLSv1.3的过程。

1 升级系统

yum update

升级后的系统版本为:

cat /etc/centos-release CentOS Linux release 7.5.1804 (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.15.1

获取编译参数:

nginx -V nginx version: nginx/1.15.1 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (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/

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

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/

进入nginx源码目录,并输入如上完整的编译参数。
开始编译:

make

查看编译好的nginx信息:

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

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

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

4 修改nginx配置文件内的ssl_protocols和ssl_ciphers,默认启用TLSv1.3的前三项常用的加密算法

...
ssl_protocols          TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers            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 28, draft 27, draft 26 NPN/SPDY h2, http/1.1 (advertised) ALPN/HTTP2 h2, 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            TLS_AES_256_GCM_SHA384, 253 bit ECDH (X25519)
 Cipher order
    TLSv1:     ECDHE-RSA-AES256-SHA
    TLSv1.1:   ECDHE-RSA-AES256-SHA
    TLSv1.2:   ECDHE-RSA-CHACHA20-POLY1305 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES256-SHA
    TLSv1.3:   TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256
5.2 使用现代浏览器

Chrome canary 69.0.3484.0 和 Firefox Nightly 63.0a1已经支持tls1.3 Draft 28。