分类目录归档:Server

在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

为caddy启用tls 1.3

更新日志

20190918

在20190305的更新中,caddy默认支持了tls 1.3,因此以下内容已过时从官网或者github下载使用即可。

nginx启用tls1.3已多时,这里记录下在caddy中启用tls1.3的过程。

安装依赖:

sudo yum -y install docker
service docker start

下载源码:

cd ~
git clone https://github.com/cloudflare/tls-tris.git
go get github.com/mholt/caddy
go get github.com/caddyserver/builds

编译go,使之支持tls1.3:

cd tls-tris; cp _dev/utils/pre-commit .git/hooks/
sudo make -f _dev/Makefile build-all

编译成功,运行如下命令确认:

GOROOT=”/home/$USER/tls-tris/_dev/GOROOT/linux_amd64/” go version
-> go version go1.11.1 linux/amd64

下载并应用caddy补丁:

cd $GOPATH/src/github.com/mholt/caddy
wget https://www.hnrk.io/md/caddy.patch
patch -p1 < caddy.patch

编译caddy:

cd $GOPATH/src/github.com/mholt/caddy/caddy
GOROOT=”/home/$USER/tls-tris/_dev/GOROOT/linux_amd64/” go run build.go

编译成功的caddy在当前目录下。直接替换原caddy后运行即已支持tls 1.3。

使用caddy反向代理deluge的webui

20191007更新

最近用下面的老方法遇到了问题,表现为打开coldawn.com/deluge一片空白,chrome错误代码为:

because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled. 
net::ERR_ABORTED 404 

经过多次尝试,仍然失败。解决办法使使用二级域名反代deluge,如下:

deluge.coldawn.com {
    proxy / http://127.0.0.1:8112 {
      transparent
      websocket
    }
}

访问deluge.coldawn.com即可。

注意将:deluge.coldawn.com改成你自己的二级域名。

老方法

方法很简单,一行搞定,代码如下:

proxy /deluge http://127.0.0.1:8112/ { transparent without /deluge header_upstream X-Deluge-Base "/deluge" }

然后访问自己的域名+/deluge即可,如:

coldawn.com/deluge

为网站开启QUIC的几点注意事项

QUIC的文章比较多了,但是开启起来仍然是件困扰人的事。本文简要记录一下为网站开启QUIC的几点注意事项。

一 QUIC对比现有HTTP2的主要优势:

  • 显著减少连接建立时间
  • 改进的拥塞控制
  • 无对头阻塞的多路复用
  • 前向纠错
  • 连接迁移

二 开启QUIC的注意事项主要有以下几点:

Caddy的13f9c34已经支持QUIC 44、43、39,运行参数中加入-quic

编译caddy时,需要为主分支的quic-go打一个补丁:
cd $GOPATH/src/github.com/mholt/caddy/vendor/github.com/lucas-clemente/quic-go/

vi quic.patch

quic.pathch的内容如下:

From 20719a7c50c1f97ff0f2272010cda5710794c1d0 Mon Sep 17 00:00:00 2001
From: Marten Seemann <martenseemann@gmail.com>
Date: Thu, 29 Nov 2018 20:33:02 +0700
Subject: [PATCH] use the original tls.Config if tls.Config.GetConfigForClient
 returns nil

---
 internal/crypto/cert_chain.go      | 15 ++++++++++-----
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/internal/crypto/cert_chain.go b/internal/crypto/cert_chain.go
index 0c728fd25..45af2952d 100644
--- a/internal/crypto/cert_chain.go
+++ b/internal/crypto/cert_chain.go
@@ -56,8 +56,7 @@ func (c *certChain) GetLeafCert(sni string) ([]byte, error) {
 }
 
 func (c *certChain) getCertForSNI(sni string) (*tls.Certificate, error) {
-	conf := c.config
-	conf, err := maybeGetConfigForClient(conf, sni)
+	conf, err := maybeGetConfigForClient(c.config, sni)
 	if err != nil {
 		return nil, err
 	}
@@ -107,7 +106,13 @@ func maybeGetConfigForClient(c *tls.Config, sni string) (*tls.Config, error) {
 	if c.GetConfigForClient == nil {
 		return c, nil
 	}
-	return c.GetConfigForClient(&tls.ClientHelloInfo{
-		ServerName: sni,
-	})
+	confForClient, err := c.GetConfigForClient(&tls.ClientHelloInfo{ServerName: sni})
+	if err != nil {
+		return nil, err
+	}
+	// if GetConfigForClient returns nil, use the original config
+	if confForClient == nil {
+		return c, nil
+	}
+	return confForClient, nil
 }

patch -p1 < quic.patch

之后再进入caddy目录进行下一步的编译:

cd $GOPATH/src/github.com/mholt/caddy

请升级到目前的最新版 1.11。

  • 在防火墙中为443端口开启udp

          Firewalld:

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

          iptables:

sudo iptables -A INPUT -p udp --dport 443 -j ACCEPT
  • 将Chrome升级到最新版

在chrome://flags/#enable-quic中启用QUIC支持。

三 一个查看QUIC支持情况的命令

curl -I https://www.coldawn.com we get
HTTP/1.1 200 OK
Alt-Svc: quic=":443"; ma=2592000; v="44,43,39"
Cache-Control: max-age=8640000
Content-Type: text/html; charset=UTF-8
Link: <https://www.coldawn.com/wp-json/>; rel="https://api.w.org/"
Server: Caddy
Strict-Transport-Security: max-age=31536000;
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-Powered-By: PHP/7.2.10
X-Xss-Protection: 1; mode=block
Date: Fri, 28 Sep 2018 04:29:41 GMT

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。

为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