安裝 Ghost

背景

一直想有一個(gè)個(gè)人博客空間,之前使用過自建的 WordPress,但是后來沒有堅(jiān)持下來。后來學(xué)會(huì)了 Node.js,想用 Node.js 開發(fā)的個(gè)人博客系統(tǒng),之前查到過 Ghost,因?yàn)槭褂玫氖?Mysql 數(shù)據(jù)庫,所以沒有想使用。由于最近要重做管理平臺(tái),數(shù)據(jù)庫計(jì)劃由 MongoDB 遷移到 Mysql,所以有了使用 Ghost 的充分理由。

目標(biāo)

  • 正常安裝 Ghost;
  • 正常使用 Ghost;
  • 學(xué)習(xí) Ghost 的代碼;
  • Mysql 的連接和使用部分;
  • 權(quán)限管理部分;
  • 業(yè)務(wù)部分;
  • 配置文件;
  • 啟動(dòng)文件;

安裝過程

安裝 Ghost

第一次使用 Ghost-CLI 安裝,提示一下內(nèi)容:

? Linux version is not Ubuntu 16,? Missing package: systemd,? Missing package: nginx

看來只有在 Ubuntu 16 上才可以使用 Ghost-CLI,我的 Centos 7 自然是不行了。因此采用最傳統(tǒng)的安裝方式。

  1. 下載最新的 Ghost 版本

    curl -L https://ghost.org/zip/ghost-latest.zip -o ghost.zip

  2. 解壓到指定文件夾

    unzip ghost.zip -d ./ghost/

  3. 安裝運(yùn)行所需要的依賴包

    npm install --production

  4. 測試運(yùn)行

    npm start --production

  5. 建立 PM2 配置文件,使用 PM2 運(yùn)行 Ghost

    pm2 ecosystem
    pm2 start ecosystem.config.js

  6. 配置 Nginx

  7. 將數(shù)據(jù)庫從 SQLite3 更換為 MariaDB,修改配置文件 config.js

database: {
  client: 'mysql',
  connection: {
    host     : '127.0.0.1',
    user     : 'your_database_user',
    password : 'your_database_password',
    database : 'ghost_db',
    charset  : 'utf8'
  }
}

配置 HTTPS

  1. 安裝 certbot;
  2. 修改原有 Nginx 配置文件;
  3. 下載證書;
  4. 再次編輯 Nginx 配置文件,啟用 HTTP2 和 HTTPS;
  5. 定期自動(dòng)更新證書

安裝 certbot

sudo yum install epel-release
sudo yum install certbot

修改原有 Nginx 配置文件

Let's encrypt 為了鑒定域名的所有權(quán),會(huì)在域名下的 /.well-known/acme-challenge 路徑下放置一個(gè)文件,并做相應(yīng)的鑒權(quán),因此需要保證相關(guān)路徑能夠正確的解析,最簡單的辦法就是直接修改 Nginx 配置文件。

location ^~ /.well-known/acme-challenge/ {
  root /usr/share/nginx/html;
}

location = /.well-known/acme-challenge/ {
  return 404;
}

下載證書

certbot certonly --webroot -w /usr/share/nginx/html/ -d domain1.com -d domain2.com

然后就會(huì)進(jìn)入安裝界面,提示輸入郵箱地址等信息,然后就安裝完畢了。證書文件被保存在 /etc/letsencrypt/live/domain.com/fullchain.pem 下。

再次編輯 Nginx 配置文件,啟用 HTTP2 和 HTTPS

upstream my_nodejs_upstream {
    server 127.0.0.1:2368;
    keepalive 64;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name domain.com;

# Redirect all HTTP requests to HTTPS with a 301 Moved
Permanently response.
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name domain.com;

    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    # intermediate configuration. tweak to your needs.
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
    ssl_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;

    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

    resolver 8.8.8.8 8.8.4.4;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_max_temp_file_size 0;
        proxy_pass http://my_nodejs_upstream/;
        proxy_redirect off;
        proxy_read_timeout 240s;
    }

    location ^~ /.well-known/acme-challenge/ {
        root    /usr/share/nginx/html;
    }

    location = /.well-known/acme-challenge/ {
        return 404;
    }
}

其中,ssl_certificate 開頭的和 ssl_certificate_key 開頭的這句分別對應(yīng)剛剛下載好的證書。
另外,ssl_dhparam 開頭的這句指向的證書需要通過以下代碼來生成。

sudo mkdir /etc/nginx/ssl
sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

定期自動(dòng)更新證書

因?yàn)?Let's encrypt 證書的有效期限是 90 天,因此在 90 天必須要更新證書以避免證書失效。根據(jù) Certbot 官網(wǎng)所述,只有在臨近到期時(shí)才會(huì)真正更換證書,因此最好的每天執(zhí)行更新命令,確保證書及時(shí)更新。

測試更新命令

使用以下命令測試更新證書,但并不會(huì)真的更新。

sudo certbot renew --dry-run

設(shè)置更新證書定時(shí)任務(wù)

首先創(chuàng)建定制任務(wù)

sudo crontabe -e

然后在文件中加入以下語句,表示在每天的 3 點(diǎn) 43 分嘗試更新證書,如果證書更新成功,則重啟 Nginx 服務(wù)以便讀取新證書

43 3 * * * certbot renew --quiet --post-hook "systemctl reload nginx"

測試定時(shí)更新語句

為確保定時(shí)更新語句有效,最好單獨(dú)測試一下,直接輸入以下語句看執(zhí)行結(jié)果

certbot renew --quiet --post-hook "systemctl reload nginx"

應(yīng)該會(huì)提示還不需要更新,不過不要緊,只要測試語句有效就可以了。至此,HTTP2 和 HTTPS 的配置全部完畢。

測試配置成果

測試服務(wù)器 SSL 的安全性

Qualys SSL Labs 提供了全面的 SSL 安全性測試,填寫你的網(wǎng)站域名,給自己的 HTTPS 配置打個(gè)分。

如果安裝本教程來配置,正常情況下應(yīng)該會(huì)得到 A+ 的得分。

測試 HTTP2

Chrome 下有個(gè)插件叫做 HTTP/2 and SPDY indicator??梢岳盟鼇聿榭丛L問的站點(diǎn)是否支持 HTTP2。

HTTP2 的問題

話說 HTTP2 之前有 2 種實(shí)現(xiàn)的協(xié)商協(xié)議,分別是 NPN 和 ALPN,后來 Chrome 就只支持 ALPN 了。但當(dāng)前大部分服務(wù)器的 OpenSSL 都是1.01e 版本,只支持 NPN。因此按照本教程部署完畢后,使用 Chrome 剛剛配置好的站點(diǎn)的時(shí)候發(fā)現(xiàn)還是不能使用 HTTP2,還需要在服務(wù)器上做一些調(diào)整才可以。

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容