commit 2a111cf8a4bf2aba174ddf298b8c5e6d82c573f6
parent ad487f53931d0e0f971706107a0c1e7b86fc193d
Author: Shimmy Xu <shimmy.xu@shimmy1996.com>
Date: Mon, 16 Oct 2017 23:11:10 -0500
New post 'Spam or Ham' and translation tweaks on list page titles.
Diffstat:
16 files changed, 497 insertions(+), 34 deletions(-)
diff --git a/config.toml b/config.toml
@@ -30,9 +30,6 @@ LanguageName = "EN"
[Languages.en.params]
description = "The greatest library ever."
-[Languages.en.navigation]
-about = "About"
-
[[Languages.en.menu.main]]
name = "Home"
url = "/en/"
@@ -59,9 +56,6 @@ title = "川坨大学图书室"
subtitle = "计划进行中。"
LanguageName = "中文"
-[Languages.zh.navigation]
-about = "关于"
-
[Languages.zh.params]
description = "最伟大的图书馆。"
diff --git a/content/_index.en.md b/content/_index.en.md
@@ -32,10 +32,9 @@ _The Plan needs to go on._
- [X] Find a suitable icon/favicon.
- [X] Improve templates for posts to display tags and categories.
- [X] Cosmetic changes, i.e. no underlines for hyperlinks.
+- [X] Deal with some nuances in using `org-mode` with `hugo` , like how to get syntax highlighting to work properly.
- [X] Host my own email.
-- [ ] Deal with some nuances in using `org-mode` with `hugo` , like how to get syntax highlighting to work properly.
-- [ ] Customizable Disqus via Disqus API.
-- [ ] Customize `hugo new` to make it more useful, i.e. create multilingual versions directly.
+- [X] Customize `hugo new` to make it more useful, i.e. create multilingual versions directly.
- [ ] Restore/rewrite and translate some of the more valuable old posts.
diff --git a/content/_index.zh.md b/content/_index.zh.md
@@ -33,8 +33,8 @@ _计划进行中_
- [X] 改善文章页面模板使其显示标签和分类。
- [X] 改善网站外观,比如隐藏超链接的下划线等。
- [X] 架设自己的邮箱。
-- [ ] 解决 `org-mode` 和 `hugo` 略不兼容的地方,比如代码高亮。
-- [ ] 尝试把 `hugo new` 变得更有用一些,比如直接创建多语言版本等。
+- [X] 解决 `org-mode` 和 `hugo` 略不兼容的地方,比如代码高亮。
+- [X] 尝试把 `hugo new` 变得更有用一些,比如直接创建多语言版本等。
- [ ] 把比较有价值的旧文章搬过来。
diff --git a/content/posts/_index.en.md b/content/posts/_index.en.md
@@ -1,6 +1,6 @@
+++
title = "Posts"
-lastmod = 2017-09-30T23:17:03-05:00
+lastmod = 2017-10-16T22:44:18-05:00
draft = false
+++
diff --git a/content/posts/_index.zh.md b/content/posts/_index.zh.md
@@ -1,6 +1,6 @@
+++
title = "归档"
-lastmod = 2017-09-30T23:17:03-05:00
+lastmod = 2017-10-16T22:44:18-05:00
draft = false
+++
diff --git a/content/posts/my-server-setups-and-whatnot.en.md b/content/posts/my-server-setups-and-whatnot.en.md
@@ -1,6 +1,6 @@
+++
title = "My Server Setups and Whatnot"
-lastmod = 2017-09-30T23:17:03-05:00
+lastmod = 2017-10-16T22:44:18-05:00
tags = ["arch-linux", "server"]
categories = ["site-related"]
draft = false
@@ -278,6 +278,15 @@ $ ntpq -p
```
+### Setting up PTR Record {#setting-up-ptr-record}
+
+It turns out that DigitalOcean handles this automatically, all I needed to do is set the droplet name to a Fully Qualified Domain Name (FQDN), in this case `www.shimmy1996.com`. I then checked if the record is in place with:
+
+```sh
+$ dig -x <ip_address>
+```
+
+
## Firing up the Server {#firing-up-the-server}
Next step would be actually preparing the server for serving contents.
diff --git a/content/posts/my-server-setups-and-whatnot.zh.md b/content/posts/my-server-setups-and-whatnot.zh.md
@@ -1,6 +1,6 @@
+++
title = "新站点架设过程"
-lastmod = 2017-09-30T23:17:03-05:00
+lastmod = 2017-10-16T22:44:19-05:00
tags = ["arch-linux", "server"]
categories = ["site-related"]
draft = false
@@ -278,6 +278,15 @@ $ ntpq -p
```
+### 设置 PTR 记录 {#设置-ptr-记录}
+
+DigitalOcean 会自动设置 PTR 记录,我唯一需要做的就是将水滴的名字改为绝对领域名称( FQDN ,帅气但是八成是机翻的译名取自 [Wikipedia](https://zh.wikipedia.org/wiki/完整網域名稱) ),也就是 `www.shimmy1996.com` 。完成这一设置后,我可以通过以下命令来查看设置是否成功。
+
+```sh
+$ dig -x <ip_address>
+```
+
+
## 正式启动服务器 {#正式启动服务器}
在完成以上设置后,就可以为服务器托管网站做准备了。
diff --git a/content/posts/spam-or-ham.en.md b/content/posts/spam-or-ham.en.md
@@ -0,0 +1,122 @@
++++
+title = "Spam or Ham"
+lastmod = 2017-10-16T22:48:16-05:00
+tags = ["email", "security"]
+categories = ["site-related"]
+draft = false
+date = 2017-10-14
+slug = "spam-or-ham"
++++
+
+As planned, I am documenting my mail server setups. Setting up the mail server is probably documented everywhere, but I had to put in some effort make my setup secure enough to prevent it from been mistaked as spam.
+
+
+## Setting up the mail server {#setting-up-the-mail-server}
+
+I really don't see how I can write anything better than [this tutorial](http://www.netarky.com/programming/arch_linux/Arch_Linux_mail_server_setup_1.html), so I will just document some of the steps that seemed missing from the tutorial.
+
+
+### Setting DNS Record {#setting-dns-record}
+
+Before anything, I needed to setup my DNS record. I created a `CNAME` for my mail server address, and added a `MX` record indicating the mail will be handled by the mail server.
+
+
+### Creating `Maildir` {#creating-maildir}
+
+After setting up `postfix` for the first time, I needed to setup the `Maildir` manually and giving it appropirate permissions:
+
+```sh
+$ mkdir -p /home/<username>/Maildir/{cur,new,tmp}
+$ chown <username> /home/<username>/Maildir/{,cur,new,tmp}
+$ chmod 0755 /home/<username>/Maildir/{,cur,new,tmp}
+```
+
+
+### SSL Certificate {#ssl-certificate}
+
+In stead of using the built-in certificate generators in `dovecot`, I choose to use the same SSL certificate for my website. I added my mail server address to the `server_name` field in `/etc/nginx/nginx.conf` and generated my certificate with `certbot`. After that, I simply changed `/etc/dovecot/conf.d/10-ssl.conf` for `dovecot` :
+
+```sh
+use_ssl = yes
+ssl_cert = </path/to/fullchain.pem
+ssl_key = </path/to/privkey.pem
+```
+
+Similarly for `postfix` I also used this certificate. Do note that `dovecot` and `postfix` should be run as `root` to have read permissions to read these certificates.
+
+
+### Mail Client {#mail-client}
+
+I am using Thunderbird as my mail client and for receiving mail. I used SSL/TLS while for sending mail, I needed to set STARTTLS.
+
+
+## Security Measures {#security-measures}
+
+After completing the email setup, I immediately tested the server by sending test emails, only to find them been tossed straight into spam by gmail. It seems that gmail has a new feature that shows the security check status on the email (accessible by 'View Original'). These measures include SPF, DKIM and DMARC. My avatar showed up as an octagon with a question mark, indicating the mail server failing the basic SPF check. In order to avoid this, I took a bunch of security measures to tick all the boxes from email security test sites like [intodns](https://intodns.com) and [mxtoolbox](https://mxtoolbox.com).
+
+
+### Sender Policy Framework (SPF) {#sender-policy-framework--spf}
+
+An SPF TXT record documents the allowed servers to send emails on behalf of this address. In my case where only mail servers documented in the MX TXT record are used, I simply put in:
+
+```sh
+v=spf1 mx -all
+```
+
+
+### DomainKeys Identified Mail (DKIM) {#domainkeys-identified-mail--dkim}
+
+I am using `opendkim` to sign and verify that emails are indeed from my server. After installing the `opendkim` package, I followed the instruction in [Arch Wiki](https://wiki.archlinux.org/index.php/OpenDKIM). First copy example configuration file from `/etc/opendkim/opendkim.conf.sample` to `/etc/opendkim/opendkim.conf` and edit (socket selection can be arbitrary):
+
+```sh
+Domain <domainname>
+KeyFile /path/to/keys.private
+Selector <myselector>
+Socket inet:<dkimsocket>@localhost
+UserID opendkim
+Conicalization relaxed/simple
+```
+
+Next, in the specified keyfile directory (the default is `/var/db/dkim/`), generate keys with:
+
+```sh
+$ opendkim-genkey -r -s <myselector> -d <domainname> --bits=2048
+```
+
+Along with the generated `.private` file is a `.txt` file with the necessary TXT record for DKIM. It basically posts the public key for your mail server. Note that the TXT record may need to be broke down into several strings to comply with the 255 character limit. To check if the TXT record has been properly setup, I used (requires package `dnsutils` ):
+
+```sh
+$ host -t TXT <myselector>._domainkey.<domainname>
+```
+
+The final step would be to start the `opendkim` service and make sure `postfix` performs the encryption upon sending email. Edit `/etc/postfix/main.cf` to be:
+
+```sh
+non_smtpd_milters=inet:127.0.0.1:<dkimsocket>
+smtpd_milters=inet:127.0.0.1:<dkimsocket>
+```
+
+After reloading `postfix`, DKIM should be in effect.
+
+
+### Domain-based Message Authentication, Reporting and Conformance (DMARC) {#domain-based-message-authentication-reporting-and-conformance--dmarc}
+
+Without surprise, there is a package `opendmarc` that implements DMARC and there is also an [Arch Wiki](https://wiki.archlinux.org/index.php/OpenDMARC) page for it. Do note that this would require SPF and DKIM to be setup first. After installation, I edited `/etc/opendmarc/opendmarc.conf`:
+
+```sh
+Socket inet:<dmarcsocket>@localhost
+```
+
+After starting the service, enable DMARC filter in `postfix` (separate with comma):
+
+```sh
+non_smtpd_milters=inet:127.0.0.1:<dkimsocket>, inet:127.0.0.1:<dmarcsocket>
+smtpd_milters=inet:127.0.0.1:<dkimsocket>, inet:127.0.0.1:<dmarcsocket>
+```
+
+The final step is to add a DMARC TXT record in DNS settings as detailed on Arch Wiki page and reload `postfix`.
+
+
+## Ticking the Boxes {#ticking-the-boxes}
+
+I tested my server by sending test email to `check-auth@verifier.port25.com` and everything seems to be working. Not to mention that my email no longer gets classified as spam by gmail and I can see my emails passing SPF, DKIM and DMARC checks in 'View Original'. I also get an detailed daily report from gmail due to DMARC. At this point, I am pretty comfortable about ditching all my previous gmail addresses and sticking to my own email. I am also looking into options of self-hosting calenders. Hopefully in the near future I can completely ditch Google for my essential communication needs.+
\ No newline at end of file
diff --git a/content/posts/spam-or-ham.zh.md b/content/posts/spam-or-ham.zh.md
@@ -0,0 +1,122 @@
++++
+title = "是 Spam 还是 Ham"
+lastmod = 2017-10-16T22:48:31-05:00
+tags = ["email", "security"]
+categories = ["site-related"]
+draft = false
+date = 2017-10-14
+slug = "spam-or-ham"
++++
+
+遵循之前的计划,我打算将设置邮箱的过程记录下来。设置邮箱大部分地方都有教程,不过我需要添加不少额外的安全设置来避免邮件被扔进垃圾箱。
+
+
+## 搭建邮件服务器 {#搭建邮件服务器}
+
+我八成是写不出比 [这篇教程](http://www.netarky.com/programming/arch_linux/Arch_Linux_mail_server_setup_1.html) 更好的步骤说明的,所以我就在这里把我额外需要的一些设置记录下来。
+
+
+### 设置 DNS 记录 {#设置-dns-记录}
+
+在开始搭建邮箱之前,我需要设置 DNS 记录。我为我的邮件服务器地址设置了一条 `CNAME` 记录,并用一条 `MX` 记录来标明所使用的邮件服务器。
+
+
+### 创建 `Maildir` {#创建-maildir}
+
+在设置好 `postfix` 之后,我需要手动创建 `Maildir` 文件夹并赋予其合适的权限:
+
+```sh
+$ mkdir -p /home/<username>/Maildir/{cur,new,tmp}
+$ chown <username> /home/<username>/Maildir/{,cur,new,tmp}
+$ chmod 0755 /home/<username>/Maildir/{,cur,new,tmp}
+```
+
+
+### SSL 证书 {#ssl-证书}
+
+我没有使用 `dovecot` 自带的证书生成器,而是直接沿用了我网站的 SSL 证书。我将邮件服务器地址加入 `/etc/nginx/nginx.conf` 中的 `server_name` 下,并用 `certbot` 生成了合适的证书。在这之后,我修改了 `dovecot` 的设置文件 `/etc/dovecot/conf.d/10-ssl.conf` :
+
+```sh
+use_ssl = yes
+ssl_cert = </path/to/fullchain.pem
+ssl_key = </path/to/privkey.pem
+```
+
+我也在 `postfix` 上用了这个证书。需要注意的是 `dovecot` 和 `postfix` 都需要用 `root` 账户运行才会有权限读取证书。
+
+
+### 邮件客户端 {#邮件客户端}
+
+我使用 Thunderbird 作为邮件客户端。收取邮件时,我使用 SSL/TLS,而发送邮件则使用 STARTTLS。
+
+
+## 安全措施 {#安全措施}
+
+设置好邮件服务器后,我试着发了几封邮件,不过发现都被 gmail 扔进了垃圾箱。似乎 gmail 最近添加了显示邮件安全检查状态的功能(在 gmail 中点击“查看原件”即可看到)。这些检查包括 SPF , DKIM , 和 DMARC 。由于我的邮件服务器没有通过最基本的 SPF 检查,所以我的头像显示为一个标着问号的八边形。为了避免邮件被扔进垃圾箱,我进行了一系列安全设置以保证我的邮件服务器能通过网上邮箱安全测试平台(我使用的是 [intodns](https://intodns.com) 和 [mxtoolbox](https://mxtoolbox.com) )的考验。
+
+
+### 发件人策略框架( SPF ) {#发件人策略框架-spf}
+
+SPF TXT 记录标明了某一域名所承认的邮件服务器地址。在我的情况下,我只会用到 MX TXT 记录中所提到的邮件服务器,所以我的 SPF TXT 记录就是:
+
+```sh
+v=spf1 mx -all
+```
+
+
+### 域名密匙邮件认证( DKIM ) {#域名密匙邮件认证-dkim}
+
+我使用 `opendkim` 来为邮件署名,以验证邮件的确来自于我的服务器。在安装了 `opendkim` 软件包后,我遵循 [Arch Wiki](https://wiki.archlinux.org/index.php/OpenDKIM) 里的步骤完成了设置。首先,复制设置文件模板 `/etc/opendkim/opendkim.conf.sample` 到 `/etc/opendkim/opendkim.conf` 并编辑(端口可以随意选择):
+
+```sh
+Domain <domainname>
+KeyFile /path/to/keys.private
+Selector <myselector>
+Socket inet:<dkimsocket>@localhost
+UserID opendkim
+Canonicalization relaxed/simple
+```
+
+接下来,在设置文件所指定的密匙文件路径下(默认为 `/var/db/dkim/` ),生成密匙:
+
+```sh
+$ opendkim-genkey -r -s <myselector> -d <domainname> --bits=2048
+```
+
+执行指令后生成的不仅仅是 `.private` 密匙文件,还有装有完成 DKIM 设置所需 TXT 记录的 `.txt` 文件。这一记录的功能在于公布邮箱服务器的公共密匙。需要注意的是这条 TXT 记录有可能会被分成数条字符串,以满足每条字符串最长 255 字符的要求。为了查看 TXT 记录是否有设置成功,我运行了(需要安装 `dnsutils` 软件包):
+
+```sh
+$ host -t TXT <myselector>._domainkey.<domainname>
+```
+
+接下,重启 `opendkim` 服务并确保 `postfix` 在发出邮件之前执行加密。编辑 `/etc/postfix/main.cf` :
+
+```sh
+non_smtpd_milters=inet:127.0.0.1:<dkimsocket>
+smtpd_milters=inet:127.0.0.1:<dkimsocket>
+```
+
+在重启 `postfix` 后, DKIM 就开始运作了。
+
+
+### 基于域名的邮件认证,报告和一致性检查( DMARC ) {#基于域名的邮件认证-报告和一致性检查-dmarc}
+
+毫无意外,有一个软件包 `opendmarc` 可以用于部署 DMARC ,并且这一软件包也有对应的 [Arch Wiki](https://wiki.archlinux.org/index.php/OpenDMARC) 页面。需要注意的是, DMARC 必须在 SPF 和 DKIM 都设置完成后才能生效。在安装软件包后,编辑 `/etc/opendmarc/opendmarc.conf`:
+
+```sh
+Socket inet:<dmarcsocket>@localhost
+```
+
+在启动 `opendmarc` 服务后,在 `postfix` 中启用 DMARC 邮件滤网(与 DKIM 滤网用逗号隔开):
+
+```sh
+non_smtpd_milters=inet:127.0.0.1:<dkimsocket>, inet:127.0.0.1:<dmarcsocket>
+smtpd_milters=inet:127.0.0.1:<dkimsocket>, inet:127.0.0.1:<dmarcsocket>
+```
+
+最后,按照 Arch Wiki 所指示的步骤在 DNS 设置中加上一条 DMARC TXT 记录并重启 `postfix` 就大功告成了。
+
+
+## 通过所有测试 {#通过所有测试}
+
+给 `check-auth@verifier.port25.com` 发送测试邮件后,我收到了一份邮件服务器的测试报告。报告显示所有安全设置都在正常运作。除此之外, gmail 不再将我的邮件扔进垃圾箱了,而“查看原件”页面下也显示我的邮件通过了 SPF , DKIM , 和 DMARC 检查。 由于启用了 DMARC , gmail 还会每天向我的邮箱发送一份安全报告。折腾到这个地步后,我对我的新邮箱比较满意了,并准备废除我之前所使用的邮箱。我还在寻找可以自己架设的日历服务,希望不久的将来我可以完全摆脱在通讯方面对 Google 服务的依赖。+
\ No newline at end of file
diff --git a/i18n/en.toml b/i18n/en.toml
@@ -1,13 +1,13 @@
[footer]
other = "© [Shimmy Xu](/en/contact/) 2017 | [Keybase](https://keybase.io/shimmy1996) | [Github](https://github.com/shimmy1996) | [Twitter](https://twitter.com/shimmy1996) | [Subscribe](/en/index.xml)"
-[Posts]
+[posts]
other = "Posts"
-[Tags]
+[tags]
other = "Tags"
-[Categories]
+[categories]
other = "Categories"
# Translation for categories
@@ -24,4 +24,8 @@ other = "Arch Linux"
[server]
other = "Server"
+[email]
+other = "Email"
+[security]
+other = "Security"
diff --git a/i18n/zh.toml b/i18n/zh.toml
@@ -1,13 +1,13 @@
[footer]
other = "© [Shimmy Xu](/zh/contact/) 2017 | [Keybase](https://keybase.io/shimmy1996) | [Github](https://github.com/shimmy1996) | [Twitter](https://twitter.com/shimmy1996) | [订阅](/zh/index.xml)"
-[Posts]
+[posts]
other = "归档"
-[Tags]
+[tags]
other = "标签"
-[Categories]
+[categories]
other = "分类"
# Translation for categories
@@ -24,3 +24,9 @@ other = "Arch Linux"
[server]
other = "服务器"
+[email]
+other = "电子邮件"
+
+[security]
+other = "安全相关"
+
diff --git a/layouts/_default/list.html b/layouts/_default/list.html
@@ -1,8 +1,7 @@
{{ partial "header.html" . }}
{{if not .IsHome }}
- {{$title := lower .Title}}
- {{$title := i18n $title}}
+ {{$title := i18n (lower .Title)}}
{{ if eq $title ""}}
<h1>{{ .Title }}</h1>
{{ else }}
diff --git a/layouts/_default/single.html b/layouts/_default/single.html
@@ -6,7 +6,7 @@
<p class="terms">
{{ range $i := (slice "categories" "tags") }}
{{ with ($.Param $i) }}
- {{ i18n ($i | title) }} | {{ range $k := . }}<a href="{{ relURL (print "/" $.Site.Language.Lang "/" $i "/" $k | urlize) }}">{{i18n $k}} </a> | {{ end }}
+ {{ i18n (lower ($i | title)) }} | {{ range $k := . }}<a href="{{ relURL (print "/" $.Site.Language.Lang "/" $i "/" $k | urlize) }}">{{i18n $k}} </a> | {{ end }}
<br />
{{ end }}
{{ end }}
diff --git a/layouts/partials/head_custom.html b/layouts/partials/head_custom.html
@@ -8,9 +8,9 @@
<meta name="msapplication-config" content="/favicon/browserconfig.xml?v=xQzOP7B4B2">
<meta name="theme-color" content="#ffffff">
<!-- Translate titles -->
-{{$title := i18n .Title}}
+{{$title := i18n (lower .Title)}}
{{ if eq $title ""}}
<title>{{ .Title }} | {{ .Site.Title }}</title>
{{ else }}
<title>{{ $title }} | {{ .Site.Title }}</title>
-{{ end }}-
\ No newline at end of file
+{{ end }}
diff --git a/org/2017.org b/org/2017.org
@@ -1,6 +1,5 @@
#+HUGO_BASE_DIR: ../
#+HUGO_SECTION: ./posts
-
#+HUGO_AUTO_SET_LASTMOD: t
* Index Page
@@ -28,7 +27,7 @@ In case you want to view by [[/en/tags/][tags]] or [[/en/categories][categories]
* Site Related :@site_related:
Site related posts.
-** DONE My Server Setups and Whatnot :arch_linux:server:
+** DONE My Server Setups and Whatnot :arch_linux:server:
:PROPERTIES:
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :date 2017-09-25 :slug my-server-setups-and-whatnot
:END:
@@ -243,6 +242,12 @@ Check time server status with:
$ ntpq -p
#+END_SRC
+***** Setting up PTR Record
+It turns out that DigitalOcean handles this automatically, all I needed to do is set the droplet name to a Fully Qualified Domain Name (FQDN), in this case =www.shimmy1996.com=. I then checked if the record is in place with:
+#+BEGIN_SRC sh
+$ dig -x <ip_address>
+#+END_SRC
+
**** Firing up the Server
Next step would be actually preparing the server for serving contents.
@@ -504,6 +509,12 @@ $ sudo systemctl enable ntpd.service
$ ntpq -p
#+END_SRC
+***** 设置 PTR 记录
+DigitalOcean 会自动设置 PTR 记录,我唯一需要做的就是将水滴的名字改为绝对领域名称( FQDN ,帅气但是八成是机翻的译名取自 [[https://zh.wikipedia.org/wiki/完整網域名稱][Wikipedia]] ),也就是 =www.shimmy1996.com= 。完成这一设置后,我可以通过以下命令来查看设置是否成功。
+#+BEGIN_SRC sh
+$ dig -x <ip_address>
+#+END_SRC
+
**** 正式启动服务器
在完成以上设置后,就可以为服务器托管网站做准备了。
@@ -559,6 +570,194 @@ $ sudo certbot --nginx
+** DONE Spam or Ham :email:security:
+:PROPERTIES:
+:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :date 2017-10-14 :slug spam-or-ham
+:END:
+
+*** DONE en
+:PROPERTIES:
+:EXPORT_TITLE: Spam or Ham
+:EXPORT_FILE_NAME: spam-or-ham.en.md
+:END:
+
+As planned, I am documenting my mail server setups. Setting up the mail server is probably documented everywhere, but I had to put in some effort make my setup secure enough to prevent it from been mistaked as spam.
+
+**** Setting up the mail server
+
+I really don't see how I can write anything better than [[http://www.netarky.com/programming/arch_linux/Arch_Linux_mail_server_setup_1.html][this tutorial]], so I will just document some of the steps that seemed missing from the tutorial.
+
+***** Setting DNS Record
+Before anything, I needed to setup my DNS record. I created a =CNAME= for my mail server address, and added a =MX= record indicating the mail will be handled by the mail server.
+
+***** Creating =Maildir=
+After setting up =postfix= for the first time, I needed to setup the =Maildir= manually and giving it appropirate permissions:
+#+BEGIN_SRC sh
+$ mkdir -p /home/<username>/Maildir/{cur,new,tmp}
+$ chown <username> /home/<username>/Maildir/{,cur,new,tmp}
+$ chmod 0755 /home/<username>/Maildir/{,cur,new,tmp}
+#+END_SRC
+
+***** SSL Certificate
+In stead of using the built-in certificate generators in =dovecot=, I choose to use the same SSL certificate for my website. I added my mail server address to the =server_name= field in =/etc/nginx/nginx.conf= and generated my certificate with =certbot=. After that, I simply changed =/etc/dovecot/conf.d/10-ssl.conf= for =dovecot= :
+#+BEGIN_SRC sh
+use_ssl = yes
+ssl_cert = </path/to/fullchain.pem
+ssl_key = </path/to/privkey.pem
+#+END_SRC
+
+Similarly for =postfix= I also used this certificate. Do note that =dovecot= and =postfix= should be run as =root= to have read permissions to read these certificates.
+
+***** Mail Client
+
+I am using Thunderbird as my mail client and for receiving mail. I used SSL/TLS while for sending mail, I needed to set STARTTLS.
+
+**** Security Measures
+After completing the email setup, I immediately tested the server by sending test emails, only to find them been tossed straight into spam by gmail. It seems that gmail has a new feature that shows the security check status on the email (accessible by 'View Original'). These measures include SPF, DKIM and DMARC. My avatar showed up as an octagon with a question mark, indicating the mail server failing the basic SPF check. In order to avoid this, I took a bunch of security measures to tick all the boxes from email security test sites like [[https://intodns.com][intodns]] and [[https://mxtoolbox.com][mxtoolbox]].
+
+***** Sender Policy Framework (SPF)
+An SPF TXT record documents the allowed servers to send emails on behalf of this address. In my case where only mail servers documented in the MX TXT record are used, I simply put in:
+#+BEGIN_SRC sh
+v=spf1 mx -all
+#+END_SRC
+
+***** DomainKeys Identified Mail (DKIM)
+I am using =opendkim= to sign and verify that emails are indeed from my server. After installing the =opendkim= package, I followed the instruction in [[https://wiki.archlinux.org/index.php/OpenDKIM][Arch Wiki]]. First copy example configuration file from =/etc/opendkim/opendkim.conf.sample= to =/etc/opendkim/opendkim.conf= and edit (socket selection can be arbitrary):
+#+BEGIN_SRC sh
+Domain <domainname>
+KeyFile /path/to/keys.private
+Selector <myselector>
+Socket inet:<dkimsocket>@localhost
+UserID opendkim
+Conicalization relaxed/simple
+#+END_SRC
+
+Next, in the specified keyfile directory (the default is =/var/db/dkim/=), generate keys with:
+#+BEGIN_SRC sh
+$ opendkim-genkey -r -s <myselector> -d <domainname> --bits=2048
+#+END_SRC
+
+Along with the generated =.private= file is a =.txt= file with the necessary TXT record for DKIM. It basically posts the public key for your mail server. Note that the TXT record may need to be broke down into several strings to comply with the 255 character limit. To check if the TXT record has been properly setup, I used (requires package =dnsutils= ):
+#+BEGIN_SRC sh
+$ host -t TXT <myselector>._domainkey.<domainname>
+#+END_SRC
+
+The final step would be to start the =opendkim= service and make sure =postfix= performs the encryption upon sending email. Edit =/etc/postfix/main.cf= to be:
+#+BEGIN_SRC sh
+non_smtpd_milters=inet:127.0.0.1:<dkimsocket>
+smtpd_milters=inet:127.0.0.1:<dkimsocket>
+#+END_SRC
+
+After reloading =postfix=, DKIM should be in effect.
+
+***** Domain-based Message Authentication, Reporting and Conformance (DMARC)
+Without surprise, there is a package =opendmarc= that implements DMARC and there is also an [[https://wiki.archlinux.org/index.php/OpenDMARC][Arch Wiki]] page for it. Do note that this would require SPF and DKIM to be setup first. After installation, I edited =/etc/opendmarc/opendmarc.conf=:
+#+BEGIN_SRC sh
+Socket inet:<dmarcsocket>@localhost
+#+END_SRC
+
+After starting the service, enable DMARC filter in =postfix= (separate with comma):
+#+BEGIN_SRC sh
+non_smtpd_milters=inet:127.0.0.1:<dkimsocket>, inet:127.0.0.1:<dmarcsocket>
+smtpd_milters=inet:127.0.0.1:<dkimsocket>, inet:127.0.0.1:<dmarcsocket>
+#+END_SRC
+
+The final step is to add a DMARC TXT record in DNS settings as detailed on Arch Wiki page and reload =postfix=.
+
+**** Ticking the Boxes
+I tested my server by sending test email to =check-auth@verifier.port25.com= and everything seems to be working. Not to mention that my email no longer gets classified as spam by gmail and I can see my emails passing SPF, DKIM and DMARC checks in 'View Original'. I also get an detailed daily report from gmail due to DMARC. At this point, I am pretty comfortable about ditching all my previous gmail addresses and sticking to my own email. I am also looking into options of self-hosting calenders. Hopefully in the near future I can completely ditch Google for my essential communication needs.
+
+*** DONE zh
+:PROPERTIES:
+:EXPORT_TITLE: 是 Spam 还是 Ham
+:EXPORT_FILE_NAME: spam-or-ham.zh.md
+:END:
+
+遵循之前的计划,我打算将设置邮箱的过程记录下来。设置邮箱大部分地方都有教程,不过我需要添加不少额外的安全设置来避免邮件被扔进垃圾箱。
+
+**** 搭建邮件服务器
+
+我八成是写不出比 [[http://www.netarky.com/programming/arch_linux/Arch_Linux_mail_server_setup_1.html][这篇教程]] 更好的步骤说明的,所以我就在这里把我额外需要的一些设置记录下来。
+
+***** 设置 DNS 记录
+在开始搭建邮箱之前,我需要设置 DNS 记录。我为我的邮件服务器地址设置了一条 =CNAME= 记录,并用一条 =MX= 记录来标明所使用的邮件服务器。
+
+***** 创建 =Maildir=
+在设置好 =postfix= 之后,我需要手动创建 =Maildir= 文件夹并赋予其合适的权限:
+#+BEGIN_SRC sh
+$ mkdir -p /home/<username>/Maildir/{cur,new,tmp}
+$ chown <username> /home/<username>/Maildir/{,cur,new,tmp}
+$ chmod 0755 /home/<username>/Maildir/{,cur,new,tmp}
+#+END_SRC
+
+***** SSL 证书
+我没有使用 =dovecot= 自带的证书生成器,而是直接沿用了我网站的 SSL 证书。我将邮件服务器地址加入 =/etc/nginx/nginx.conf= 中的 =server_name= 下,并用 =certbot= 生成了合适的证书。在这之后,我修改了 =dovecot= 的设置文件 =/etc/dovecot/conf.d/10-ssl.conf= :
+#+BEGIN_SRC sh
+use_ssl = yes
+ssl_cert = </path/to/fullchain.pem
+ssl_key = </path/to/privkey.pem
+#+END_SRC
+
+我也在 =postfix= 上用了这个证书。需要注意的是 =dovecot= 和 =postfix= 都需要用 =root= 账户运行才会有权限读取证书。
+
+***** 邮件客户端
+我使用 Thunderbird 作为邮件客户端。收取邮件时,我使用 SSL/TLS,而发送邮件则使用 STARTTLS。
+
+**** 安全措施
+设置好邮件服务器后,我试着发了几封邮件,不过发现都被 gmail 扔进了垃圾箱。似乎 gmail 最近添加了显示邮件安全检查状态的功能(在 gmail 中点击“查看原件”即可看到)。这些检查包括 SPF , DKIM , 和 DMARC 。由于我的邮件服务器没有通过最基本的 SPF 检查,所以我的头像显示为一个标着问号的八边形。为了避免邮件被扔进垃圾箱,我进行了一系列安全设置以保证我的邮件服务器能通过网上邮箱安全测试平台(我使用的是 [[https://intodns.com][intodns]] 和 [[https://mxtoolbox.com][mxtoolbox]] )的考验。
+
+***** 发件人策略框架( SPF )
+SPF TXT 记录标明了某一域名所承认的邮件服务器地址。在我的情况下,我只会用到 MX TXT 记录中所提到的邮件服务器,所以我的 SPF TXT 记录就是:
+#+BEGIN_SRC sh
+v=spf1 mx -all
+#+END_SRC
+
+***** 域名密匙邮件认证( DKIM )
+我使用 =opendkim= 来为邮件署名,以验证邮件的确来自于我的服务器。在安装了 =opendkim= 软件包后,我遵循 [[https://wiki.archlinux.org/index.php/OpenDKIM][Arch Wiki]] 里的步骤完成了设置。首先,复制设置文件模板 =/etc/opendkim/opendkim.conf.sample= 到 =/etc/opendkim/opendkim.conf= 并编辑(端口可以随意选择):
+#+BEGIN_SRC sh
+Domain <domainname>
+KeyFile /path/to/keys.private
+Selector <myselector>
+Socket inet:<dkimsocket>@localhost
+UserID opendkim
+Canonicalization relaxed/simple
+#+END_SRC
+
+接下来,在设置文件所指定的密匙文件路径下(默认为 =/var/db/dkim/= ),生成密匙:
+#+BEGIN_SRC sh
+$ opendkim-genkey -r -s <myselector> -d <domainname> --bits=2048
+#+END_SRC
+
+执行指令后生成的不仅仅是 =.private= 密匙文件,还有装有完成 DKIM 设置所需 TXT 记录的 =.txt= 文件。这一记录的功能在于公布邮箱服务器的公共密匙。需要注意的是这条 TXT 记录有可能会被分成数条字符串,以满足每条字符串最长 255 字符的要求。为了查看 TXT 记录是否有设置成功,我运行了(需要安装 =dnsutils= 软件包):
+#+BEGIN_SRC sh
+$ host -t TXT <myselector>._domainkey.<domainname>
+#+END_SRC
+
+接下,重启 =opendkim= 服务并确保 =postfix= 在发出邮件之前执行加密。编辑 =/etc/postfix/main.cf= :
+#+BEGIN_SRC sh
+non_smtpd_milters=inet:127.0.0.1:<dkimsocket>
+smtpd_milters=inet:127.0.0.1:<dkimsocket>
+#+END_SRC
+
+在重启 =postfix= 后, DKIM 就开始运作了。
+
+***** 基于域名的邮件认证,报告和一致性检查( DMARC )
+毫无意外,有一个软件包 =opendmarc= 可以用于部署 DMARC ,并且这一软件包也有对应的 [[https://wiki.archlinux.org/index.php/OpenDMARC][Arch Wiki]] 页面。需要注意的是, DMARC 必须在 SPF 和 DKIM 都设置完成后才能生效。在安装软件包后,编辑 =/etc/opendmarc/opendmarc.conf=:
+#+BEGIN_SRC sh
+Socket inet:<dmarcsocket>@localhost
+#+END_SRC
+
+在启动 =opendmarc= 服务后,在 =postfix= 中启用 DMARC 邮件滤网(与 DKIM 滤网用逗号隔开):
+#+BEGIN_SRC sh
+non_smtpd_milters=inet:127.0.0.1:<dkimsocket>, inet:127.0.0.1:<dmarcsocket>
+smtpd_milters=inet:127.0.0.1:<dkimsocket>, inet:127.0.0.1:<dmarcsocket>
+#+END_SRC
+
+最后,按照 Arch Wiki 所指示的步骤在 DNS 设置中加上一条 DMARC TXT 记录并重启 =postfix= 就大功告成了。
+
+**** 通过所有测试
+给 =check-auth@verifier.port25.com= 发送测试邮件后,我收到了一份邮件服务器的测试报告。报告显示所有安全设置都在正常运作。除此之外, gmail 不再将我的邮件扔进垃圾箱了,而“查看原件”页面下也显示我的邮件通过了 SPF , DKIM , 和 DMARC 检查。 由于启用了 DMARC , gmail 还会每天向我的邮箱发送一份安全报告。折腾到这个地步后,我对我的新邮箱比较满意了,并准备废除我之前所使用的邮箱。我还在寻找可以自己架设的日历服务,希望不久的将来我可以完全摆脱在通讯方面对 Google 服务的依赖。
+
* Emacs :@emacs:
** TODO Get =emacs= To Work With =fcitx= :emacs:fcitx:
diff --git a/org/fixed.org b/org/fixed.org
@@ -37,10 +37,9 @@
- [X] Find a suitable icon/favicon.
- [X] Improve templates for posts to display tags and categories.
- [X] Cosmetic changes, i.e. no underlines for hyperlinks.
+- [X] Deal with some nuances in using =org-mode= with =hugo= , like how to get syntax highlighting to work properly.
- [X] Host my own email.
-- [ ] Deal with some nuances in using =org-mode= with =hugo= , like how to get syntax highlighting to work properly.
-- [ ] Customizable Disqus via Disqus API.
-- [ ] Customize =hugo new= to make it more useful, i.e. create multilingual versions directly.
+- [X] Customize =hugo new= to make it more useful, i.e. create multilingual versions directly.
- [ ] Restore/rewrite and translate some of the more valuable old posts.
**** Recent Posts
@@ -77,8 +76,8 @@
- [X] 改善文章页面模板使其显示标签和分类。
- [X] 改善网站外观,比如隐藏超链接的下划线等。
- [X] 架设自己的邮箱。
-- [ ] 解决 =org-mode= 和 =hugo= 略不兼容的地方,比如代码高亮。
-- [ ] 尝试把 =hugo new= 变得更有用一些,比如直接创建多语言版本等。
+- [X] 解决 =org-mode= 和 =hugo= 略不兼容的地方,比如代码高亮。
+- [X] 尝试把 =hugo new= 变得更有用一些,比如直接创建多语言版本等。
- [ ] 把比较有价值的旧文章搬过来。
**** 最新日志