blog

My blog at www.shimmy1996.com

git clone git://git.shimmy1996.com/blog.git

2017-09-25-my-server-setups-and-whatnot.zh.md (13062B)

    1 +++
    2 title = "新站点架设过程"
    3 draft = false
    4 date = 2017-09-25
    5 slug = "my-server-setups-and-whatnot"
    6 +++
    7 
    8 ## 为何要重新建站?新站建在哪里? {#为何要重新建站-新站建在哪里}
    9 
   10 在忍受了笨重的 Wordpress 三年后(以及 Bluehost 充满2003年设计感的管理面板),我终于决定放弃旧站另起炉灶。我对 Wordpress 博客主要有这些不满:
   11 
   12 -   体积庞大,占用很多不必要的服务器空间。
   13 -   没法使用我熟悉的工具来方便地备份。
   14 -   没有良好的命令行界面,而命令行正在成为我做任何事情的首选工具。
   15 -   缺少一些我所需要的基本功能,比如多语言支持。在部分人手里 WordPress 或许极为强大,但是我不想投入时间学习 CSS/js/php ,也不想从那些源头不明的 WordPress 插件商店里下载任何东西。
   16 -   这些 WordPress 主题/插件商店让我想起 Ubuntu 软件中心。
   17 -   WordPress 有很多我用不到的功能,比如用户系统。这用在个人博客上显然是杀鸡用牛刀。
   18 
   19 在我确定了自己的需求后,我很容易地就找到了替代品:一个用我所知道的编程语言(或者我愿意学习的编程语言)所实现的快而小巧并带有原生多语言支持的静态站点生成器,那就是 `hugo` 。
   20 
   21 至于站点托管服务,我本来考虑使用 github pages 或 netlify 这种简单快速的解决办法,但是考虑到是个人站点,还是 VPS 这种功能强大一些的选择比较合适。而且 github pages 不支持自定义域名的 https ,这对我来说无法接受。我列出了所有比较出名的 VPS 服务提供商,筛出支持 Arch Linux 的部分,最后选择了 DigitalOcean 。由于我想要完全切断和 Bluehost 的联系,我把自己的域名也转移到了 Google Domains 。
   22 
   23 
   24 ## 安装 Arch Linux {#安装-arch-linux}
   25 
   26 注意 Arch Linux 其实并不适合用作服务器操作系统。如果一切以系统稳定性为优先,那么选择一个非滚动更新的 Linux 发行版比较合适。我在服务器上用 Arch Linux 主要是因为我在我的所有其他电脑上也都运行 Arch Linux。如果你选择使用 Arch Linux 作为服务器操作系统,最好勤于备份:虽然我还没遇到这种情况,但是常有人抱怨 Arch Linux 很容易被玩坏。
   27 
   28 
   29 ### 安装系统 {#安装系统}
   30 
   31 显然我得到的关于 DigitalOcean 支持 Arch Linux 的情报已经过时了,他们已经停止支持 Arch Linux 有一阵子了。好在有 [digitalocean-debian-to-arch](https://github.com/gh2o/digitalocean-debian-to-arch) ,使得在水滴( droplet , DigitalOcean 对每个服务器的称呼)上安装 Arch Linux 并不困难。我只需要 [新建一个 droplet](https://www.digitalocean.com/community/tutorials/how-to-create-your-first-digitalocean-droplet) ,通过 `ssh` 登录服务器,并执行:
   32 
   33 ```sh
   34 # wget https://raw.githubusercontent.com/gh2o/digitalocean-debian-to-arch/debian9/install.sh -O install.sh
   35 # bash install.sh
   36 ```
   37 
   38 
   39 ### 系统设置 {#系统设置}
   40 
   41 上述安装完成后,我的 droplet 上就有了带有网络的 Arch Linux 。绝大部分的额外设置都可以在 [Arch Wiki](https://wiki.archlinux.org/index.php/Installation%5Fguide) 找到。我并没有想把这篇日志写成完整的教程,所以细节部分最好参考 Arch Wiki。记录在这篇日志里的指令只是做个人记录之用。
   42 
   43 
   44 #### 系统时钟 {#系统时钟}
   45 
   46 同步系统时钟并设置时区。
   47 
   48 ```sh
   49 # timedatectl set-ntp true
   50 # timedatectl settimezone <Region>/<City>
   51 ```
   52 
   53 
   54 #### 安装基础软件包 {#安装基础软件包}
   55 
   56 安装/升级 `base` 和 `base-devel` 软件包。
   57 
   58 ```sh
   59 # pacman -S base base-devel
   60 ```
   61 
   62 
   63 #### Fstab {#fstab}
   64 
   65 生成 `fstab` 。
   66 
   67 ```sh
   68 # genfstab -U / >> /etc/fstab
   69 ```
   70 
   71 
   72 #### 设置系统语言环境 {#设置系统语言环境}
   73 
   74 在 `/etc/locale.conf` 里去掉 `en_US.UTF-8 UTF-8` 的注释,然后运行:
   75 
   76 ```sh
   77 locale-gen
   78 ```
   79 
   80 在 `/etc/locale.conf` 里设置 `LANG=en_US.UTF-8` 。
   81 
   82 
   83 #### 主机名 {#主机名}
   84 
   85 编辑 `/etc/hosts` 以加入水滴的主机名:
   86 
   87 ```sh
   88 127.0.1.1    <hostname>.localdomain <hostname>
   89 ```
   90 
   91 
   92 #### 引导加载程序和 Initramfs {#引导加载程序和-initramfs}
   93 
   94 针对英特尔处理器的优化:
   95 
   96 ```sh
   97 # pacman -S intel-ucode
   98 # grub-mkconfig -o /boot/grub/grub.cfg
   99 ```
  100 
  101 在 initramfs 里加入 `crc32` 模组,不然可能导致水滴无法启动。编辑 `/etc/mkinitcpio.conf` :
  102 
  103 ```sh
  104 MODULES= "crc32 libcrc32c crc32c_generic crc32c-intel crc32-pclmul"
  105 ```
  106 
  107 重新生成 initramfs 镜像。
  108 
  109 ```sh
  110 # mkinitcpio -p linux
  111 ```
  112 
  113 
  114 #### Root 用户密码 {#root-用户密码}
  115 
  116 你懂的。
  117 
  118 ```sh
  119 # passwd
  120 ```
  121 
  122 
  123 ### 用户设置 {#用户设置}
  124 
  125 这是一些让 Arch Linux 使用起来更加友好的设置。
  126 
  127 
  128 #### 创建用户帐号 {#创建用户帐号}
  129 
  130 显然只使用 root 帐号不是什么好主意:
  131 
  132 ```sh
  133 # useradd -m -G wheel -s /bin/bash <username>
  134 # passwd <username>
  135 ```
  136 
  137 
  138 #### 把用户加入 Sudoer {#把用户加入-sudoer}
  139 
  140 编辑 `/etc/sudoers` 并加入:
  141 
  142 ```sh
  143 <username> ALL=(ALL) ALL
  144 ```
  145 
  146 
  147 #### 以用户身份登录 {#以用户身份登录}
  148 
  149 剩下的设置都会以用户身份执行:
  150 
  151 ```sh
  152 # su <username>
  153 ```
  154 
  155 
  156 #### 软件包管理器 {#软件包管理器}
  157 
  158 我一开始使用 `packer` 来同时使用 `pacman` 和安装 AUR 软件包。但是在我了解到其软件安装过程有 [诸多安全隐患](https://wiki.archlinux.org/index.php/AUR%5Fhelpers#Comparison%5Ftable) 后,我开始改用 `trizen` ( `pacaur` 是另一个较为稳妥的选择,而且在 reddit 上有一个机器人会在所有提到 `yaourt` 的帖子下面安利 `pacaur` ): `trizen` 会提示用户在安装前检查 `PKGBUILD` , `*.install` 以及其他代码,而且 `trizen` 是用 Perl 而不是 Bash 写的。想要安装 `trizen` ,先根据 [AUR 页面](https://aur.archlinux.org/packages/trizen/) 通过 `pacman` 安装 `trizen` 所依赖的软件包,然后克隆其 [git 仓库](https://github.com/trizen/trizen) 到本地。进入包含 `PKGBUILD` 的文件夹并运行:
  159 
  160 ```sh
  161 $ makepkg
  162 ```
  163 
  164 来编译软件包,
  165 
  166 ```sh
  167 $ pacman -U trizen-*.pkg.tzr.xz
  168 ```
  169 
  170 来安装 `trizen`.
  171 
  172 
  173 #### 常用软件包 {#常用软件包}
  174 
  175 在设置完软件包管理器后,就可以大肆安装各种软件了!我的一些必备软件包括 `emacs` (在服务器上我只安装了命令行版本, `emacs-nox`), `tmux` (可以使用同一个命令行窗口来同时运行多个指令,非常有用), `zsh` , `vim` (作快速编辑之用)。
  176 
  177 
  178 ## 安全相关 {#安全相关}
  179 
  180 Arch Linux 安装完成之后,我在把网站搬进去之前进行了一些安全方面的设置。
  181 
  182 
  183 ### 使用 `ssh` 安全登录 {#使用-ssh-安全登录}
  184 
  185 在本地机器上生成 ssh 密匙:
  186 
  187 ```sh
  188 $ ssh-keygen -t rsa
  189 ```
  190 
  191 把 ssh 密匙发送到服务器:
  192 
  193 ```sh
  194 $ ssh-copy-id <username>@<server>
  195 ```
  196 
  197 接下来再服务器上编辑 `/etc/ssh/sshd_config` :
  198 
  199 ```sh
  200 PermitRootLogin no
  201 ChallengeResponseAuthentication no
  202 PasswordAuthentication no
  203 UsePAM no
  204 AllowUsers <username>
  205 ```
  206 
  207 这些改动会禁止 root 账户登录,禁止使用密码登录,并只允许特定用户通过 ssh 登录。
  208 
  209 除此之外,把用于 ssh 的端口(默认为22)改掉也是一个很棒的安全措施。继续编辑同一个文件(请记牢所选择的端口):
  210 
  211 ```sh
  212 port <non-std-port>
  213 ```
  214 
  215 为了让这些改动生效,重启 `ssh` 进程:
  216 
  217 ```sh
  218 $ sudo systemctl restart sshd.service
  219 ```
  220 
  221 接下来保留目前的 `ssh` 链接不变并在一个新窗口内尝试建立新链接以确认一切正常(保留原有链接以防设置出错):
  222 
  223 ```sh
  224 $ ssh -p <non-std-port> <username>@<server>
  225 ```
  226 
  227 
  228 ### 防火墙设置 {#防火墙设置}
  229 
  230 `ufw` 作为防火墙非常方便易用。使用 `trizen` 来安装 `ufw` 并开放允许连接的端口:
  231 
  232 ```sh
  233 $ trizen -S ufw
  234 $ sudo ufw allow <port>/<protocol>
  235 ```
  236 
  237 如果想要允许 `ssh` 链接,开放 `22/tcp` 或 `ssh` (如果你改掉了默认端口,开放 `<non-std-port>/tcp` )。其他一些常用的端口有:
  238 
  239 | Port      | Usage                 |
  240 |-----------|-----------------------|
  241 | `80/tcp`  | `http`                |
  242 | `443/tcp` | `https`               |
  243 | `143`     | imap 通信             |
  244 | `993`     | imap `ssl` 通信       |
  245 | `25`      | 收取外界来的邮件      |
  246 | `587`     | smtp 通信 (不论有无 `ssl` ) |
  247 
  248 回顾已开放的端口并开启防火墙:
  249 
  250 ```sh
  251 $ sudo ufw show added
  252 $ sudo ufw enable
  253 ```
  254 
  255 设置自动启动:
  256 
  257 ```sh
  258 $ sudo systemctl enable ufw.service
  259 ```
  260 
  261 
  262 ### 同步服务器时间 {#同步服务器时间}
  263 
  264 使用 `ntp` 同步服务器时间:
  265 
  266 ```sh
  267 $ trizen -S ntp
  268 $ sudo systemctl enable ntpd.service
  269 ```
  270 
  271 检查时间服务器的状态:
  272 
  273 ```sh
  274 $ ntpq -p
  275 ```
  276 
  277 
  278 ### 设置 PTR 记录 {#设置-ptr-记录}
  279 
  280 DigitalOcean 会自动设置 PTR 记录,我唯一需要做的就是将水滴的名字改为绝对领域名称( FQDN ,帅气但是八成是机翻的译名取自 [Wikipedia](https://zh.wikipedia.org/wiki/完整網域名稱) ),也就是 `shimmy1996.com` 。完成这一设置后,我可以通过以下命令来查看设置是否成功。
  281 
  282 ```sh
  283 $ dig -x <ip_address>
  284 ```
  285 
  286 
  287 ## 正式启动服务器 {#正式启动服务器}
  288 
  289 在完成以上设置后,就可以为服务器托管网站做准备了。
  290 
  291 
  292 ### 建立网页文件夹 {#建立网页文件夹}
  293 
  294 创建一个网页文件夹来放网页文件,一个比较普遍的选择是:
  295 
  296 ```sh
  297 $ mkdir ~/public_html
  298 ```
  299 
  300 确认该文件夹(以及用户的 `home` 文件夹)有合适的权限设置。权限设置可以用 `chmod` 修改(一般设成 `755` 就好)。可以在网页文件夹中放一个简单的 `index.html` 来方便测试。
  301 
  302 
  303 ### 安装 `nginx` {#安装-nginx}
  304 
  305 用 `trizen` 安装 `nginx` ,并编辑 `/etc/nginx/nginx.conf` 来设立 `http` 服务器(带有 `listen 80 default_server` 设置的部分):
  306 
  307 ```sh
  308 server_name www.<domainname> <domainname>
  309 root /path/to/public_html
  310 ```
  311 
  312 在 `server_name` 这一行可以多列一些网址。如果你想一并架设邮箱服务器的话,一并将邮箱服务器地址列入网址就免去了生成额外的 ssl 证书的麻烦。在这些设置完成后,(重新)开始 `nginx` 并将其设为开机启动:
  313 
  314 ```sh
  315 $ sudo systemctl restart nginx.service
  316 $ sudo systemctl enable nginx.service
  317 ```
  318 
  319 
  320 ### DNS 设置 {#dns-设置}
  321 
  322 下一步是为服务器完成 DNS 记录的设置。一开始必须设置的记录有三种: `NS` , `A` ,和 `CNAME` 。我记下了一些比较常用的记录:
  323 
  324 | 记录种类 | 主机名        | 数值           | 用法                      |
  325 |------|------------|--------------|-------------------------|
  326 | `NS`    | @             | DNS 服务器的地址 | 确认用于解析域名的服务器  |
  327 | `A`     | @             | 水滴的 IPv4 地址 | 将主机名重定向到 IP 地址  |
  328 | `CNAME` | www (可以是任何东西) | @              | 将 `www.<hostname>` 设为主机名的 |
  329 | `MX`    | @             | 邮箱服务器地址 | 指定邮箱服务器            |
  330 | `CAA`   | @             | 标明 SSL 证书的授权机构 | 阻止其他授权机构为本站发行 SSL 证书 |
  331 
  332 我的域名托管在 Google Domains ,但我的网站用的是 DigitalOcean 的 DNS ,所以我需要在 DigitalOcean 上完成设置并在 Google Domains 里加入 `NS` 记录。
  333 
  334 在完成这些设置后,我就可以通过我的域名访问所架设的网站了,不过 DNS 记录通常需要数小时才会完全生效。
  335 
  336 
  337 ### SSL 证书 {#ssl-证书}
  338 
  339 [Let's Encrypt](https://letsencrypt.org) 是个非常棒的项目。使用 [`certbot`](https://certbot.eff.org/) 这个工具就可以很方便的生成 SSL 证书。这里向 EFF 和 Linux 基金会的人们致以谢意。生成证书只需要运行 [EFF 网站](https://certbot.eff.org/#arch-nginx) 上所记载的命令即可:
  340 
  341 ```sh
  342 $ sudo pacman -S certbot-nginx
  343 $ sudo certbot --nginx
  344 ```
  345 
  346 为了给证书增加一点可信度,我还在 DNS 记录中加了一条 `CAA` 记录,标明 `letsencrypt.org` 是唯一允许给本站 SSL 证书授权的机构。目前 Let's Encrypt 还不支持通配符证书,不过会在 [2018年1月](https://letsencrypt.org/2017/07/06/wildcard-certificates-coming-jan-2018.html) 添加这一支持。由于没有通配符证书,我只好在 `nginx.config` 里加上所有二级域名(这样生成证书的才能够为这些域名提供验证)。
  347 
  348 
  349 ## 下一步? {#下一步}
  350 
  351 在鼓捣了几个小时后(其实大部分时间是在等 DNS 记录扩散),我的新站就上线了。既然选择了运行 VPS,我打算好好发挥它的潜能并架设了自己的电子邮箱。我正在考虑把架设邮箱过程中从各个网站七拼八凑其来的命令行笔记也整理成一篇日志。目前我仍在试图寻找使用 `org-mode` 在 `hugo` 里写多语言日志的最优工作流程。当我确信已经找到一套可以接受的解决方案的时候我会一并写成日志。