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` 里写多语言日志的最优工作流程。当我确信已经找到一套可以接受的解决方案的时候我会一并写成日志。