分类
Linux Windows

Linux 入域简明教程

Linux 加入 Active Directory 域其实不难。这一切皆 Samba 所赐。

不管读者你怎么想,对于我而言,Linux 加入 Active Directory 域(以下简称「入域」)一直是一件繁琐又容易出问题的事。然而,事实并非如此。熟练使用 Samba,可以让入域的过程简单、轻松,丝毫不逊色于 Windows 的入域体验(当然,需要人工配置的地方是更多的,相比于 Windows 的开箱即用而言)。

这不是任何产品的官方文档、帮助或使用说明,仅代表博主个人的经验总结,难免会有疏漏和错误之处。请务必结合官方文档进行阅读,以作补充。

注意!

准备工作

首先,是入域前的准备工作。包含以下几个部分:

  • 设置主机名(Hostname)和 Hosts。主机名这里建议设置为 FQDN,具体原因恕博主不是很清楚。Hosts 根据主机名修改本机解析即可。
  • 设置 DNS。和 Windows 入域一样,你需要设置 DNS 为域 DNS,不赘述。
  • 设置时间同步。和 Windows 入域一样,你需要精确设置时间,不赘述。

这里是域名的一个例子: SERVER-1.<AD 域 FQDN>。相应的 Hosts:

127.0.0.1 localhost
# 127.0.1.1 可以改为其他地址与否我不是很清楚,需结合环境修改。
127.0.1.1 SERVER-1.<AD 域 FQDN>

设置完成后,为确保一切顺利,建议自行检测 DNS 解析和时间同步,不赘述。

安装必要软件

对于 Arch Linux,所需的软件包为 samba smbclientpython-dnspython。最后一项是否需要存疑,但没有似乎无法成功注册 DNS。

一些发行版可能会自动启动服务,可以考虑先停止。

对于其他发行版,读者可以自行搜寻。

设置 Kerberos

Kerberos 是 Active Directory 的重要组成部分。入域前需要更改 Kerberos 设置( /etc/krb5.conf ,不同发行版可能有所不同):

[libdefaults]
   default_realm = <AD 域 FQDN>
   dns_lookup_realm = false
   dns_lookup_kdc = true
   # 这里是 Kerberos CCACHE 的路径,需要搭配后续 Samba 设定使用。见下文。
   default_ccache_name = /run/user/%{uid}/krb5cc

为了在用户登录时自动刷新 Kerberos Ticket,可以指定 pam_winbind 将 krb5cc 文件存放到特定位置。Kerberos 的默认位置为 /tmp/krb5cc_(UID)。在本实例中,将会设置默认路径为 /run/user/(UID)/krb5ccdefault_ccache_name 的意图在于告诉 klist 等命令去新的默认位置查找 krb5cc。请注意,/run/user/(UID) 是由 systemd logind 创建的用户临时目录。如果你的环境中没有 systemd,请自行改为其他路径。

配置 Samba

Samba 是入域的主要组件。打开 Samba 配置( /etc/samba/smb.conf,不同发行版可能有所不同),并写入:

[global]
   workgroup = <NETBIOS 名,如 CONTOSO>
   security = ADS
   realm = <AD FQDN 地址>

   # 在用户登录时自动刷新 Kerberos Ticket
   winbind refresh tickets = Yes
   # 将 NTFS ACL 存到 Extend ACL 中,方便 Linux 访问 Windows ACL
   vfs objects = acl_xattr
   # 这两条均为启用 NTFS ACL 之用。
   map acl inherit = Yes
   store dos attributes = Yes

   # 指定 Keytab 文件。
   dedicated keytab file = /etc/krb5.keytab
   kerberos method = secrets and keytab

   # 如果只有一个域,可以在登录时免输入完整域名(CONTOSO\User -> User)
   winbind use default domain = yes

之后,如果需要,禁用打印机共享。打印机和文件共享是 Samba 的另外几个功能。(同时 Samba 还提供作为域控制器的功能,不议。)

   # 如需禁用打印机共享,添加下面的配置
   load printers = no
   printing = bsd
   printcap name = /dev/null
   disable spoolss = yes

然后设置 idmap。idmap 为 AD 用户 & 组以及 Linux 用户 & 组之间提供映射。

由于博主对 idmap 理解较少,为了不误导读者,恕不进行详细讲解。读者可以自行从文末的相关链接中找到介绍。以下为 Arch Wiki 上的示例配置:

   # 如果你在 AD 中为用户配置了 RFC2307 属性,使用本配置。
   # UID/GID mapping for local users
   idmap config * : backend = tdb
   idmap config * : range = 3000-7999

   # UID/GID mapping for domain users
   idmap config <AD NETBIOS 名称>:backend = ad
   idmap config <AD NETBIOS 名称>:schema_mode = rfc2307
   idmap config <AD NETBIOS 名称>:range = 10000-999999
   idmap config <AD NETBIOS 名称>:unix_nss_info = yes

   # 如果在 AD 中为用户设置了 gidNumber,添加:
   idmap config INTERNAL:unix_primary_group = yes

   # Template settings for users without ''unixHomeDir'' and ''loginShell'' attributes 
   template shell = /bin/bash
   template homedir = /home/%U

如果你没有设置 RFC2307 属性,使用以下配置:

   # UID/GID mapping for local users
   idmap config * : backend = tdb
   idmap config * : range = 3000-7999

   # UID/GID mapping for domain users
   idmap config <AD NETBIOS 名称>:backend = rid
   idmap config <AD NETBIOS 名称>:range = 10000-999999

   # Template settings for users
   template shell = /bin/bash
   template homedir = /home/%U

Samba 配置至此完成。

入域

一个命令即可:

sudo net ads join -U <入域所用用户名>

然后自行祈祷不会出问题。成功的输出应为:

Enter <入域所用用户>'s password:
Using short domain name -- <NETBIOS 名>
Joined '<主机名>' to dns domain '<AD 域 FQDN>'

你的输出很可能有差异。没关系,只要不报错即可。

之后需要启动服务:smbnmbwinbind。非 systemd 用户请自行搜索相关服务。

配置 NSS

需要配置 NSS,否则无法解析用户和组。打开 NSS 配置文件( /etc/nsswitch.conf ,不同发行版可能有所差异),并编辑:

...
passwd: files winbind mymachines systemd
group: files winbind mymachines systemd
...

随后,测试是否可以获取用户和组:

wbinfo -u
wbinfo -g
getent passwd <AD 用户>

配置 PAM

配置 PAM 以登录域用户。这里需要使用 pam_winbind 来认证用户。

创建 pam_winbind 配置( /etc/security/pam_winbind.conf ):

[Global]
   # 调试日志,后续可以去除。
   debug = yes
   debug_state = yes
   
   try_first_pass = yes

   # 启用 Kerberos
   krb5_auth = yes
   # Kerberos CCACHE 存储方式和路径,见下文。
   krb5_ccache_type = FILE:/run/user/%u/krb5cc

   # 自动创建 Home 目录
   mkhomedir = yes

联系上文 Kerberos 配置,制定了默认路径为 /run/user/(UID)/krb5cc。这里的 pam_winbind 也指定了这个路径,这样在登录后便会自动创建该文件了。如果你的环境与博主环境不同,应自行更改路径。同时,pam_winbind 还支持其他存储方式,比如文件夹或内核 Keyring,读者可以自行研究。

最后,编辑相应的 pam.d 配置文件。很抱歉,博主对 PAM 配置知之甚少,所以仅贴出个人 /etc/pam.d/system-auth。其他发行版的路径会有所不同。如果发行版有提供图形化编辑工具,也可以使用。因为发行版之间差异很大,不建议复制粘贴到读者的环境。

#%PAM-1.0

auth       required                    pam_faillock.so      preauth
# 添加这行
auth       [success=3 default=ignore]  pam_winbind.so
auth       [success=2 default=ignore]  pam_unix.so          try_first_pass nullok
-auth      [success=1 default=ignore]  pam_systemd_home.so
auth       [default=die]               pam_faillock.so      authfail
auth       optional                    pam_permit.so
auth       required                    pam_env.so
auth       required                    pam_faillock.so      authsucc

# 添加这行
-account   [success=2 default=ignore]  pam_winbind.so
account    [success=1 default=ignore]  pam_systemd_home.so
account    required                    pam_unix.so
account    optional                    pam_permit.so
account    required                    pam_time.so

# 添加这行
-password  [success=2 default=ignore]  pam_winbind.so
password   [success=1 default=ignore]  pam_systemd_home.so
password   required                    pam_unix.so          try_first_pass nullok shadow
password   optional                    pam_permit.so

session    required                    pam_limits.so
# 添加这行
session    required                    pam_winbind.so
session    required                    pam_unix.so
session    optional                    pam_permit.so

对于 systemd-logind 用户:添加后似乎需要重启 systemd-logind,否则在登录时将无法创建 /run/user/(UID)/ 目录和设置 XDG 环境变量。具体表现为 pam_systemd 出错 No such process。原因未知。

初次登录后可能还需再登录一次才能获取 Kerberos Ticket。

完成

使用 AD 帐户登录,测试是否成功。

登录后使用 klist 检查 Kerberos Ticket 是否成功初始化。

入域后尝试使用域 DNS 解析本机,检查 DNS 是否添加。如果没有,尝试手动 Replicate 域控。

相关链接(建议阅读)

  • https://wiki.archlinux.org/index.php/Active_Directory_integration
  • https://wiki.samba.org/index.php/Setting_up_Samba_as_a_Domain_Member