再谈给家人配置电脑

Author: R.W.Flurando

Tags: guix, vnc, docker, oci, 家人, 电脑

书接上回

话说我弄了一番Linux Mint中文配置,结果十来天下来,还是放弃了。

一直以为是显卡支持问题,但仔细搜查后发现不是,居然是asus主板的限制。只要你运行的系统不是Windows且驱动了显卡,那么显示就不会亮。特点是启动时对SKYLAKE或KABYLAKE的检查会失败而警告,然后cpu出现intel_pch_xxxxx问题,game over!

也就是说,这台电脑除非你跑Windows,不然显示只能软件渲染。

软显等于不清晰,那我还要这个显示屏干什么?干脆改变策略,用Guix系统加VNC。

至于家里人不会用Guix,他们只要会guix install <app>flatpak install --user flathub <app>就行了。系统配置之前弄Windows和Linux Mint都不情愿,就不提供了。

这次我的目的有所改变,要给家人日常可用,且不担心弄坏系统。

配置清单

以Guix系统为基础,简中,XFCE4,多用户,跑VNC,拿docker搭noVNC。

步骤

装系统

老套路,先拿guix系统配置算一个EFI生镜像出来,然后用bin456789的重装脚本给它刷到电脑硬盘上。

有坑,还是我家专属的坑。

原来广电宽带配华为免费路由器连局域网ipv6都没有,只能申请到ipv4地址,这就导致大佬的udcpcd相关脚本冲掉ipv4配置后会因为等不到ipv6地址而在slaac失败后完全失去网络配置。

气得我开分支把ipv6和所有flush命令全删了,终于装上系统。

打印机

吃了不懂电脑的亏,我发现我家里就没有一样东西是不需要驱动、用公开透明的API就能指挥的。

这不,HP LaserJet 1020 Plus,须要往它内存里传一个闭源插件才能动。

之前用的是Debian系那边,apt下hplip,但是hplip又特别蠢,电脑或打印机只要重连一下,就因为试图再传插件而弄乱ppd配置,结果是除非打印机内存断电冷却加电脑hp相关配置完全重装外无法使用。

这次用nonguix社区配置,交给cups管理,ppd配置开机后可读不可写,应该是解决了。社区大佬牛逼。

同时配置局域网内无验证打印。

(service cups-service-type
    	       (cups-configuration
    		(browse-web-if? #t)
    		(browsing? #t)
    		(default-shared? #t)
    		(listen '("0.0.0.0:631" "/var/run/cups/cups.sock"))
    		(location-access-controls
    		 (list (location-access-control
    			(path "/")
    			(access-controls '("Order allow,deny"
    					   "Allow @LOCAL")))
    		       (location-access-control
    			(path "/admin")
    			(access-controls '("Order allow,deny"
    					   "AuthType Basic"
    					   "Require user @SYSTEM"
    					   "Allow localhost")))))
    		(policies
    		 (list (policy-configuration
    			(name "default")
    			(access-controls
    			 (list
    			  (operation-access-control
    			   (operations
    			    '(Send-Document
    			      Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs
    			      Cancel-Job Close-Job Cancel-My-Jobs Set-Job-Attributes
    			      Create-Job-Subscription Renew-Subscription
    			      Cancel-Subscription Get-Notifications
    			      Reprocess-Job Cancel-Current-Job Suspend-Current-Job
    			      Resume-Job CUPS-Move-Job Validate-Job
    			      CUPS-Get-Document))
    			   (access-controls '("Order allow,deny"
    					      "Allow @LOCAL")))
    			  (operation-access-control
    			   (operations
    			    '(Pause-Printer
    			      Cancel-Jobs
    			      Resume-Printer Set-Printer-Attributes Enable-Printer
    			      Disable-Printer Pause-Printer-After-Current-Job
    			      Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer
    			      Activate-Printer Restart-Printer Shutdown-Printer
    			      Startup-Printer Promote-Job Schedule-Job-After
    			      CUPS-Authenticate-Job CUPS-Add-Printer
    			      CUPS-Delete-Printer CUPS-Add-Class CUPS-Delete-Class
    			      CUPS-Accept-Jobs CUPS-Reject-Jobs CUPS-Set-Default))
    			   (access-controls '("AuthType Basic"
    					      "Require user @SYSTEM"
    					      "Order deny,allow")))
    			  (operation-access-control
    			   (operations '(All))
    			   (access-controls '("Order deny,allow"))))))))
    		(extensions
    		 (list cups-filters hplip-plugin))))

VNC

重头戏来了。

配置VNC,得先把桌面环境弄好。

问题是我的镜像配置是基于无头服务器配置改的,只好配合grep -r xxx ./来翻源代码,找到默认桌面服务比无头服务多出来的配置并手动贴上去。

有几个不知为啥报错,我图方便直接删。

然后添加xfce4桌面,别问我怎么不用gnome、plasma之类的,我当然试过,因为不知道怎么指定xvnc用它们的X11版而失败。

没错,VNC目前无法在Wayland下使用,一进Wayland就断开连接了。

开xdmcp,关gdm自动锁屏,按guix文档来就可以。

(service xvnc-service-type (xvnc-configuration
                                          (display-number 0)
                                          (localhost? #f)
                                          (xdmcp? #t)
                                          (inetd? #t)))
          (service xfce-desktop-service-type)
          (service gdm-service-type
    	       (gdm-configuration
    		(auto-login? #f)
                        (auto-suspend? #f)
                        (xdmcp? #t)
    		(wayland? #f)
    		(gnome-shell-assets
                         (list adwaita-icon-theme
    		       font-adobe-source-han-sans))))

重启后herd status xvnc确认是跑起来也验证过能进桌面,现在把docker打开。

docker这里有一个误区,很多人觉得docker是安全的,其实不然,只是分出一个cgroup怎么可能安全。也有很多人觉得docker不安全,得加上--user 1001:1001甚至专门弄个没多少权限的用户来运行,这样才安全,其实也不然。大费周章弄个“安全用户”提升的安全性和直接root没什么区别,你真怕就拿更完整的虚拟化方案跑。

毕竟docker只是方便不同开发环境的人可以轻松运行一些东西,你真要安全就是QubeOS之类的。

在我们布置网络服务时只要一定程度的安全就行了,比如源代码开放,社区监管等等。再高你横竖也达不到,即便达到了也会因为木桶效应被人为因素掩盖。

为什么提docker,因为我准备在docker里跑noVNC和ssl-proxy。

docker嘛,有了compose文件就没啥好说的。

(simple-service 'oci-novnc
    		      oci-service-type
    		      (oci-extension
    		       (networks (list (oci-network-configuration
    					(name "vnc")
    					(gateway "172.255.0.1")
    					(subnet "172.255.0.0/16")
    					(ip-range "172.255.0.0/24"))))
    		       (containers
    			(list
    			 (oci-container-configuration
    			  (provision "novnc")
    			  (network "vnc")
    			  (image "cuteminded/novnc:latest")
    			  (environment '("VNCSERVER=172.255.0.1"
    					 "VNCPORT=5900"))
    			  (extra-arguments '("--ip" "172.255.0.2"))
    			  (auto-start? #t)
    			  (respawn? #t))
    			 (oci-container-configuration
    			  (provision "ssl-proxy")
    			  (network "vnc")
    			  (image "fsouza/docker-ssl-proxy:latest")
    			  (environment '("DOMAIN=hostname.local"
    					 "TARGET_HOST=172.255.0.2"
    					 "TARGET_PORT=6080"
    					 "CLIENT_MAX_BODY_SIZE=20M"
    					 "SSL_PORT=443"))
    			  (ports
    			   '(("443" . "443")))
    			  (extra-arguments '("--ip" "172.255.0.3"))
    			  (auto-start? #t)
    			  (respawn? #t))))))

注意,我这里拿5900端口举例子对应显示器编号0,如果你选择的显示器编号是3,那就5903,灵活应对好吧。

hostname也别忘记改,找不到hostname.local的话跑avahi服务并开5353端口。

同时呢,给家人创建帐号,在users栏里添加

(user-account
  (name "me")
  (comment "最接近神的男人")
  (password (crypt "123456" "salt:changeme"))
  (group "users")
  (supplementary-groups '("audio" "video"))
  (home-directory "/home/me"))

配置后重启,试一下浏览器访问https://hostname.local/进xfce环境。

可行后继续,我们需要配置防火墙来防止攻击。

(service nftables-service-type
    	       (nftables-configuration
    		(ruleset (plain-file "nftables.conf" "\
table inet filter {
  chain input {
    type filter hook input priority 0; policy accept;
    ct state invalid drop
    ct state established,related accept
    iifname \"lo\" accept
    iifname {\"enp0\", \"wlp0\"} tcp dport 5900 drop
    iifname != \"lo\" udp dport 177 drop
  }
  chain forward {
    type filter hook forward priority 0; policy drop;
  }
  chain output {
    type filter hook output priority 0; policy accept;
  }
}
"))))

如果基础配置中包含了iptables就在modify-services那里用(delete xxxxx-service-type)删掉。

我这里入站默认是允许,黑名单,并不符合安全规范,但在我这台机器的网络环境下已经够好,按自己理解来吧。

重启后再试可行,就是自签名ssl证书还是不安全,只有加密不防中间人攻击。但我懒得再加固,等家里人用起来并准备进行私密计算再说吧。

本地化

还差一步,没有中文环境,我们在locale那里配置,还是改系统定义

(locale "zh_CN.utf8")
(locale-definitions (cons (locale-definition (name "zh_CN.utf8") (source "zh_CN")) %default-locale-definitions))

重启后发现可行了,注意之前gdm配置的gnome-shell-assets里的font包,很重要。

用户环境

打开之后家里人说没有浏览器,我一看还真是……

好吧,好人做到底,使用guix-home-service-type把用户环境也给定义了。

于是我拿自己的用户定义改了改,再加到用户后面。

(service guix-home-service-type `(("me" ,my-home-config)))

前面是用户名,后面是用户定义。

感想

这回我是满意了,虽然可定制性对用户较少,但几乎不会弄坏,可以让家里人放开了用。

系统配置保证主系统不崩,用户配置保证用户环境不崩,可以说非常方便。

至于安全嘛,安全因素在于人,家人对电脑不感兴趣,没必要弄得很安全。