正如您从我糟糕的语言水平所看到的,英语不是我的母语。 我用英语编写本文档是为了 Linux 社区的利益。 所以,请原谅我糟糕的英语。 并且,如果您会说葡萄牙语,请用这种语言与我交流。
本文档旨在启发您(和我自己)构建 Linux 网关或防火墙的过程,该网关或防火墙在用户登录或注销其 Windows 工作站时按需修改规则。
在本文档中,我将尝试展示如何构建一个网关来 NAT 或 MASQUERADE Windows 工作站。发挥您的想象力来修改它,以获得任何级别的网络管理。您可以使用它来授予或拒绝访问您网络上的服务、服务器或整个子网。
假设您必须构建一个网关,让 Windows 工作站访问 Internet,并且您需要在允许每个用户访问外部网络之前对其进行身份验证。您首先想到的解决方案是 Squid。当 http 和 ftp 访问足以满足您的用户时,这确实是一个很好的解决方案。当涉及到让他们访问其他服务(如 pop、smtp、ssh、数据库服务器或其他任何东西)时,您会立即想到 NAT 或 MASQUERADE。但是用户身份验证会发生什么呢?
好吧,这是我的解决方案。它可以为您提供用户身份验证以及对其访问外部网络的精细控制。
我们知道 SAMBA 可以充当域控制器,因此它可以验证 Windows 计算机上的用户。作为 PDC,SAMBA 可以将 netlogon 脚本推送到 Windows 工作站。我们可以使用此 netlogon 脚本来强制 Windows 工作站从我们的 Linux PDC 挂载给定的共享。这个“强制”共享应该有 preexec 和 postexec 脚本,这些脚本应该在用户登录或注销时触发。有一个名为 smbstatus 的程序,它列出正在使用的共享,同时还提供工作站的用户名和 IP 地址。我们只需要从 smbstatus 输出中 grep 此信息并更新我们的防火墙规则。
如果您不耐烦并且不喜欢阅读,请访问http://sourceforge.net/projects/smbgate/,但最终您可能会发现自己回到这里阅读。
不对本文档的内容承担任何责任。 使用这些概念、示例和其他内容需要您自担风险。 由于这是本文档的新版本,因此可能存在错误和不准确之处,当然这可能会对您的系统造成损害。 请谨慎操作,尽管这种情况极不可能发生,但作者不对其承担任何责任。
所有版权均归其各自所有者所有,除非另有明确说明。 在本文档中使用术语不应被视为影响任何商标或服务标志的有效性。
对特定产品或品牌的命名不应被视为认可。
本文档的最新版本可以在 http://ram.eti.br 或 http://www.tldp.org 找到
相关 HOWTO 可以在 Linux 文档项目主页 https://tldp.cn 找到。
提供葡萄牙语版本。
Guillaume Lelarge 的法语翻译版本可在 http://www.traduc.org 找到
匈牙利语翻译版本可在 http://tldp.fsf.hu 找到
如果您想贡献翻译,请这样做。
欢迎提供贡献和批评。
也非常欢迎更正我的英语!
如果您在包含的脚本中发现任何错误,请告诉我。
您可以在 ricardo@ram.eti.br 或 ricardo.mattar@bol.com.br 找到我
版权 (c) 2002-2003 Ricardo Alexandre Mattar
根据自由软件基金会发布的 GNU 自由文档许可证,第 1.2 版或任何更高版本的条款,允许复制、分发和/或修改本文档; 不包含不变部分,不包含封面文字,也不包含封底文字。 许可证的副本包含在标题为“GNU 自由文档许可证”的部分中。
感谢 Carlos Alberto Reis Ribeiro 向我介绍 Linux。
感谢 Cesar Bremer Pinheiro 激励我编写本文档。
感谢 Guillaume Lelarge 在修订方面提供的(持续)帮助。
感谢 Erik Esplund 进一步的语言更正。
感谢 Albert Teixid� 对代码的改进。
感谢 Felipe Cordeiro Caetano 在我的主要测试站点上提供的帮助。
感谢安全通信公司 RASEAC 赞助我的工作。
本文档面向经验丰富的系统管理员。
您必须对以下内容有相当的了解(至少知道这些是什么)
幸运的是,互联网上有大量关于这些主题的文档。
在您的服务器上安装,您至少需要
本 Howto 假定您有一个来自 2.4 系列的内核,因为它使用 iptables。 除此之外,没有已知的问题表明它不应该在 2.2 内核盒子上工作,并且脚本适应 ipchains。
当然,您需要安装 iptables 用户空间工具、如果您想运行 CGI 工具来更改密码和 SAMBA,则需要安装 apache http 服务器。 并且您需要一个使用 iptables 模块编译的内核。
您可能希望使用 DHCP。 如果是这样,设置起来很容易。 请记住配置 dhcp 服务器以提供名称服务器 IP 地址和网关 IP 地址。 Windows 机器将很好地利用这些信息。
通常,来自常见 Linux 发行版的任何基本系统设置都适合此网关示例。 只需检查您是否拥有 Samba 和 IPTABLES。
需要额外的目录层次结构来完成本 howto 的示例
这用于跟踪用户和 IP 地址
/var/run/smbgate/
这是我放置用户特定脚本的地方
/etc/smbgate/users/
和特定于组的脚本
/etc/smbgate/groups/
netlogon 共享的目录
/home/samba/netlogon/
跟踪共享的目录
/home/samba/samba/
示例中的某些脚本和守护程序需要这些层次结构。
您的发行版的内核不太可能没有使用 Iptables 编译,用户空间工具也没有安装。 无论如何,如果您没有它,请参阅 http://www.netfilter.org 或 http://www.iptables.org 以获取软件和文档。
您需要一个基本的防火墙设置才能使网关正常工作。 请查看 IPTABLES TUTORIAL 上的 iptables 教程。 这是一篇有趣的阅读。 无论如何,如果您没有时间,以下代码在某种程度上(非常)宽松,但它可能满足您的需求
#!/bin/sh IPTABLES=/usr/sbin/iptables /sbin/depmod -a /sbin/insmod ip_tables /sbin/insmod ip_conntrack /sbin/insmod ip_conntrack_ftp /sbin/insmod ip_conntrack_irc /sbin/insmod iptable_nat /sbin/insmod ip_nat_ftp echo "1" > /proc/sys/net/ipv4/ip_forward echo "1" > /proc/sys/net/ipv4/ip_dynaddr $IPTABLES -P INPUT ACCEPT $IPTABLES -F INPUT $IPTABLES -P OUTPUT ACCEPT $IPTABLES -F OUTPUT $IPTABLES -P FORWARD ACCEPT $IPTABLES -F FORWARD $IPTABLES -t nat -F
您会注意到此代码实际上什么都不做,但会加载与 nat 和防火墙相关的内核模块并打开数据包路由。 您可以(并且应该)在那里放置任何规则,以使您的网关具有标准行为,但更大的魔力将由 SAMBA 守护程序调用的脚本完成。
请记住,此代码没有丝毫安全性! 请勿在生产环境中使用这些示例。 此示例仅用于教育目的。 您必须添加适合您的系统的防火墙配置。
您已被警告!
检查你是否已安装Samba。 如果你的发行版没有预先打包Samba,请访问 http://www.samba.org 获取软件包,并阅读关于如何安装Samba的文档。 在他们的网站上浏览并了解它。 该网站有大量的文档,也许你的LINUX发行版也有大量的SAMBA文档。
我们需要将SAMBA设置为主要域控制器(Primary Domain Controller,PDC)。 我将在这里给出一个示例配置文件,但你应该阅读 Samba HOWTO Collection 并尽可能多地了解PDC。
由于我不打算重写SAMBA文档,这里提供一个示例smb.conf文件
# Global parameters [global] workgroup = DOMAIN netbios name = LINUX server string = Linux PDC encrypt passwords = Yes map to guest = Bad Password passwd program = /usr/bin/passwd unix password sync = Yes max log size = 50 time server = Yes socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192 add user script = /usr/sbin/useradd -d /dev/null -g 100 -s /bin/false -M %u logon script = %a.bat domain logons = Yes os level = 64 lm announce = True preferred master = True domain master = True dns proxy = No printing = lprng [homes] comment = Home Directories path = /home/%u read only = No [printers] comment = All Printers path = /var/spool/samba printable = Yes browseable = No available = No [netlogon] comment = NetLogon ShARE path = /home/samba/netlogon guest account = [samba] comment = login tracking share path = /home/samba/samba browseable = No root preexec = /usr/local/bin/netlogon.sh %u %I root postexec = /usr/local/bin/netlogoff.sh %u
你必须使用它,或者阅读SAMBA文档,如果你真的想控制你的服务器和网络。
使用 "logon script = %a.bat" 会让Samba评估客户端操作系统并调用相应的登录脚本。 如果你想要一个静态脚本,只需更改为 "logon script = netlogon.bat"。 实际上,你可以在这里做任何事情,甚至在登录期间生成任何脚本。
netlogon共享是Windows工作站从中下载登录脚本的位置。 我们需要这个共享来放置一个登录脚本,它会告诉工作站挂载一个用于跟踪用户IP地址的共享。
正如你所见,在你的smb.conf中必须有一行如下内容
logon script = netlogon.bat
这一行将告诉你的Windows客户端下载并执行名为netlogon.bat的脚本。 这个脚本必须放置在netlogon共享中。 因此,我们还需要一个netlogon.bat脚本给你的Windows工作站。 你可以使用以下示例,并将其放置在netlogon共享中,在本例中:/home/samba/netlogon/NETLOGON.BAT。
REM NETLOGON.BAT net use z: \\linux\samba /yes
这个脚本将告诉Windows工作站挂载指定的共享,这样我们就可以通过smbstatus程序的输出来跟踪用户和工作站。
非常简单! 但还不够...
正如你所看到的,我们还需要一个跟踪共享,在这个例子中,我命名为samba。 你可以在smb.conf中看到跟踪共享的配置
[samba] comment = login tracking share path = /home/samba/samba browseable = No root preexec = /usr/local/bin/netlogon.sh %u %I root postexec = /usr/local/bin/netlogoff.sh %u
正如你可以猜测或知道,如果你阅读了SAMBA文档,root preexec和root postexec行告诉SAMBA,当用户挂载或卸载共享时,运行指定的脚本。 在这种情况下,我们将用户名作为参数传递给脚本。 注意行尾的%u。 这些脚本是调用脚本或程序来修改我们网关的数据包过滤规则的工具。
请注意,netlogon.sh脚本必须检查引用的工作站是否已经挂载了跟踪共享。
看看netlogon.sh和netlogoff.sh脚本
#!/bin/sh # # netlogon.sh # # usage: # netlogon.sh <username> # if [ -f /var/run/smbgate/$1 ] ; then exit 0 fi echo $2 > /var/run/smbgate/$1 IPTABLES='/usr/sbin/iptables' EXTIF='eth0' COMMAND='-A' ADDRESS=`cat /var/run/smbgate/$1` GROUP=`groups $1 | gawk '// { print $3 }'` if [ -f /etc/smbgate/users/$1 ] ; then /etc/smbgate/users/$1 $COMMAND $ADDRESS $EXTIF else if [ -f /etc/smbgate/groups/$GROUP ] ; then /etc/smbgate/groups/$GROUP $COMMAND $ADDRESS $EXTIF else /etc/smbgate/users/default.sh $COMMAND $ADDRESS $EXTIF fi fi
此脚本(netlogon.sh)旨在在用户登录时运行,并将根据用户名以及用户所属的组来选择将执行哪些脚本。 用户IP地址将被写入/var/run/smbgate下的文件中以进行跟踪。 该文件将采用用户的名称,稍后将在用户注销时使用。 IP地址将作为参数传递给一个带有用户名的脚本,该脚本最终将更新防火墙。
请注意,此netlogon.sh脚本尝试一个用户脚本,如果找不到用户脚本,则尝试一个组脚本,最后如果找不到组脚本,则尝试default.sh脚本。 你可以根据你的意愿和需要修改此逻辑和行为,只需记住相应地修改其他脚本。
如果用户属于多个组,这些脚本很可能会失败。 我没有时间编写更好的代码。
#!/bin/sh # # netlogoff.sh # # usage: # netlogoff.sh <username> # IPTABLES='/usr/sbin/iptables' EXTIF='ppp0' COMMAND='-D' TRACKSHARE="samba" ADDRESS=`cat /var/run/smbgate/$1` GROUP=`groups $1 | gawk '// { print $3 }'` NM=`smbstatus -u $1 | grep $TRACKSHARE | wc -l` if [ $NM -gt 0 ]; then exit fi if [ -f /etc/smbgate/users/$1 ] ; then /etc/smbgate/users/$1 $COMMAND $ADDRESS $EXTIF else if [ -f /etc/smbgate/groups/$GROUP ] ; then /etc/smbgate/groups/$GROUP $COMMAND $ADDRESS $EXTIF else /etc/smbgate/users/default.sh $COMMAND $ADDRESS $EXTIF fi fi rm -f /var/run/smbgate/$1
此脚本(netlogoff.sh)旨在在用户注销时运行,并将从/var/run/smbgate/user文件中获取地址,该地址将作为参数传递给/etc/smbgate/users/user脚本,该脚本将防火墙更新到用户未登录时的所需状态。
某些版本的Windows,例如Windows 2000,每次登录会多次挂载跟踪共享。 这可能会导致netlogon.sh和netlogoff.sh出现问题,多次触发脚本。 这可能会造成真正的混乱。 因此,你可能更喜欢在cron中使用注销检查脚本,而不是由SAMBA触发的netlogoff.sh脚本。 这是一个例子
#!/bin/sh # checklogout.sh # # usage: # intended to run at cron (maybe each 10 minutes) TRACKDIR="/var/run/smbgate" DIRLENGTH=${#TRACKDIR} TRACKSHARE="samba" EXTIF='eth0' COMMAND='-D' if [ -d $TRACKDIR ]; then for n in $TRACKDIR/*; do [ -d $n ] && continue; if [ -f $n ] ; then IPADDRESS=`cat $n` USERNAME=${n:$DIRLENGTH+1} NMS=`smbstatus -u $USERNAME | grep $TRACKSHARE | grep $IPADDRESS | grep -v grep | wc -l` if [ $NMS == 0 ] ; then rm -f $n GROUP=`groups $USERNAME | gawk '// { print $3 }'` if [ -f /etc/smbgate/users/$USERNAME ] ; then /etc/smbgate/users/$USERNAME $COMMAND $IPADDRESS $EXTIF else if [ -f /etc/smbgate/groups/$GROUP ] ; then /etc/smbgate/groups/$GROUP $COMMAND $IPADDRESS $EXTIF else /etc/smbgate/users/default.sh $COMMAND $IPADDRESS $EXTIF fi fi fi else exit 0 fi done fi
在这种情况下,你应该从smb.conf上的跟踪共享中删除root postexec子句
root postexec = /usr/local/bin/netlogoff.sh %u
以下是一个标准的/etc/smbgate/users/user脚本。 这是实际修改防火墙规则的脚本。
#!/bin/sh # COMMAND=$1 ADDRESS=$2 EXTIF=$3 IPTABLES='/usr/sbin/iptables' $IPTABLES $COMMAND POSTROUTING -t nat -s $ADDRESS -o $EXTIF -j MASQUERADE
我们还应该在/etc/smbgate/users/中有一个default.sh脚本,以便为网关提供默认行为。
#!/bin/sh # # default.sh COMMAND=$1 ADDRESS=$2 EXTIF=$3 IPTABLES='/usr/sbin/iptables' #$IPTABLES $COMMAND POSTROUTING -t nat -s $ADDRESS -o $EXTIF -j MASQUERADE exit 0
挂载跟踪共享并触发脚本来更新防火墙,并等待它们在卸载时再次触发以重置防火墙规则的整个方案可能过于混乱和松散。 随着Samba项目发布新功能,它甚至可能变得过时。
最新的Samba版本具有列出已登录用户的功能。 我在一个脚本中使用此功能来跟踪用户并在他们登录和注销时更新防火墙。 此脚本不需要本文中描述的所有工作。 实际上,它非常容易使用。
你可以从项目站点 http://sourceforge.net/projects/smbgate/ 下载代码
你可能希望在一个盒子上运行你的PDC,并出于任何原因将另一个盒子作为托管网关。 如果是这样,你必须设置你的网关以接受来自PDC的rsa身份验证登录,而无需密码。
查看 www.openssh.org 以获取有关如何正确设置你的ssh服务器和客户端的信息。
你应该阅读ssh文档,并确保你完全理解你在设置rsa或任何其他类型的加密身份验证时所做的事情。
如果安全不是问题,只需使用我的例子并继续。
要在预定作为PDC的机器上创建密钥对,请执行以下命令
pdc:~# ssh-keygen -t rsa
回答问题并将生成的公钥复制到网关本身。 通常,公钥进入"~/.ssh/id_rsa.pub"
pdc:~# cd .ssh pdc:~# scp id_rsa.pub root@gateway:/root/.ssh/authorized_keys2
以下是修改为使用ssh加密身份验证的标准/etc/smbgate/users/user脚本。
#!/bin/sh # COMMAND=$1 ADDRESS=$2 EXTIF=$3 IPTABLES='/sbin/iptables' ssh root@gateway $IPTABLES $COMMAND POSTROUTING -t nat -s $ADDRESS -o $EXTIF -j MASQUERADE
请注意,iptables二进制文件是通过ssh在“网关”上调用的。 再次,请确保你阅读了ssh服务器文档。
我们将坚持在Windows工作站上设置网络、用户管理和策略。
我不会经历所有这些步骤,命名每个对话框。 我假设如果你可以阅读和理解本文档,你就可以找到解决这个问题的方法。
首先,除非你真的需要,否则删除除TCP/IP之外的所有网络协议。 即使没有自己的协议,Windows机器也喜欢广播很多,这并不能让任何人高兴。 无论如何,有了TCP/IP谁还需要其他东西?
如果你在你的Linux盒子上设置了一个DHCP服务器,请记住Windows工作站除了自己的IP地址外,还可以从中获取域名服务器和网关的地址。 因此,你无需在每个工作站上设置所有这些项目。
配置Windows工作站以登录域,并提供你的Linux服务器的域名。 这对于网关工作至关重要。
你必须知道,为了将某些版本的Windows加入SAMBA域控制器,你必须在你的Linux PDC中创建机器帐户。 查看SAMBA文档,了解如何为你的特定Windows版本设置你的PDC。
此版本似乎不需要特殊配置即可加入Linux PDC域。
netlogon脚本应命名为“WfWg.bat”,以便当%a被翻译时,选择正确的脚本。
例子
REM WFWG.BAT net use z: \\linux\samba /yes
这些版本似乎也不需要特殊配置即可加入Linux PDC域。
netlogon脚本应命名为“Win95.bat”,以便当%a被翻译时,选择正确的脚本。
例子
REM WIN95.BAT net use z: \\linux\samba /yes
此版本需要在Linux盒子上设置机器帐户。 查看SAMBA文档。
netlogon脚本应命名为“WinNT.bat”,以便当%a被翻译时,选择正确的脚本。
例子
REM WINNT.BAT net use z: \\linux\samba /yes /persistent:no
此版本需要在Linux盒子上设置机器帐户。 再次,查看SAMBA文档。
netlogon脚本应命名为“Win2K.bat”,以便当%a被翻译时,选择正确的脚本。
例子
REM WIN2K.BAT net use z: \\linux\samba /yes /persistent:no
此版本需要在Linux盒子上设置一个机器帐户,并在注册表中进行调整,如下所示。
找到键“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\RequireSignOrSeal”。 默认值为1。将其设置为0,它将不再抱怨加入域。
如果你有许多工作站要配置,请创建一个名为anything.reg的文件,其中包含以下内容,并使用它来修改“错误的”注册表。
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters] "requiresignorseal"=dword:00000000
此版本还需要在登录脚本中进行调整。 有时它坚持使挂载持久。 netlogon脚本应命名为“WinXP.bat”,以便当%a被翻译时,选择正确的脚本。
例子
REM WINXP.BAT net use z: \\linux\samba /yes /persistent:no
Windows CD上捆绑了一个名为策略编辑器的实用程序。 文件名是poledit.exe。 这个工具,正如其名称所暗示的那样,允许创建用户和系统策略文件。
不幸的是,此工具不会生成纯文本配置文件,因此我无法在此处放置示例。
使用策略编辑器为你的工作站和用户创建策略。 你应该禁用本地密码缓存和域缓存,以获得一些安全性。 将策略文件另存为config.pol,并将其放置在你的Linux服务器的netlogon共享中。 这样,你的Windows工作站将下载并使用config.pol文件来设置它们的策略。 当然,此任务必须在Windows机器上完成。
如果你不使用config.pol文件,你的Windows工作站会烦扰你,要求你输入Windows密码,你将会变得疯狂,试图同步和管理你的域和Windows密码。 操作系统似乎不知道它加入了域。 你必须告诉它,然后你必须打它的脸,以便它相信你。
通过常用方法添加Linux用户并使用smbpasswd设置samba密码将会有效。 如果你有任何疑问,请参阅SAMBA文档。 这不是一个难题。
我将此问题作为一个主要主题,因为我仍然无法学习如何在不使用Web界面的情况下从Windows工作站管理用户和用户密码。 我找不到,也不知道如何构建集成工具来解决这个问题。 因此,我正在使用CGI程序来完成它。
尝试 http://changepassword.sourceforge.net 上的软件包,这似乎是一个不错的选择。
正如您在本指南的前面部分所看到的,每次跟踪共享被挂载时,SAMBA 守护进程都会调用一个 netlogon.sh 脚本。该 netlogon.sh 脚本会调用一个以用户名为名称的脚本,并将该用户的工作站的 IP 地址作为参数传递给该脚本。该用户脚本将应用所需的规则。
例如,如果您想给予用户完全的互联网访问权限
#!/bin/sh # COMMAND=$1 ADDRESS=$2 EXTIF=$3 IPTABLES='/usr/sbin/iptables' $IPTABLES $COMMAND POSTROUTING -t nat -s $ADDRESS -o $EXTIF -j MASQUERADE
如果您不想更改任何特定用户的设置,只需给他们一个空的脚本
#/bin/sh # exit 0
或者干脆不要为权限较低的用户创建任何脚本,让他们使用默认的 default.sh 脚本,该脚本可以是空的,或者只是给予有限的访问权限,如下所示
#!/bin/sh # COMMAND=$1 ADDRESS=$2 EXTIF=$3 EXTIFADDRESS=$4 IPTABLES='/usr/sbin/iptables' $IPTABLES $COMMAND POSTROUTING -t nat -s $ADDRESS -o $EXTIF --dport 25 -j SNAT --to-source $EXTIFADDRESS $IPTABLES $COMMAND POSTROUTING -t nat -s $ADDRESS -o $EXTIF --dport 110 -j SNAT --to-source $EXTIFADDRESS
请记住,此脚本需要您修改之前的所有脚本以包含额外的参数,或者直接修改 script 脚本。并且请记住,如果您不理解 iptables,本指南对您毫无用处。
只需在 Linux PDC 中创建您的用户组,并将用户添加到组中。 就这样。
请记住,如果您的用户属于多个组,本指南中的示例脚本可能会失败。 如果您需要这样做,请记住调整脚本。
您将需要定义组特定的脚本,并将它们放置在“/etc/smbgate/groups/”目录中。 请记住,脚本必须以组命名,至少如果您想遵循本指南中的示例。
本指南的默认方案是检查用户脚本,然后检查组脚本,最后检查默认脚本。 如果您想修改此行为,请记住调整 netlogon.sh、netlogoff.sh(或 checklogout.sh)脚本。 整个逻辑都在这些脚本中。
IPTABLES 教程 作者:Oskar Andreasson
Samba HOWTO 合集 SAMBA 团队编写
GNU 自由文档许可证 1.2 版,2002 年 11 月
版权所有 (C) 2000,2001,2002 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 允许任何人复制和分发本许可文档的完整副本,但不允许对其进行更改。
0. 前言
本许可证的目的是使手册、教科书或其他功能性和有用的文档在自由的意义上是“自由的”: 确保每个人都拥有有效自由地复制和重新分发它,无论是否修改它,无论是商业性的还是非商业性的。 其次,本许可证为作者和出版商保留了一种方法,以获得对其工作的认可,同时不被认为对他人所做的修改负责。
本许可证是一种“反版权”,这意味着文档的衍生作品本身必须在同一意义上是自由的。 它补充了 GNU 通用公共许可证,该许可证是为自由软件设计的反版权许可证。
我们设计本许可证是为了将其用于自由软件的手册,因为自由软件需要自由文档: 自由程序应附带提供与软件相同自由的手册。 但是,本许可证不限于软件手册; 它可以用于任何文本作品,无论主题或是否作为印刷书籍出版。 我们主要推荐本许可证用于以指导或参考为目的的作品。
1. 适用性和定义
本许可证适用于任何手册或其他作品,以任何媒介形式,其中包含版权所有者放置的声明,声明它可以在本许可证的条款下分发。 这样的声明授予在全球范围内、免版税、无限期限的使用该作品的许可,条件是符合此处所述的条件。“文档”,以下是指任何此类手册或作品。 任何公众成员都是被许可人,并被称为“您”。 如果您以需要版权法许可的方式复制、修改或分发作品,则您接受许可。
“文档的修改版本”是指包含文档或其一部分的任何作品,无论是逐字复制,还是经过修改和/或翻译成另一种语言。
“次要章节”是文档的命名附录或前言章节,专门处理文档的出版商或作者与文档的整体主题(或相关事项)的关系,并且不包含可能直接属于该整体主题的任何内容。 (因此,如果文档部分是数学教科书,则次要章节可能不会解释任何数学知识。)这种关系可能是与主题或相关事项的历史联系,或者与它们的法律、商业、哲学、道德或政治立场有关。
“不变章节”是某些次要章节,其标题被指定为不变章节的标题,该声明表明文档在本许可证下发布。如果某个章节不符合上述次要章节的定义,则不允许将其指定为不变。 文档可能包含零个不变章节。 如果文档未识别任何不变章节,则不存在任何不变章节。
“封面文字”是在声明文档在本许可证下发布的声明中列出的某些短文本段落,作为封面文本或封底文本。 封面文本最多可以有 5 个字,封底文本最多可以有 25 个字。
文档的“透明”副本是指以机器可读的格式表示的副本,该格式的规范可供公众使用,适用于使用通用文本编辑器(对于由像素组成的图像)通用绘图程序或(对于绘图)一些广泛可用的绘图编辑器来直接修改文档,并且适用于输入到文本格式化程序或自动翻译成各种适用于输入到文本格式化程序的格式。 以其他透明文件格式制作的副本,其标记或缺少标记的安排旨在阻止或劝阻读者进行后续修改,则不是透明的。 如果用于任何大量的文本,则图像格式不是透明的。 不是“透明”的副本称为“不透明”。
透明副本的适用格式示例包括不带标记的纯 ASCII、Texinfo 输入格式、LaTeX 输入格式、使用公开可用的 DTD 的 SGML 或 XML 以及符合标准的简单 HTML、PostScript 或 PDF,专为人工修改而设计。 透明图像格式的示例包括 PNG、XCF 和 JPG。 不透明格式包括只能由专有文字处理器读取和编辑的专有格式、DTD 和/或处理工具通常不可用的 SGML 或 XML,以及某些文字处理器仅用于输出目的而生成的机器生成的 HTML、PostScript 或 PDF。
“标题页”对于印刷书籍是指标题页本身,以及为清晰地容纳本许可证要求出现在标题页中的材料所需的后续页面。 对于没有标题页格式的作品,“标题页”是指文本正文开始之前,最突出的作品标题附近的文本。
“标题为 XYZ”的章节是指文档的命名子单元,其标题完全是 XYZ,或者在翻译成另一种语言的 XYZ 文本后的括号中包含 XYZ。(这里 XYZ 代表下面提到的特定章节名称,例如“致谢”、“献词”、“背书”或“历史”。)当您修改文档时,“保留标题”表示它仍然是根据此定义“标题为 XYZ”的章节。
文档可能在声明本许可证适用于文档的声明旁边包含免责声明。 这些免责声明被认为是通过引用包含在本许可证中,但仅限于免责声明:这些免责声明可能具有的任何其他含义均无效,并且对本许可证的含义没有影响。
2. 逐字复制
您可以以任何媒介复制和分发文档,无论是商业性的还是非商业性的,前提是本许可证、版权声明以及声明本许可证适用于该文档的许可声明在所有副本中均被复制,并且您不得对本许可证的条件添加任何其他条件。 您不得使用技术措施来阻碍或控制您制作或分发的副本的阅读或进一步复制。 但是,您可以接受复制的报酬。 如果您分发足够多的副本,您还必须遵守第 3 节中的条件。
您也可以在上述相同的条件下借出副本,并且您可以公开展示副本。
3. 大量复制
如果您发布文档的印刷副本(或通常具有印刷封面的媒体中的副本),数量超过 100,并且文档的许可声明要求封面文本,则必须将副本包裹在带有所有这些封面文本的封面上,清晰易读:封面上的封面文本,以及封底上的封底文本。 两个封面还必须清晰易读地标识您为这些副本的出版商。 封面必须以同样突出和可见的方式呈现标题的所有单词的完整标题。 您可以在封面上添加其他材料。 以仅限于封面的更改进行复制,只要它们保留文档的标题并满足这些条件,就可以在其他方面被视为逐字复制。
如果任何一个封面的所需文本过于冗长而无法清晰地放置,您应将列出的第一个文本(尽可能多地合理放置)放在实际封面上,并将其余文本继续放在相邻页面上。
如果您发布或分发超过 100 份不透明的文档副本,您必须在每个不透明的副本中附带一份机器可读的透明副本,或者在每个不透明的副本中或随附声明一个计算机网络位置,以便一般网络用户可以通过公共标准网络协议访问并下载完整的透明文档副本,且不包含任何附加材料。如果您使用后一种选择,您必须采取合理谨慎的措施,当您开始大量分发不透明副本时,确保该透明副本在该声明的位置保持可访问状态,直到您向公众分发(直接或通过您的代理商或零售商)该版本的最后一个不透明副本至少一年之后。
建议(但非强制)您在重新分发大量副本之前,事先与文档作者联系,让他们有机会为您提供文档的更新版本。
4. 修改
您可以根据上述第2和第3节的条件复制和分发文档的修改版本,前提是您在完全按照本许可证的条款下发布修改版本,且修改版本扮演文档的角色,从而许可对修改版本的拥有者进行分发和修改。此外,您必须在修改版本中做到以下几点:
A. 在扉页(以及封面上,如果存在的话)使用与文档标题不同的标题,并与之前的版本标题不同(如果存在任何之前的版本,应在文档的历史记录部分列出)。如果该版本的原始出版商允许,您可以使用与之前版本相同的标题。B. 在扉页上列出作为作者的一个或多个对修改版本中的修改负责的个人或实体,以及至少五位文档的主要作者(如果少于五位,则列出所有主要作者),除非他们免除您的此项义务。C. 在扉页上声明修改版本的出版商名称,作为出版商。D. 保留文档的所有版权声明。E. 在其他版权声明旁边添加适当的修改版权声明。F. 在版权声明之后立即包含一份许可声明,允许公众根据本许可证的条款使用修改版本,其格式如下文附录所示。G. 在该许可声明中保留文档的许可声明中给出的不变章节和要求的封面文本的完整列表。H. 包含本许可证的未更改副本。I. 保留题为“历史记录”的章节,保留其标题,并在其中添加一项,至少说明扉页上给出的修改版本的标题、年份、新作者和出版商。如果文档中没有题为“历史记录”的章节,请创建一个章节,说明扉页上给出的文档的标题、年份、作者和出版商,然后添加一项,描述前述句子中描述的修改版本。J. 保留文档中给出的用于公共访问文档透明副本的网络位置,以及文档中给出的其所基于的先前版本的网络位置。这些可以放在“历史记录”部分。您可以省略至少在文档本身出版前四年发布的文档的网络位置,或者如果该版本原始出版商允许。K. 对于任何题为“致谢”或“献词”的章节,保留该章节的标题,并保留该章节中每个贡献者致谢和/或献词的所有实质内容和语气。L. 保留文档的所有不变章节,其文本和标题均保持不变。章节编号或同等内容不被视为章节标题的一部分。M. 删除任何题为“背书”的章节。修改版本中不得包含此类章节。N. 请勿重命名任何现有章节为“背书”,或在标题上与任何不变章节冲突。O. 保留所有免责声明。
如果修改版本包含符合辅助章节条件的新前言章节或附录,并且不包含从文档复制的材料,您可以选择将部分或全部这些章节指定为不变章节。为此,请将它们的标题添加到修改版本的许可声明中的不变章节列表中。这些标题必须与其他任何章节标题不同。
您可以添加一个题为“背书”的章节,前提是它只包含各个方对您的修改版本的背书--例如,同行评审声明,或文本已被组织批准为标准权威定义。
您可以添加最多五个单词的段落作为封面文字,以及最多 25 个单词的段落作为封底文字,添加到修改版本中封面文字列表的末尾。任何一个实体只能添加(或通过安排添加)一段封面文字和一段封底文字。如果文档已包含用于相同封面的封面文字,该文字以前由您添加或由您代表的同一实体安排添加,则您不得添加另一个封面文字;但您可以替换旧的封面文字,前提是获得添加旧封面文字的前任出版商的明确许可。
文档的作者和出版商不通过本许可证允许使用他们的名字来宣传或断言或暗示对任何修改版本的认可。
5. 合并文档
您可以按照上述第 4 节中针对修改版本的定义,将文档与其他根据本许可证发布的文档合并,前提是您在组合中包含所有原始文档的所有不变章节,并保持不变,并将它们全部列为您的组合作品的许可声明中的不变章节,并且您保留他们的所有免责声明。
组合作品只需要包含本许可证的一份副本,多个相同的不变章节可以替换为单个副本。如果存在多个具有相同名称但内容不同的不变章节,请通过在每个章节的末尾括号中添加该章节的原始作者或出版商的姓名(如果已知),或者添加唯一的数字,使每个此类章节的标题都是唯一的。在组合作品的许可声明中的不变章节列表中,对章节标题进行相同的调整。
在组合中,您必须合并各种原始文档中题为“历史记录”的所有章节,形成一个题为“历史记录”的章节;同样合并题为“致谢”的所有章节,以及题为“献词”的所有章节。您必须删除题为“背书”的所有章节。
6. 文档集合
您可以创建一个由文档和其他根据本许可证发布的文档组成的集合,并将各种文档中本许可证的各个副本替换为集合中包含的单个副本,前提是您在所有其他方面都遵循本许可证的规则来逐字复制每个文档。
您可以从这样的集合中提取单个文档,并在本许可证下单独分发它,前提是您将本许可证的副本插入到提取的文档中,并在所有其他方面都遵循本许可证,关于该文档的逐字复制。
7. 与独立作品的聚合
如果汇编的版权不用于限制汇编用户的合法权利,超出单个作品允许的范围,则将文档或其衍生作品与其他单独和独立的文档或作品汇编在一个存储或分发介质的卷中或卷上,称为“聚合”。当文档包含在聚合中时,本许可证不适用于聚合中不是文档的衍生作品的其他作品。
如果第 3 节的封面文字要求适用于这些文档副本,那么如果文档少于整个聚合的一半,则文档的封面文字可以放置在将文档括在聚合内的封面上,或者如果文档是电子形式,则放置在封面的电子等效物上。否则,它们必须出现在括号整个聚合的印刷封面上。
8. 翻译
翻译被认为是修改的一种,因此您可以根据第 4 节的条款分发文档的翻译版本。将不变章节替换为翻译需要其版权持有者的特别许可,但您可以除了这些不变章节的原始版本之外,还包含部分或全部不变章节的翻译版本。您可以包含本许可证的翻译版本,以及文档中的所有许可声明,以及任何免责声明,前提是您还包含本许可证的原始英文版本以及这些声明和免责声明的原始版本。如果本许可证的翻译版本与原始版本或声明或免责声明之间存在分歧,则以原始版本为准。
如果文档中的章节题为“致谢”、“献词”或“历史记录”,则保留其标题(第 4 节)的要求通常需要更改实际标题。
9. 终止
除非本许可证明确规定,否则您不得复制、修改、再许可或分发文档。任何其他尝试复制、修改、再许可或分发文档的行为均无效,并将自动终止您在本许可证下的权利。但是,根据本许可证从您那里收到副本或权利的各方,只要这些各方保持完全合规,其许可证就不会被终止。
10. 本许可证的未来修订
自由软件基金会可能会不时发布 GNU 自由文档许可证的新的修订版本。这些新版本在精神上与当前版本相似,但在细节上可能有所不同,以解决新的问题或疑虑。请访问 https://gnu.ac.cn/copyleft/。
每个版本的许可证都有一个独特的版本号。如果文档指定适用本许可证的某个特定版本号“或任何后续版本”,您可以选择遵循该指定版本的条款和条件,或者遵循自由软件基金会已发布的(非草案)任何后续版本。如果文档没有指定本许可证的版本号,您可以选择自由软件基金会发布的(非草案)任何版本。
附录:如何将本许可证用于您的文档
要在您编写的文档中使用本许可证,请将许可证副本包含在文档中,并在标题页之后放置以下版权和许可证声明:
版权所有 (c) YEAR YOUR NAME。 授权您根据 GNU 自由文档许可证 1.2 版本或自由软件基金会发布的任何后续版本的条款复制、分发和/或修改本文档;不包含不变部分,不包含封面文字,不包含封底文字。 许可证副本包含在题为“GNU 自由文档许可证”的部分中。
如果您有不变部分、封面文字和封底文字,请用以下内容替换“with...Texts.”这一行:
不变部分为 LIST THEIR TITLES,封面文字为 LIST,封底文字为 LIST。
如果您有不变部分但没有封面文字,或者三种情况的其他组合,请将这两种替代方案合并以适应具体情况。
如果您的文档包含重要的程序代码示例,我们建议您同时选择免费软件许可证(例如 GNU 通用公共许可证)发布这些示例,以允许在自由软件中使用它们。