在 Archlinux 上用 winbind 配合 pam 配置 Windows AD 认证登录

作为不清真的网络管理员,为了配置一套完整的统一认证系统,陈老师采用了 Windows AD 的方法给这里配置统一认证。重装了系统,自然要把之前的统一认证再配到新装的 Archlinux 上。 参考资料: Active Directory Integration 首先安装相应的包: pacman -S samba 我们还没有配好 Kerberos,所以跳过。 然后配置 /etc/samba/smb.conf ,以下是一个例子。可以根据文档微调。 [global] security = ads realm = YOUR-AD-HERE workgroup = YOUR-GROUP-HERE idmap uid = 10000-20000 idmap gid = 10000-20000 winbind enum users = yes winbind enum groups = yes template homedir = /home/%D/%U template shell = /bin/bash client use spnego = yes client ntlmv2 auth = yes encrypt passwords = yes winbind use default domain = yes restrict anonymous = 2 这样,域上的用户 user 会拿到 home 目录为 /home/YOUR-DOMAIN-HERE/user ,uid 在 10000-2000范围内的用户。在一会经过配置之后,可以通过 getent passwd 验证。

Read More

在服务器上安装 Archlinux 记录

有一台服务器的 Ubuntu 挂了,我们想在上面重装一个 Archlinux 。我们首先下载了 archlinux-2018.04.01 的 ISO, 直接 dd 到 U 盘上,但是遇到了问题。 首先遇到的问题是,一启动之后就会花屏。我们一开始怀疑是 NVIDIA 驱动的问题,于是想改 kernel param 但是发现,这个 ISO 是 hybrid 的,我们在 macOS 和 Windows 上都不能 mount 上这种类型的盘。于是我们选择自己搞分区表。我们把 U 盘插到电脑上,然后在 Linux 虚拟机内重新分区为 GPT ,然后 mount 到 /mnt/usb ,再重新下载 archlinux iso ,不过此时刚好上游更新了 archlinux-2018.05.01 的影响。我们把 ISO 中根分区 mount 到 /mnt/iso 上来,然后 cp -a /mnt/iso/* /mnt/usb 。调整了 grub 中的内核参数,仍然无果。我们认为问题可能在显卡上,就把那张显卡拔下来了,果然显示就正常了,但是新的问题就来了。 一启动, fstab 尝试把 LABEL=ARCHISO_201805 挂在上来,但是失败。于是我们把 U 盘插到 mac 上,用 Disk Utility 给分区命了名,再插回去,然后这个 Live CD 的 Systemd 就成功起来了。接下来就是根据官方的 Installation Guide 进行安装各种东西。安装完后,在 /boot/EFI 的操作上也出现了一些问题,一开始忘记调用 grub-mkconfig ,导致重启以后进入 grub-rescue ,所以又回到 Live CD 重新 grub-mkconfig 。同时对 systemd-networkd 也进行了相应的调整,这样开机以后可以配好网络。主要就是在网卡上配上两个 VLAN 和相应的 DHCP 和静态地址。

Read More

使用 Cisco AC + AP 组合搭建网络实践

有一台已配置好直接可用的 AC 在地址 ac-address 。我们需要搭建交换机 + AP 的网络,并且用一台 Linux 服务器进行 DHCP 从而给 AP 分发 AC 的地址。这里以 systemd-networkd 为例。 我们约定,vlan 2 上联外网, vlan 3 为 Linux 服务器和 AP 的内部网络。 接下来,配置交换机给 Linux 服务器的端口为 trunk 口,然后将下联 Cisco AP 的端口都设为 access vlan 3 模式。接下来在 Linux 服务器上配置 DHCP 服务器和 NAT 。 如果 Linux 服务器的 interface 名称为 eno1 : 配置两个 VLAN interface: $ cat /etc/systemd/network/eno1.network [Match] Name=eno1 [Network] VLAN=eno1.2 VLAN=eno1.3 相应添加 VLAN 配置: $ cat /etc/systemd/network/eno1.2.network [NetDev] Name=eno1.

Read More

把 GDB 降级到 8.0.1

在 macOS 上使用 GDB 需要 codesigning 。但是在 GDB 升级到 8.1 后这种方法不知道为何失效了。所以我安装回了 GDB 8.0.1 并且重新 codesigning ,现在又可以正常升级了。 对 Formula 进行 patch: diff --git a/Formula/gdb.rb b/Formula/gdb.rb index 29a1c590..25360893 100644 --- a/Formula/gdb.rb +++ b/Formula/gdb.rb @@ -1,14 +1,15 @@ class Gdb < Formula desc "GNU debugger" homepage "https://www.gnu.org/software/gdb/" - url "https://ftp.gnu.org/gnu/gdb/gdb-8.1.tar.xz" - mirror "https://ftpmirror.gnu.org/gdb/gdb-8.1.tar.xz" - sha256 "af61a0263858e69c5dce51eab26662ff3d2ad9aa68da9583e8143b5426be4b34" + url "https://ftp.gnu.org/gnu/gdb/gdb-8.0.1.tar.xz" + mirror "https://ftpmirror.gnu.org/gdb/gdb-8.0.1.tar.xz" + sha256 "3dbd5f93e36ba2815ad0efab030dcd0c7b211d7b353a40a53f4c02d7d56295e3" bottle do - sha256 "43a6d6cca157ef70d13848f35c04e11d832dc0c96f5bcf53a43330f524b3ac40" => :high_sierra - sha256 "fe7c6261f9164e7a744c9c512ba7e5afff0e74e373ece9b5aa19d5da6443bfc2" => :sierra - sha256 "cd89001bcf8c93b5d6425ab91a400aeffe0cd5bbb0eccd8ab38c719ab5ca34ba" => :el_capitan + sha256 "e98ad847402592bd48a9b1468fefb2fac32aff1fa19c2681c3cea7fb457baaa0" => :high_sierra + sha256 "0fdd20562170c520cfb16e63d902c13a01ec468cb39a85851412e7515b6241e9" => :sierra + sha256 "f51136c70cff44167dfb8c76b679292d911bd134c2de3fef40777da5f1f308a0" => :el_capitan + sha256 "2b32a51703f6e254572c55575f08f1e0c7bc2f4e96778cb1fa6582eddfb1d113" => :yosemite end deprecated_option "with-brewed-python" => "with-python@2"

Read More

近来做 Stanford CS140e 的一些进展和思考(8)

在上一篇文章之后,我其实还是很忙,但是一直心理惦记着这件事,毕竟只剩最后的一点点就可以做完了,不做完总是觉得心痒。 今天做的部分是调度。我们目前只在 EL0 运行了一个 shell ,每当触发 exception 时回到 kernel 进行处理,再回到原来的地方。但现在,我要实现一个 preemtive round-robin scheduler ,就需要管理当前的所有进程,并且维护当前的进程状态,当时钟中断到来的时候,决定下一个 time slice 要执行的进程,再切换过去。这个过程当然会遇到不少的坑。 首先,我们需要判断一个进程是否可以执行了。考虑到阻塞的 IO ,作者提供了一个优雅的方法:如果这个进程阻塞在 IO 上,那么,提供一个函数,在 scheduler 中调用,判断所需要的数据是否到达。这样,我们就可以一个循环把下一个 time slice 要执行的线程找到。如果找不到,就等待 interrupt 再尝试。 困难的地方在于,在启动的时候,切换到一个起始线程。并且在上下文切换的时候,在 process 1 -> kernel -> process 2 这两步过程中,有许多寄存器都需要仔细考虑如何实现。并且在这个过程中,我也发现了之前写的代码中的问题,最终修复了(目前来看是 working 了)。 我的代码实现在 这里 。下一步就要写 syscall 了。希望能在期中前抽时间赶紧把这个做完。 18:54 PM Update: 刚实现完了 sleep 的 syscall 。比预想中要简单。果然找到了自己实现的调度器的 BUG 。此系列大概是完结了。 2019-02-12 Update: 下一篇文章。

Read More

近来做 Stanford CS140e 的一些进展和思考(7)

在上一篇文章之后,我很长时间都没有在继续我这个项目,清明节刚好闲下来了我就回来继续啃它。Stanford那边已经结课,最后的 3-spawn 也只有一部分,剩下的部分不知道什么时候作者才会填上去了。 这次主要要写的代码就是,对异常的处理。这里的异常并不是我们编程语言中的 catch/throw ,而是硬件的异常。AArch64 和 x86 一样,也有不同的特权级别的区分,前者是 EL0~EL3 ,后者则是 RING0 和 RING3 。特权级别高可以往特权级别低转换,但是反过来,只能通过异常的方式提高特权等级,并且切换特权等级后只有固定的一些代码可能会跳转,这就是 exception handler/vectors 。这些函数可以知道是什么原因调用了他们,根据硬件规定好的文档,我们可以知道发生了什么事情,是对齐出错了呢,还是用户调用了 syscall 呢,等等。根据不同的情况,我们需要进行不同的处理。当处理完之后,我们需要考虑,跳转回用户代码的时候,回到哪里,提供什么值,不提供什么。 实现的话,需要很多步骤。首先是构造好 exception vector ,这里作者已经写好了一个宏(这里 @BenYip 遇到了一个 assembler 的 BUG ),直接用宏就可以把它写出来。然后,我们需要把它加载到当前 EL 的 VBAR_ELx 寄存器中,当 CPU 抛出异常的时候,就会找到这里相应的处理器进行处理。进到这里以后,我们首先先不考虑太多上下文保存的事情–我们先保证能处理异常,恢复也是个有很多坑的步骤,作者也是在这里分成了两个 Subphase 。首先还是从 ESR_ELx 中解析到错误的来源的具体内容,如果是我们在 shell 中自己调用的 brk 2 指令,我们就自己新开一个 shell ,修改了提示符以示区别。这样,我们就成功地捕捉到了这个异常。由于我们还无法恢复回去,所以我们直接死循环。 接下来我们要做的是,从异常中恢复出来。由于用户代码可能在各种地方抛出异常,异常也分同步和异步两种情况,这里有许多需要考虑的问题。为了简化,我们目前只考虑同步的 brk 2 导致的 Brk 异常。为了能恢复之后能够正常运行,我们需要把所有的寄存器都保存下来,即 TrapFrame 。保存的时候需要讲究 AArch64 平台下 SP 寄存器的对齐问题。我们也要把一些特殊的寄存器保存下来。还有一点,就是,因为 exception handler 中调用了 context_save 函数,所以此时的 lr 本身也需要进行保存,这个地方也卡了我很久。最后,再把这些一个一个地恢复到原来的样子,调整 ELR_EL1 使得退回到原来的状态时,会跳过当前的 brk 2 指令,调用它的下一调指令。这样,我们就成功地在遇到异常时,弹出一个 shell ,而且还可以回退回来。

Read More

偶遇清华吴文虎教授

今天百团大战,正准备收摊的时候,天空工场那边来了一位长者,在和他们聊着什么。我很感兴趣,就上去听。老人大概已有八十高龄(后来查,是1936年生),但依然精神矍铄,首先和我们讲,作为工科的学生,一定在理解原理的基础上,多多去实践。他举了他自己的例子,他首先在电机系学习,后来,计算机系成立(当时还是自动控制系),他转到了计算机系,重新学起了计算机,说计算机编程学起来并没有什么难的。当年,苹果公司送过来了中国第一台 Apple-2 ,他们就把电脑拆了下来研究原理,又装上去继续工作。后来,他就在计算机系任教,教的正是《程序设计基础》这门课程。他十分重视实践,在第一年开课的时候就说,最关键的就是实践,安排了一些编程实验课,期中期末就是大作业。一开始有一些同学不重视实践,结果期末就挂科了。后来同学们就明白了实践的重要性,实践起来发现并没有那么难,最后就说,“吴老师,你说得对”。他又谈到了他的体育,他当年是北京长跑代表队的集训队选手,擅长一千五百米项目,他三千米只需要九分钟就能跑完。我们都感到自愧不如。我们说,现在的《程序设计基础》是徐明星老师在教,他说徐明星是他的博士生,邬晓钧也是他的博士生,他另外还有一个高徒我记不清楚了。他还是IOI中国队的前教练,听到我们有过一些OI基础,表示了赞许和鼓励。还有一些细节记不清楚了,记起来了再补充吧。

Read More

〖新手向〗绕过 C++ 类的访问限制

这是一篇很水的文章,面向萌新,已经知道了的可以自觉绕道。 昨天上课,有同学问,如果用户偷偷把 private 改成 public 再和原有的库链接,是不是就可以在用户代码里更改了。这个答案是肯定的。下面我们就做个实验: 首先,创建 good_class.h 和 good_class.cpp: class SomeClass { private: int data; public: int getData(); }; #include "good_class.h" int SomeClass::getData() { return data; } 然后,首先编译, clang++ -c good_class.cpp -o good_class.o 然后,修改 good_class.cpp 并写一个 evil_user.cpp class SomeClass { public: int data; public: int getData(); }; #include <stdio.h>#include "good_class.h" int main() { SomeClass a; a.data = 37; printf("%d\n", a.getData()); return 0; } 编译: clang++ good_class.o evil_user.cpp -o evil 然后 evil 如愿地输出了 37 。

Read More

近来做 Stanford CS140e 的一些进展和思考(6)

在上一篇文章之后,作者终于更新了测试的用例,我的程序终于可以成功跑过所有测试,也成功在树莓派跑起来。不过,我的代码中很多地方的错误处理比较偷懒,往往直接 panic ,显然并不友好。同时,我想到了使用 cargo-fuzz 来进行自动化测试,果然,使用这个很快就修复了不少我没想到的会出错的地方,比如乘法溢出,目录项没有正确结束等等。目前还发现一个 timeout 的问题,研究发现大概是文件的 cluster chain 中出现了环,导致一直读取文件而没有停止。要解决这个问题,我目前想到的是 Floyd 的判圈算法,但还没上实现。等过几天,新的 Assignment 3 出了以后,再继续更新。希望作者少点跳票,多点勤奋,哈哈哈哈哈 更新:下一篇在这里。

Read More