开始使用 EiBlog

自从上个月换用 VPS 建站以来,JerryQu 的小站上的文章给了我极大的帮助和启发,我尽力去实现他所提到和用到的功能。然而毕竟能力有限,又没有深入系统地学习过 Web 服务器的相关内容,因此照猫画虎却不得其要领。再加上十分喜欢他网站的布局和配色,所以一直期待他网站的开源。

就在几天前,偶然发现 Deepzz 将 Jerry Qu 的博客部署了出来,开源到了 GitHub,并附上了完善的安装文档。

Exciting !!!

感谢 Deepzz 和 Jerry Qu,向两位大神致敬。

断断续续花了三天时间,终于搭建成功。中间遇到了许多问题,参考了许多文章,以下作为一个记录和整合。

搜索功能暂时不能使用,找不到原因,不知道该如何解决。

环境准备

以下命令均是在 Ubuntu 16.04.3 LTS 环境下进行的,请根据实际的系统做适当修改。

SSH 连接

在 macOS 下可以直接使用系统自带的「终端」来连接。

ssh username@ip/domain -p port

# e.g.
# ssh root@1.12.23.123 -p 69
# ssh joey@example.com -p 96

在 Windows 下可以借助 PuTTY 等软件来连接。

修改密码 & 添加用户

# 修改 root 用户的密码
passwd root

# 添加新用户
adduser newusername

# 为新用户添加 sudo 权限
gpasswd -a newusername sudo

# 避免后面的更新出问题
reboot

系统更新

sudo dpkg --configure -a
sudo apt-get update
sudo apt-get -y upgrade
reboot

更新内核 & 开启 BBR

su root
wget --no-check-certificate https://github.com/teddysun/across/raw/master/bbr.sh
chmod +x bbr.sh
./bbr.sh

安装依赖

sudo apt-get install -y unzip autoconf libtool python-pip
sudo pip install --upgrade pip
sudo pip install virtualenv

安装 Nginx

先建立一个目录,后面下载的内容全都放到这个目录里,安装完成之后可以方便地删除。

mkdir install && cd install

安装 PCRE

PCRE各个版本

wget https://ftp.pcre.org/pub/pcre/pcre-8.41.tar.gz
tar -zxf pcre-8.41.tar.gz && cd pcre-8.41
./configure
make
sudo make install
cd ../

安装 zlib

zlib各个版本

wget https://zlib.net/zlib-1.2.11.tar.gz
tar -zxf zlib-1.2.11.tar.gz && cd zlib-1.2.11
./configure
make
sudo make install
cd ../

获取 nginx-ct

wget -O nginx-ct-1.3.2.zip -c https://github.com/grahamedgecombe/nginx-ct/archive/v1.3.2.zip
unzip nginx-ct-1.3.2.zip

安装 libbrotli

git clone https://github.com/bagder/libbrotli
cd libbrotli
./autogen.sh
./configure
make
sudo make install
cd  ../

获取 ngx_brotli

git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli
git submodule update --init
cd ../

获取 OpenSSL

为了支持 TLS 1.3,获取的是 OpenSSL 1.1.1 的 draft-18 分支。

git clone -b tls1.3-draft-18 --single-branch https://github.com/openssl/openssl.git openssl

安装 Nginx

Nginx各个版本

wget https://nginx.org/download/nginx-1.13.3.tar.gz
tar -zxf nginx-1.13.3.tar.gz && cd nginx-1.13.3
./configure --add-module=../ngx_brotli --add-module=../nginx-ct-1.3.2 --with-openssl=../openssl --with-openssl-opt='enable-tls1_3 enable-weak-ssl-ciphers' --with-http_v2_module --with-http_ssl_module --with-http_gzip_static_module

# 在这里需要修改一下编译的文件,否则会遇到[奇怪的错误](https://github.com/openssl/openssl/issues/3884)。
vim ./objs/Makefile
# 修改第 415 行的内容,将「-lpthread」移到该行最后面的「\」前面
# -ldl -lpthread -lcrypt -lm -lpcre ../openssl/.openssl/lib/libssl.a ../openssl/.openssl/lib/libcrypto.a -ldl -lz \
# 修改为
# -ldl -lcrypt -lm -lpcre ../openssl/.openssl/lib/libssl.a ../openssl/.openssl/lib/libcrypto.a -ldl -lz -lpthread \

make
sudo make install
cd ../

配置 Nginx

sudo vim /etc/init.d/nginx

Ubuntu 参考本博客 Nginx 配置之完整篇,将以下内容粘贴进去。

#! /bin/sh

### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the nginx web server
# Description:       starts nginx using start-stop-daemon
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/nginx/sbin/nginx
NAME=nginx
DESC=nginx

test -x $DAEMON || exit 0

# Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
  . /etc/default/nginx
fi

set -e

. /lib/lsb/init-functions

case "$1" in
  start)
    echo -n "Starting $DESC: "
    start-stop-daemon --start --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
        --exec $DAEMON -- $DAEMON_OPTS || true
    echo "$NAME."
    ;;
  stop)
    echo -n "Stopping $DESC: "
    start-stop-daemon --stop --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
        --exec $DAEMON || true
    echo "$NAME."
    ;;
  restart|force-reload)
    echo -n "Restarting $DESC: "
    start-stop-daemon --stop --quiet --pidfile \
        /usr/local/nginx/logs/$NAME.pid --exec $DAEMON || true
    sleep 1
    start-stop-daemon --start --quiet --pidfile \
        /usr/local/nginx/logs/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS || true
    echo "$NAME."
    ;;
  reload)
    echo -n "Reloading $DESC configuration: "
    start-stop-daemon --stop --signal HUP --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
        --exec $DAEMON || true
    echo "$NAME."
    ;;
  status)
    status_of_proc -p /usr/local/nginx/logs/$NAME.pid "$DAEMON" nginx && exit 0 || exit $?
    ;;
  *)
    N=/etc/init.d/$NAME
    echo "Usage: $N {start|stop|restart|reload|force-reload|status}" >&2
    exit 1
    ;;
esac

exit 0

CentOS 参考这里,将以下内容粘贴进去。

#!/bin/sh
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15
# description:  NGINX is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /usr/local/nginx/nginx.conf
# config:      /etc/sysconfig/nginx
# pidfile:     /var/run/nginx.pid /usr/local/nginx/logs
# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)

NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"

[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx

lockfile=/usr/local/nginx/logs/nginx.lock

make_dirs() {
    #make required directories

   user=`$nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`

   options=`$nginx -V 2>&1 | grep 'configure arguments:'`
   for opt in $options; do
       if [ `echo $opt | grep '.*-temp-path'` ]; then
           value=`echo $opt | cut -d "=" -f 2`
           if [ ! -d "$value" ]; then
               # echo "creating" $value
               mkdir -p $value && chown -R $user $value
           fi
       fi
   done
}  

start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    make_dirs
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

restart() {
    configtest || return $?
    stop
    sleep 1
    start
}

reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
}

force_reload() {
    restart
}

configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}

rh_status() {
    status $prog
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac

添加执行权限

sudo chmod a+x /etc/init.d/nginx

尝试启动

# Ubuntu
sudo service nginx start 

# Ubuntu & CentOS
sudo /etc/init.d/nginx start

假如遇到 nginx.service 错误,依次运行下面四条命令。

sudo vim /lib/systemd/system/nginx.service
sudo systemctl daemon-reload
sudo rm /lib/systemd/system/nginx.service
sudo systemctl daemon-reload

设置开机自动启动 Nginx。

sudo update-rc.d -f nginx defaults

现在在浏览器中输入 VPS 的 IP 地址,如果看到 Nginx 的欢迎界面,说明已经安装成功。

安装 Docker

这里使用比较简单的脚本安装,其他安装方式参考官方文档

curl -fsSL get.docker.com -o get-docker.sh
sudo sh get-docker.sh

安装 Docker Compose

经过尝试,这里必须切换回 root 用户才能安装。

su root
curl -L https://github.com/docker/compose/releases/download/1.15.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
su rs

部署 Eiblog

获取镜像

sudo docker pull registry.cn-hangzhou.aliyuncs.com/deepzz/eiblog:v1.3.0
sudo docker pull mongo:3.5.11
sudo docker pull elasticsearch:2.4.1

添加配置文件

sudo mkdir -p /data/eiblog
git clone https://github.com/eiblog/eiblog.git
sudo mv ./eiblog/conf/ /data/eiblog
mv ./eiblog/docker-compose.yml ~/
sudo mkdir -p /data/eiblog/conf/es/config/scripts

尝试启动 EiBlog

cd ~
sudo docker-compose up -d

现在在浏览器中输入 VPS 的「IP 地址:9000」,如 1.12.23.123:9000,如果看到 EiBlog 的界面,说明已经部署成功。

修改配置文件

eiblog.conf

位于 /data/eiblog/conf/nginx/domain/,是 Nginx 的配置文件,至关重要。它的合理配置,是网站顺利运行的关键。

所有的 deepzz.com 都应改成自己的域名。

证书部分要仔细配置。ssl_ct 根据自己的实际情况选择启用还是关闭;ssl_dhparamssl_ct_static_scts 根据自己的实际情况合理设置路径;ssl_ciphersssl_protocols 根据自己的实际情况设置包含哪些项。这部分可以在完成后面几项之后再返回来设置。

app.yml

位于 /data/eiblog/conf/,是 EiBlog 的配置文件,包含了 Disqus、Google 统计、静态资源、网站后台等一系列设置,是 EiBlog 能否发挥全部功力的关键。

Disqus 部分必须修改,否则网站的所有评论都会发送给 Deepzz 的账户。

Google 统计暂时没有启用,因为没几个人访问。

CDN 经过实际测试,并不一定是七牛。在将 st.days.one 解析到之前购买的香港虚拟主机后,也可以正常使用。

docker-compose.yml

位于 ~/,是 Docker Compose 的配置文件,包含了 EiBlog 运行所需的三个镜像的配置,镜像的名称和 tag 要和前面 pull 的镜像名称和 tag 保持一致,否则将无法启动 EiBlog。

申请 Let’s Encrypt 证书

这里使用 acme.sh 这个强大的工具。

安装 acme.sh

curl  https://get.acme.sh | sh

清空 EiBlog 里带的证书并创建新证书的存放路径

sudo rm -rf /data/eiblog/conf/ssl
sudo rm -rf /data/eiblog/conf/scts

mkdir -p /data/eiblog/conf/ssl
mkdir -p /data/eiblog/conf/scts/rsa
mkdir -p /data/eiblog/conf/scts/ecc

申请 RSA 证书

sudo "/home/rs/.acme.sh"/acme.sh --issue -d example.com -d st.example.com -d www.example.com -w /home/blog/ -k 4096

将 RSA 证书放置到正确位置

sudo "/home/rs/.acme.sh"/acme.sh --install-cert -d example.com --key-file /data/eiblog/conf/ssl/domain.rsa.key --fullchain-file /data/eiblog/conf/ssl/domain.rsa.pem --reloadcmd "service nginx restart"

申请 ECDSA 证书

sudo "/home/rs/.acme.sh"/acme.sh --issue -d example.com -d st.example.com -d www.example.com -w /home/blog/ -k ec-256

将 ECDSA 证书放置到正确位置

sudo "/home/rs/.acme.sh"/acme.sh --ecc --install-cert -d example.com --key-file /data/eiblog/conf/ssl/domain.ecc.key --fullchain-file /data/eiblog/conf/ssl/domain.ecc.pem --reloadcmd "service nginx restart"

生成迪菲-赫尔曼密钥

openssl dhparam -out /data/eiblog/conf/ssl/dhparams.pem 2048

最后几项

HPKP

这一部分在 eiblog.conf 的众多 add_header 中,里面默认存在的是 Deepzz 的证书的 Key,与自己申请的 SSL 证书的 Key 不完全相同。

开启它十分简单,参考 HTTP Public Key Pinning 介绍

由于使用了双证书,因此分别生成了「站点 RSA 证书」、「站点 ECDSA 证书」、「Let’s Encrypt 中间证书」和「根证书」四个证书的 Key,他们的排列顺序不是任意的,应该按照站点证书、中间证书、根证书这样由小到大的顺序串成链,否则将无法开启 HPKP。

Certificate Transparency

这部分在 eiblog.conf 中比较靠前的部分,不是必须的,假如不开启,则 eiblog.conf 中的 ssl_ct 应当设为 offssl_ct_static_scts 也应注释掉。

开启它十分简单,参考 Certificate Transparency 那些事

Nginx 和 EiBlog 的配合

proxy_pass 的设置是 Nginx 和 EiBlog 能否顺利接合的关键。

proxy_pass 中的端口(默认是 9000),应和 docker-compose.yml 中 eiblog 部分 : 前面的端口(默认是 9000)保持一致。这样才能保证 Nginx 正确地输出 EiBlog 所输出地内容。

app.yml 应设为 http mode,其端口(默认是 9000)应和 docker-compose.yml 中 eiblog 部分 : 后面的端口(默认是 9000)保持一致。这样才能保证 EiBlog 正确地输出内容。

这一部分不建议修改,默认即可。

结束

到这里,所有的准备工作都已经结束,应该去认真配置 eiblog.conf 了。

如果一切顺利,将可以顺利从 https://example.com 访问到网站,并且所有的 http 请求会被跳转到相应的 https。

通过 SSL LabsHTTP Security Report 可以检测 SSL 的各项配置是否正确。

参考

本文链接:参与评论 »

--EOF--

专题「网站」的其它文章 »

Comments