使用ssh密钥方式部署Hexo到自己的服务器, 并使用nginx进行访问

这个真的是折腾死我了, 用git啥的我的主服务器ssh端口又不是22, 找了半天配端口没找到, 试了rsync, windows还要安装太麻烦…http访问git没时间搞…最后sftp满足使用, 但是网上教程少之又少, 而且提示给的贼不明确, 走了不少弯路, 走了2小时才走通. 说到底是, 我马虎, 权限配错的锅, 简短记录一下.

(English version translate by GPT-3.5)

减少踩坑的检查

  1. 确保权限正确, id_rsa, authorized_keys的权限是600``, .ssh目录权限是700
  2. 确保部署的目录已经创建好

准备工作

  1. 准备一台云服务器
  2. 准备好nginx的用户和组, nginx安装将跳过, 这里假设nginx的用户是nginx, 组是nginx.
  3. 安装好npm, 并有hexo待部署, 这里npm安装, hexo初始化将跳过.

服务器端生成密钥

一般情况下, 极其不推荐去生成一个root的密钥, 这里推荐使用一个低权限的子用户, 这样要崩也是hexo崩掉了.

  1. 首先创建一个新的用户, 就叫hexo

    1
    2
    3
    4
    [root@VM_0_7_centos nginx]# useradd -g nginx -s /bin/bash hexo
    [root@VM_0_7_centos nginx]#

    这表示创建一个隶属于nginx组的用户, -s是指指定用户登入后所使用的shell, 如果不希望用户能登陆, 可以指定/sbin/nologin
  2. 因为使用密钥登陆, 因此密码啥的就不创建了, 使用su hexo登陆这个用户

    1
    2
    [root@VM_0_7_centos nginx]# su hexo
    [hexo@VM_0_7_centos nginx]$
  3. 使用 ssh-keygen -t rsa来生成密钥, 将有如下步骤

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    [hexo@VM_0_7_centos nginx]$ ssh-keygen -t rsa
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/hexo/.ssh/id_rsa): # 将密钥保存到括号的目录, 直接回车即可
    Created directory '/home/hexo/.ssh'.
    Enter passphrase (empty for no passphrase): # 输入密钥的密码(类似于pin, 只对改密钥生效, 输入过程不会显示)
    Enter same passphrase again: # 再次输入密钥的密码(依然不会显示)
    Your identification has been saved in /home/hexo/.ssh/id_rsa.
    Your public key has been saved in /home/hexo/.ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:bu2oc2gNB7QPN8eIMDz2rph/YieoMVKUSM3VLRXAFVo hexo@VM_0_7_centos
    The key's randomart image is:
    +---[RSA 2048]----+
    | .o...o.=Eo |
    |.. +* .+o. |
    |. o. * +.o |
    | . * + o |
    | . . =So |
    | . o.o. |
    |+ + . =o . |
    |.o+ = *.oo |
    |.. o.*.+. . |
    +----[SHA256]-----+
    [hexo@VM_0_7_centos nginx]$ # 创建完成
  4. 可以看到在~/.ssh目录下生成了如下的文件

    1
    2
    3
    4
    5
    6
    [hexo@VM_0_7_centos nginx]$ cd ~/.ssh/
    [hexo@VM_0_7_centos .ssh]$ ll
    total 8
    -rw------- 1 hexo nginx 1766 Jan 20 16:45 id_rsa
    -rw-r--r-- 1 hexo nginx 400 Jan 20 16:45 id_rsa.pub
    [hexo@VM_0_7_centos .ssh]$
  5. 将公钥复制到authorized_keys中, 使用命令 cat id_rsa.pub >> authorized_keys

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    为什么一定要是authorized_keys的文件, 可以看到/etc/ssh/sshd_config的配置中定义了, 默认使用.ssh/authorized_keys的里存储的密钥信息, 当然也可以把它改成id_rsa.pub

    .
    .
    #LoginGraceTime 2m
    #PermitRootLogin yes
    #StrictModes yes
    #MaxAuthTries 6
    #MaxSessions 10

    #PubkeyAuthentication yes

    # The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
    # but this is overridden so installations will only check .ssh/authorized_keys
    AuthorizedKeysFile .ssh/authorized_keys

    #AuthorizedPrincipalsFile none

    #AuthorizedKeysCommand none
    #AuthorizedKeysCommandUser nobody
    .
    .

  6. 将authorized_keys权限改成600 chmod 600 authorized_keys , 不然其他用户得到了公钥就不好了.

    1
    2
    3
    4
    5
    6
    7
    8
    [hexo@VM_0_7_centos .ssh]$ ll
    total 12
    -rw-r--r-- 1 hexo nginx 400 Jan 20 16:50 authorized_keys # 可以看到authorized_keys默认是644的权限, 这样届时登陆会被拒绝掉的.
    -rw------- 1 hexo nginx 1766 Jan 20 16:45 id_rsa
    -rw-r--r-- 1 hexo nginx 400 Jan 20 16:45 id_rsa.pub
    # 更改为600
    [hexo@VM_0_7_centos .ssh]$ chmod 600 authorized_keys
    [hexo@VM_0_7_centos .ssh]$
  7. 新建一个文件夹, 到时候hexo的内容就存在这个文件夹, 我这里用root新建一个/usr/hexoWeb, 并chmod -R 755 /usr/hexoWeb将权限改为自己读写, 他人仅可读和执行, 并将用户组改成hexo:nginx chown -R hexo:nginx /usr/hexoWeb

  8. 编辑id_rsa私钥, 然后复制出里面的内容, 直接vi复制也行, ssh过去取出来也行, cat出来然后复制也行, 建一个txt文件, 然后粘贴在里面保存即可 ,至此, 服务器端配置完毕, 可以删掉服务器上生成的id_rsa和id_rsa.pub了, 一个已经复制过来了, 一个已经合并在authorized_keys里面了.

Hexo配置sftp

  1. 我初始化了一个hexo, 反正hexo init运行超快的. 目录文件结构是这样子的, 我直接把刚刚复制的key丢在了根目录最后一个文件.

    hexo dir
    初始的Hexo是这样子的(NexT好可怕..改的根本就是2个风格…)
    hexo page

  2. 根据官方SFTP的安装方法, 需要先装一个叫做hexo-deployer-sftp的组件, cd /d到Hexo根目录, 运行npm install hexo-deployer-sftp --save, 也可以npm install cnpm, 然后再cnpm install hexo-deployer-sftp --save, 会快点 直接执行也行.

    1
    2
    3
    4
    5
    6
    7
    D:\hexoTest>cnpm install hexo-deployer-sftp --save
    √ Installed 1 packages
    √ Linked 19 latest versions
    √ Run 0 scripts
    anti semver hexo-deployer-sftp@0.1.0 › sftp-sync-deploy@0.5.0 › @types/ssh2-streams@0.1.4 › @types/node@* delcares @types/node@*(resolved as 10.12.18) but using ancestor(sftp-sync-deploy)'s dependency @types/node@^6.0.51(resolved as 6.14.2)
    anti semver hexo-deployer-sftp@0.1.0 › sftp-sync-deploy@0.5.0 › @types/ssh2@0.5.37 › @types/node@* delcares @types/node@*(resolved as 10.12.18) but using ancestor(sftp-sync-deploy)'s dependency @types/node@^6.0.51(resolved as 6.14.2)
    √ All packages installed (20 packages installed from npm registry, used 501ms(network 489ms), speed 150.21kB/s, json 20(73.46kB), tarball 0B)
  3. 配置sftp, sftp配置实例是这样子的, 可以看到必填的是type, host, user

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Example:
    deploy:
    type: sftp
    host: <host>
    port: [port] # Default is 21 # 注意, 一般的ssh是22, 估计是官方打错了, 源码默认是22的(21是FTP端口)
    user: <user>
    pass: <pass> # leave blank for paswordless connections
    privateKey: [path/to/privateKey] # Optional
    passphrase: [passphrase] # Optional
    agent: [path/to/agent/socket] # Optional, defaults to $SSH_AUTH_SOCK
    remotePath: [remotePath] # Default is `/`
  4. 最后我的配置是这样子的

    1
    2
    3
    4
    5
    6
    7
    deploy:
    type: sftp
    host: 118.*.*.219
    user: hexo
    privateKey: privatekey.txt
    remotePath: /usr/hexoWeb
    passphrase: testtest # 如果没有就不填
  5. 最后运行, hexo hexo d (或者是hexo deploy) , 顺利结束.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    D:\hexoTest>hexo d
    INFO Start processing
    INFO Files loaded in 266 ms
    INFO Generated: index.html
    INFO Generated: archives/index.html
    INFO Generated: fancybox/blank.gif
    INFO Generated: fancybox/jquery.fancybox.css
    INFO Generated: fancybox/fancybox_loading@2x.gif
    INFO Generated: fancybox/fancybox_sprite.png
    INFO Generated: fancybox/fancybox_overlay.png
    INFO Generated: archives/2019/01/index.html
    INFO Generated: fancybox/helpers/fancybox_buttons.png
    INFO Generated: fancybox/fancybox_loading.gif
    INFO Generated: archives/2019/index.html
    INFO Generated: fancybox/fancybox_sprite@2x.png
    INFO Generated: css/fonts/FontAwesome.otf
    INFO Generated: js/script.js
    INFO Generated: fancybox/jquery.fancybox.pack.js
    INFO Generated: css/style.css
    INFO Generated: fancybox/helpers/jquery.fancybox-buttons.css
    INFO Generated: fancybox/helpers/jquery.fancybox-media.js
    INFO Generated: fancybox/helpers/jquery.fancybox-buttons.js
    INFO Generated: fancybox/helpers/jquery.fancybox-thumbs.js
    INFO Generated: css/fonts/fontawesome-webfont.eot
    INFO Generated: fancybox/helpers/jquery.fancybox-thumbs.css
    INFO Generated: css/fonts/fontawesome-webfont.woff
    INFO Generated: css/images/banner.jpg
    INFO Generated: css/fonts/fontawesome-webfont.ttf
    INFO Generated: css/fonts/fontawesome-webfont.svg
    INFO Generated: 2019/01/20/hello-world/index.html
    INFO Generated: fancybox/jquery.fancybox.js
    INFO 28 files generated in 550 ms
    INFO Deploying: sftp
    * Deploying to host 118.*.*.219
    * local dir = D:\hexoTest\public
    * remote dir = /usr/hexoWeb

    file uploaded : index.html
    file uploaded : js/script.js
    sync completed : js
    file uploaded : archives/index.html
    file uploaded : css/style.css
    file uploaded : fancybox/blank.gif
    file uploaded : fancybox/fancybox_overlay.png
    file uploaded : fancybox/fancybox_sprite@2x.png
    file uploaded : fancybox/fancybox_loading@2x.gif
    file uploaded : fancybox/fancybox_sprite.png
    file uploaded : fancybox/fancybox_loading.gif
    file uploaded : fancybox/jquery.fancybox.pack.js
    file uploaded : fancybox/jquery.fancybox.css
    file uploaded : fancybox/jquery.fancybox.js
    file uploaded : fancybox/helpers/fancybox_buttons.png
    file uploaded : fancybox/helpers/jquery.fancybox-buttons.css
    file uploaded : fancybox/helpers/jquery.fancybox-buttons.js
    file uploaded : fancybox/helpers/jquery.fancybox-media.js
    file uploaded : fancybox/helpers/jquery.fancybox-thumbs.css
    file uploaded : fancybox/helpers/jquery.fancybox-thumbs.js
    sync completed : fancybox/helpers
    sync completed : fancybox
    file uploaded : css/fonts/fontawesome-webfont.eot
    file uploaded : css/fonts/fontawesome-webfont.svg
    file uploaded : css/fonts/fontawesome-webfont.woff
    file uploaded : css/fonts/fontawesome-webfont.ttf
    file uploaded : css/fonts/FontAwesome.otf
    sync completed : css/fonts
    file uploaded : css/images/banner.jpg
    sync completed : css/images
    sync completed : css
    file uploaded : archives/2019/index.html
    file uploaded : archives/2019/01/index.html
    sync completed : archives/2019/01
    sync completed : archives/2019
    sync completed : archives
    file uploaded : 2019/01/20/hello-world/index.html
    sync completed : 2019/01/20/hello-world
    sync completed : 2019/01/20
    sync completed : 2019/01
    sync completed : 2019
    INFO Deploy done: sftp

    D:\hexoTest>
  6. 去服务端看到文件已经上去了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [hexo@VM_0_7_centos hexoWeb]$ pwd
    /usr/hexoWeb
    [hexo@VM_0_7_centos hexoWeb]$ ll
    total 28
    drwxr-xr-x 3 hexo nginx 4096 Jan 20 17:32 2019
    drwxr-xr-x 3 hexo nginx 4096 Jan 20 17:32 archives
    drwxr-xr-x 4 hexo nginx 4096 Jan 20 17:32 css
    drwxr-xr-x 3 hexo nginx 4096 Jan 20 17:32 fancybox
    -rw-r--r-- 1 hexo nginx 6659 Jan 20 17:33 index.html
    drwxr-xr-x 2 hexo nginx 4096 Jan 20 17:32 js
    [hexo@VM_0_7_centos hexoWeb]$

配置Nginx

  1. 打开nginx.conf配置, 添加如下即可

    img

  2. 访问IP, 发现可以访问了

    img

  3. 试着发一篇文章上去, 标题和内容都是 这是新的文章, 然后再部署上去

    1
    2
    3
    4
    D:\hexoTest>hexo new 这是新的文章
    INFO Created: D:\hexoTest\source\_posts\这是新的文章.md

    D:\hexoTest>
  4. Ctrl+F5强制刷新下, 发现已经部署上去了.

    img

常见错误

  1. Error: Connection Error: All configured authentication methods failed

    1. 表示配置中的信息填写不正确, 不能通过配置中的信息连接到远程服务器, 检查下配置的每一个参数, 然后再试一次, 最好tail -f /var/log/secure看下服务器是否有登录日志, 只要登录到服务器, 不管是否成功都会有日志, 先排除网络问题.
    2. 服务器的.ssh目录确保是700权限, authorized_keys确保是600权限(似乎655也行, 即.ssh除了自己外, 其他人不能有写入权限)
    3. 确保填写的用户名和生成密钥的用户名是同一个
    4. 如果没有删掉服务器的id_rsa的话, 使用ssh -i id_rsa 用户名@127.0.0.1 -p 22来自己连接下本机, 确保这个密钥能够连接的上, 这样可以排除服务器配置错误的问题
    5. 检查authorized_keys这个是否拼错了, 以及查看/etc/ssh/sshd_configAuthorizedKeysFile .ssh/authorized_keys后面的文件是否写死某个文件了
  2. Error: Remote Error: No such directory ****

    没有创建这个目录, 先创建一下

  3. InvalidAsn1Error: encoding too long

    输入的密钥密码错误

  4. error:0606508A:digital envelope routines:EVP_DecryptFinal_ex:data not multiple of block length

    密钥复制出来的时候, 丢了或少了什么.

  5. Remote Error: Cannnot create directory. Permission denied /**** 等带有Permission denied的内容

    不能用这个用户去建立里面的文件, 即没有权限以当前用户读取这个文件. 如果在非用户根目录下建立文件, 确保文件夹权限是rwx(7), 且文件夹属于当前用户