使用K3的个人服务器配置

2021-01-01 09:04:29

本文档将描述我在2020年如何管理个人服务器。它将讨论

我管理自己的专用服务器已经有15年多了,我已经30岁了,这一切都要归功于Benjamin Bayart Internet libre,ou minitel 2.0或非法语" Free的演讲互联网或minitel 2.0"。对于那些不知道什么是迷你旅馆的人,让我为您引述Wikipedia。

Minitel是可通过电话线访问的videotex在线服务,并且是在万维网之前世界上最成功的在线服务。它是在法国布列塔尼雷恩附近的Cesson-Sévigné发明的。

从本质上讲,这次演讲是关于在2007年引起人们的注意,即互联网开始失去其去中心化的性质,并且由于我们对网络上所有内容的依赖,都依赖于集中式大公司,因此它看起来更像是minitel 2.0。如今,随着云的出现,这个警告铃声变得更加响亮,因为我们的计算机现在只是用于远程访问数据/计算的漂亮屏幕。

我从顽固的极端主义者出发,在父屋电话线后面托管一台由废料制成的服务器,使用Gentoo重新编译所有内容,控制每个USE标志,并高兴地向编译命令行添加-mtune = native。几年后,由于厌倦了整夜不得不在旧版Intel Pentium 3上重新编译所有内容,因为我错过了使用该新软件所必需的USE标志,因此我改用了Debian。

那时我以为我已经有了完美的安装程序,只需执行apt-get安装,几分钟后就可以安装好软件,还有其他功能吗?

也是在那时,我从在我父母的家中托管服务器切换到托管公司。我当时正在上大学,并打电话给父母让他们重启机器,因为由于部件老化而导致机器冻结,这花费了太多时间。我一直担心会丢失一些电子邮件,而IRC上的朋友抱怨我的服务器提供的频道的存档/历史记录不再可用。如此艰难的决定,尤其是由于所有东西都是手动安装而没有配置管理的,所以我去看望我的父母告诉他们,我正在从他们的关心中删除服务器,将其托管在online.net上,他们应该期望从现在起,我打来的电话甚至更少。

丰富了这些新的可用带宽,并且在将手动部署移植到Ansible之后,我真的以为这次设置非常完美。易于安装和配置管理!真的还有什么呢?

我找到了我的游轮,并和平地航行着,直到依赖性怪物将我赶下船。当您尝试将所有内容(邮件,Web服务器,gitlab,pop3,imap,torrent,owncloud,munin等)加载到Debian上的一台计算机中时,最终最终会激活不稳定的存储库以获取最新版本的软件包和最终导致软件之间版本冲突,以至于进行了apt-get update&& apt-get升级现在是您的宿敌。

在避免系统升级的同时,我花了一些时间与Kvm / Xen,FreeBSD jails,Illumos,微内核(我认为这将是未来的:x)和Docker镇的新玩家一起玩!由于太忙/懒惰而无法重新安装所有新东西,因此我最终使用了Docker,而Docker使我能够逐步隔离/修补使我烦恼的软件。您好,Python项目!

这种混合设置工作了一段时间,但管理起来很笨拙,尤其是在混合使用Ansible的情况下。我最终将所有内容移动到容器中,而不是没有麻烦的后缀,现在Ansible感觉很奇怪,而systemd和Docker之间的集成很奇怪,我只是在花时间胶合琐碎的事情。

因此,本月我花了一些时间来创建并与您共享我在2020年管理个人服务器的完美新设置!

因此,让我们开始吧。第一步是创建一个GPG密钥。这个密钥将用于加密我们拥有的每个秘密,以便能够在git存储库中提交它们。有了git内部的秘密,我们的存储库将能够独立运行并跨机器移植。我们将能够进行git clone并开始工作!

该GPG密钥将成为您基础结构的守护者,如果它泄漏,任何人都可以访问您的基础结构。因此,请将其存储在安全的地方,即YubiKey上

如果您尚未完成此操作,甚至可以签署git commit以便获得验证。由于您的pgp键,在github中添加了标签。如何解释这里

现在我们有了PGP密钥,我们将使用出色的工具SOPS对其进行加密。

肥皂不是很广为人知,但是非常实用且易于使用,这在安全工具中是一次很棒的加法。

之后,只需调用sops即可使用您的GPG密钥创建一个新秘密。 Sops会强制使用YAML,因此您的文件必须是有效的YAML。

❯mkdir secretssecrets_decrypted❯sops secrets / foobar.yml *具有默认值的编辑器*❯cat secrets / foorbar.yml#文件的内容已加密hello:ENC [AES256_GCM,data:zpzQz + siZxcshJj4PBvX2GMm3sWibxRPCgil2 = + EB6L。 。

-|无法使用PGP密钥解密数据密钥: golang.org/x/crypto/openpgp错误:无法加载secring:打开/home/chronos/user/.gnupg/secring.gpg:没有这样的文件或|目录; GPG二进制错误:退出状态2

还有其他命令可让您避免将解密的机密转储到文件系统上。如果您对此功能感兴趣,请查看

既然我们已经能够在我们的存储库中安全地存储机密信息了,现在该生成一个新的ssh密钥以便能够登录到我们未来的下一个服务器了。

我们将为ssh密钥设置一个密码短语,并使用ssh-agent /钥匙串,以避免每次都键入密码

#不要忘记设置一个强密码短语并将密钥的默认名称从id_rsa更改为其他名称,稍后在onssh-keygen上将很有用#将ssh密钥添加到密钥环中eval $( --agents ssh〜/ .ssh / your_private_key)

sops secrets / ssh.yml#编辑yaml文件以获取您的私钥和公共ssh密钥的2部分#在此部分中粘贴密钥的内容git add secrets / ssh.ymlgit commit -m' Adding ssh key&# 39;

现在,我们希望该存储库是自包含的,并且可以轻松地跨机器移植。一种有效的方法是使用Ansible来自动化我们的部署。但是在此设置中,我们不会充分利用配置管理的全部功能,因此我选择使用一个简单的makefile来自动执行部署。

❯mkdirconfig❯cat Makefile。电话:安装安装:sops -d --extract' [" public_key"]' --output〜/ .ssh / erebe_rsa.pub secrets / ssh.yml sops -d-提取' [" private_key"]' -输出〜/ .ssh / erebe_rsa.key secrets / ssh.yml chmod 600〜/ .ssh / erebe_rsa。 * grep -q erebe.eu〜/ .ssh / config> / dev / null 2>& 1 || cat config / ssh_client_config>> 〜/ .ssh / config mkdir〜/ .kube ||出口0

安装部分正在解密ssh密钥,安装它们,然后查看我的〜/ .ssh / config以查看我是否已经有服务器部分,以便在缺少时添加它。这样我就可以做一个ssh my-server并正确设置所有东西

我们有一个带有ssh密钥的git存储库,因此现在是时候使用这些密钥并在其后面获得一个真正的服务器了。

我个人使用的是来自online.net的1层dedibox,现在重命名为scaleway,每月8欧元。他们的机器坚如磐石,价格便宜,并且超过15年以来从未遇到过问题。您可以自由选择所需的任何提供者,但在这里我对要看的东西的建议

磁盘空间:使用容器会消耗大量磁盘空间。因此,请使用至少具有60G空间的计算机。

公用带宽限制:所有托管公司都会限制公用带宽,以免出现种子种子箱问题。因此,您以相同的价格获得的价格越高,它就越好(即:scaleway提供250Mbit / s,而OVH仅提供200Mbit)

免费的备份存储:在某个时候,我们将要备份数据,因此请查看它们是否为备份提供了一些外部存储

域名/免费邮件帐户:如果您打算将它们用作您的域名注册商,请查看它们是否可以为您提供电子邮件帐户存储空间,以便将其配置为不丢失邮件的备用

获得服务器提供商后,进行安装并为操作系统选择Debian。在某些时候,他们会要求您提供ssh密钥,因此请提供您先前创建的密钥。如果可以选择文件系统,请使用XFS而不是ext4,因为它为容器运行时提供了良好的支持。

机器已经安装到位并且可以与外界接触。要做的第一件事就是保护机器!我们想 :

HOST = $ {my-server}。电话:安装软件包#... package:ssh $ {HOST}' apt-get update&& apt-get install -y curl htop mtr tcpdump ncdu vim dnsutils strace linux-perf iftop' #启用自动安全更新ssh $ {HOST}' echo" unattended-upgrades无人值守升级/ enable_auto_updates布尔值true" | de bconf-set-selections&& apt-get install无人值守升级-y'

这样一来,机器就可以自行安装安全更新,而无需要求我们手动键入apt-get update&& apt-get升级

我们将禁用密码身份验证,仅允许公共密钥身份验证。由于我们的ssh密钥在我们的存储库中已加密,因此如果需要,它们将始终对我们可用(只要我们拥有GPG密钥)。

由于我不使用任何配置管理(即Ansible),因此使用普通用户并利用特权提升(sudo)来进行root用户操作是一种乏味的工作。因此,我允许在SSH服务器上进行root登录,使事情更易于管理。如果计划使用配置管理系统,请禁用root登录身份验证。

警告在执行此操作之前,请确保您能够正确使用ssh密钥登录,否则您将需要重新安装计算机/使用托管服务提供商的应急控制台进行修复。

❯Makefile.PHONY:安装软件包ssh#...#检查文件是否与git存储库不同,是​​否重新上传并重新启动ssh服务器sh:ssh $ {HOST}" cat / etc / ssh / sshd_config" |差异-config / sshd_config \ || (scp config / sshd_config $ {HOST}:/ etc / ssh / sshd_config&& ssh $ {HOST} systemctl重新启动

该计划的最后一部分是通过制定防火墙规则来保护网络安全。

我想靠近真实事物,因此我直接使用iptables创建防火墙规则。这是以必须重复IPv4和IPv6规则为代价的。

我们希望iptables规则的部署是幂等的,因此我们将创建一个自定义链来避免与默认链混淆。此外,我将直接使用iptables命令而不是iptable-restore,因为iptables-restore文件当程序仅管理防火墙规则的一部分时,需要整体且不能很好地组合。稍后我们将安装Kubernetes,这将使我们避免混乱代理规则。

#!/ bin / sh#仅在用于我们的主NIC时执行[" $ IFACE" !=" enp1s0" ] ||退出0#为了从online.netsysctl -w net.ipv6.conf.enp1s0.accept_ra = 2 #######################获得IPv6租约/路由#######IPv4 ###########################重置我们的自定义chainiptables -P INPUT ACCEPTiptables -D INPUT -jUSER_CUSTOMiptables -F USER_CUSTOMiptables -X USER_CUSTOMiptables -N USER_CUSTOM#允许回送接口iptables -A USER_CUSTOM -i lo -j ACCEPT#允许wireguard接口iptables -A USER_CUSTOM -i wg0 -j ACCEPT#允许Kubernetes接口iptables -A CECEPTips -A USERC USER_CUSTOM -i法兰绒-1 -j ACCEPT#允许已经接受的连接iptables -A USER_CUSTOM -p tcp -m conntrack --ctstate已建立,相关-j ACEPPTiptables -A USER_CUSTOM -p udp -m conntrack -ctstate已建立,相关-j ACCEPT -A USER_CUSTOM -p icmp -m conntrack --ctstate已建立,相关-j ACCEPT#接受传入的ICMP-服务器提供者使用ping监视机器iptables -A USER_CUSTOM -p icmp -j ACCEPT#允许sshiptables- USER_CUSTOM -p tcp --dport 22 -j ACCEPT#允许http / httpsiptables -A USER_CUSTOM -p tcp --dport 80 -j ACCEPTiptables -A USER_CUSTOM -p tcp --dport 443 -j ACCEPT#允许SMTP和IMAPiptables -A USER_CUSTOM -p tcp --dport 25 -j ACCEPTiptables -A USER_CUSTOM -p tcp --dport 993 -j ACCEPT#允许wireguardiptables -A USER_CUSTOM -p udp --dport 995 -j ACCEPT#允许kubernetes k3S api服务器#我们要去在将我们的VPN设置为不暴露给internetiptables之后将其禁用-A USER_CUSTOM -p tcp --dport 6443 -j ACCEPT#添加我们的自定义chainiptables -I INPUT 1 -j USER_CUSTOM#如果没有可匹配的表-P,则默认情况下是DROP INCOMING TRAFFIC INPUT DROP #######IPv6 ########使用ip6tables代替iptables执行相同的操作#接受传入的ICMPip6tables -A USER_CUSTOM -p icmpv6 -j ACCEPT#如果提供者允许则允许ipv6路由自动配置支持itip6tables -A USER_CUSTOM -p udp --dport 546 -j ACCEPTip6tables -A USER_CUSTOM -p icmpv6 --icmpv6-type router-advertisem ent -j ACCEPTip6tables -A USER_CUSTOM -p icmpv6 -icmpv6类型的路由器请求-j ACCEPTip6tables -A USER_CUSTOM -p icmpv6 -icmpv6类型邻居广告-j ACCEPTip6tables -A USER_CUSTOM -p icmpv6 -征求-j ACCEPTip6tables -A USER_CUSTOM -p icmpv6 -icmpv6-type回声请求-j ACCEPTip6tables -A USER_CUSTOM -p icmpv6 -icmpv6-type echo-r​​eply -j ACCEPT

我不限制ssh连接的速率,因为在大多数情况下,受到该限制的是我。如今,大多数bot扫描ssh服务器都足够智能,可以安排时间来避免速率限制。即使我们仅允许公共密钥身份验证,一些bot也会无休止地尝试连接到我们的SSH服务器,希望有一天会出现漏洞。就像海浪不知疲倦地撞击在岸上。

-A USER_CUSTOM -p tcp -m conntrack --ctstate NEW --dport 22 -m最近--set --name SSH -A USER_CUSTOM -p tcp -m conntrack --ctstate NEW --dport 22 -m最近--update --seconds 60 --hitcount 4 --rttl --name SSH -j DROP-A USER_CUSTOM -p tcp -m conntrack --ctstate NEW --dport 22 -j ACCEPT

我们将在if-pre-up中部署这些规则,以在计算机重新启动时自动还原它们。由于这些规则是幂等的,因此我们在调用它们时强制执行它们以确保它们就位。

现在我们已经配置了服务器并且更加安全了,我们想为其分配一个可爱的DNS名称,而不是为其分配IP地址。如果您不知道什么是DNS,请参阅:

我个人使用GANDI.net,因为它们提供带有域名的免费邮箱。当我在服务器上运行后缀/邮件服务器来接收和存储电子邮件时,为了避免设置和管理繁琐的DKIM,我使用GANDI SMTP邮件服务器发送我的电子邮件,并且被信任/最终不会成为垃圾邮件。稍后在设置您的邮件服务器时将对此进行更多介绍。

传播应该足够快(如果您打算对通配符使用let的加密DNS质询)

这很简单,只需要获取有关如何使用注册商的API的信息。对于gandi,我们将使用其cli gandi并在纯文本文件中管理我们的区域。

@ 10800 IN SOA ns1.gandi.net。 hostmaster.gandi.net。 1579092697 10800 3600 604800 10800 @ 10800在A AAA.195:154.119.61 @ 10800在2001:bc8:3d8f :: cafe @ 10800在MX 1中mail.erebe.eu。@ 10800在MX 10中spool.mail.gandi.net。@ 10800在MX 50中fb.mail.gandi.net.api 10800在A 195.154.119.61api 10800中AAAA 2001:bc8:3d8f :: cafe ...

根据您的注册商,FAI和您在记录中设置的TTL的不同,新记录在任何地方传播/更新都可能需要花费一些时间,请耐心等待!

现在,我们已保护了服务器的安全,并附加了域名,并且我们可以轻松地重新安装。

下一步是在其上安装Kubernetes。仅在单台机器上使用Kubernetes的选择可能会引起争议。 Kubernetes是一个容器编排器,因此您只能在管理服务器群时利用其全部功能。此外,运行香草Kubernetes需要安装ETCD和其他重量级组件,并且配置每个模块以使其能够正常协同工作还有些困难。

与K3S相遇,K3S是经过修剪和打包的Kubernetes集群,位于单个二进制文件中。这个奇才是由牧场主实验室(Rancher Labs)买给我们的,该实验室是集装箱操作员领域的佼佼者之一。他们为您做出了决定(用SQLite代替ETCD,网络覆盖,负载均衡器等),以使k3尽可能小并易于设置。但这是一个100%兼容的Kubernetes集群。

在服务器上安装Kubernetes的主要好处是,它允许我为所有部署提供标准接口,将所有内容存储在git中,并允许我在开发项目时利用skaffold等其他工具。我的服务器也是我的游乐场,因此很高兴与当下的事物保持联系。

警告安装完所有组件后,只需运行Kubernetes服务器组件,即可在1.74GHz 2cores的Intel(R)Atom(TM)CPU C2338上添加{5%,10%} CPU。因此,如果您已经受CPU限制,请不要使用它或扩展服务器。

kubernetes_install:ssh $ {HOST}' export INSTALL_K3S_EXEC =" --no-deploy servicelb --no-deploy traefik --no-deploy local-storage&#34 ;; \ curl -sfL https://get.k3s.io | sh-'

servicelb一切都将存在于同一台计算机上,因此不需要负载平衡,在大多数情况下,我们将尽可能直接使用主机网络来避免网络覆盖

traefik我在Nginx / HAProxy上有更多的反向代理经验,因此我将使用Nginx入口控制器代替Traefik。随意使用

local-storage此应用程序用于为主机自动创建本地卷(PV),因为我们只有一台计算机,所以我们将绕过这种复杂性,仅使用HostPath卷

并检查您的服务器是否处于“就绪”状态(可能需要一些时间)。如果是这样,恭喜!您有一个Kubernetes控制平面正在工作!

现在已经完成了,我们需要自动化kubeconfig安装的设置。

在您的服务器上,复制kube配置文件/etc/rancher/k3s/k3s.yaml的内容,并在secrets / kubernetes-config.yml下使用sops对其进行加密。请确保将配置中的127.0.0.1替换为服务器的IP /域名。

如果制作正确,并且您在本地计算机上安装了kubectl,则应该可以

我有许多小型的宠物项目,这些项目暴露了一个HTTP端点,我想将其暴露给Internet的其余部分。由于我已经阻塞了除端口80和443以外的所有传入流量,因此我需要在这两个端口下复用每个应用程序。为此,我需要安装反向代理,该代理还将执行TLS终止。

由于在k3s安装过程中禁用了默认的反向代理Traefik,因此需要安装自己的代理。我的选择去了Nginx。我对HaProxy非常了解,知道它是可靠的,并且是Kubernetes上两者之间最成熟的。

要将其安装在K3s群集上,请使用Helm图表或直接与kube应用一起使用。 请参阅裸机安装指南 警告:请勿直接从文档nginx-ingress批注('-' 不是真正的'-' 并且您的注释将不会被识别🤦 为了避免同时管理头盔部署,我将直接从以下位置提供的YAML文件中进行安装: 我只是在编辑部署,以便Nginx反向代理使用HostNetwork并避免考虑网络覆盖。 ......