Chinaunix首页 | 论坛 | 博客

~~~

  • 博客访问: 41891
  • 博文数量: 9
  • 博客积分: 1425
  • 博客等级: 上尉
  • 技术积分: 95
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-25 09:42
文章分类

全部博文(9)

文章存档

2020年(5)

2007年(2)

2006年(2)

我的朋友
最近访客

分类: BSD

2006-07-25 09:42:33

FreeBSD 安全 HOWTO
本文出自: 作者: (2001-08-24 10:00:00)
 
  o 前言
o 这份 HOW-TO 是必要的吗? 
FreeBSD 是一个非常安全的作业系统。也正因为它的 source code 是可以免费的取得,
这个 OS 长久以来不断的有人改进加强。管 FreeBSD 一出厂就非常安全, 但是仍然
有更多加强安全性的措施, 来满足"偏执狂"的你 :) 这份 HOW-TO 会教你一些步骤, 以
更加强你机器的整体安全。

o 这份文件会说明 tripwire, tcp_wrappers, cops, satan, 和其它的工具吗?

除了 SSH 之外, 不会。这是一份针对 FreeBSD 的文件 - 除此之外, 已经有很多文件
说明上述的工具了。目前呢, 我只想关心的是关於 BSD 的部份。

o 谁要读这份 HOW-TO?
任何想让他的系统更安全的人。这份 HOW-TO 包含了一些很基本的步骤, 和某些很杂
的步骤。如果你有任何的疑问, 或者想要加以补充, 请 eMail 到维护人 jkb@best.com
又, 管大部份的内容是针对 FreeBSD 的, 但仍然会套用到其它的 Unix OSes 上面。
(特别是 OpenBSD 和 NetBSD)

o 这份 HOW-TO 还有其它语言的版本吗 ?
就我所知, 有俄语版:
http://www.etrust.ru/osa/security.html
和中文版:


o TODO:
将包含 /etc/login.conf 和 login classes
将提及使用 X 的场合
将会有 html 版

o 网路
o inetd (Inet Daemon)
网路在系统安全上扮演了一个很重要的角色。FreeBSD 的根基是有着内建网路功能, 且
具有最稳最快的 TCP/IP stacks 的 4.4BSD。这个 stack 支援了非常多的协定像是
telnet, ftp, talk, rsh 等... 这些 service 的的主设定档便是 /etc/inetd.conf。
要编辑这个档, 请输入 "vi /etc/inetd.conf" (在这个例子里, 我使用 vi 。你可以
使用其它你较为上手的编辑器。或许你可以试试 pico)。如果你要使用 pico, 请在启
动它时加上 -w 选项:
-w 关掉自动断行。(因此可以容许超过 80 字元的行存在)

这选项在编辑 /etc/inetd.conf 时非常有用。
当然了, 你也可以使用 ee - 它随着 FreeBSD 一起 "出厂" 的, 而且也是 root 预设
的编辑器。不过, 请再 "echo $EDITOR" 确认一次。 开启了这个档案後, 你可以看
到里面怎麽描述每个 service 怎麽启动, 要以那位使用者执行等等的资讯。(man 5
inetd.conf)既然这个档案是许多 internet service 的主要设定档, 好好的设定它便
是一件十分重要的事。你要关掉一个 service的话,只消在那一行前面加个 "#" 符号。
基本的概念是, 关掉些你不熟悉的 services - 如果你不知道那个 service 是啥, 或
者不知道它可以干啥。理想状态下, 你不须要把所有的 service 都打开。例如, 你的
器只是要跑 web server。这种情况下, 你只要启动 ssh 和 httpd 便够了。关於啥是
ssh, 下面会说明。如果你啥 service 都不想跑, 最直接乾脆的方法是-关掉 inetd。
做法很简单, 只要编辑 /etc/rc.conf 并且把

inetd_enable="YES"

改成

inetd_enable="NO"

就可以了。
如此一来没人可以 telnet, rlogin, 或 ftp 到你的电脑。
如果你决定要启动你的 inetd 的话, 记得启动 log 选项, 并提高一个 service 每分
钟启动的上限数目。(预设值是 256, 我建议提高到 1024-自行参照下面解说调整吧!)
为什麽要这麽做呢...? 就 modem user 或是低速专线用户是没什麽差别。但高速线路
的人, 上限值太低会蹦出一个 DoS attack(Denial of Service)。某个坏心的人可以简
单的用一个 shell script 同时搞出超过 256 个 connections, 这麽一来你的 inetd
会很不幸的阵亡。换句话说, 如果你想让每分钟每个 service 可接受的connection 数
多点, 记得做如下的设定, 不然来个坏心的人就可以搞垮你的电脑。因此, 在这行

inetd_enable="YES"

下面的

inetd_flags=""

要改成:

inetd_flags="-l -R 1024"

这会将连线的动作都 log 下来(-l 参数)而且将同时最大连线数从预设的 256 增加到
1024。你还须要对你的 /etc/syslog.conf 作些修改, 这些等会儿会提到。

o SSH

在以下提到的案例中, 你完全不须要 run inetd。例如, 如果你只有跑 web, news, 或
是 nfs server, 那麽就没有必要在你的机器上再跑其它的services。但是你一定会问,
"我要怎麽控制我的机器啊!?" 嗯嗯, 所以现在要介绍 SSH。你可以透过 SSH (Secure
Shell) 来登入你的机器。Secure Shell 当初便是设计来取代 rsh, rlogin 等其它的
Berkeley r* 命令。相信你很快就会了解 SSH 是如何有用,而且开始使用它,来代替其
它的程式像是 telnet 和 ftp。SSH 具有很多功能,但是最为人知的是, 它的加密通讯
方式, 也就是防止你的密码和资料以明码的方式在网路上传输。如果你使用 telnet,你
的通讯内容可能会被"窃听": 传输中的资料被改变, 通讯内容被看到。(不是有 S/Key
可以解决吗? 很不幸的, 它还是有着插入资料和连接时被破解的问题) 我希望你可以完
全的关掉 inetd 而使用 SSH。如果你认为完全不靠 inetd 来启动某些 services,是完
完全全不可能的事, 那麽希望你至少启动 log 功能, 而且要增加每分钟同一个 servi-
ce 可启动的次数。 (原因上面有提到)
你可以从 ftp://ftp.funet.fi/pub/unix/security/login/ssh 下载 SSH。
若你想要更简单的方法:

# cd /usr/ports/security/ssh
# make install

如果你有不是使用 Unix 的使用者, 那麽可以从下面的站台抓到 win32 SSH 程式:
~ci2/ssh/
~roca/ttssh.html

~cigaly/ssh
SecureCRT from 


o inetd (part II)

o telnetd

好吧, 你仍然执意要使用 inetd。那麽我们来看看在 inetd.conf 有那些选项, 可以增
进你的系统安全。在攻击某系统之前, 攻击者都会先收集该系统的相关资讯。就 teln-
etd 而言, 你可以试试在 telnetd 那行後面加个 -h:

telnet stream tcp nowait root /usr/libexec/telnetd telnetd -h

从 telnetd 的 man page 可以知道:

-h Disable the printing of host-specific information before login
has been completed.

当有很多管道可以获得系统资讯的同时, 这招和下面的那招是个不错的解决方案。如果
你认为跑 telnet daemon 是没有必要的, 那麽只消加个 "#" 在该行的最前面就行了:

#telnet stream tcp nowait root /usr/libexec/telnetd telnetd

有个极不错的措施是, 你可以拒绝没有完整 FQDN 的人来连线。要做到这点, 也只要加
个 -U 选项到 telnetd 後面:

telnet stream tcp nowait root /usr/libexec/telnetd telnetd -h -U

这是个小动作, 但是对你的系统安全有莫大的助益。

o ftpd

现在来看看 ftp。 对於 ftp FreeBSD 已经做了一些 log 的动作 。 可以看到在
/etc/inetd.conf 里面 ftpd 那一行已经加了 "-l"。然而, 你还是要设定你的syslogd
, 使它可以接受 ftp daemon 产生的 log。从 man page 可以得知:

-l Each successful and failed ftp(1) session is logged using syslog
with a facility of LOG_FTP. If this option is specified twice,
the retrieve (get), store (put), append, delete, make directory,
remove directory and rename operations and their filename argu-
ments are also logged. Note: LOG_FTP messages are not displayed
by syslogd(8) by default, and may have to be enabled in syslogd(8)'s
configuration file.
每个成功或是失败的 ftp 登入尝试, 都会以 LOG_FTP 机制纪录起来。如
果这个选项被指定了两次, 所有的下载 (get), 上载(put), 新增, 删除,
建立目录, 及更名的动作和档案名字都会被纪录下来。 又: LOG_FTP 讯
息预设是不会被 syslogd(8) 纪录下来的。你还要在 syslogd(8) 的设定
档里面启动这个功能才行。

让我们开启 syslogd 纪录 ftpd log 的功能吧~ 这个档案是 /etc/syslog.conf (别忘
了顺便看看 man 5 syslog.conf)。把下面这一行加到这个设定档里:

ftp.* /var/log/ftpd

也不要忘了执行这个指令 "touch /var/log/ftpdlog", 因为 syslogd 不能写入到一个
没有被开启过的档案。如果你想要你的 ftpd 提供你更多的 log 讯息, 那麽就在 ftp
那一行多加个 "-l" 吧:

ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l -l

如果你想要确定你的使用者们都用 scp (Secure Copy, 附属在 SSH 里面), 但是又想
要提供 anonymous ftp 服务, 也只消加个 "-A" 在 ftp 那行後面就行了:

ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l -A

你也可以编辑 /etc/ftpwelcome, 说明目前接受 anonymous ftp 登入, 但是系统内的
使用者就得使用 rcp 了。如果你有提供 anonymous ftp, 你可以使用 -S 选项来记录
传输的情形:

ftp stream tcp nowait root /usr/libexec/ftpd ftpd -A -S

o fingerd

Finger 服务预设值还算安全: 它不容许不带 user name 的 query。这是一件不错的事
(tm)。然而, 就是有些人无论如何也不想 run fingerd。这种情形下, 你只要简单的给
它加个 "#" 在这行的最前面就可以了。又, 你想要 log 住谁来 finger 的话, 加个
"-l" 也就行了:

finger stream tcp nowait nobody /usr/libexec/fingerd fingerd -s -l

Fingerd 产生的 log 资讯预设是写到 /var/log/messages。如果你想要这些资讯写入
到特定的档案里去, 那麽就在 /etc/syslog.conf 加入这一行:

daemon.notice /var/log/fingerd

/* !fingerd anyone? */

$ man 5 syslog.conf

除了 ftp, telnet 和 finger 之外, 你实在不须要在 /etc/inetd.conf 中再多启动任
何东西了。通常我都会关掉 talk 及 comsat等我个人不须要的东西。如同我之前讲的,
如果你不知到某个 servcie 是干嘛用的, 而且你也不须要它, 那麽就关掉它。一些和
网路有关而且很有用的 man page 是: inetd, ftpd, telnetd, fingerd, syslogd,
comsat, talkd, rshd, rlogind, inetd.conf。并且记得要看 man page 的"SEE ALSO"
部份, 以获得更多的相关资讯。

o ipfw (IP FrewWall)

IP FireWall 做的是 packet 过滤的工作。没错, 就是只有这样。然而, 你要考虑的事
是, 你的 kernel 要有支援 ipfw。 通常在我管的机器上, 我都会重编核心使其支援
ipfw。大概看起来是这样:

options IPFIREWALL #finger the net
options IPFIREWALL_VERBOSE #log the net
options IPFIREWALL_DEFAULT_TO_ACCEPT

第一行表示最其本的 IP FireWall 支援。第二行让 ipfw 可以把接受或拒绝 packets
的纪录 log 起来。第三行非常重要, 让 ipfw 预设值是接受任何地方来的 packets 。
如果你不这样做, 预设值拒绝任何地方来的 packets。我个比比较喜欢後者, 但我又认
为在我自己的工作站上, 或一个让人登入的工作站, 预设拒绝任何 packets 不是一件
太好的事。

********** NOTE ************
如果你搞不清楚自己在做啥事, 那就不要用这个选项。
就设定 firewall 而言, 这是不甚正确的。预设任何东西都该被挡掉才是正确的。如果
你是要建置一台高安全性的系统, 或一台 firewall 的话,那就千万不要加入这个选项:

options IPFIREWALL_DEFAULT_TO_ACCEPT

记住一件事: 要预设拒绝任接受任何 packets, 然後再加入 rule 来设定你想要接
受那些 packets。查看 /etc/rc.firewall 以得到更多的资讯。再一次提醒你, 不要使
用这个 option, 除非你只是想要防止 DoS attacks 或暂时把某些 port/network ban
掉。
*****************************

o log_in_vain

你也可以透过 sysctl 命令, 来改变一些有用的系统变数:

# sysctl -w net.inet.tcp.log_in_vain=1
# sysctl -w net.inet.udp.log_in_vain=1

这会把尝试向你的机器要求你没有的服务的 connections log 起来。例如, 如果你在
你的机器没有跑 DNS server, 而又有个人想要向你的机器要求 DNS 服务, 这时候你就
会看到

Connection attempt to UDP yourIP:53 from otherIP:X
(X 是某个 high port #)

你用 "dmesg" 命令就可以看到这一行。Dmesg 秀出的是系统的 kernel message
buffer。然而, 这个 buffer 的空间是有限的, 所以系统也会把这些讯息写入到
/var/log/messages 里面去:

# tail -1 /var/log/messages
Jun 12 19:36:03 ugh /kernel: Connection attempt to UDP yourIP:53 from
otherIP:X

o final notes
理论上呢, 你的系统现在已经比你装好它时更安全些了。你现在可以做一些事来确定你
目前的更动:

$ netstat -na | grep LISTEN

这会告诉你那些 service 在那些 port 跑。越少越好 :) 又, 再跑一些其它的 port
scanners (strobe, nmap) 来找出你开了那些 port。
而要确要你的 syslogd 已经开始纪下你刚刚想要 log 的事件, 可以这麽做:

# cd /var/log
# tail -10 fingerd ftpd messages

在 log 档里面没看到任何东西的话, 记得重新启动 inetd 和 syslogd:

# kill -HUP `cat /var/run/syslog.pig` `cat /var/run/inetd.pid`

o Filesystem

既然 Unix 把什麽东西都当作档案来看待, 好好的保护你的档案系统便是很重要的事。
有件事是在你安装作业系统前便要完成的: 必须要计划并设计好你的 partition 该怎
麽切割。有几个很重要的原因让你要这麽做: 一个是你可以 mount 不同的档案系统以
赋与不同的选项 (下面有几个例子)。别一个是,如果你想要把你的 filesystem export
出去, 你须要更加细微的控制。如果你是一个从 Linux 转入 FreeBSD 的使用者, 你会
发现 Linux 是把任何东西都往 root partition "/" 塞, 而 FreeBSD 预设便要 "/",
"/usr", 和 "/var"。这也使得要使用如 dump 般的工具较容易。且让我们来讨论 se-
curity 吧! 有一件事我通常会做的是, 我会把一般 users 可以写入的 partition 分
开来割, 而这些 partitons 便可以用 "nosuid" 的方式来 mount。从 mount 的 man
page 可以知道:

nosuid Do not allow set-user-identifier or set-group-identifier
bits to take effect. Note: this option is worthless if a
public available suid or sgid wrapper like suidperl is
installed on your system.

让 suid 或 sgid bit 失效。又: 对於像 suidperl 这些公开使用
的程式, 设这个选项便没用。

因此你会有个 partition 给一般使用者使用: /home 或 /usr/home。然後你可以另外
开个 partion 给 /var/tmp 然後再把你的 /tmp 指到这里:

# rm -rf /tmp
# ln -s /var/tmp /tmp

你可以参考这个例子:

# cat /etc/fstab
# Device Mountpoint FStype Options Dump Pass#
/dev/sd0s1b none swap sw 0 0
/dev/sd0s1a / ufs rw 1 1
/dev/sd0s1g /usr ufs rw 2 2
/dev/sd0s1h /usr/home ufs rw 2 2
/dev/sd0s1f /var ufs rw 2 2
/dev/sd0s1e /var/tmp ufs rw,nosuid 2 2
proc /proc procfs rw 0 0

现在你可以确定一般 users 可以写入的目录不是以 "-nosuid" 的方式被 mount, 就是
没有可以写入。现在你还要关心的就是 /var/spool/uucppublic"。
你可以把 "/var" 以 "-nosuid" 的方式来 mount , 或下这个命令:

# chmod o-w /var/spool/uucppublic


如果你想要找出你所有的可写入目录, 下这个命令:

# find / -perm -0777 -type d -ls

如同 man page 指出的, 具有 suid/sgid 的程式会让你的 nosuid 失效。找出那些程
式是 suid 或 sgid 的吧:

# find / -perm -2000 -ls
# find / -perm -4000 -ls

同时你不止可以用 "-ls" 而只是知道有那些程式。你可以把不是很有用的程式 "chmod
000"。像是 uustat, uucico 等, 如果你从来不碰 uucp 的话。或是 ppp 和 pppd, 如
果你绝不会用到他们。又, 你不会去用到印表机的话, 把 lpr lprd 也 chmod 000 吧!
也许改天会有个人写个 shell script 来问你那些东西要 chmod 000 掉。

现在你也许想问, 有什麽方式可以防止攻击者重新以非 "-nosuid" 的方式 mount 你的
filesystem ? Well, 没有, 除非你改变你的 securelevel。

o securelevel

FreeBSD kernel 有个观念叫 securelevel。当还有人在争论这是不是够完美时,这个
机制已经够防止大部份的 "script kiddiez"。Securelevel 是指你的 kernel 在执行

的安全等级。每一个等级具有不同的保护和检查机制。这些是 init(8) 的 man page:

The kernel runs with four different levels of security. Any superuser
process can raise the security level, but only init can lower it. The
security levels are:
Kernel 可以以四种不同的安全等级来执行。任何 superuser process 可以提高安全
等级, 但是只有 init 可以降低它。这四种等级分别是:

-1 Permanently insecure mode - always run the system in level 0 mode.
永远不安全模式 - 切换到 level 0 吧!

0 Insecure mode - immutable and append-only flags may be turned off.
All devices may be read or written subject to their permissions.
不安全模式 - "不可更动"和"只能附加"这两个旗标(flag)可以被改变。所有的
devices 可以照着它们的读写权限被读写。

1 Secure mode - the system immutable and system append-only flags may
not be turned off; disks for mounted filesystems, /dev/mem, and
/dev/kmem may not be opened for writing.
安全模式 - "不可更动"和"只能附加" 的旗标不能被取消; mount 上来的档案系
统, /dev/mem, 和 /dev/kmem 不能写入。

2 Highly secure mode - same as secure mode, plus disks may not be
opened for writing (except by mount(2)) whether mounted or not.
his level precludes tampering with filesystems by unmounting them,
but also inhibits running newfs(8) while the system is multi-user.
高安全模式 - 和安全模式一样, 又多加了不管硬碟有没有被 mount 起来,
除了 mount(2) 之外都不能写入。它防止一个档案系统在 umount 的时候被
搞乱。而且在这个等级也禁止在 multi-user 时执行 newfs(8)。

如果安全等级最初是 -1, 那麽 init 就会保持原状。否则在 single user mode 时,
init 会把安全等级调到 0, 而在 multiuser mode 时会以 1 来跑。如果你希望在
multiuser 模式是以等级 2 在跑, 你可以先进入 single user mode, 编辑 /etc/rc,
使用 sysctl 来更动。

若是你的系统只拿来跑 web server 之类的, 你可以放心的将 securelevel调高到2。
但若是你要跑 X server, 把你的 securelevel 调至 1 或更高会导致一些问题。因为
X server 必须要写入 /dev/mem 和 /dev/kmem, 而 securelevel 1 不允许你这麽做。
有一个解决的方法是, 在启动 X server 後再调高 securelevel。但我的意见是, 如果
你跑 X server 的话, 你已经有了其它的安全问题须要考量, 而不止是 securelevel。
以下这个指令会显示出你目前的 securelevel 设定值。

# sysctl kern.securelevel


如果要提高你的 securelevel:
# sysctl -w kern.securelevel=X
X 可以是 0, 1 或 2。

又在 securelevel 是 1 的话, 你在 "make world" 时也会有些问题。因为 "make
install" 时会在 kernel 上加上 immutable flag:

# ls -lo /kernel
-r-xr-xr-x 1 root wheel schg 1061679 Jun 30 01:27 /kernel

"schg" flag 会防止你安装新的 kernel:

nfr# id
uid=0(root) gid=0(wheel) groups=0(wheel), 2(kmem)

nfr# sysctl kern.securelevel
kern.securelevel: 2

nfr# rm -rf /kernel
rm: /kernel: Operation not permitted

nfr# mv /kernel /tmp/
mv: rename /kernel to /tmp//kernel: Operation not permitted

如果你在 securelevel 1 或 2, 那麽 schg flag 是不能被改变的。

# chflags noschg /kernel
chflags: /kernel: Operation not permitted

值得留意的是, /boot.config 可以改变你开机时的系统设定,要预防有心人篡改
你应该这麽做:

# touch /boot.config
# chflags schg /boot.config

你可以看看系统预设还有那些执行档是有 schg flag 的。

# ls -lo /sbin | grep schg
-r-x------ 1 bin bin schg 204800 Jul 19 20:38 init
# ls -lo /bin | grep schg
-r-sr-xr-x 1 root bin schg 192512 Jul 19 20:36 rcp

再回过头来谈谈锁定系统这件事吧! 既然刚刚谈到了 immutable flags, 何不试着把整
个 /sbin 和 /bin 都设成 schg flag 呢 !? 这会给想 crack你系统的人一点小挫折。
(假设你的系统也正以适当的 securelevel 咦髦?

# chflags schg /bin/*
# chflags schg /sbin/*

不过 /sbin 可能被改成别的名字,再重新创造一份新的 /sbin ,所以改变 /sbin 与
/bin 的 schg flag 是很合理的想法,我们可以依照以下的方式改变 /sbin 和 /bin
的 schg flag:

# chflags schg /bin/*
# chflags schg /sbin/*

这些 schg flag 的档案会让你在 "make world" 时有问题。
("make installworld" 也是)

无论如何 ,最好是以 single user 模式来 "make world"。有关 "makr world" 的相
资讯, 还有为什麽要这麽做, 到下面这个网页来看看:



现在你已经适当的锁定你的系统, 也以只跑必要的的 service, 而档案系统也适当的
mount 上来, 且也以适合的 kernel securelevel 咦髦小?
与以上所述的相关 man pages 有: init(8), chflags(1), sysctl(8)。

o Logging

系统纪录是很重要的。如果你的统被人攻击, 透过它你可以找到一些蛛丝马迹。Unix的
标准 log 动作是透过 syslogd(8) 来达成的。它从 /etc/rc 中被启动, 一直执行到系
统关机为止。你可以用以下的方式确定你的系统上是否正在执行 syslogd:

$ ps -axu | grep syslogd

Syslogd 会在启动时读取 /etc/syslogd.conf。这个档案很重要, 因为它告诉 syslogd
要纪录那些东西, 而这些东西又该放在那里。你也许想看看 syslod 和 syslod.conf
的 man pages:

$ man syslogd ; man 5 syslog.conf

既然 Unix 当初就是设计作为网路作业系统, syslogd 可以而且预设值也接受其它系统
的纪录。它自己也是可以把纪录透过网路送到其它的电脑去。想当然耳, 它可以纪录下
自己系统发生的每件事 - 而这也正是预设值。因为 syslogd 使用 UDP - 所以资料是
可以被伪造的。你至少可以作一件事: 不要让你的 syslogd 接受来自其它电脑的纪录
讯息。在 /etc/rc.conf 加个 "-s" 就可以了:

syslogd_flags="-s" # Flags to syslogd (if enabled).

如果你有接受特定机器之纪录的必要 (像是你的 router, 或是 web server), 使用
"-a" 来指定特定的 hosts, domains, 或 subnets。
下次你重新启动你的系统时, syslogd便会拒绝来自其它地方的纪录讯息。如果有人尝
试送资料进来, syslogd 将会加以纪录。

如果你不想重新启动你的系统, 那麽只要把 syslogd kill -9, 然後再以 root 的身份
启动 syslogd 便可以了。记得加上 "-s"这个参数。
如果有人尝试攻击你的系统而且失败了, 你的系统纪录便不会被伪造。但如果你的系统
己经被攻陷了, 而且 /var/log 整个被干掉了呢 !?还是有方法可以防止的。 其一便是
在你的网路系统中再架一台机器拿来纪录整个网路中发生的事, 而且也不要再干其它的
事了。除了 UDP port 514 之外, 其它的也都不用再开了。这样子一来你便可以纪录下
所有机器 (routers, firewalls, serves, workstations) 发生的所有事。你可以只送
敏感的讯息给它, 或者任何你觉得重要的。这台机器可以是老旧 486, 但有颗大大的硬
碟。记得要设定好正确的 "-a" 选项, 免得搞出没收到纪录的乌龙事。你也可以接台老
旧的点阵印表机给它, 以印出敏感的事件(像是失败的登入尝试)。如果你把系统纪录印
到纸上, 一位攻击者要清除它是很困难的(除非有内奸, 哈哈!)。还有其它的方法,例如
透过 serial port (cuaaN) 或是 parallel port (lpN) 送出纪录到别台机器上。

每个人都有不同的记录需求。但是有一件事我通常会做的是在 /etc/syslog.conf 加入
这一行:

auth.* /var/log/authlog

FreeBSD 出厂时便包含了 newsyslog。这玩意会定时压缩纪录档并清除掉旧的纪录。设
定档位於 /etc/newsyslog.conf - 请看一下 man page 以得到更多的资讯:

% man newsyslog

不像 syslogd, newsyslog 不是一直都在执行的。它是从 crontab 启动的:

% grep newsyslog /etc/crontab
0 * * * * root /usr/sbin/newsyslog
%

你可以修改 /etc/newsyslog.conf 以符合你的需求。我通常会改变它预设的档案模式,
从 664 改成 660 - 因为没有必要让一般的使用者去查看你的系统纪录。你应该这麽
做:

# cd /var/log
# chmod g-w,o-r * ; chmod a+r wtmp

这会防止一般使用者读取纪录档, 除非它们在适当的 group (wheel 或之类的)。还有,
记得把记录档的 group 都改成 wheel -- 这纯粹只是为了方便: 如果你是在 wheel 这
个 group; 你当然是可以 su(1) 到 root 然後读记录档。但是这麽做以後你便可以直
接读记录档了, 岂不方便乎!?
你还要在 /etc /newsyslog.conf 中加入 "root.wheel":

/var/log/maillog root.wheel 640 7 100 * Z
/var/log/authlog root.wheel 640 7 100 * Z
/var/log/messages root.wheel 640 7 100 * Z

这会在记录档达到 100K 时将它压缩并加以编号, 将 mode 改成 640, chown 成
root.wheel, 并将旧的记录档干掉 - 这就是我们要的。

当然,标准的 Unix 还有其他不同的 syslog 程式可供选择,其中之一是 CORE EDI 的
ssyslog (secure syslog). 可以在以下的地方找到:



另外还有 nsyslog (new syslog),这是写 bpfilter 那一伙人写出来的,你可以在
~avalon/nsyslog.html 找到这个程式。

不管你选用那一种程式 (标准的 syslog , ssyslog ,或 nsyslog),你应该也去看看
一些帮你分析系统 log 的程式,帮你省下去用 grep 查询 log file 的麻烦。

其中之一是 logcheck , 可以在这个地方下载:
http://www.psionic.com/abacus/abacus_logcheck.html

另外一个类似的程式叫做 logsurfer , 你可以从这个网页下载:



o Misc. hints and tips

o LKM

在正式提供服务的系统上, 也许该关掉 LKM。为什麽? 请看:
Phrack Magazine Volume 7, Issue 51 September 01, 1997, article 09
要关掉 LKMs, 在 kernel 设定档中加入这一行:

options NOLKM


o Portmap

FreeBSD 出厂的预设值会将 portmap 这项功能打开。如果你不需要它的话,把它关掉。
如果你没有跑任何需要呼叫 RPC 的程式的话,你就不需要跑这个程式。如果要关掉
portmap 这个程式,你可以去修改 /etc/rc.conf , 把

portmap_enable="YES" # Run the portmapper service (or NO).

改成

portmap_enable="NO" # Run the portmapper service (or NO).


o Sendmail

FreeBSD 出厂的预设值也会执行 sendmail 的功能。从很久以前 sendmail 就以不安全
且漏洞百出闻名。最近人们努力的将 sendmail 中的错误清除,但是由於 sendmail是一
个很肥大的程式,要将所有的错误都抓出来相当的困难。换句话说:如果你不需要它的话
,最好把它关掉。如果你真的需要它的话,最好到 sendmail 的网站去看看有没有新的
patches 或是 hacks, sendmail 的网站在 。
此外,如果你的 sendmail 版本是 8.8 以後的版本,请设定好你的系统,以防止 spammer
利用你的系统去干坏事。设定 anti-spam 的资讯可以在
下找到。

如果你决定要把 sendmail 关掉的话,只要去修改 /etc/rc.conf (没错,又是它)中的:

sendmail_enable="YES" # Run the sendmail daemon (or NO).

改成

sendmail_enable="NO" # Run the sendmail daemon (or NO).


o Ports and Packages

在一台高安全性的系统上, 最好不要使用 ports 或 packakges。 你不会真正知道是不
是安装 suid 的程式进你的系统 -- 而且你不会想再多这些 suid 的东西了, 相信我。
管你在 pkg_add 时可以使用不同的选项(如 "-v" 或 "-n"), 最好还是自己来: 抓回
它的 source code, 自己 compile, 再手动安装完成。

o Filesystem quota

如果你的系统是 "shell" type server,你可能希望设定使用者的 quota (可用空间)。
如此一来可以保护你的系统免受 Denial of Service 攻击方式的侵扰(不论是有意或
是无意的)。在未设定 quota 的系统上使用者可以随意的灌爆你的硬碟。要把 quota
这项功能打开,你可以修改 /etc/rc.conf 中的这项设定:

check_quotas="NO" # Check quotas (or NO).

改成

check_quotas="YES" # Check quotas (or NO).


请先看看以下的 man page,这些文件说明如何使用 quota 的各项设定,并且有一些设定
的例: quotaon, edquota, repquota, quota
请确定在 /etc/fstab 中有加入 "userquota" , 详见 man 5 fstab。


o Crontab

如果你使用了 /etc/crontab 的话,这项功能有可能提供入侵者一些额外的资讯。
请确定你做过 "chmod 640 /etc/crontab"


o BPF

BPF 是 berkeley packet filter 的缩写,要使用这项功能前你必须修改 kernel,以达
成监听网路的目的。像 tcpdump 和 NFR 这些程式都使用 BPF。然而 BSD的监听程式
也都透过 BPF 来达成,如果有人拿到你系统的 root 权限的话,在系统上设定 BPF 功
能反而帮助他们更容易的监听你的网路。如果没有必要的话,不要设定 kernel 中 BPF
的功能。 FreeBSD 出厂的设定值是将这个功能关闭起来的。


o CVSup, CVS, 等等

如果你是使用 CD-ROM 安装你的系统的话,很有可能当你拿到你的 CD-ROM时,已经发现
某些程式有错误存在了。在大部份的情况下(我们希望如此),这些错误与系统安全无关
。然而,我建议你将你的系统升级到最新的 -current (或是 -stable,视你的喜好而定)
版本。如此你可以确定你系统上的的是最新版本的系统原始码。
你需要的资讯在这边可以找到:



在更新你作业系统的原始码後你必须去 "make world",详细的文件在:




o SSH

使用 ssh 以代替 telnet, ftp, rlogin, rsh 等的重要性, 再怎麽强调都是不够的。
对於使用慢速线路的人 (dial-up, 56K frame), ssh 有 -C 选项:

-C Requests compression of all data (including stdin,
stdout, stderr, and data for forwarded X11 and
TCP/IP connections). The compression algorithm is
the same used by gzip, and the "level" can be con-
trolled by the CompressionLevel option (see below).
Compression is desirable on modem lines and other
slow connections, but will only slow down things on
fast networks. The default value can be set on a
host-by-host basis in the configuration files; see
the Compress option below.
将资料压缩後再传出去, 包括了 stdin, stdout, stderr
还有透过 X11 还有 TCP/IP。压缩的演算法同 gzip, 而且
可以指定压缩的 level。对於 moden users 和使用慢速线
路的人, 这功能是不错的。 但有高速线路的人, 这麽搞只
会拖慢速度。在主机对连时可以设预设值, 请再参照文件。

这会让你用起来快一点 :) 总之就是用 SSH 就对了啦! 拜, 拜, 使用 ssh。 如果
你硬是不信邪, 再也没什麽安全措施可以帮助你了 !!

o Related URLs

FreeBSD Hardening Project:


FreeBSD ipfw Configuration Page:
~pgilley/freebsd/ipfw

FreeBSD Security advisories:
ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/

FreeBSD Security web page:
http://www.freebsd.org/security/security.html

Security tools in FreeBSD:


o Thanks

对於这份仍在赶工的文件我有许多的感谢。你的批评, 指教, 才让这份文件得以问世。
(
)
本文出自: 作者: (2001-08-24 10:00:00)
 
  o 前言
o 这份 HOW-TO 是必要的吗? 
FreeBSD 是一个非常安全的作业系统。也正因为它的 source code 是可以免费的取得,
这个 OS 长久以来不断的有人改进加强。管 FreeBSD 一出厂就非常安全, 但是仍然
有更多加强安全性的措施, 来满足"偏执狂"的你 :) 这份 HOW-TO 会教你一些步骤, 以
更加强你机器的整体安全。

o 这份文件会说明 tripwire, tcp_wrappers, cops, satan, 和其它的工具吗?

除了 SSH 之外, 不会。这是一份针对 FreeBSD 的文件 - 除此之外, 已经有很多文件
说明上述的工具了。目前呢, 我只想关心的是关於 BSD 的部份。

o 谁要读这份 HOW-TO?
任何想让他的系统更安全的人。这份 HOW-TO 包含了一些很基本的步骤, 和某些很杂
的步骤。如果你有任何的疑问, 或者想要加以补充, 请 eMail 到维护人 jkb@best.com
又, 管大部份的内容是针对 FreeBSD 的, 但仍然会套用到其它的 Unix OSes 上面。
(特别是 OpenBSD 和 NetBSD)

o 这份 HOW-TO 还有其它语言的版本吗 ?
就我所知, 有俄语版:
http://www.etrust.ru/osa/security.html
和中文版:


o TODO:
将包含 /etc/login.conf 和 login classes
将提及使用 X 的场合
将会有 html 版

o 网路
o inetd (Inet Daemon)
网路在系统安全上扮演了一个很重要的角色。FreeBSD 的根基是有着内建网路功能, 且
具有最稳最快的 TCP/IP stacks 的 4.4BSD。这个 stack 支援了非常多的协定像是
telnet, ftp, talk, rsh 等... 这些 service 的的主设定档便是 /etc/inetd.conf。
要编辑这个档, 请输入 "vi /etc/inetd.conf" (在这个例子里, 我使用 vi 。你可以
使用其它你较为上手的编辑器。或许你可以试试 pico)。如果你要使用 pico, 请在启
动它时加上 -w 选项:
-w 关掉自动断行。(因此可以容许超过 80 字元的行存在)

这选项在编辑 /etc/inetd.conf 时非常有用。
当然了, 你也可以使用 ee - 它随着 FreeBSD 一起 "出厂" 的, 而且也是 root 预设
的编辑器。不过, 请再 "echo $EDITOR" 确认一次。 开启了这个档案後, 你可以看
到里面怎麽描述每个 service 怎麽启动, 要以那位使用者执行等等的资讯。(man 5
inetd.conf)既然这个档案是许多 internet service 的主要设定档, 好好的设定它便
是一件十分重要的事。你要关掉一个 service的话,只消在那一行前面加个 "#" 符号。
基本的概念是, 关掉些你不熟悉的 services - 如果你不知道那个 service 是啥, 或
者不知道它可以干啥。理想状态下, 你不须要把所有的 service 都打开。例如, 你的
器只是要跑 web server。这种情况下, 你只要启动 ssh 和 httpd 便够了。关於啥是
ssh, 下面会说明。如果你啥 service 都不想跑, 最直接乾脆的方法是-关掉 inetd。
做法很简单, 只要编辑 /etc/rc.conf 并且把

inetd_enable="YES"

改成

inetd_enable="NO"

就可以了。
如此一来没人可以 telnet, rlogin, 或 ftp 到你的电脑。
如果你决定要启动你的 inetd 的话, 记得启动 log 选项, 并提高一个 service 每分
钟启动的上限数目。(预设值是 256, 我建议提高到 1024-自行参照下面解说调整吧!)
为什麽要这麽做呢...? 就 modem user 或是低速专线用户是没什麽差别。但高速线路
的人, 上限值太低会蹦出一个 DoS attack(Denial of Service)。某个坏心的人可以简
单的用一个 shell script 同时搞出超过 256 个 connections, 这麽一来你的 inetd
会很不幸的阵亡。换句话说, 如果你想让每分钟每个 service 可接受的connection 数
多点, 记得做如下的设定, 不然来个坏心的人就可以搞垮你的电脑。因此, 在这行

inetd_enable="YES"

下面的

inetd_flags=""

要改成:

inetd_flags="-l -R 1024"

这会将连线的动作都 log 下来(-l 参数)而且将同时最大连线数从预设的 256 增加到
1024。你还须要对你的 /etc/syslog.conf 作些修改, 这些等会儿会提到。

o SSH

在以下提到的案例中, 你完全不须要 run inetd。例如, 如果你只有跑 web, news, 或
是 nfs server, 那麽就没有必要在你的机器上再跑其它的services。但是你一定会问,
"我要怎麽控制我的机器啊!?" 嗯嗯, 所以现在要介绍 SSH。你可以透过 SSH (Secure
Shell) 来登入你的机器。Secure Shell 当初便是设计来取代 rsh, rlogin 等其它的
Berkeley r* 命令。相信你很快就会了解 SSH 是如何有用,而且开始使用它,来代替其
它的程式像是 telnet 和 ftp。SSH 具有很多功能,但是最为人知的是, 它的加密通讯
方式, 也就是防止你的密码和资料以明码的方式在网路上传输。如果你使用 telnet,你
的通讯内容可能会被"窃听": 传输中的资料被改变, 通讯内容被看到。(不是有 S/Key
可以解决吗? 很不幸的, 它还是有着插入资料和连接时被破解的问题) 我希望你可以完
全的关掉 inetd 而使用 SSH。如果你认为完全不靠 inetd 来启动某些 services,是完
完全全不可能的事, 那麽希望你至少启动 log 功能, 而且要增加每分钟同一个 servi-
ce 可启动的次数。 (原因上面有提到)
你可以从 ftp://ftp.funet.fi/pub/unix/security/login/ssh 下载 SSH。
若你想要更简单的方法:

# cd /usr/ports/security/ssh
# make install

如果你有不是使用 Unix 的使用者, 那麽可以从下面的站台抓到 win32 SSH 程式:
~ci2/ssh/
~roca/ttssh.html

~cigaly/ssh
SecureCRT from 


o inetd (part II)

o telnetd

好吧, 你仍然执意要使用 inetd。那麽我们来看看在 inetd.conf 有那些选项, 可以增
进你的系统安全。在攻击某系统之前, 攻击者都会先收集该系统的相关资讯。就 teln-
etd 而言, 你可以试试在 telnetd 那行後面加个 -h:

telnet stream tcp nowait root /usr/libexec/telnetd telnetd -h

从 telnetd 的 man page 可以知道:

-h Disable the printing of host-specific information before login
has been completed.

当有很多管道可以获得系统资讯的同时, 这招和下面的那招是个不错的解决方案。如果
你认为跑 telnet daemon 是没有必要的, 那麽只消加个 "#" 在该行的最前面就行了:

#telnet stream tcp nowait root /usr/libexec/telnetd telnetd

有个极不错的措施是, 你可以拒绝没有完整 FQDN 的人来连线。要做到这点, 也只要加
个 -U 选项到 telnetd 後面:

telnet stream tcp nowait root /usr/libexec/telnetd telnetd -h -U

这是个小动作, 但是对你的系统安全有莫大的助益。

o ftpd

现在来看看 ftp。 对於 ftp FreeBSD 已经做了一些 log 的动作 。 可以看到在
/etc/inetd.conf 里面 ftpd 那一行已经加了 "-l"。然而, 你还是要设定你的syslogd
, 使它可以接受 ftp daemon 产生的 log。从 man page 可以得知:

-l Each successful and failed ftp(1) session is logged using syslog
with a facility of LOG_FTP. If this option is specified twice,
the retrieve (get), store (put), append, delete, make directory,
remove directory and rename operations and their filename argu-
ments are also logged. Note: LOG_FTP messages are not displayed
by syslogd(8) by default, and may have to be enabled in syslogd(8)'s
configuration file.
每个成功或是失败的 ftp 登入尝试, 都会以 LOG_FTP 机制纪录起来。如
果这个选项被指定了两次, 所有的下载 (get), 上载(put), 新增, 删除,
建立目录, 及更名的动作和档案名字都会被纪录下来。 又: LOG_FTP 讯
息预设是不会被 syslogd(8) 纪录下来的。你还要在 syslogd(8) 的设定
档里面启动这个功能才行。

让我们开启 syslogd 纪录 ftpd log 的功能吧~ 这个档案是 /etc/syslog.conf (别忘
了顺便看看 man 5 syslog.conf)。把下面这一行加到这个设定档里:

ftp.* /var/log/ftpd

也不要忘了执行这个指令 "touch /var/log/ftpdlog", 因为 syslogd 不能写入到一个
没有被开启过的档案。如果你想要你的 ftpd 提供你更多的 log 讯息, 那麽就在 ftp
那一行多加个 "-l" 吧:

ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l -l

如果你想要确定你的使用者们都用 scp (Secure Copy, 附属在 SSH 里面), 但是又想
要提供 anonymous ftp 服务, 也只消加个 "-A" 在 ftp 那行後面就行了:

ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l -A

你也可以编辑 /etc/ftpwelcome, 说明目前接受 anonymous ftp 登入, 但是系统内的
使用者就得使用 rcp 了。如果你有提供 anonymous ftp, 你可以使用 -S 选项来记录
传输的情形:

ftp stream tcp nowait root /usr/libexec/ftpd ftpd -A -S

o fingerd

Finger 服务预设值还算安全: 它不容许不带 user name 的 query。这是一件不错的事
(tm)。然而, 就是有些人无论如何也不想 run fingerd。这种情形下, 你只要简单的给
它加个 "#" 在这行的最前面就可以了。又, 你想要 log 住谁来 finger 的话, 加个
"-l" 也就行了:

finger stream tcp nowait nobody /usr/libexec/fingerd fingerd -s -l

Fingerd 产生的 log 资讯预设是写到 /var/log/messages。如果你想要这些资讯写入
到特定的档案里去, 那麽就在 /etc/syslog.conf 加入这一行:

daemon.notice /var/log/fingerd

/* !fingerd anyone? */

$ man 5 syslog.conf

除了 ftp, telnet 和 finger 之外, 你实在不须要在 /etc/inetd.conf 中再多启动任
何东西了。通常我都会关掉 talk 及 comsat等我个人不须要的东西。如同我之前讲的,
如果你不知到某个 servcie 是干嘛用的, 而且你也不须要它, 那麽就关掉它。一些和
网路有关而且很有用的 man page 是: inetd, ftpd, telnetd, fingerd, syslogd,
comsat, talkd, rshd, rlogind, inetd.conf。并且记得要看 man page 的"SEE ALSO"
部份, 以获得更多的相关资讯。

o ipfw (IP FrewWall)

IP FireWall 做的是 packet 过滤的工作。没错, 就是只有这样。然而, 你要考虑的事
是, 你的 kernel 要有支援 ipfw。 通常在我管的机器上, 我都会重编核心使其支援
ipfw。大概看起来是这样:

options IPFIREWALL #finger the net
options IPFIREWALL_VERBOSE #log the net
options IPFIREWALL_DEFAULT_TO_ACCEPT

第一行表示最其本的 IP FireWall 支援。第二行让 ipfw 可以把接受或拒绝 packets
的纪录 log 起来。第三行非常重要, 让 ipfw 预设值是接受任何地方来的 packets 。
如果你不这样做, 预设值拒绝任何地方来的 packets。我个比比较喜欢後者, 但我又认
为在我自己的工作站上, 或一个让人登入的工作站, 预设拒绝任何 packets 不是一件
太好的事。

********** NOTE ************
如果你搞不清楚自己在做啥事, 那就不要用这个选项。
就设定 firewall 而言, 这是不甚正确的。预设任何东西都该被挡掉才是正确的。如果
你是要建置一台高安全性的系统, 或一台 firewall 的话,那就千万不要加入这个选项:

options IPFIREWALL_DEFAULT_TO_ACCEPT

记住一件事: 要预设拒绝任接受任何 packets, 然後再加入 rule 来设定你想要接
受那些 packets。查看 /etc/rc.firewall 以得到更多的资讯。再一次提醒你, 不要使
用这个 option, 除非你只是想要防止 DoS attacks 或暂时把某些 port/network ban
掉。
*****************************

o log_in_vain

你也可以透过 sysctl 命令, 来改变一些有用的系统变数:

# sysctl -w net.inet.tcp.log_in_vain=1
# sysctl -w net.inet.udp.log_in_vain=1

这会把尝试向你的机器要求你没有的服务的 connections log 起来。例如, 如果你在
你的机器没有跑 DNS server, 而又有个人想要向你的机器要求 DNS 服务, 这时候你就
会看到

Connection attempt to UDP yourIP:53 from otherIP:X
(X 是某个 high port #)

你用 "dmesg" 命令就可以看到这一行。Dmesg 秀出的是系统的 kernel message
buffer。然而, 这个 buffer 的空间是有限的, 所以系统也会把这些讯息写入到
/var/log/messages 里面去:

# tail -1 /var/log/messages
Jun 12 19:36:03 ugh /kernel: Connection attempt to UDP yourIP:53 from
otherIP:X

o final notes
理论上呢, 你的系统现在已经比你装好它时更安全些了。你现在可以做一些事来确定你
目前的更动:

$ netstat -na | grep LISTEN

这会告诉你那些 service 在那些 port 跑。越少越好 :) 又, 再跑一些其它的 port
scanners (strobe, nmap) 来找出你开了那些 port。
而要确要你的 syslogd 已经开始纪下你刚刚想要 log 的事件, 可以这麽做:

# cd /var/log
# tail -10 fingerd ftpd messages

在 log 档里面没看到任何东西的话, 记得重新启动 inetd 和 syslogd:

# kill -HUP `cat /var/run/syslog.pig` `cat /var/run/inetd.pid`

o Filesystem

既然 Unix 把什麽东西都当作档案来看待, 好好的保护你的档案系统便是很重要的事。
有件事是在你安装作业系统前便要完成的: 必须要计划并设计好你的 partition 该怎
麽切割。有几个很重要的原因让你要这麽做: 一个是你可以 mount 不同的档案系统以
赋与不同的选项 (下面有几个例子)。别一个是,如果你想要把你的 filesystem export
出去, 你须要更加细微的控制。如果你是一个从 Linux 转入 FreeBSD 的使用者, 你会
发现 Linux 是把任何东西都往 root partition "/" 塞, 而 FreeBSD 预设便要 "/",
"/usr", 和 "/var"。这也使得要使用如 dump 般的工具较容易。且让我们来讨论 se-
curity 吧! 有一件事我通常会做的是, 我会把一般 users 可以写入的 partition 分
开来割, 而这些 partitons 便可以用 "nosuid" 的方式来 mount。从 mount 的 man
page 可以知道:

nosuid Do not allow set-user-identifier or set-group-identifier
bits to take effect. Note: this option is worthless if a
public available suid or sgid wrapper like suidperl is
installed on your system.

让 suid 或 sgid bit 失效。又: 对於像 suidperl 这些公开使用
的程式, 设这个选项便没用。

因此你会有个 partition 给一般使用者使用: /home 或 /usr/home。然後你可以另外
开个 partion 给 /var/tmp 然後再把你的 /tmp 指到这里:

# rm -rf /tmp
# ln -s /var/tmp /tmp

你可以参考这个例子:

# cat /etc/fstab
# Device Mountpoint FStype Options Dump Pass#
/dev/sd0s1b none swap sw 0 0
/dev/sd0s1a / ufs rw 1 1
/dev/sd0s1g /usr ufs rw 2 2
/dev/sd0s1h /usr/home ufs rw 2 2
/dev/sd0s1f /var ufs rw 2 2
/dev/sd0s1e /var/tmp ufs rw,nosuid 2 2
proc /proc procfs rw 0 0

现在你可以确定一般 users 可以写入的目录不是以 "-nosuid" 的方式被 mount, 就是
没有可以写入。现在你还要关心的就是 /var/spool/uucppublic"。
你可以把 "/var" 以 "-nosuid" 的方式来 mount , 或下这个命令:

# chmod o-w /var/spool/uucppublic


如果你想要找出你所有的可写入目录, 下这个命令:

# find / -perm -0777 -type d -ls

如同 man page 指出的, 具有 suid/sgid 的程式会让你的 nosuid 失效。找出那些程
式是 suid 或 sgid 的吧:

# find / -perm -2000 -ls
# find / -perm -4000 -ls

同时你不止可以用 "-ls" 而只是知道有那些程式。你可以把不是很有用的程式 "chmod
000"。像是 uustat, uucico 等, 如果你从来不碰 uucp 的话。或是 ppp 和 pppd, 如
果你绝不会用到他们。又, 你不会去用到印表机的话, 把 lpr lprd 也 chmod 000 吧!
也许改天会有个人写个 shell script 来问你那些东西要 chmod 000 掉。

现在你也许想问, 有什麽方式可以防止攻击者重新以非 "-nosuid" 的方式 mount 你的
filesystem ? Well, 没有, 除非你改变你的 securelevel。

o securelevel

FreeBSD kernel 有个观念叫 securelevel。当还有人在争论这是不是够完美时,这个
机制已经够防止大部份的 "script kiddiez"。Securelevel 是指你的 kernel 在执行

的安全等级。每一个等级具有不同的保护和检查机制。这些是 init(8) 的 man page:

The kernel runs with four different levels of security. Any superuser
process can raise the security level, but only init can lower it. The
security levels are:
Kernel 可以以四种不同的安全等级来执行。任何 superuser process 可以提高安全
等级, 但是只有 init 可以降低它。这四种等级分别是:

-1 Permanently insecure mode - always run the system in level 0 mode.
永远不安全模式 - 切换到 level 0 吧!

0 Insecure mode - immutable and append-only flags may be turned off.
All devices may be read or written subject to their permissions.
不安全模式 - "不可更动"和"只能附加"这两个旗标(flag)可以被改变。所有的
devices 可以照着它们的读写权限被读写。

1 Secure mode - the system immutable and system append-only flags may
not be turned off; disks for mounted filesystems, /dev/mem, and
/dev/kmem may not be opened for writing.
安全模式 - "不可更动"和"只能附加" 的旗标不能被取消; mount 上来的档案系
统, /dev/mem, 和 /dev/kmem 不能写入。

2 Highly secure mode - same as secure mode, plus disks may not be
opened for writing (except by mount(2)) whether mounted or not.
his level precludes tampering with filesystems by unmounting them,
but also inhibits running newfs(8) while the system is multi-user.
高安全模式 - 和安全模式一样, 又多加了不管硬碟有没有被 mount 起来,
除了 mount(2) 之外都不能写入。它防止一个档案系统在 umount 的时候被
搞乱。而且在这个等级也禁止在 multi-user 时执行 newfs(8)。

如果安全等级最初是 -1, 那麽 init 就会保持原状。否则在 single user mode 时,
init 会把安全等级调到 0, 而在 multiuser mode 时会以 1 来跑。如果你希望在
multiuser 模式是以等级 2 在跑, 你可以先进入 single user mode, 编辑 /etc/rc,
使用 sysctl 来更动。

若是你的系统只拿来跑 web server 之类的, 你可以放心的将 securelevel调高到2。
但若是你要跑 X server, 把你的 securelevel 调至 1 或更高会导致一些问题。因为
X server 必须要写入 /dev/mem 和 /dev/kmem, 而 securelevel 1 不允许你这麽做。
有一个解决的方法是, 在启动 X server 後再调高 securelevel。但我的意见是, 如果
你跑 X server 的话, 你已经有了其它的安全问题须要考量, 而不止是 securelevel。
以下这个指令会显示出你目前的 securelevel 设定值。

# sysctl kern.securelevel


如果要提高你的 securelevel:
# sysctl -w kern.securelevel=X
X 可以是 0, 1 或 2。

又在 securelevel 是 1 的话, 你在 "make world" 时也会有些问题。因为 "make
install" 时会在 kernel 上加上 immutable flag:

# ls -lo /kernel
-r-xr-xr-x 1 root wheel schg 1061679 Jun 30 01:27 /kernel

"schg" flag 会防止你安装新的 kernel:

nfr# id
uid=0(root) gid=0(wheel) groups=0(wheel), 2(kmem)

nfr# sysctl kern.securelevel
kern.securelevel: 2

nfr# rm -rf /kernel
rm: /kernel: Operation not permitted

nfr# mv /kernel /tmp/
mv: rename /kernel to /tmp//kernel: Operation not permitted

如果你在 securelevel 1 或 2, 那麽 schg flag 是不能被改变的。

# chflags noschg /kernel
chflags: /kernel: Operation not permitted

值得留意的是, /boot.config 可以改变你开机时的系统设定,要预防有心人篡改
你应该这麽做:

# touch /boot.config
# chflags schg /boot.config

你可以看看系统预设还有那些执行档是有 schg flag 的。

# ls -lo /sbin | grep schg
-r-x------ 1 bin bin schg 204800 Jul 19 20:38 init
# ls -lo /bin | grep schg
-r-sr-xr-x 1 root bin schg 192512 Jul 19 20:36 rcp

再回过头来谈谈锁定系统这件事吧! 既然刚刚谈到了 immutable flags, 何不试着把整
个 /sbin 和 /bin 都设成 schg flag 呢 !? 这会给想 crack你系统的人一点小挫折。
(假设你的系统也正以适当的 securelevel 咦髦?

# chflags schg /bin/*
# chflags schg /sbin/*

不过 /sbin 可能被改成别的名字,再重新创造一份新的 /sbin ,所以改变 /sbin 与
/bin 的 schg flag 是很合理的想法,我们可以依照以下的方式改变 /sbin 和 /bin
的 schg flag:

# chflags schg /bin/*
# chflags schg /sbin/*

这些 schg flag 的档案会让你在 "make world" 时有问题。
("make installworld" 也是)

无论如何 ,最好是以 single user 模式来 "make world"。有关 "makr world" 的相
资讯, 还有为什麽要这麽做, 到下面这个网页来看看:



现在你已经适当的锁定你的系统, 也以只跑必要的的 service, 而档案系统也适当的
mount 上来, 且也以适合的 kernel securelevel 咦髦小?
与以上所述的相关 man pages 有: init(8), chflags(1), sysctl(8)。

o Logging

系统纪录是很重要的。如果你的统被人攻击, 透过它你可以找到一些蛛丝马迹。Unix的
标准 log 动作是透过 syslogd(8) 来达成的。它从 /etc/rc 中被启动, 一直执行到系
统关机为止。你可以用以下的方式确定你的系统上是否正在执行 syslogd:

$ ps -axu | grep syslogd

Syslogd 会在启动时读取 /etc/syslogd.conf。这个档案很重要, 因为它告诉 syslogd
要纪录那些东西, 而这些东西又该放在那里。你也许想看看 syslod 和 syslod.conf
的 man pages:

$ man syslogd ; man 5 syslog.conf

既然 Unix 当初就是设计作为网路作业系统, syslogd 可以而且预设值也接受其它系统
的纪录。它自己也是可以把纪录透过网路送到其它的电脑去。想当然耳, 它可以纪录下
自己系统发生的每件事 - 而这也正是预设值。因为 syslogd 使用 UDP - 所以资料是
可以被伪造的。你至少可以作一件事: 不要让你的 syslogd 接受来自其它电脑的纪录
讯息。在 /etc/rc.conf 加个 "-s" 就可以了:

syslogd_flags="-s" # Flags to syslogd (if enabled).

如果你有接受特定机器之纪录的必要 (像是你的 router, 或是 web server), 使用
"-a" 来指定特定的 hosts, domains, 或 subnets。
下次你重新启动你的系统时, syslogd便会拒绝来自其它地方的纪录讯息。如果有人尝
试送资料进来, syslogd 将会加以纪录。

如果你不想重新启动你的系统, 那麽只要把 syslogd kill -9, 然後再以 root 的身份
启动 syslogd 便可以了。记得加上 "-s"这个参数。
如果有人尝试攻击你的系统而且失败了, 你的系统纪录便不会被伪造。但如果你的系统
己经被攻陷了, 而且 /var/log 整个被干掉了呢 !?还是有方法可以防止的。 其一便是
在你的网路系统中再架一台机器拿来纪录整个网路中发生的事, 而且也不要再干其它的
事了。除了 UDP port 514 之外, 其它的也都不用再开了。这样子一来你便可以纪录下
所有机器 (routers, firewalls, serves, workstations) 发生的所有事。你可以只送
敏感的讯息给它, 或者任何你觉得重要的。这台机器可以是老旧 486, 但有颗大大的硬
碟。记得要设定好正确的 "-a" 选项, 免得搞出没收到纪录的乌龙事。你也可以接台老
旧的点阵印表机给它, 以印出敏感的事件(像是失败的登入尝试)。如果你把系统纪录印
到纸上, 一位攻击者要清除它是很困难的(除非有内奸, 哈哈!)。还有其它的方法,例如
透过 serial port (cuaaN) 或是 parallel port (lpN) 送出纪录到别台机器上。

每个人都有不同的记录需求。但是有一件事我通常会做的是在 /etc/syslog.conf 加入
这一行:

auth.* /var/log/authlog

FreeBSD 出厂时便包含了 newsyslog。这玩意会定时压缩纪录档并清除掉旧的纪录。设
定档位於 /etc/newsyslog.conf - 请看一下 man page 以得到更多的资讯:

% man newsyslog

不像 syslogd, newsyslog 不是一直都在执行的。它是从 crontab 启动的:

% grep newsyslog /etc/crontab
0 * * * * root /usr/sbin/newsyslog
%

你可以修改 /etc/newsyslog.conf 以符合你的需求。我通常会改变它预设的档案模式,
从 664 改成 660 - 因为没有必要让一般的使用者去查看你的系统纪录。你应该这麽
做:

# cd /var/log
# chmod g-w,o-r * ; chmod a+r wtmp

这会防止一般使用者读取纪录档, 除非它们在适当的 group (wheel 或之类的)。还有,
记得把记录档的 group 都改成 wheel -- 这纯粹只是为了方便: 如果你是在 wheel 这
个 group; 你当然是可以 su(1) 到 root 然後读记录档。但是这麽做以後你便可以直
接读记录档了, 岂不方便乎!?
你还要在 /etc /newsyslog.conf 中加入 "root.wheel":

/var/log/maillog root.wheel 640 7 100 * Z
/var/log/authlog root.wheel 640 7 100 * Z
/var/log/messages root.wheel 640 7 100 * Z

这会在记录档达到 100K 时将它压缩并加以编号, 将 mode 改成 640, chown 成
root.wheel, 并将旧的记录档干掉 - 这就是我们要的。

当然,标准的 Unix 还有其他不同的 syslog 程式可供选择,其中之一是 CORE EDI 的
ssyslog (secure syslog). 可以在以下的地方找到:



另外还有 nsyslog (new syslog),这是写 bpfilter 那一伙人写出来的,你可以在
~avalon/nsyslog.html 找到这个程式。

不管你选用那一种程式 (标准的 syslog , ssyslog ,或 nsyslog),你应该也去看看
一些帮你分析系统 log 的程式,帮你省下去用 grep 查询 log file 的麻烦。

其中之一是 logcheck , 可以在这个地方下载:
http://www.psionic.com/abacus/abacus_logcheck.html

另外一个类似的程式叫做 logsurfer , 你可以从这个网页下载:



o Misc. hints and tips

o LKM

在正式提供服务的系统上, 也许该关掉 LKM。为什麽? 请看:
Phrack Magazine Volume 7, Issue 51 September 01, 1997, article 09
要关掉 LKMs, 在 kernel 设定档中加入这一行:

options NOLKM


o Portmap

FreeBSD 出厂的预设值会将 portmap 这项功能打开。如果你不需要它的话,把它关掉。
如果你没有跑任何需要呼叫 RPC 的程式的话,你就不需要跑这个程式。如果要关掉
portmap 这个程式,你可以去修改 /etc/rc.conf , 把

portmap_enable="YES" # Run the portmapper service (or NO).

改成

portmap_enable="NO" # Run the portmapper service (or NO).


o Sendmail

FreeBSD 出厂的预设值也会执行 sendmail 的功能。从很久以前 sendmail 就以不安全
且漏洞百出闻名。最近人们努力的将 sendmail 中的错误清除,但是由於 sendmail是一
个很肥大的程式,要将所有的错误都抓出来相当的困难。换句话说:如果你不需要它的话
,最好把它关掉。如果你真的需要它的话,最好到 sendmail 的网站去看看有没有新的
patches 或是 hacks, sendmail 的网站在 。
此外,如果你的 sendmail 版本是 8.8 以後的版本,请设定好你的系统,以防止 spammer
利用你的系统去干坏事。设定 anti-spam 的资讯可以在
下找到。

如果你决定要把 sendmail 关掉的话,只要去修改 /etc/rc.conf (没错,又是它)中的:

sendmail_enable="YES" # Run the sendmail daemon (or NO).

改成

sendmail_enable="NO" # Run the sendmail daemon (or NO).


o Ports and Packages

在一台高安全性的系统上, 最好不要使用 ports 或 packakges。 你不会真正知道是不
是安装 suid 的程式进你的系统 -- 而且你不会想再多这些 suid 的东西了, 相信我。
管你在 pkg_add 时可以使用不同的选项(如 "-v" 或 "-n"), 最好还是自己来: 抓回
它的 source code, 自己 compile, 再手动安装完成。

o Filesystem quota

如果你的系统是 "shell" type server,你可能希望设定使用者的 quota (可用空间)。
如此一来可以保护你的系统免受 Denial of Service 攻击方式的侵扰(不论是有意或
是无意的)。在未设定 quota 的系统上使用者可以随意的灌爆你的硬碟。要把 quota
这项功能打开,你可以修改 /etc/rc.conf 中的这项设定:

check_quotas="NO" # Check quotas (or NO).

改成

check_quotas="YES" # Check quotas (or NO).


请先看看以下的 man page,这些文件说明如何使用 quota 的各项设定,并且有一些设定
的例: quotaon, edquota, repquota, quota
请确定在 /etc/fstab 中有加入 "userquota" , 详见 man 5 fstab。


o Crontab

如果你使用了 /etc/crontab 的话,这项功能有可能提供入侵者一些额外的资讯。
请确定你做过 "chmod 640 /etc/crontab"


o BPF

BPF 是 berkeley packet filter 的缩写,要使用这项功能前你必须修改 kernel,以达
成监听网路的目的。像 tcpdump 和 NFR 这些程式都使用 BPF。然而 BSD的监听程式
也都透过 BPF 来达成,如果有人拿到你系统的 root 权限的话,在系统上设定 BPF 功
能反而帮助他们更容易的监听你的网路。如果没有必要的话,不要设定 kernel 中 BPF
的功能。 FreeBSD 出厂的设定值是将这个功能关闭起来的。


o CVSup, CVS, 等等

如果你是使用 CD-ROM 安装你的系统的话,很有可能当你拿到你的 CD-ROM时,已经发现
某些程式有错误存在了。在大部份的情况下(我们希望如此),这些错误与系统安全无关
。然而,我建议你将你的系统升级到最新的 -current (或是 -stable,视你的喜好而定)
版本。如此你可以确定你系统上的的是最新版本的系统原始码。
你需要的资讯在这边可以找到:



在更新你作业系统的原始码後你必须去 "make world",详细的文件在:




o SSH

使用 ssh 以代替 telnet, ftp, rlogin, rsh 等的重要性, 再怎麽强调都是不够的。
对於使用慢速线路的人 (dial-up, 56K frame), ssh 有 -C 选项:

-C Requests compression of all data (including stdin,
stdout, stderr, and data for forwarded X11 and
TCP/IP connections). The compression algorithm is
the same used by gzip, and the "level" can be con-
trolled by the CompressionLevel option (see below).
Compression is desirable on modem lines and other
slow connections, but will only slow down things on
fast networks. The default value can be set on a
host-by-host basis in the configuration files; see
the Compress option below.
将资料压缩後再传出去, 包括了 stdin, stdout, stderr
还有透过 X11 还有 TCP/IP。压缩的演算法同 gzip, 而且
可以指定压缩的 level。对於 moden users 和使用慢速线
路的人, 这功能是不错的。 但有高速线路的人, 这麽搞只
会拖慢速度。在主机对连时可以设预设值, 请再参照文件。

这会让你用起来快一点 :) 总之就是用 SSH 就对了啦! 拜, 拜, 使用 ssh。 如果
你硬是不信邪, 再也没什麽安全措施可以帮助你了 !!

o Related URLs

FreeBSD Hardening Project:


FreeBSD ipfw Configuration Page:
~pgilley/freebsd/ipfw

FreeBSD Security advisories:
ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/

FreeBSD Security web page:
http://www.freebsd.org/security/security.html

Security tools in FreeBSD:


o Thanks

对於这份仍在赶工的文件我有许多的感谢。你的批评, 指教, 才让这份文件得以问世。
(
)
阅读(1718) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:.bash_profile和.bashrc的什么区别

给主人留下些什么吧!~~