告别图床,自建小型图片服务器

摘要: 使用 nginx 和 sftp 解决图床问题。

起因

最近突然发现自己的博客站点图片不能正常显示了,排查之后发现原来是新浪图床做了防盗链。

W3C 新版的 referrer policy 浏览器端默认值为 no-referrer-when-downgrade(仅当发生协议降级时 Https –> Http 不发送 Referrer 信息),所以我只需要在 html 头部加上

<meta name="referrer" content="no-referrer">

即不发送 referrer ,新浪图片服务器没法知道请求来源,图片就能正常显示了。然而,因为我的博客站点还用了 busuanzi 访客统计 和 百度统计,如果不在请求头加上 referrer 信息,它们也会因为无法知道请求的正确来源而失效,当然这种顾此失彼的结果并非是我想要的。

之前一直都是用新浪图床作为写 markdown 的图床,之所以没有考虑用七牛,又拍等云服务商的对象储存服务,很大一部分原因是使用它们的服务生成的图片外链的域名是需要备案的,不想走繁琐的程序,又或者是 https 外链需要额外付费,时间限制等等。

那就自己折腾吧,想到自己放博客网站的 VPS 上本来就有 20G 的网页空间,而且我玩的还是 Hexo 这种不占空间静态站点,拿来做一个小型图片服务器满足自己的写 markdown 的需求绰绰有余。

开始行动

基本思路:

  1. 通过 sftp 将本地图片素材或截图上传到服务器空间。
  2. 用二级域名在 nginx 中配置一个新 server 访问 sftp 目录。
  3. markdown 写作时通过二级域名 + 路径生成图片外链。

sftp

选择 sftp 而不是直接使用 ftp 是因为 sftp 是更安全的协议,使用加密传输,设置也更加简单。

设置 sftp 用户

# 添加用户组
groupadd sftp

# 添加用户到组,并设置不能登陆 shell,不生成用户目录
useradd -g sftp -s /sbin/nologin -M sftpuser  

# 设置用户密码
passwd sftpuser

设置 sftp 目录和目录权限

# 设置 sftp 根目录和根目录权限
mkdir /home/wwwroot 
chown root:sftp /home/wwwroot
chmod 755 /home/wwwroot

# 设置 sftp 具体目录和权限,这个目录要给 sftp 组成员写权限,所以设置为 775
mkdir /home/wwwroot/blog
chown root:sftp /home/wwwroot/blog
chmod 775 /home/wwwroot/blog

配置 sshd_config
修改 /etc/ssh/sshd_config 结尾部分为:

# override default of no subsystems
# Subsystem     sftp    /usr/libexec/openssh/sftp-server
Subsystem       sftp    internal-sftp

# Example of overriding settings on a per-user basis
#Match User anoncvs
#       X11Forwarding no
#       AllowTcpForwarding no
#       PermitTTY no
#       ForceCommand cvs server

Match Group sftp   #限制的用户组
ChrootDirectory /home/wwwroot  #根目录
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no

测试配置和 sftp 连接

sshd -t && systemctl restart sshd  # CentOS 7

# 测试连接
sftp sftpuser@127.0.0.1

子域名 和 nginx 配置

既然自己做图片服务器了,外链格式就不能再杂乱无章,首先要先搞定的是子域名。

决定使用用 img.luckycoding.com 作为图片外链的域名,在域名解析添加一条 A 记录指向 VPS 地址。

之前申请的是单域名 https 证书,所以想了想还是去弄一个泛域名证书吧,以后再用其他二级域名也可以随时加上 https 小锁头了。

这里我申请的是 Let's Encrypt Authority X3 的证书,虽然只有 3 个月期限,貌似是自动续,万一过期了在去操作一下即可,申请过程反正是秒验证颁发,基本不用等待。

申请地址:https://www.sslforfree.com

申请后下载证书和私钥文件包,上传至服务器 nginx/conf/ 目录下

配置 nginx.conf,新增一个 server 为二级域名服务,其中 location 根目录配置为之前设置的 sftp 的根目录即可:

server {
        listen 443;
        server_name  img.luckycoding.com;
        ssl on;
        ssl_certificate certificate.crt;
        ssl_certificate_key private.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置
        ssl_prefer_server_ciphers on;
        location / {
            root   /home/wwwroot; #站点目录
        }
    }

至此服务端的工作已经完成,接下来介绍下我在自己的电脑上是怎么配置的让获取图片外链更加方便吧。

客户端配置 transmit 和 snipaste

MacOS 下载 transmit 用来连接图片服务器 sftp。(windows 下可用 expandrive 代替)

配置 transmit
新建一个 sftp 服务器连接

点击储存为 Droplat,即可将 sftp 配置储存为一个 MacOS APP,这样直接拖动图片至该 APP 上即可完成上传操作并复制图片外链到剪贴板。

snipaste 是 Windows 和 MacOS 下一款优秀的截图软件。在 sinpaste 中预设好自己的截图命名。

所以现在写文章需要配图的时候,只需截图并拖放图片至 transmit 生成的 blog APP 上,直接 command + v 粘贴图片外链即可,非常方便。

后续

站点迁移

这样自建的小型图片服务器如果遇上要迁移站点,文章中的外链和使用第三方图床一样是不会受到影响的,只要新站点 nginx 上配置的域名和目录名不变即可。

如遇特殊情况需要修改站点目录,可以通过 sed 批量修改 markdown 文章中的外链。

# 如修改外链中 /blog 路径为 /others
sed -i -E 's#(img.luckycoding.com)/blog/(.*)#\1/others/\2#g' *.md

PS: MacOS 中的 sed 同时使用 -i -E 选项会有问题,安装 GNU sed 后使用 gsed 命令即可。

brew install gnu-sed

~~ 本文完 ~~

Tips:本站使用 Disqus 评论,被墙访客请科学上网后点击加载。