专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »Unix/FreeBsd » unix高级编程:Unix高级安全设置第四部分-FreeBSD系.. »正文

unix高级编程:Unix高级安全设置第四部分-FreeBSD系..

来源: 发布时间:星期二, 2008年12月9日 浏览:2次 评论:0
Unix高级安全设置第四部分-FreeBSD系列第四部分 总结

没有绝对安全的网络系统,网络信息对抗是一个长期的研究课题,安全问题是多种多样,且随着时间技术的变化而变化,而黑客的侵入手段也随之不断变化,所以安全防护也是非常重要的,保持清醒正确的认识,同时掌握最新的安全问题情况,再加上完善有效的安全策略,是可以阻止大部分的网络入侵,从而保持最小程度的经济损失。

第五部分 附录

5.1 Free BSD系列

FreeBSD 是一个非常安全的操作系统。也正因为它的 source code 是可以免费的取得,这个 OS 长久以来不断的有人改进加强。尽管 FreeBSD 一出厂就非常安全, 但是仍然有更多加强安全性的措施,这份 HOW-TO 会教你一些步骤, 以更加强你机器的整体安全。

5.1.1 网络

5.1.1.1 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 作些修改, 这些等会儿会提到。

5.1.1.2 SSH
在以下提到的案例中, 你完全不须要 run inetd。例如, 如果你只有跑 web, news, 或是 nfs server, 那么就没有必要在你的机器上再跑其它的services。但是你一定会问,\"我要怎么控制我的机器啊!?\" 嗯嗯, 所以现在要介绍 SSH。你可以透过 SSH (SecureShell) 来登入你的机器。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

5.1.1.3 inetd (part II)

好吧, 你仍然执意要使用 inetd。那么我们来看看在 inetd.conf 有那些选项, 可以增进你的系统安全。在攻击某系统之前, 攻击者都会先收集该系统的相关信息。就 telnetd 而言, 你可以试试在 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

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

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

每个成功或是失败的 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

5.1.1.5 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\"部份, 以获得更多的相关信息。

5.1.1.6 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 不是一件太好的事。如果你搞不清楚自己在做啥事, 那就不要用这个选项。

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

options IPFIREWALL_DEFAULT_TO_ACCEPT

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

5.1.1.7 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 messagebuffer。

然而, 这个 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

5.1.1.8 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`

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

5.1.1.10 securelevel
FreeBSD kernel 有个观念叫 securelevel。当还有人在争论这是不是够完美时,这个机制已经够防止大部份的 \"script kiddiez\"。Securelevel 是指你的 kernel 在执行时的安全等级。每一个等级具有不同的保护和检查机制。这些是 init(8) 的 man page:

Kernel 可以以四种不同的安全等级来执行。任何 superuser process 可以提高安全等级,但是只有 init 可以降低它。

这四种等级分别是:
-1 永远不安全模式 - 切换到 level 0 吧!
0 不安全模式 - \"不可更动\"和\"只能附加\"这两个旗标(flag)可以被改变。所有的devices 可以照着它们的读写权限被读写。
1 安全模式 - \"不可更动\"和\"只能附加\" 的旗标不能被取消; mount 上来的档案系统, /dev/mem, 和 /dev/kmem 不能写入。
2 高安全模式 - 和安全模式一样, 又多加了不管硬盘有没有被 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\" 的相信息, 还有为什么要这么做, 到下面这个网页来看看:

http://www.nothing-going-on.demo ... rld/make-world.html

现在你已经适当的锁定你的系统, 也以只跑必要的的 service, 而档案系统也适当的mount 上来, 且也以适合的 kernel secureleve

如果本文没有解决您的问题,请进老妖怪开发者社区提问

相关文章

读者评论

  • 共0条 分0页

发表评论

  • 昵称:
  • 内容: