jul 31
一直以来,在 Solaris 和 Linux 下都习惯了 bash 的风格,比如命令补全、历史命令编辑、nohup 后台运行,等等。
现在基本上只使用 FreeBSD ,而 FreeBSD 默认的shell并不是 bash,bash 需要额外 ports 安装,而且 bash ports 是安装在 /usr/local/bin/bash 的,我一般都把 /usr/local 从根分区分离出去,这样的话,如果系统有问题需要进入单用户模式的时候,bash 是不可用的。
研究了一下,如果csh经过一定的设置,也是很好用的:
1、设置命令补全,修改 /etc/csh.cshrc 文件:
set autolist
2、显示类似 [dirk@trinity /usr/local/etc]# 这样的提示符,修改 /etc/csh.cshrc 文件:
set prompt = '[%B%n@%m%b %B%~%b%] #'
3、让 ls 命令显示目录的时候带 / 斜杠区分普通文件,修改 /etc/csh.cshrc 文件:
alias ls ls -F
4、让 csh 具有历史命令编辑功能,还是 /etc/csh.cshrc 文件:
bindkey "^W" backward-delete-word
bindkey -k up history-search-backward
bindkey -k down history-search-forward
5、最后,使用 script 命令替代 nohup 命令:
script -a script.log "command"
jul 31
FreeBSD 默认的 shell 是 /bin/csh,相对于 Linux 下广泛使用的 /usr/ports/shell/bash 来说,默认设置的 /bin/csh 使用起来不太友好。比如命令补全功能,需要这样的设置。
/bin/csh 的历史命令功能是非常强大的:
For example, consider this bit of someone's history list:
9 8:30 nroff -man wumpus.man
10 8:31 cp wumpus.man wumpus.man.old
11 8:36 vi wumpus.man
12 8:37 diff wumpus.man.old wumpus.man
The commands are shown with their event numbers and time stamps. The
current event, which we haven't typed in yet, is event 13. `!11' and
`!-2' refer to event 11. `!!' refers to the previous event, 12. `!!'
can be abbreviated `!' if it is followed by `:' (`:' is described
below). `!n' refers to event 9, which begins with `n'. `!?old?' also
refers to event 12, which contains `old'. Without word designators or
modifiers history references simply expand to the entire event, so we
might type `!cp' to redo the copy command or `!!|more' if the `diff'
output scrolled off the top of the screen.默认的 /bin/csh 只保存 100 条历史命令,并且当你使用同一个账号开启多个连接到同一台服务器的时候,最终保存的历史命令可能只有最后退出那次会话的命令,其他连接中使用的命令没有保存起来。通过设置以下参数可以让 /bin/csh 合并多连接状态的历史命令:
set history = 2000
set savehist = 2000 merge
可以将以上设置保存到 /etc/csh.cshrc 或者 ~/.cshrc。(更多信息请参考“man csh”)
jul 31
用于附件下载的几台服务器中,有一台是 I386 架构,今天发现网络响应很慢,但系统负载一点都不高,看了看 netstat -rm 发现:
6065/6656/6656 sfbufs in use (current/peak/max)
705762 requests for sfbufs delayed
295194 requests for I/O initiated by sendfile
原来系统的 nsfbufs 满了。 man tuning 后,发现主要是 sendfile(2) 系统调用需要占用 nsfbufs,而现在越来越多的应用开始依靠 sendfile(2) 来传送文件,比如 Lighttpd 等。而我在服务器上使用 Lighttpd 作为静态附件的下载服务,可见对 sendfile(2) 的调用非常之频繁(netstat -rm 中有70万次的请求被延迟,只顺利完成近30万次)。
由此,增大 nsfbufs 参数即可解决此问题,在 /boot/loader.conf 文件中设置:
kern.ipc.nsfbufs="32768"
注:
- AMD64 架构系统没有此问题;
- kern.ipc.nsfbufs 的值应根据系统实际情况调整;
- kern.ipc.nsfbufs 参数调整需要重启动系统;
jul 31
Unix 的 syslogd 记录的日志信息不包含年份,在 FreeBSD,Linux 下都是如此。如果系统的日志文件记录的时间跨度足够长(比如你的日志信息很少或者你的日志轮询尺寸设置的非常大),如果超过一年,那么就会发生无法辨识日志发生年份的问题。一般情况下,这算不得什么,但在某些情形下多少会引起麻烦。
FreeBSD 下有一个每天进行安全性报告的 /etc/periodic/daily/450.status-security 脚本,它的目的之一就是将 /var/log/auth.log 文件中属于昨天发生的失败、错误信息通过邮件方式发送给系统管理员。如果 auth.log 文件记录的足够长,超过一年,那么就会发生重叠问题,stats-security 脚本会发出错误的报告。
假设,一台 FreeBSD 主机在 2006 年 01 月 22 号托管到机房,在这一天,为了测试系统状态,做了很多可能从安全性上来说不太正常的操作,比如,你可能 telnet 到本地的 sshd,看到正常的连接信息后直接“quit”了,这个时候,/var/log/auth.log 会记录一条类似认证失败的日志条目。在此之后,这台主机非常稳定,很少发生登录操作,也没有受到任何攻击,这就使得 /var/log/auth.log 文件的日志量非常少,当时间跨过一年,到达 2007 年 01 月 23 号的早晨,系统每天发送的安全报告邮件中称,系统的 sshd 服务在昨天(也就是 01 月 22 号)受到了不安全的认证攻击,这个时候,绝大部分系统管理员不可能想到或者记起是去年自己的测试操作,正常的情况下,系统管理员会进行大量的安全检查,直到查出昨天的攻击来自哪里。如果这台主机是关键性的系统,或者属于非常重视安全性的组织,这个小小的误解也许会引起很大的误会或者损失。
这个问题,不能说是系统的漏洞,但多少算是 Unix 系统的缺陷,只是这个缺陷在一般情况下不太可能引起问题。目前有类似 syslog-ng 和 Sawmill 这样的针对 Unix syslogd 的改进系统,支持年份的记录。
jul 31
国内的ISP以及服务器托管机房(IDC)在网络上的限制越来越多,从先前的屏蔽扫描信号、禁止Traceroute,到现在开始中断长时间空闲TCP连接。
如果你SSH到远程服务器,长时间不操作的话,很容易被掐掉,这个东西真的很讨厌的,比如你在升级系统,正好升级脚本需要管理员手工确认一个东西,而你由于忙于其他事物疏忽这个东西,等你回过来,连接已经中断,没法操作,只能重新开启连接后重新开始。如果是必须一次完成的操作,这个时候会引起严重后果。
OpenSSH有一个 ClientAliveInterval 参数,在你的 sshd_config 配置文件中设置一个合适的值,比如:
ClientAliveInterval 15
就可以让 OpenSSH 服务器端在空闲的时候定时向客户端请求一个数据包。另外, man sshd_config 可以看到,这个参数只在 SSH protocol version 2 中有效(不过,为了安全起见,早就应该使用 SSH2 了)。
jul 31
FreeBSD 下有一个 rcorder 的命令,它打印出 /etc/rc.d/ 目录下脚本文件的启动顺序。从习惯上来说,我们可能以为 /etc/rc.d/ 下的脚本是通过类似名称排序的简单方式确定启动顺序的,其实不然,rc 脚本机制在其中起了非常重要的作用。
rc 脚本机制是通过在相应脚本中设置一定的标志来影响脚本的启动顺序,比如:REQUIRE、PROVIDE、BEFORE、KEYWORD 等,这些词的含义是显而易见的。REQUIRE 表示当前脚本会需要哪些服务先行启动;PROVIDE 表示当前脚本提供的服务名称,用于其他脚本依附;BEFORE 表示在哪些服务启动之前启动当前脚本。
当你的 /etc/rc.d/* 基本服务依赖通过 Ports 安装的服务先行启动的时候,这个排序机制非常有用。比如有一个 /usr/ports/dns/bind9-dlz 的软件,功能就是将 BIND 后端的域名信息保存到数据库,对于巨量域名信息服务器非常有用。这个时候,你需要让 PostgreSQL 服务在 /etc/named 服务启动之前就必须就位,否则,named 将无法连接 PostgreSQL,一直等待到超时,严重影响服务器正常启动。如果使用 rc 脚本机制,非常容易就能很好的解决。
首先,我们需要将 /usr/local/etc/rc.d/010.pgsql.sh 挪到 /etc/rc.d/pgsql,这是因为和 rcorder 相关的排序机制只能用在 /etc/rc.d 目录。然后我们编辑 /etc/rc.d/pgsql 文件中 rcorder 标志:
# PROVIDE: postgresql
# REQUIRE: LOGIN sshd
# KEYWORD: shutdown
# BEFORE: named
为了远程管理方便,我们让 PostgreSQL 在 sshd 之后启动。接着,我们需要修改 /etc/rc.d/named 的排序标志:
# PROVIDE: named
# REQUIRE: SERVERS cleanvar postgresql
# KEYWORD: shutdown
在 /etc/rc.d/named 脚本中的 REQUIRE 部分增加了在 /etc/rc.d/pgsql “PROVIDE”的名称:postgresql,这样,系统认为在启动 /etc/rc.d/named 之前需要预先启动 /etc/rc.d/pgsql 服务。
最后,你可以通过 rcorder /etc/rc.d/* 命令察看完整的服务启动顺序清单。
dec 01
FreeBSD 6.0 增加了一个 savecore 的服务,在系统崩溃时处理内存的 DUMP。但在某些从 5.4 升级上来的系统中,启动的过程中可能会有以下错误:
/etc/rc.d/savecore: WARNING: Dump device does not exist. Savecore not run.
这是由于 savecore 服务需要一个和系统物理内存相同大小的交换分区 (swap) 用于 DUMP,如果你的交换分区设置不合理,或者使用了文件系统作为附加交换区,savecore 服务就无法运行,报告以上错误。看来,分配内存的两倍作为交换区,平均分布到两块硬盘的方案是比较合理的。
dirk 发表于 2005-12-01 Thursdayfreebsd nov 21
在上篇 FreeBSD 6.0 Release 下的 cvsd-buildroot 问题 中,虽然知道了问题在于 devfs 上,但没有解决每次系统启动自动挂接 /export0/cvsd/dev 目录的问题。
研究了一下 devfs,可以通过以下方式实现系统启动自动挂接 /export0/cvsd/dev 设备目录问题,并保证正确的规则集:
1、先将设备目录自动挂接,将以下行添加到 /etc/fstab 文件中:
devfs /export0/cvsd/dev devfs rw 0 0
2、编辑 /etc/devfs.rules 文件设定我们自己的 devfs rules:
[devfsrules_cvsd_jail=10]
add hide
add path null unhide
add path zero unhide
3、编辑 /etc/rc.conf 文件,设定相应的 devfs 规则集:
devfs_rulesets="/etc/defaults/devfs.rules /etc/devfs.rules"
# Files containing devfs(8) rules.
devfs_set_rulesets="/export0/cvsd/dev=devfsrules_cvsd_jail"
# A list of /mount/dev=ruleset_name settings to apply
# (must be mounted already, i.e. fstab(5))
重新启动系统试验,That’s ok.
nov 18
系统从 5.4-Release-p8 升级到 6.0-Release 后,cvsd 的初始化工具 cvsd-buildroot 一直不能用:
[root@rednora ~]# cvsd-buildroot /export0/cvsd
creating directory structure under /export0/cvsd... done.
installing binaries... cvs.
locating libnsl.so... not found (probably not fatal)
locating libnss_compat.so... not found (probably not fatal)
locating /lib/ld-linux.so.2... not found (probably not fatal)
locating /lib64/ld-linux-x86-64.so.2... not found (probably not fatal)
locating ld-elf.so... /usr/libexec/ld-elf.so.1
locating libnss_compat.so.2... not found (probably not fatal)
locating libnss_files.so.2... not found (probably not fatal)
locating /usr/libexec/ld.so... /usr/libexec/ld.so
locating /usr/lib/ld.so.1... not found (probably not fatal)
locating nss_files.so.1... not found (probably not fatal)
installing libraries... ld-elf.so.1 ld.so libgnuregex.so.3 libmd.so.3
libcrypt.so.3 libz.so.3 libgssapi.so.8 libkrb5.so.8 libasn1.so.8
libcrypto.so.4 libroken.so.8 libcom_err.so.3 libc.so.6.
creating /export0/cvsd/dev devices... FAILED (unable to use devices)
adding users to /export0/cvsd/etc/passwd...getent: not found
getent: not found
getent: not found
getent: not found
.
getent: not found
getent: not found
getent: not found
making /export0/cvsd/etc/pwd.db...done.
fixing ownership... done.
chrooted system created in /export0/cvsd
if your cvs binary changes (new version) you should rerun cvsd-buildroot
研究了一下 cvsd-buildroot 脚本,发现问题在于为 cvsd 创建的 jail 中的 dev/null 和 dev/zero 设备文件失效。找了一圈,发现在 6.0 中加强了 devfs 的使用,需要把 /export0/cvsd/dev 加载为 devfs 才能用:
[root@rednora ~]# mount_devfs devfs /export0/cvsd/dev
但这么操作之后,发现所有设备文件都出现在了 /export0/cvsd/dev 目录中,而我们只是需要 null 和 zero,这就需要用到 devfs 的 rule 设置:
[root@rednora ~]# devfs -m /export0/cvsd/dev ruleset 10
[root@rednora ~]# devfs -m /export0/cvsd/dev rule -s 10 add hide
[root@rednora ~]# devfs -m /export0/cvsd/dev rule -s 10 add path null unhide
[root@rednora ~]# devfs -m /export0/cvsd/dev rule -s 10 add path zero unhide
[root@rednora ~]# devfs -m /export0/cvsd/dev rule -s 10 applyset
经过这些设置,cvsd 又恢复正常了!
@TODO:
这些信息在系统重启后会丢失,需要仔细研究 devfs 在 FreeBSD 系统中使用,添加到相应的启动脚本中。
Recent Comments