普通视图

发现新文章,点击刷新页面。
昨天以前初等記憶體

Maddy 自建邮件服务

2022年1月10日 22:15
Featured image of post Maddy 自建邮件服务

从白嫖 Yandex 域名邮箱到 FastMail 付费托管邮箱,一直在找适合自己的域名邮件服务,传统的自建方式模块过于分散,上手难度较大,后在 NickCao 老师推荐下尝试了 Maddy。Maddy 目前只提供了命令行运行的 Linux 服务端,WebUI 或者本地客户端需自行选择,仅需手动配置一下 POP3/IMAP(收) 和 SMTP(发) 服务端地址即可。我目前使用的是 Thunderbird (电脑)和 K-9 Mail(Android)。

下载:Github | 上游服务器 文档:maddy.email

服务器

部分 VPS 提供商会为了防止广告等原因会禁用 25 号 TCP 端口的 SMTP 端口,但多数情况下(比如 Google Cloud 就不允许)也可以开工单说明邮箱用途和性质,对于个人性质的域名邮箱来说一般不会有太多限制。如果机器本身或者 VPS 提供商还配有防火墙,请打开对应端口(25,465,993)。

使用邮件服务需要关闭 CDN 代理,故存在机器 IP 暴露风险,在选择机器时候注意避开其它敏感数据服务

配置

可以从 docker 拉取,但这里以 binary + 自己配置方式为主。

maddy.conf

完整版配置

一般放在 /etc/maddy/maddy.conf

 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
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# 预设了三个变量,方便后续使用
$(hostname) = mail.example.com
$(primary_domain) = example.com
$(local_domains) = $(primary_domain)

# 如果要使用 nginx 反代,这里可以选择 tls off,但如此一来没法生成 dkim 密钥对
# 在之后检查时日志内会有安全警告,故推荐直接用 maddy 管理
# tls off
tls file /etc/letsencrypt/live/$(local_domains)/fullchain.pem /etc/letsencrypt/live/$(local_domains)/privkey.pem

# 数据用 SQLite3 存储较为简单、轻量
auth.pass_table local_authdb {
 table sql_table {
 driver sqlite3
 dsn credentials.db
 table_name passwords
 }
}

storage.imapsql local_mailboxes {
 driver sqlite3
 dsn imapsql.db
}

# ----------------------------------------------------------------------------
# SMTP endpoints + message routing

hostname $(hostname)

table.chain local_rewrites {
 optional_step regexp "(.+)\+(.+)@(.+)" "$1@$3"
 optional_step static {
 entry postmaster postmaster@$(primary_domain)
 }
 optional_step file /etc/maddy/aliases
}

msgpipeline local_routing {
 destination postmaster $(local_domains) {
 modify {
 replace_rcpt &local_rewrites
 }

 deliver_to &local_mailboxes
 }

 default_destination {
 reject 550 5.1.1 "User doesn't exist"
 }
}

# smtp 使用 25 号端口发送邮件
smtp tcp://[::]:25 {
 # tls self_signed
 limits {
 # Up to 20 msgs/sec across max. 10 SMTP connections.
 all rate 20 1s
 all concurrency 10
 }

 dmarc yes
 check {
 require_mx_record
 dkim # 若无则不检查
 spf
 }

 source $(local_domains) {
 reject 501 5.1.8 "Use Submission for outgoing SMTP"
 }
 default_source {
 destination postmaster $(local_domains) {
 deliver_to &local_routing
 }
 default_destination {
 reject 550 5.1.1 "User doesn't exist"
 }
 }
}

# 如果使用 nginx 反代则这里监听到本地端口即可 tcp://127.0.0.1:587
# 不使用则邮件客户端以 SSL/TLS 方式直接访问该地址
submission tls://[::]:465 {
 limits {
 # Up to 50 msgs/sec across any amount of SMTP connections.
 all rate 50 1s
 }

 auth &local_authdb

 source $(local_domains) {
 check {
 authorize_sender {
 prepare_email &local_rewrites
 user_to_email identity
 }
 }

 destination postmaster $(local_domains) {
 deliver_to &local_routing
 }
 default_destination {
 modify {
 dkim $(primary_domain) $(local_domains) default
 }
 deliver_to &remote_queue
 }
 }
 default_source {
 reject 501 5.1.8 "Non-local sender domain"
 }
}

target.remote outbound_delivery {
 limits {
 # Up to 20 msgs/sec across max. 10 SMTP connections
 # for each recipient domain.
 destination rate 20 1s
 destination concurrency 10
 }
 mx_auth {
 dane
 mtasts {
 cache fs
 fs_dir mtasts_cache/
 }
 local_policy {
 min_tls_level encrypted
 min_mx_level none
 }
 }
}

target.queue remote_queue {
 target &outbound_delivery

 autogenerated_msg_domain $(primary_domain)
 bounce {
 destination postmaster $(local_domains) {
 deliver_to &local_routing
 }
 default_destination {
 reject 550 5.0.0 "Refusing to send DSNs to non-local addresses"
 }
 }
}

# ----------------------------------------------------------------------------
# IMAP endpoints
# 同上,使用 nginx 反代则改为监听本地端口 tcp://127.0.0.1:143
imap tls://[::]:993 {
 auth &local_authdb
 storage &local_mailboxes
}

Nginx Config(可选)

如果是由 Maddy 自身直接处理 TLS 则不需要该项配置

 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
upstream maddy_imaps {
 # 指向本地 Maddy IMAP 监听服务端口
 server 127.0.0.1:143;
}

upstream maddy_smtps {
 # 指向本地 Maddy SMTP 服务监听端口
 server 127.0.0.1:587;
}

server {
 listen 993 ssl;
 proxy_pass maddy_imaps;
 ssl_certificate /etc/letsencrypt/live/<example.com>/fullchain.pem; # 换成自己的域名证书
 ssl_certificate_key /etc/letsencrypt/live/<example.com>/privkey.pem; # 换成自己的域名证书
 ssl_protocols SSLv3 TLSv1.1 TLSv1.2 TLSv1.3;
 ssl_ciphers HIGH:!aNULL:!MD5;
 ssl_session_timeout 4h;
 ssl_handshake_timeout 30s;
}

server {
 listen 465 ssl;
 proxy_pass maddy_smtps;
 ssl_certificate /etc/letsencrypt/live/<example.com>/fullchain.pem; # managed by Certbot
 ssl_certificate_key /etc/letsencrypt/live/<example.com>/privkey.pem; # managed by Certbot
 ssl_protocols SSLv3 TLSv1.1 TLSv1.2 TLSv1.3;
 ssl_ciphers HIGH:!aNULL:!MD5;
 ssl_session_timeout 4h;
 ssl_handshake_timeout 30s;
}

注册账户

maddy 的 systemd service 正常启动后可以使用:

1
2
3
4
5
6
7
$ sudo -u maddy -s # 切换到 maddy 用户
$ maddyctl creds create <username@example.com> --password <YourPassword>
$ maddyctl creds list # 查看你刚创建的用户名
$ maddyctl imap-acct create <username@example.com> # 创建一个邮件储存账户
$ maddyctl imap-acct list # 查看刚创建的 imap 储存账户
$ maddyctl imap-mboxes list <username@example.com> # 可以看到该账户下有哪些分类
$ maddyctl imap-msgs list <username@example.com> <INBOX> # 可以查看当前账户对应分类接收到的邮件,一般收件在 INBOX 中

DNS 设置

这里以 Cloudflare 托管 DNS 服务为例,其它应该也能找到对应 DNS 设置面板。使用了子域名 mail.example.com 作为邮件服务专用。

类型 名称 内容 代理状态
A mail 服务器实际 IPv4 地址 仅限 DNS
AAAA mail 服务器实际 IPv6 地址(如果有) 仅限 DNS
MX @ mail.example.com 仅限 DNS
TXT mail v=spf1 mx ~all 仅限 DNS

spf 值这里推荐使用仅允许 mx,若有其他来源也可以添加。

Reverse DNS

为了避免拒收,进一步提高邮件投递率,需要配置 rDNS 以便收信方邮件服务商溯源。

以 Vultr 为例,其 Reverse DNS 页面在 机器详情 > Settings > IPv4 / IPv6 选项卡内,在 Reverse DNS 中填入自己的邮件服务域名即可,如 mail.example.com,如果存在多条公共 IP 地址,则都需要填写。

多域名配置 (如无可跳过)

  1. local_domains 后面加上新的域名
1
2
3
$(primary_domain) = example.com
$(secondary_domain) = example.org
$(local_domains) = $(primary_domain) $(secondary_domain)
  1. 在 tls file 后面添加对应的证书,如果用 nginx 反代的话则添加对应的 host 路由和域名。
1
tls file /etc/letsencrypt/live/$(primary_domain)/fullchain.pem /etc/letsencrypt/live/$(primary_domain)/privkey.pem /etc/letsencrypt/live/$(secondary_domain)/fullchain.pem /etc/letsencrypt/live/$(secondary_domain)/privkey.pem
  1. 将新域名的 dkim 密钥内容也添加到 DNS 的 TXT 记录中

  2. dmarc 和 rDNS 同理

客户端

客户端有诸多选择,不变的是手动设置方式:

  • IMAP 和 SMTP 服务器地址都设置为 mail.example.com,连接方式均为 SSL/TLS,用户名和密码均为先前所设置,认证方式均为 Normal Password
  • IMAP 端口为 993
  • SMTP 端口为 465

小结

Oh My Yandex

可以写一些稍微正经的内容,发送到 https://www.mail-tester.com 内所给的邮件地址,来测试自己的邮箱评分。

虽然说自建邮箱可能还是存在邮件投递到垃圾箱里的问题,但有了 Maddy 后搭建一个自己的域名邮箱确实变成了相对简单的工作。

Linux 用户环境变量设置

2021年2月23日 20:35
Featured image of post Linux 用户环境变量设置

序言

Linux 下的用户环境变量配置常显得十分琐碎,如 .xprofile、.pam_environment 亦或是各种 shell 配置文件。

  • .xprofile 受限于 x11 服务,在 wayland 或未启动图形界面等情况下不会被读取。
  • .pam_environment 由于提权漏洞频出(如:CVE-2010-4708CVE-2011-3148),已经被上游遗弃,一些发行版为了兼容老的用户配置,在 /etc/pam.d/system-login 中临时加入 session required pam_env.so user_readenv=1 以恢复读取该文件中环境变量的行为,并非长久之计。

参考了依云的 Linux 的环境变量怎么设 一文,遂选用 systemd 的 environment.d 作为用户环境变量配置方案。

介绍

配置文件目录如下:

  • ~/.config/environment.d/*.conf [✓]
  • /run/environment.d/*.conf
  • /etc/environment.d/*.conf
  • /usr/lib/environment.d/*.conf
  • /etc/environment

其写法如下:

  • 环境变量=值
  • 环境变量=${值:-如果为空的默认值}
  • 环境变量=${值:+添加值}
  • 可以读取 $HOME, $PATH 等原有的环境变量,如:PATH=~/.local/bin:$PATH

apps.conf

由于我是 fish + tmux 用户,需要自己导出一下生成的环境变量文件到命令行。

~/.config/fish/conf.d/env_init.fish

1
2
3
if not contains $PATH $USER
 export (/usr/lib/systemd/user-environment-generators/30-systemd-environment-d-generator)
end

show environments

关于 KDE/Plasma 的补充

Plasma and the systemd startup

在 Plasma 5.21 和 Systemd 246 以及后续更新版本中,可以使用 systemd 来启动和管理 KDE 服务。

其中一个好处在于:其环境变量可直接继承自 environment.d 而无需再手动设置 systemd-environment-d-generator 生成的环境变量。

启用后重启生效。

1
$ kwriteconfig5 --file startkderc --group General --key systemdBoot true

使用 Systemd 进行管理后可利用其 CGroups 限制资源分配和使用等诸多特性(或许可以给你的应用加上 cgproxy?),进一步细化和统一用户配置方案,再次感谢开发者为此做出的努力。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ systemctl --user set-property app-telegramdesktop-b9317feb02e54b4c93dd1c97a06711a4.scope MemoryMax=1500M MemoryLimit=1G
$ systemctl --user status app-telegramdesktop-b9317feb02e54b4c93dd1c97a06711a4.scope
 ● app-telegramdesktop-b9317feb02e54b4c93dd1c97a06711a4.scope - Telegram Desktop
 Loaded: loaded (/usr/share/applications/telegramdesktop.desktop; transient)
 Transient: yes
 Drop-In: /run/user/1000/systemd/transient/app-telegramdesktop-b9317feb02e54b4c93dd1c97a06711a4.scope.d
 └─50-MemoryLimit.conf, 50-MemoryMax.conf
 Active: active (running) since Tue 2021-02-23 21:02:37 CST; 5min ago
 Tasks: 44 (limit: 18425)
 Memory: 351.0M (max: 1.4G limit: 1.0G)
 CPU: 20.056s
 CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/app-telegramdesktop-b9317feb02e54b4c93dd1c97a06711a4.scope
 └─15363 /usr/bin/telegram-desktop --

在 QEMU/KVM 虚拟机上安装 NixOS 发行版

2021年1月7日 22:57
Featured image of post 在 QEMU/KVM 虚拟机上安装 NixOS 发行版

前言

2019 年 1 月的时候知道了这个发行版,当时 @NixOS_zh 群刚建立(后来这群凉了),就开虚拟机玩了一下,时隔多年发现又有不少人对其颇感兴趣,便决定重新写一下安装相关的教程。

本文以 Arch Linux 作为宿主机,大体步骤与 Arch Wiki 相近

QEMU/KVM 虚拟机配置

ArchLinux Wiki: KVM | QEMU | Libvirt

0. 检测硬件是否支持 KVM

一般情况下需要进入到 BIOS 对应页面打开虚拟化支持,常见对应设置项如下:

  • AMD: SVM Support
  • Intel: Intel Virtual Technology

开启虚拟化后在宿主机上用命令行检测(比如我的是 AMD 的处理器):

1
2
$ LC_ALL=C lscpu | grep Virtualization
Virtualization: AMD-V

内核支持检测,如果使用的是 ArchLinux 提供的官方内核,即 core/linux 则已经包含了对应的 kvm 模块(kvmkvm_amdkvm_intel):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ zgrep CONFIG_KVM /proc/config.gz
CONFIG_KVM_GUEST=y
CONFIG_KVM_MMIO=y
CONFIG_KVM_ASYNC_PF=y
CONFIG_KVM_VFIO=y
CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y
CONFIG_KVM_COMPAT=y
CONFIG_KVM_XFER_TO_GUEST_WORK=y
CONFIG_KVM=m
CONFIG_KVM_INTEL=m
CONFIG_KVM_AMD=m # 可以看到有该模块
CONFIG_KVM_AMD_SEV=y
CONFIG_KVM_MMU_AUDIT=y

查看这些内核模块是否已自动加载:

1
2
3
4
5
$ lsmod |grep kvm
kvm_amd 114688 8
ccp 118784 1 kvm_amd
kvm 933888 1 kvm_amd
irqbypass 16384 1 kvm

如果没有自动加载则手动:

1
2
$ sudo modprobe kvm
$ sudo modprobe kvm_amd # 对应你的 CPU 类型

1. 准虚拟化(使用 VIRTIO)

检测 VIRTIO 模块是否可用:

 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
$ zgrep VIRTIO /proc/config.gz
CONFIG_BLK_MQ_VIRTIO=y
CONFIG_VIRTIO_VSOCKETS=m
CONFIG_VIRTIO_VSOCKETS_COMMON=m
CONFIG_NET_9P_VIRTIO=m
CONFIG_VIRTIO_BLK=m
CONFIG_SCSI_VIRTIO=m
CONFIG_VIRTIO_NET=m
CONFIG_VIRTIO_CONSOLE=m
CONFIG_HW_RANDOM_VIRTIO=m
CONFIG_DRM_VIRTIO_GPU=m
CONFIG_VIRTIO=y
CONFIG_VIRTIO_MENU=y
CONFIG_VIRTIO_PCI=m
CONFIG_VIRTIO_PCI_LEGACY=y
CONFIG_VIRTIO_VDPA=m
CONFIG_VIRTIO_PMEM=m
CONFIG_VIRTIO_BALLOON=m
CONFIG_VIRTIO_MEM=m
CONFIG_VIRTIO_INPUT=m
CONFIG_VIRTIO_MMIO=m
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
CONFIG_VIRTIO_DMA_SHARED_BUFFER=m
CONFIG_RPMSG_VIRTIO=m
CONFIG_VIRTIO_FS=m
CONFIG_CRYPTO_DEV_VIRTIO=m

准虚拟化设备列表(主要确保以下几个模块有对应开启,若未开启则手动用 modprobe 命令开启):

  • 网络设备 (virtio-net)
  • 硬盘设备 (virtio-blk)
  • 控制器设备 (virtio-scsi)

2. 安装 QEMU

1
$ sudo pacman -S qemu

Arch Wiki: PCI 直通

如果需要启用 PCI 直通功能则需要在内核参数中添加 intel_iommu=on 或者 amd_iommu=on,同时可以在其后添加 iommu=pt,以防前者失效,以下命令检测是否开启成功,由于本人所用 AMD Ryzen 5 4600U 支持方面还有些问题,故此不做展示。

1
$ sudo dmesg | grep -i -e DMAR -e IOMMU

3. 安装 libvirt

1
$ sudo pacman -S libvirt virt-manager dnsmasq edk2-ovmf

为了避免每次都需要询问 root 密码,建议将自己的用户添加到 libvirt 组:

1
$ sudo usermod -aG libvirt <YourUserName>

编辑服务端配置文件 /etc/libvirt/libvirtd.conf,取消如下几行的注释:

1
2
3
4
5
unix_sock_group = "libvirt"
unix_sock_ro_perms = "0777" # set to 0770 to deny on-group libvirt users
unix_sock_rw_perms = "0770"
auth_unix_ro = "none"
auth_unix_rw = "none"

同时添加 ipv4 的内核转发参数:

1
$ sudo echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.d/00-network.conf

设置开机启动和运行服务。

1
$ sudo systemctl enable --now libvirtd.service

4. 配置 virt-manager

添加连接

建议重启以应用之前的设置,此时在 Virtual Machine Manager 的界面应该可以看到一些已经连接上的服务端,如果没有则在菜单栏自行添加,推荐初次连接系统级服务来创建虚拟机。

添加虚拟机

NixOS 镜像下载

将下载到的镜像文件所在目录创建为文件系统池,随后在其中选择镜像文件进行加载。

添加镜像池 选择镜像

设置合适的系统资源和网络配置等(初次使用推荐用 NAT 模式较为简单,Bridge 模式之后会提到如何配置)。

虚拟机能用的内存和CPU核心数量设置 存储空间设置

如果你的宿主机支持的话,推荐使用 UEFI 模式启动(由 extra/edk2-ovmf 这个提供,中途安装的话要重启 libvirtd 服务以生效)。

EFI Firmware

调整镜像到启动优先级最高,最后启动工具栏上的 Begin Install 就可以安装了。 更改启动优先级

NixOS 系统安装

NixOS 使用手册

0. 进入引导界面

ISO Grub NixOS 镜像启动

由于我下载的是最小化镜像,所以并没有图形界面,如果下载的是带 Gnome 或者 KDE 的镜像的话应该可以看到界面了,稍后我也会以最小化镜像的方式开始安装图形界面。

1. 磁盘分区

查看当前块设备状态,可以看到我们之前分配的盘 vda 还未被挂载

lsblk

建议使用 GPT 分区表,按照可以按照图中对 bootswap(可选)和 root 分区进行创建,注意下方 Type 选择对应的分区类型,Write 写入后退出。

1
$ sudo cfdisk /dev/vda

cfdisk

格式化分区,可以看到格式化后效果如下:

1
2
3
4
$ sudo mkfs.fat -F32 /dev/vda1
$ sudo mkswap /dev/vda2
$ sudo swapon
$ sudo mkfs.xfs -L root /dev/vda3

mkfs check

2. 分区挂载

1
2
3
$ sudo mount /dev/vda3 /mnt
$ sudo mkdir -p /mnt/boot
$ sudo mount /dev/vda1 /mnt/boot

挂载后可以检查是否挂载成功,不要重复挂载。

挂载

3. 系统配置

由命令生成默认的配置文件:

1
2
$ sudo nixos-generate-config --root /mnt
$ sudo nano /mnt/etc/nixos/configuration.nix

可以看到已经有了 systemd-boot 作为 bootloader 引导操作系统。其他一些基本配置,按照自己的需求取消注释并修改内容即可,注意创建用户 users.users.<YourUserName> 及其对应的用户组,完成后 Ctrl + O 保存。

config

如果网络情况欠佳的话可以设置 http_proxy 或者更换更新频道到国内镜像站:

TUNA Nix Help

1
$ sudo nix-channel --add https://mirrors.tuna.tsinghua.edu.cn/nix-channels/nixos-20.09 nixos

使用 sudo nixos-install 进行安装并设置 root 密码,完成之后取消挂载并重启(记得更改启动项顺序到虚拟硬盘)。

1
2
3
4
5
6
7
8
$ sudo nixos-install
...
setting root password...
Enter new UNIX password: ***
Retype new UNIX password: ***

$ sudo umount -r /mnt
$ reboot

调整启动顺序

NixOS 系统配置和使用

0. 检查引导状态

重启登陆后可以查看引导状态:

1
$ sudo bootctl status

systemd-boot 状态

1. 配置桌面环境

/etc/nixos/configuration.conf 配置文件参考如下

 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
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

{ config, pkgs, ... }:

{
 imports =
 [ # Include the results of the hardware scan.
 ./hardware-configuration.nix
 ];

 # Use the systemd-boot EFI boot loader.
 boot.loader.systemd-boot.enable = true;
 boot.loader.efi.canTouchEfiVariables = true;

 networking.hostName = "axionl"; # 设置 hostname.
 # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.

 # Set your time zone.
 time.timeZone = "Asia/Shanghai"; # 设置时区

 # The global useDHCP flag is deprecated, therefore explicitly set to false here.
 # Per-interface useDHCP will be mandatory in the future, so this generated config
 # replicates the default behavior.
 networking.useDHCP = false;
 networking.interfaces.enp1s0.useDHCP = false;
 networking.networkmanager.enable = true; # 启用 NetworkManager 替代默认的 DHCP

 # Configure network proxy if necessary
 networking.proxy.default = "http://192.168.122.1:8888"; # 设置一个外部代理(可选)
 # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";

 # Select internationalisation properties.
 i18n.defaultLocale = "en_US.UTF-8"; # 默认语言环境
 # console = {
 # font = "Lat2-Terminus16";
 # keyMap = "us";
 # };



 # Configure keymap in X11
 services.xserver.layout = "us"; # 设置键盘布局
 # services.xserver.xkbOptions = "eurosign:e";

 # Enable CUPS to print documents.
 services.printing.enable = false; # 启用打印服务(不需要可禁止)

 # Enable sound.
 sound.enable = true; # 允许声音
 hardware.pulseaudio.enable = true;

 # Enable touchpad support (enabled default in most desktopManager).
 services.xserver.libinput.enable = true; # 允许触摸板

 # Define a user account. Don't forget to set a password with ‘passwd’.
 # 创建用户并添加到用户组
 users.users.axionl = {
 isNormalUser = true;
 extraGroups = [ "wheel" "networkmanager" ]; # Enable ‘sudo’ for the user.
 shell = pkgs.fish; # 指定终端(默认为 bash)
 };

 # List packages installed in system profile. To search, run:
 # $ nix search wget
 # 在系统层面安装软件包
 environment.systemPackages = with pkgs; [
 htop
 neofetch
 fish
 spice-vdagent
 virglrenderer
 ];

 # Some programs need SUID wrappers, can be configured further or are
 # started in user sessions.
 # programs.mtr.enable = true;
 # programs.gnupg.agent = {
 # enable = true;
 # enableSSHSupport = true;
 # };

 # List services that you want to enable:

 # Enable the OpenSSH daemon.
 # services.openssh.enable = true;

 # Open ports in the firewall.
 # networking.firewall.allowedTCPPorts = [ ... ];
 # networking.firewall.allowedUDPPorts = [ ... ];
 # Or disable the firewall altogether.
 # networking.firewall.enable = false;

 # This value determines the NixOS release from which the default
 # settings for stateful data, like file locations and database versions
 # on your system were taken. It‘s perfectly fine and recommended to leave
 # this value at the release version of the first install of this system.
 # Before changing this value read the documentation for this option
 # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
 system.stateVersion = "20.09"; # Did you read the comment?

 # X Windows Server
 # 启动 X 显示服务
 services.xserver.enable = true;
 # services.qemuGuest.enable = true;
 # services.spice-vdagentd.enable = true;
 # 允许 SDDM 作为窗口管理器
 services.xserver.displayManager.sddm.enable = true;
 # 安装 Plasma KDE 作为桌面环境
 services.xserver.desktopManager.plasma5.enable = true;

 # Packages
 # 允许第三方闭源软件包
 nixpkgs.config.allowUnfree = true;
}

修改配置文件之后需要使用命令重建并推荐重启生效:

1
$ sudo nixos-rebuild switch --upgrade

日常使用的时候理论上可以多套配置(profile)兼容和切换,当配置过多的时候可用 nix-collect-garbage -d 来完成,详见文档

在用户层面安装软件包使用 nix 包管理器进行搜索和安装:

1
2
3
4
5
$ nix search <软件包名称> # 搜索
$ nix-env -i <软件包名称> # 安装
$ nix-env -qa # 列出可安装的包
$ nix-env -e <软件包名称> # 卸载软件包
$ nix-env --rollback # 软件包回滚

更多用法可见官方文档

2. 截图

预览

[归档] SmartDNS 一个智能分流的 DNS 服务

2021年1月2日 09:41
Featured image of post [归档] SmartDNS 一个智能分流的 DNS 服务

介绍

项目地址

DNS

域名系统(英语:Domain Name System,缩写:DNS)是互联网的一项服务。它作为将域名和 IP 地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。通常情况下本地的解析请求会发送到离你最近的 DNS 服务器,它可能是你的无线路由器、宿舍楼梯下的服务器或者运营商的地区性服务器等,但由于各种原因导致解析效果不理想,延迟高等问题,这时可以考虑换一个网络质量好的域名解析服务,错峰出行,减少拥堵。

SmartDNS

SmartDNS 集成了多种出栈请求协议,包括常用的 UDP 和较为现代的 DNS-Over-Https 等,能够在给定的规则列表中挑选出一个延迟最低的域名解析服务,并向其发送请求。同时其内部也提供 DNS 缓存,如果缓存能够命中则直接从本地缓存中返回对应 IP 地址,如未能查找到则继续向上级 DNS 服务传播请求。

structure

配置

默认配置文件

推荐项目:dnsmasq-china-list

作者肥猫在其项目中提供了几个较为常用的匹配规则列表,对于非 Arch Linux 用户而言可以把项目克隆到本地然后构建对应的配置文件,而 Arch 用户可以从 CN 源 里安装 smartdns-china-list-git 以获取自动更新。

生成对应的配置文件操作如下,具体参考,可见其生成形式为 nameserver /<域名>/<组名>,后面的组名就是对应我们后来需要的匹配规则而制定的。

1
2
$ cd dnsmasq-china-list
$ make smartdns SERVER=china

默认的配置文件中有很多不常用的项目,作为自己的配置文件一般精简到自己需要的功能配置即可。

 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
 # (可选)引入额外的规则列表,用绝对路径
conf-file /etc/smartdns/accelerated-domains.china.smartdns.conf
conf-file /etc/smartdns/apple.china.smartdns.conf
conf-file /etc/smartdns/google.china.smartdns.conf

# 本地监听端口
bind [::]:53

# 缓存大小
cache-size 4096

# 重启时读取之前的缓存
cache-persist yes

# 缓存文件存放位置
cache-file /var/cache/smartdns.cache

# 传统 UDP 协议(以阿里 DNS 为例)
server 223.5.5.5

# DNS Over TLS (以 CloudFlare DNS 为例)
server-tls 1.0.0.1

# DNS Over Https (以烧饼 DNS 为例)
server-https https://doh.dns.sb/dns-query -group china -group example

更多 DNS 服务地址:dnscrypt.info

如果有多个分组需求,可以自定义规则配置文件,服务配置后面再添加 -group [组名]

-exclude-default-group 标记为排除在默认组之内的服务需至少在一个组才可能被访问到。

启动

1
2
3
# smartdns -c smartdns.conf
or
# systemctl enable --now smartdns.service

默认在后台运行,推荐使用自带的 systemd service 来进行管理,如果 /ect/resolv.conf 没有被更改成监听本地的话可以检查一下文件是否有特殊标志位(lsattr),手动修改即可(chattr )。

1
2
3
4
$ cat /etc/resolv.conf

# DNS managed by SmartDNS
nameserver 127.0.0.1

Banner Artwork

Teleport 小记

2020年12月6日 23:04
Featured image of post Teleport 小记

简介

常用于跨平台集群管理,提供多设备认证、远程操作和反向代理。

项目地址:github.com/gravitational/teleport

官方网站:goteleport.com

安装

有以下几种方式,单个可执行文件内已经包含 web 管理平台、服务端和客户端功能。(Windows 目前仅支持客户端)

快速配置

服务端及 Web 管理平台

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
teleport:
 data_dir: /var/lib/teleport # 数据存放目录
auth_service:
 enabled: true
 cluster_name: "demo_cluster"
 listen_addr: 0.0.0.0:3025 # 认证监听地址
 tokens:
 - proxy,node,app:<nodes_auth_token> # 节点认证密令
ssh_service:
 enabled: true
 labels:
 env: staging
app_service:
 enabled: true
 debug_app: false
proxy_service:
 enabled: true
 listen_addr: 0.0.0.0:3023 # 反向代理监听地址
 web_listen_addr: 0.0.0.0:3080 # web 管理页面地址
 tunnel_listen_addr: 0.0.0.0:3024 # 隧道监听地址
 public_addr: <https://example.domain.org:3025> # 反向代理公共地址
 https_keypairs: # 本地测试时可不设置证书
 - key_file: <key_file_path>
 - cert_file: <cert_file_path>

可由如下命令启用服务端进行测试,要点如下:

  • 在本地测试时即便没有填写 https_keypairs 也仍然需要在监听的 web 地址前面加上 https://,或者使用 --insecure-no-tls 命令行参数对 http:// 进行访问。
  • 如果配置中含有非对应权限目录或者证书文件,则调整到对应权限,如 /var/lib/teleport 仅限 root 权限访问,则需要调整到对应的权限再启动命令。
  • 所有的登陆行文均在 web_listen_addr 所指示的地址发生。
  • 注意证书所对应的域名与可访问的相同
1
$ teleport start --config teleport.yaml

tctlteleport 的一个命令行管理工具,在 teleport 服务运行时,可以由它对用户、节点、密令等进行动态管理。

1
2
# 创建一个初始用户
$ tctl users add <username> <login_user, login_group> --config teleport.yaml

添加好用户后可访问提示的地址,输入账户密码,用手机两步验证器扫码后填入验证码即可初始化成功。配置文件中支持除 otp 外还支持 github auth 认证等方式。

注册界面 登陆界面

常用的两步验客户端

子节点

除了服务端平台自己可以作为节点外,还可以添加其他的子节点构成集群,大体上分为两类:

  • 子节点有公网可以访问
  • 非公网节点需要反向代理(roles 内需要含有 proxy)。

静态子节点

静态子节点配置文件需要对应服务端里的地址和 <nodes_auth_token>,随后直接在节点上运行即可。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
teleport:
 nodename: "my_laptop"
 data_dir: /var/lib/teleport/
 auth_token: <nodes_auth_token>
 auth_servers:
 - <https://example.domain.org:3025> # 认证地址
proxy_service:
 enabled: false # 本地子节点暂时无需启动反向代理服务端
ssh_service:
 enabled: true
 labels:
 env: local_node
auth_service:
 enabled: false # 本地子节点暂时无需启动认证服务端

动态子节点

动态子节点需要在服务端上进行添加,由以下命令生成一个临时的 token 以添加子节点。

1
$ tctl nodes add --roles=node,proxy --ttl=5m --config teleport.yaml

得到形如下方的命令:

1
2
3
4
$ teleport start \
 --roles=node,proxy \
 --token=<random_token> \
 --auth-server=<https://example.domain.org:3025>

添加成功后可以在 web 界面内看到所有的节点。 Server Page

客户端

安装包内自带一个名为 tsh 的可执行文件,用于命令行认证和登陆

1
$ tsh login --proxy=<https://example.domain.org:3025> --user=<username>

登陆后可以使用 ls 命令查看已添加的节点

1
2
3
4
5
6
$ tsh ls

Node Name Address Labels
-------------- -------------- ----------------
demo_cluster 127.0.0.1:3022 env=core_service
my_laptop ⟵ Tunnel env=local_node

使用 ssh 来登陆节点终端

1
$ tsh ssh <node_name>

高级配置

配合 K8S 管理服务

TBC…


Banner Artwork

❌
❌