<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>温室小花.技术.博客 --纯粹的unix技术博客 &#187; shell</title>
	<atom:link href="http://www.evanjiang.net.cn/archives/category/scripting_language/shell/feed" rel="self" type="application/rss+xml" />
	<link>http://www.evanjiang.net.cn</link>
	<description>红颜弹指老，刹那芳华，与其天涯思君，恋恋不舍，莫若相忘于江湖！</description>
	<lastBuildDate>Sun, 05 Sep 2010 14:51:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>unix常用指令及参数</title>
		<link>http://www.evanjiang.net.cn/archives/893.html</link>
		<comments>http://www.evanjiang.net.cn/archives/893.html#comments</comments>
		<pubDate>Wed, 08 Apr 2009 13:48:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[debian linux]]></category>
		<category><![CDATA[freebsd unix]]></category>
		<category><![CDATA[netbsd unix]]></category>
		<category><![CDATA[openbsd unix]]></category>
		<category><![CDATA[other linux]]></category>
		<category><![CDATA[redhat linux]]></category>
		<category><![CDATA[sco unix]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[sun unix]]></category>
		<category><![CDATA[suse linux]]></category>
		<category><![CDATA[www]]></category>
		<category><![CDATA[unix 常用命令 及参数]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=893</guid>
		<description><![CDATA[<p>


 <p>常用组合键
ctrl+h,backspace :删除前面的字符.
ctrl+u:删除一整行.
ctrl+c,del,break: 强行终止正在运行的程序.
ctrl+d:
常用指令
1.date:查看当前时间.
2.cal:查看某一个月的月历.
3.Finger 命令:显示一个用户的详细信息.
4.who命令:显示所有登陆用户.who an i
5.clear 命令:执行清屏动作.
6.echo 命令:将命令名后跟随的参数显示在屏幕echo hello </p>
<p>world
7.banner 命令:将命令名后跟的ACSSII字符串以大字的方式显</p>
<p>示在屏幕上banner hello
8.wc 命令:用于计算一个指定的文件中的行数单词及字符数:
   格式wc[-c(计算字符的数目)] [-l(计算行的数目)] [-w(计算</p>
<p>单词的数目)] filename
9.passwd 命令,用于修改口令.
10.man 命令:联机手册
六.shell的基本功能:命令解释器,程序设计语言.
shell的退出命令.
1.exit 主要用于退出B_shell
2.logout 主要用于退出C_shell
3.ctrl+d 用于退出各类shell
第三章 通信
内部通信
外部通信





下.
mail命令模式常用命令
 如有下页则显示,否则退出mail.
p      显示本邮件信息
d      删除当前邮件
n      显示下一个邮件
q      退出 mail,把末删除的邮件保存到个人邮箱中.
R    [...]]]></description>
			<content:encoded><![CDATA[<p style="float: left;margin: 4px;"><script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 160x600, 创建于 10-2-7 */
google_ad_slot = "8970910006";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p> <p>常用组合键<br />
ctrl+h,backspace :删除前面的字符.<br />
ctrl+u:删除一整行.<br />
ctrl+c,del,break: 强行终止正在运行的程序.<br />
ctrl+d:<br />
常用指令<br />
1.date:查看当前时间.<br />
2.cal:查看某一个月的月历.<br />
3.Finger 命令:显示一个用户的详细信息.<br />
4.who命令:显示所有登陆用户.who an i<br />
5.clear 命令:执行清屏动作.<br />
6.echo 命令:将命令名后跟随的参数显示在屏幕echo hello </p>
<p>world<br />
7.banner 命令:将命令名后跟的ACSSII字符串以大字的方式显</p>
<p>示在屏幕上banner hello<br />
8.wc 命令:用于计算一个指定的文件中的行数单词及字符数:<br />
   格式wc[-c(计算字符的数目)] [-l(计算行的数目)] [-w(计算</p>
<p>单词的数目)] filename<br />
9.passwd 命令,用于修改口令.<br />
10.man 命令:联机手册<br />
六.shell的基本功能:命令解释器,程序设计语言.<br />
shell的退出命令.<br />
1.exit 主要用于退出B_shell<br />
2.logout 主要用于退出C_shell<br />
3.ctrl+d 用于退出各类shell<br />
第三章 通信<br />
内部通信<br />
外部通信<1,电子邮件,2.即时通信<br />
一.即时通讯<br />
1.write 交谈命令 (半双工通信)<br />
格式 write student1<br />
ctrl+d 退出write<br />
Write协议:消息发送结束用O(结束)<br />
结束谈话用OO(结束并退出)<br />
2.mesg 消息开关命令.用于查询和开关本终端的消息接收状态.<br />
格式:mesg [-y] [-n]<br />
$ mesg 查询本终端当前的消息接收状态<br />
is y 可以接收消息<br />
is n 拒绝接收消息<br />
$ mesg n 设置关闭状态<br />
$ mesg y 设置打开状态<br />
3.talk 双向通信命令 (全双工方式)<br />
4.wall 广播信息命令<br />
二,电子邮件<br />
$ mail username  发送邮件<br />
$ mail                 接收邮件<br />
系统邮箱:在/usr/mail或/var/mail下,每个用户都有一个以其名字</p>
<p>命名的邮箱.例如:student8的系统邮箱可能为:/var/mail/student8<br />
个人邮箱:个人邮箱通常为用户自己的主目录(home)下的mbox<br />
<span id="more-893"></span><br />
文件.用户读过的邮件如果末删除或转存,则存放在个人邮箱中</p>
<p>.例如:student8的个人邮箱可能是:/home/student8/mbox<br />
1.发送邮件:<br />
$ mail student8<br />
给多个用户发送邮件<br />
a.$ mail student1 student2 student3 把用户列出来.<br />
b.$ mail TEACHER TEACHER为用户组名,即向属于TEACHER</p>
<p>组所有用记发邮件.<br />
c.$ alias usr_list student1 student2 student3给student1 student2 </p>
<p>student3等多个名字建立一个部的别名usr_list,该别名只在本</p>
<p>shell中起作用,退出shell后无效.<br />
$ mail usr_list<br />
把已有的文件作为邮件发送给用户:<br />
$ mail student8 < my_letter<br />
发邮件给不存在的用户:<br />
$ mail meizhegeren<br />
mail命令本身能正常执行,由于无有效的接收方,所以系统把邮</p>
<p>件退回到用户主目录下dead.letter中.<br />
2.接收邮件<br />
不带参数输入mial表示读取邮件.此时已进入出境mail命令模式<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
下.<br />
mail命令模式常用命令<br />
<cr> 如有下页则显示,否则退出mail.<br />
p      显示本邮件信息<br />
d      删除当前邮件<br />
n      显示下一个邮件<br />
q      退出 mail,把末删除的邮件保存到个人邮箱中.<br />
R     回复邮件<br />
!      执行shell命令.<br />
?      显示mail的内部命令.<br />
第四章 文件系统<br />
与目录相关的命令(pwd,cd,mkdir,rmdir,ls)<br />
与文件相关的命令(cp,mv,ln,more,rm)<br />
1.pwd 显示当前工作目录<br />
2.cd  改变当前目录<br />
3.mkdir 创建目录<br />
格式 mkdir dir_name<br />
4.rmdir 删除目录<br />
格式 rmdir dir_name<br />
     a.只能是空目录.<br />
      b.有写的权限<br />
一次操作多个目录<br />
- p 选项.在当前目录下逐级创建目录,也可以逐级删除目录.<br />
5.ls 显示目录<br />
$ ls -a 显示所有文件(以点开头的文件名是隐藏文件)<br />
$ ls -R 显示所有子目录的内容<br />
$ ls &#8211; l  能得到目录中的文件的详细信息.<br />
-:普通 d: 目录 c: 字符设备 b: 块设备 p:管道<br />
$ ls &#8211; C 以多列的格式列表,按列排序.<br />
$ ls &#8211; F 如果是目录,文件名后加/,如果是可执行文件,加*表示.<br />
$ ls &#8211; m 按页宽列文件,以逗号分隔.<br />
$ ls &#8211; p 如果是目录,文件名后加/<br />
$ ls &#8211; r 以字母反序列表<br />
$ ls &#8211; s 以文件块为单位显示文件大小<br />
$ ls &#8211; x 以多列的格式列表,按行排序.<br />
$ ls -G 以不同的颜色显示.<br />
$ ls -lc 显示更新时间<br />
$ ls -i   inode序号将列在第一列<br />
$ ls -lu 显示访问时间<br />
$ ls -I   显示更改时间<br />
6.touch 命令:作用是用来修改文件访问时间更改时间的.并可以</p>
<p>用来创建0字节长度的文件.<br />
格式 touch 命令参数<br />
7.cp 命令:复制文件<br />
格式 cp source target<br />
         $ cp file1 file2 &#8230; Target-dir<br />
$ cp -i 如果目标文件存在,请求确认<br />
$ cp -r 复制目录到新的目录<br />
8.mv 命令:移动文件或命名文件<br />
格式:mv source target<br />
9.ln 命令:ln命令的主要功能是给一个已经存在的文件再取一个</p>
<p>名字.新的文件名与原文件名可以在同一个目录下,也可以以在</p>
<p>不同的目录下,新老文件名代表同一个文件.<br />
格式ln source-file target-file<br />
作用:在现有的文件与新文件之间建立新链接,使一个文件具有</p>
<p>一个以上的名字.<br />
显示文件内容命令<br />
10.cat 命令:用来显示.创建或者合并文件<br />
格式cat filename<br />
11.more 命令:逐屏显示文件内容.翻屏时用<space>键.<br />
格式:$ more filename<br />
12.rm 命令:删除文件(删除后无法恢复)<br />
格式:$ rm file<br />
         $ rm file1 file2<br />
$ rm -i 删除文件前,给出确认<br />
$ rm -r 删除指定的目录及目录中的所有文件和子目录.即删除</p>
<p>整个目录结构.<br />
13.lp 命令:打印命令<br />
14.cut 命令:切取文件内容,用于切取文件中的列或字段.它把文</p>
<p>本文件中每一行的一部分显示输出.运行时必须指定功能选项.<br />
- f 指定字段的位置<br />
-c 指定列的位置<br />
-d 指定字段分隔符,缺省的字段分隔符是制表符tab<br />
15.paste 命令:连接文件.<br />
作用:把文件一行接一行地连接在一起,或者把两个或多个文件</p>
<p>的域连到一个新文件里.<br />
格式: $paste 选项 参数<br />
选项:-d 指定分隔符.默认是制表符<br />
第五章 文件权限<br />
16.chmod 命令:修改文件权限,常用chmod命令修改文件(包括普</p>
<p>通,目录和设备)的访问权限,<br />
格式: chmod pattern filename &#8230;<br />
finename 为要修改的权限文件名.可以有多个.<br />
pattern 为将改变成的权限,可以用两种形式表示:字母式和数字</p>
<p>形式.<br />
a,字母形式(符号模式)<br />
字母形式由用户类别(u,g,o). 如何改变(+,-)和权限(r,w,x)三部分</p>
<p>组成.<br />
u:本用户g:同组用户o:其它用户. + :增加权限 -:删除权限<br />
r:读w:写x:执行<br />
例如:chmod u+x file1<br />
         chmod o-w file2 file3<br />
          chmod go+r file4<br />
b,    数值形式<br />
格式: chmod 777 file1<br />
*新建文件或目录最大权限=状态掩码+新建文件或目录缺省</p>
<p>权限.此时unask为000<br />
对一个新建的文件,umask值为022则指定该文件的权限为644:<br />
对一个新建的目录,umask值为022则指定该目录的权限为755<br />
17.sort 命令:作用在于将指定的文件中的文件进行排序,并把排</p>
<p>序的结果输出到指定的标准输出中.<br />
格式:$srot [-t delimiter] [+field] [.column]][option]<br />
选项: -d 以字典顺序进行排序<br />
          -<br />
18.head 命令:用于查看一个文件.或多个文件的前面几行的内</p>
<p>容.<br />
格式:$ head [-number_of_lines] file(s)<br />
19.tail 命令:用于显示从指定行开始直到文件末尾的文件内容<br />
格式;tail [-number_of_lines | +number_of_lines]file<br />
20.tee 命令:在获得输入后,将把该输入数据送到两个地点:标准<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
输出和文件.<br />
21.grep 命令: 用于选项定包含特定模式的文本行.<br />
21.find 命令:在目录中递归地搜索包括有特定字符的文件名.<br />
22.df 命令:磁盘空间监测命令.显示当前系统中各个逻辑磁盘</p>
<p>中空闲的磁盘块数和空闲的索引节点(即可建立的新文件数)<br />
23.du 命令:查看磁盘使用情况统计,统计指定的目录及所有子</p>
<p>目录的磁盘使用情况,统计单位是磁盘块数.<br />
选项:-a 显示所有文件及子目录<br />
24.fsck 命令:文件系统管理:用于检测和修复文件文件的错误,<br />
25.tar命令:文件存储与备份.该命令可以把文件系统中的一个</p>
<p>或一组文件打成一个文件包.存放到外存上或硬盘上文件系统</p>
<p>的其它地方.常用于多个文件(包括目录)的备份或转移.<br />
格式: tar -cvf target file1 file2 file3 &#8230;把file1 file2 file3等文件备份到</p>
<p>档案文件target中.<br />
         tar -tvf target 检查档案文件target中包含的文件信息.<br />
         tar -xvf targer [file1] 从档案文件target中提取全部或file指定</p>
<p>的文件.<br />
26.shutdown 命令:系统关机<br />
选项:-h 完全关机<br />
         -r 关机并重新启动系统<br />
         time 关机时间,如17:30<br />
         message 关机前向所有已登陆用户发送消息<br />
例如: shutdown -r now 现在关机重启.<br />
27.crypt 文件加密命令:用于对文本文件进行加密和解密.以防</p>
<p>止文件内容泄密.<br />
例如:$ crypt < file > file.cry 对file加密,结果保存在file.cry中.key:加</p>
<p>密口令<br />
        $ crypt <aaa.cry > aaa 对aaa.cry解密,结果保存到aaa中. key:</p>
<p>解密口令<br />
附:$ vi -x file.cry 编辑一个加密后的文件<br />
28.compress/uncompress 文件压缩和解压命令<br />
格式:compress data_file 加压后自动在文件名后加一个.Z<br />
         umcompress abc.Z<br />
29.at 定时执行任务:在指定的时间一次性执行规定的任务.<br />
at 15:30 在15:30分执行<br />
who >> userlist 把上机用户清单发到userlist<br />
30,cron 系统定量执行任务:<br />
31,crontab 任务描述文件的管理命令.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/893.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Step-by-Step Guide to Building an OpenBSD PPPoE Gateway, with Firewall</title>
		<link>http://www.evanjiang.net.cn/archives/845.html</link>
		<comments>http://www.evanjiang.net.cn/archives/845.html#comments</comments>
		<pubDate>Mon, 23 Mar 2009 14:21:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[dns]]></category>
		<category><![CDATA[ftp]]></category>
		<category><![CDATA[mail]]></category>
		<category><![CDATA[openbsd unix]]></category>
		<category><![CDATA[pf]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[www]]></category>
		<category><![CDATA[Building  OpenBSD PPPoE Gateway]]></category>
		<category><![CDATA[with Firewall]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=845</guid>
		<description><![CDATA[<p style="float: right;margin: 4px;">


</p> <p>Introduction
Why would one install his own personal gateway to the Internet? Because it is quite easy to do. And also because it simply is the most reliable, safest way to connect machines to a dedicated xDSL modem. Moreover, we can stash a whole bunch of useful features in such a little [...]]]></description>
			<content:encoded><![CDATA[<p>Introduction<br />
Why would one install his own personal gateway to the Internet? Because it is quite easy to do. And also because it simply is the most reliable, safest way to connect machines to a dedicated xDSL modem. Moreover, we can stash a whole bunch of useful features in such a little box. Here is a list: </p>
<p>PPPoE Gateway<br />
PPPoE is a curious beast forced down our throats by some DSL providers. On one side, it does not really break anything, has low overhead and allows you to change IP adresses very easily &#038; quickly. On the other side, it sucks big time because it does add overhead to the IP packets, is proprietary, non-standard, forces you to change IP adresses unpredictably, and is unsupported in most operating systems. A good PPPoE gateway simply hides PPPoE from the machines on your internal network. It makes life much easier because you don&#8217;t have to install any special &#8220;access manager&#8221; software on your windoze boxen. They will just work (provided you set their IP address correctly). </p>
<p>Firewall<br />
A firewall is quite mandatory for any machine directly connected to the Big Bad Internet. We want an industrial-strength stateful inspection firewall and this is what we&#8217;ll get. </p>
<p>NAT (Network Adress Translation)<br />
The name seems complex, but it is really quite simple: this allows the gateway machine to act on the internet on behalf of all the machines located on the intranet (your internal home network). Even though you might have two, three or even ten computers on your local network, a NAT equipped gateway will hide them to outside observers. They will only see a single very busy machine, with a single IP address. </p>
<p>DNS (Domain Name Service) cache<br />
Having your own DNS server will lower the latency of getting DNS translations for all the machines on your intranet. This will not really decrease the traffic on your DSL modem by a large percentage, but it will improve the quality of the &#8220;internet experience&#8221; on your local network. </p>
<p>Dynamic DNS tracker<br />
Free dynamic DNS services are extremely useful to xDSL customers. They allow you to have your very own domain name, free of charge, which will follow in real-time your IP address changes. The catch is that the top-level part of your domain must be one of their supplied choices. They are not that bad, really&#8230; Personally, I use DYNDNS but any of the multiple free dynamic DNS providers out there will do just fine. Simply make sure they have a client &#8220;updater&#8221; which can compile and run under OpenBSD. </p>
<p>WEB server<br />
Most ISP&#8217;s only allow a few megabytes of disk for web service. Moreover, they never give you direct access to the web logs. Having your own web server allows you the luxury of using all the disk space you want, plus the added advantage of complete control over the web service (cgi-bin) and its logs. Moreover, OpenBSD comes with a crypto-enabled version of Apache and all the tools you need to create RSA-keyed certificates. </p>
<p>Mail server<br />
Have you ever wanted to create a temporary email address just to receive some password? Or simply wanted addresses tailored for specific domains of interest? These are only a few of the many advantages of having your own mail server. </p>
<p>NTP server<br />
The Network Time Protocol allow you to synchronize the gateway&#8217;s clock to one of the numerous atomic time references available on the internet. Moreover, the same program is also used as a local time server, so that all your intranet machines can themselves synchronize their clocks to the gateway&#8217;s clock. NTP synchronizations are made in tiers, like this, in order to lower the burden on the public time servers. </p>
<p>This page is for all those of you who have are lucky enough to enjoy a dedicated xDSL connection and would like to have a small firewall installation. In my search for the holy grail, i found the answer to most of my wishes in the OpenBSD package. This step-by-step guide is a collection of notes taken while I was installing the thing. They are intended to help my friends do their own setups very quickly and easily, without having to bug me too much <img src='http://www.evanjiang.net.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  They should help you too.</p>
<p>Constructive comments can be sent there &#8230; Have fun and GOOD LUCK!</p>
<p><span id="more-845"></span><br />
Getting some hardware<br />
The first thing to think about when one embarks on the firewalling adventure is to establish on what hardware you are going to install the thing. This seems unimportant at first, but don&#8217;t forget that this box will be turned on 24/7, so the components you use must be reliable.</p>
<p>What are the minimum requirements? My system uses about 50% of its CPU to support Sympatico&#8217;s ADSL rate (around 900 kbps). It is built with the following components:</p>
<p>An ancient 486 motherboard (with an ISA bus) given to me by a friend (thanks Christian!). It runs at 66 MHz.<br />
32 MB of brand new RAM i bought for it.<br />
A 200 MB hard disk, which was dying after about 1 year of faithful use (it came with the motherboard). This disk was recently replaced with the cheapest brand new drive i could find. I didn&#8217;t know they still made those slow 3600 RPM drives <img src='http://www.evanjiang.net.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Anyway, the old drive is kept as a kind of extreme emergency backup.<br />
Two ISA-bus ethernet cards. I&#8217;ll talk more about this later.<br />
A CD-ROM drive. Very optional, but can make life easier.<br />
A &#8220;home&#8221; grade hub &#038; cat5 cabling. This is not strictly necessary if you&#8217;ll have only one machine connected to your firewall: you can make do with a special &#8220;crossover&#8221; cat5 cable instead. The cable that comes with xDSL modems is usually (always?) a crossover cable. Anyway, for two or more machines, the hub is mandatory. Small hubs can be bought for a very reasonable price (~40$ cdn).<br />
or<br />
Alternatively, many older ethernet cards come with a BNC female connector. This can be used to connect the machines on your network with coax cables, without any hub. However, be warned that a 10base-2 network must follow certain rules if you want it to work flawlessly. Follow them.<br />
This gives a good approximation of what you need. The MOST important part is the RAM. Make absolutely sure that whatever RAM you use is reliable. Old boxen were usually setup to run Windoze, and it was not a big deal if the machine had flaky RAM because of the way Windoze works&#8230;</p>
<p>OpenBSD (like any real OS out there) is much less tolerant of flaky RAM, because it actually uses all of it. It will crash quite quickly if your RAM is marginal, probably within 5-10 minutes. You have been warned.</p>
<p>Finally, the OpenBSD hardware list is there. Try to make sure that whatever hardware you use in your gateway box figures on that list. It&#8217;s a long list <img src='http://www.evanjiang.net.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>The ethernet cards<br />
There is a boring thing of which we must talk about here. You see, there are many kinds of ethernet cards, and you must make sure you have the right ones for your machine. If you have a PCI-based machine, then all is well. Whatever ethernet card you put in there will probably be supported by OpenBSD. However, you must be a bit more careful if you have an ISA-based machine.</p>
<p>It is most likely that your box will not have any ethernet cards to start with since most people did not have networks at home in the pre-historic era of 4 years ago. You need two cards. One will be connected to the DSL modem (the big, bad outerworld), while the other is connected to your internal network hub (your intranet). The gateway&#8217;s job will be to pass (or block) packets between those two network cards. For security, its very important that the outside world packets cannot reach directly any of the intranet machines. This is the reason why we use two ethernet cards: complete logical and electrical isolation. Why so much isolation? For example, if someone(s) were launching a full (distributed or not) denial of service attack on your gateway box, its internet-connected ethernet card would be extremely busy, but your intranet would see nothing of this. While any communication with the outside world would probably fail, at least your intranet machines would still be able to talk to each other.</p>
<p>ISA cards use dedicated I/O ports and IRQ&#8217;s in your machine. Those must be setup either with jumpers directly on the card, or with a special DOS program if the card is of the more recent &#8220;Plug &#038; Play&#8221; type. This DOS program is always supplied with the card, when purchased brand new.</p>
<p>If your card is Plug&#038;Play, you must disable the Plug&#038;Play, and program specific I/O port and IRQ values with the setup software that comes with the card. Make sure that you program both cards with different sets of I/O ports and IRQs! Otherwise they will battle each other for cycles on the bus and the result will not be pretty. Once you have set the parameters on the card it will remember them and you don&#8217;t have to reprogram anything later on, even if the computer is turned off.</p>
<p>It is good at this point to know a few magic numbers:</p>
<p>Card Type I/O #1 IRQ #1 Mem #1 I/O #2 IRQ #2 Mem #2<br />
NE2000 (ne) 0&#215;240 9 &#8212; 0&#215;300 10 &#8212;<br />
SMC WD-8003 (we) 0&#215;280 9 0xd0000 0&#215;300 10 0xcc000 </p>
<p>For example, i use two cards made by AOpen: the model ALN-101. They are Plug&#038;Play and use the NE2000 chip. The first one is setup at I/O port 0&#215;240, IRQ 9. It is known as &#8220;ne0&#8243; in the GENERIC openBSD kernel. The second one is set at I/O port 0&#215;300, IRQ 10. It is known as &#8220;ne1&#8243;. If the cards were programmed differently, the GENERIC kernel would not recognize them &#8220;out of the box&#8221; and you would have to re-configure the kernel. It can be done, but its much easier to setup the hardware once than re-configure the kernel every time it gets upgraded.</p>
<p>Some of you might have problems setting the card to an arbitrary combination of IO port and IRQ number. This is allright, just let the card decide what it wants and simply reconfigure your kernel to accomodate that. What is important is that both ethernet cards are not set to conflicting values. Otherwise, any combination that the cards like will be programmable in the kernel.</p>
<p>Last but not least: some cards can be used in the so-called &#8220;full-duplex&#8221; mode. Be aware that if you want to use an ethernet card in full-duplex, your hub must also be full-duplex, as well as the other ethernet cards in the system. A full-duplex hub is much more expensive and not necessary at all. Unless you know what you are doing, program your ethernet cards to use the half-duplex mode, otherwise it won&#8217;t play nice with the other components in your local network, including the xDSL modem <img src='http://www.evanjiang.net.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
(注，这里需要说NE2000等旧款的基于486机的网卡也可以用，但现在这些网卡，其本难找，所以至少要用8139系列芯片的10-100M自适应的网卡来做应用）</p>
<p>The hard disk<br />
The most secure storage medium is one which can&#8217;t be erased. Some firewalls actually use setups like this (with CD-ROMS) but we&#8217;ll build our firewall with a classic, writeable hard drive because:</p>
<p>We don&#8217;t need &#8220;Absolute Security&#8221;, do we? We can&#8217;t have it anyway <img src='http://www.evanjiang.net.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
We want to use an &#8220;out-of-the-box&#8221; OpenBSD distro. This will make maintenance (security, patches, etc&#8230;) much easier.<br />
Almost any hard disk out there will work OK, since 200 MB is a safe minimum size. The only thing you must remember is that this disk will run 24/7, so if you use an old drive, it will likely die relatively soon. The venerable drive my friend gave me lasted 6 months before i had to change it, YMMV.</p>
<p>No keyboard?<br />
Of course you&#8217;ll need a keyboard&#8230; and a monitor too, but just for the installation. After the firewall is successfully installed, you will be able to talk to it through encrypted ssh connections over your internal network, so a keyboard &#038; monitor will not be really useful at that point.</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>Getting the software<br />
We will be using OpenBSD. Why? Because it is the most secure freely available operating system out there. All the source code included in the mainstream distribution CD&#8217;s has been audited for years by the OpenBSD team, which is why sometimes an exploit published on BugTraq is found not to work on OpenBSD simply because the faulty code was already fixed months ago.</p>
<p>I strongly suggest you buy their CD-ROM kit as it comes with a set of very cool stickers&#8230; You can also download their stuff for free, of course, but you won&#8217;t have the stickers then <img src='http://www.evanjiang.net.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>This Guide is written for OpenBSD 3.0.</p>
<p>The easiest way to install the software is to use a CD-ROM drive on your firewall box. If you don&#8217;t have that, you can do a network install with the &#8220;ftp&#8221; protocol, either directly to an outside OpenBSD mirror, or to one of your own internal machines equipped with an ftp server. Be aware that if your DSL provider forces you to use PPPoE (boooo!), then of course your link to the outside world will not be functional yet at installation time, which is one more reason to use the CD-ROM. If your machine can boot a CD-ROM, great! It will gladly boot the OpenBSD disc. Otherwise, simply create a boot diskette according to the README and boot that. This diskette is also your rescue disk, so don&#8217;t lose it.<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>Installing OpenBSD<br />
The installation of OpenBSD is very easy, once you have the right hardware, and the right answers to some of the questions. In the following steps, i&#8217;ll assume you can follow the instructions of the install program and focus only on the tricky little things you should know to make your life easier.</p>
<p>fdisk &#038; disklabel<br />
After you boot the installer, one of the very first things you&#8217;ll have to do is partition your disk. This is done with the &#8220;fdisk&#8221; and &#8220;disklabel&#8221; programs. The installer will ask you if you want to use the entire hard disk for OpenBSD. Answer No, even if it is not entirely true. If you say yes, the whole fdisk step will be bypassed, and you will not be able to change the default cylinder/head/sector configuration in order to boot off the hard disk without resorting to the silly &#8220;FDISK /MBR&#8221; DOS command which is a stupid solution to a stupid problem.<br />
The default OpenBSD fdisk partition setup choice is in slot #3. If you want, you can move your OpenBSD partition in slot #0 with no ill effect.</p>
<p>Important: On some systems, to make sure your system boots off the hard disk, you must set the starting CHS (cylinder/head/sector) to C=0, H=0, S=1, because fdisk suggested an incorrect value for H in OpenBSD 2.7, and still does in 2.8 &#8230; If you use &#8220;1&#8243;, as it suggests, your system will not be able to boot from the hard disk.</p>
<p>After the disk is partitioned with fdisk, you use disklabel to further organize the partition. A label behaves like a traditional partition (as used in Linux, for example), except that you can put as many labels as you want in the single OpenBSD partition. This is useful.</p>
<p>On a fully partitioned system, the disk labels might look like this: </p>
<p>  a:  2097648        0    4.2BSD     1024  8192    16   # /               1 GB<br />
  b:   262080  2097648      swap                        # SWAP          128 MB<br />
  c: 20015856        0    unused        0     0         # (whole disk)   10 GB<br />
  d:  2097648  2359728    4.2BSD     1024  8192    16   # /usr            1 GB<br />
  e:  2097648  4457376    4.2BSD     1024  8192    16   # /tmp            1 GB<br />
  f:  2097648  6555024    4.2BSD     1024  8192    16   # /var            1 GB<br />
  g:  4194288  8652672    4.2BSD     1024  8192    16   # /usr/local      2 GB<br />
  h:  7168896 12846960    4.2BSD     1024  8192    16   # /home           3 GB<br />
On my firewall, i like to keep things simpler, so it goes like this: </p>
<p>#        size   offset    fstype   [fsize bsize   cpg]<br />
  a: 18874800        0    4.2BSD     1024  8192    16   # (Cyl.    0 &#8211; 18724)<br />
  b:  1141056 18874800      swap                        # (Cyl. 18725 &#8211; 19856)<br />
  c: 20015856        0    unused        0     0         # (Cyl.    0 &#8211; 19856)As you see, the &#8216;c&#8217; label is a placeholder for the whole disk, in all cases. Don&#8217;t delete or otherwise change this, or you&#8217;ll be in trouble. </p>
<p>One of the main disadvantages of having a single partition is that one could do bad things in such quantity that the log files would simply fill up the whole drive. OpenBSD doesn&#8217;t like it when all its disk space is full. You can guess the rest of the story. In practice, this is not an issue, since i monitor my log files daily, but it could be an issue for someone out there. </p>
<p>On a fully partitioned system, the &#8220;df&#8221; command says this, after the OS is installed, with its complete source trees: </p>
<p>Filesystem      1K-blocks     Used    Avail Capacity  Mounted on<br />
/dev/wd0a         1015269    25985   938521     3%    /<br />
/dev/wd0d         1015269   480284   484222    50%    /usr<br />
/dev/wd0e         1015269        1   964505     0%    /tmp<br />
/dev/wd0f         1015269     5141   959365     1%    /var<br />
/dev/wd0g         2030307     8698  1920094     0%    /usr/local<br />
/dev/wd0h         3470505       27  3296953     0%    /home</p>
<p>On my system i have this:</p>
<p>Filesystem                           1K-blocks     Used    Avail Capacity  Mounted on<br />
/dev/wd0a                              9137589   503054  8177656     6%    /</p>
<p>In this example, the full OpenBSD source tree is installed, which explains why the thing uses up about 500 MB. Without the source tree, you only need about 120 MB in there, but having the source tree allows you to make security patches as they are published. This is important and i&#8217;ll talk about it more later.</p>
<p>Active FTP<br />
If you do an FTP install to a private FTP server, it might be necessary to use active FTP. </p>
<p>Crypto, SSL, etc&#8230;<br />
The crytographic packages are included in the CD&#8217;s since release 2.9 of OpenBSD. They will be automatically installed. </p>
<p>UTC time zone<br />
Keep your server in the UTC time zone. This way, your firewall logs will be timestamped in UTC time and it will be simpler to have them interpreted by the abuse@&#8230; services of ISP&#8217;s. Also, it is important to make sure the gateway is time-synchronized to one of the numerous public NTP servers out there, because having only an IP address is not enough to pin down internet abusers. In this age of dynamic IP allocations you need both IP address and exact time in order to positively identify the origin of an IP packet. Keep your gateway synchronized.<br />
Why not GMT instead? Read all about it there.</p>
<p>Normally, the installer will ask you for a time zone at install time. If you want to change it later, simply make /etc/localtime point to /usr/share/zoneinfo/UTC with a soft link: </p>
<p>ln -s /usr/share/zoneinfo/UTC /etc/localtime</p>
<p>First Boot<br />
reboot &#8230; did your machine boot correctly? If not, please consult the numerous FAQ&#8217;s available at the OpenBSD site. Are you sure you set H=0 in fdisk? By the way, if it doesn&#8217;t boot from hard disk, you can probably still force it by first booting the install diskette, and entering &#8220;boot wd0a:/bsd&#8221; at the initial prompt. You have about 5 seconds to make your mind, when you see this prompt, act swiftly.<br />
On first boot, you will probably get a message like &#8220;ssh-keygen: generating new DSA host key&#8230;&#8221;, followed with an equivalent message for the RSA host key. They might take quite a long time on a 486 (5-10 minutes), so Don&#8217;t Panic! &#8482; , the machine is not crashed, and the boot process will eventually follow its course, given time. This will happen only on the first boot.</p>
<p>Kernel extra configuration<br />
If, at this point, the kernel sees all you devices (including both ethernet cards), congratulations. If not, you can reconfigure the kernel without having to recompile it by simply using the config utility. Typically, you would copy your current kernel (the &#8220;/bsd&#8221; file) to an appropriate backup name (e.g. &#8220;/bsd.ORIGINAL&#8221;), and issue this command: </p>
<p>config -e -f /bsd<br />
and make whatever changes you need. You should know what you&#8217;re doing in order to use this command without blowing your system up into tiny bits &#038; pieces. Don&#8217;t forget to save your changes. If this modified kernel doesn&#8217;t work OK, just boot the &#8220;/bsd.ORIGINAL&#8221; kernel instead, and you will have another chance. </p>
<p>Sys control files<br />
The services allowed by OpenBSD are configured by a couple of files in the /etc directory. Actually, this directory contains all the configuration files of OpenBSD, for your convenience, but this is something you&#8217;ll only appreciate later, when you become an experienced BSD maintainer&#8230; We&#8217;ll come back to that /etc directory quite often.<br />
For now, just make sure that the following are enabled:</p>
<p>In the file /etc/sysctl.conf:<br />
net.inet.ip.forwarding=1</p>
<p>and in /etc/rc.conf:<br />
sendmail_flags=&#8221;-L sm-mta -bd -q30m&#8221;<br />
named_flags=&#8221;"<br />
httpd_flags=&#8221;-DSSL&#8221;</p>
<p>Important: If you plan to use PPPoE, don&#8217;t enable pf here because you want to start it in a controlled manner, after PPPoE is started. Enabling &#8220;pf&#8221; here would make it start at the very beginning of the boot process and this would not work. </p>
<p>PPP &#038; PPPoE<br />
Ahhhh&#8230; the Evil Beast. Installing a good, working PPP and PPPoE can be quite a tricky task. In OpenBSD 3.0, it is included and works well, once properly configured. This version of PPP supports the &#8220;mssfixup&#8221; instruction which magically allows you to avoid setting MTU&#8217;s at 1492 or less on all of your intranet&#8217;s machines. This is very recommended as it avoids a whole bunch of problems with Windows machines, internet appliances, etc&#8230;<br />
Notice that there is an excellent Network FAQ available from the OpenBSD site. It contains a lot of information on what to do with those ethernet adapters. </p>
<p>The configuration file for ppp is in /etc/ppp/ppp.conf. Mine contains exactly this:</p>
<p>default:<br />
 set log Phase Chat IPCP CCP tun command<br />
 set redial 15 0<br />
 set reconnect 15 10000</p>
<p>pppoe:<br />
 set device &#8220;!/usr/sbin/pppoe -i ne0&#8243;<br />
 disable acfcomp protocomp<br />
 deny acfcomp<br />
 set mtu max 1492<br />
 set speed sync<br />
 enable lqr<br />
 set lqrperiod 5<br />
 set cd 5<br />
 set dial<br />
 set login<br />
 set timeout 0<br />
 set authname xxxxxxx<br />
 set authkey xxxxxx<br />
 add! default HISADDR<br />
 enable dns<br />
 enable mssfixupNotice how we specify the real network interface ne0 to pppoe (with double quotes), and that i use &#8220;max 1492&#8243; for the MTU value, as suggested by many people. Also, no value is specified for the MRU, the PPP network address translation is not enabled, the magic &#8220;mssfixup&#8221; is enabled and i use the &#8220;add!&#8221; command instead of plain &#8220;add&#8221; (suggested by Chris Pockele).</p>
<p>Also notice that the authname and authkey fields don&#8217;t contain double-quote characters. You should put in there your own ISP identification and password. Some ISPs require authname to have a full identification (e.g. &#8220;username@sympatico.ca&#8221;), while other ISPs will want to have only &#8220;username&#8221; in the authname field. Experiment.</p>
<p>Robert Jameson (thanks Robert!) reports that some ISPs require you to specify the pppoe service you want. This is done on the &#8220;set device&#8221; line. For example: </p>
<p>      set device &#8220;!/usr/sbin/pppoe -n Shasta_1 -i ne0&#8243;</p>
<p>VERY IMPORTANT!</p>
<p>For some reason, the routes setup automatically by ppp at linkup time were not correctly defined prior to OpenBSD version 3.0. The MTU&#8217;s were wrong, leading to all sorts of subtle problems. This is now fixed, and we can safely use the &#8220;add default HISADDR&#8221; command in the ppp config file, with no special route commands at all in the ppp.linkup file. The MTUs will be properly set to 1492 on all the routes which go through the external interface. </p>
<p>The command &#8220;netstat -rn&#8221; confirms this:</p>
<p>pcreal# netstat -rn<br />
Routing tables</p>
<p>Internet:<br />
Destination        Gateway            Flags     Refs     Use    Mtu  Interface<br />
default            65.92.185.1        UGS         3    13423   1492   tun0<br />
65.92.185.1        65.92.185.97       UH          1        0   1492   tun0<br />
127.0.0.1          127.0.0.1          UH          1     1045  33224   lo0<br />
192.168.1/24       link#2             UC          0        0   1500   ne1<br />
192.168.1.1        0:e0:18:90:a7:c7   UHL         3    10475   1500   ne1<br />
&#8230;</p>
<p>A friend from Australia (thanks Doug!) suggested i clarify the following points:</p>
<p>(1) The 64.229.x.x adresses will NOT be the same in your setup! Those are the adress blocks of my PPPoE service provider (Sympatico). Your own setup will use, most likely, different address blocks.</p>
<p>(2) The ppp daemon creates a virtual network interface (&#8220;tun0&#8243;) out of thin air. This virtual network interface is internally linked to the actual physical interface (&#8220;ne0&#8243; in my system), but you will never have to deal directly with &#8220;ne0&#8243; in your configuration files. For example, the firewall rules are written with the virtual &#8220;tun0&#8243; interface, not the physical &#8220;ne0&#8243; interface. In my setup, the internal interface is &#8220;ne1&#8243;, and the external interface is &#8220;tun0&#8243;. Here is Doug&#8217;s analogy with the Windows world:</p>
<p>&#8220;&#8230; think of the PPPoE adaptor like the dialup adaptor in a Windows<br />
control panel. it doesn&#8217;t really exist but you gotta have it&#8230;&#8221;(3) The ppp daemon takes care of automatically assigning the name servers and the routes. Consequently, make sure there is no file &#8220;/etc/mygate&#8221;, and bear in mind that &#8220;/etc/resolv.conf&#8221; will be automatically generated as well, at connection time. This has the advantage that you don&#8217;t need to know anything about the details of your connection (name server adresses, etc&#8230;) to your ISP. Your user ID and password are sufficient, as the ppp daemon will negociate with the server and obtain the information it needs to open the connection.</p>
<p>(4) Since the ppp daemon will take are of the external network interface, you don&#8217;t need a &#8220;/etc/hostname.ne0&#8243; file. However, you do need a file to describe your internal network interface (in my case, &#8220;ne1&#8243;):</p>
<p>pcreal# cat /etc/hostname.ne1<br />
inet 192.168.1.2 255.255.255.0 NONENormally, this file should have been built by the setup program of OpenBSD, but if not, you must manually put it there and replace the &#8220;192.168.1.2&#8243; with whatever address you want your gateway to have as seen from your internal network.</p>
<p>Another friend, from France (thanks Xavier!), sent me this ascii picture of the network connections:</p>
<p>           |                                      |<br />
   internet| ====> |DSL Modem| ====>|server|=====>|LAN (HUB)<br />
           |                   tun0           ne1 |<br />
           |                   =ne0               |</p>
<p>Note: I consider this PPP/PPPoE setup to be a work in progress. I continually discover new things about it&#8230; so, please bear with me and do send me your feedback about your own experience regarding PPP/PPPoE. It really is a pain, but apparently we will be stuck with it for a long long time, so we might as well learn how to tame the thing!</p>
<p>Second Boot<br />
reboot &#8230; your machine should boot correctly. You won&#8217;t have internet access yet because the ppp program is not activated. If you want to try it out, just issue </p>
<p>ifconfig ne0 up<br />
ppp -ddial pppoeand ping/telnet away. Don&#8217;t worry if you get &#8220;carrier settings ignored&#8221;, or &#8220;change route failed&#8221; messages. Be careful because at this point you have no firewall rules set, so you are very vulnerable. Also, make sure your xDSL modem is plugged in the correct ethernet card&#8230;</p>
<p>If all works well, then you should kill the &#8220;ppp&#8221; process. Only restart it when the firewall rules are in place.</p>
<p>The afterboot phase<br />
Follow the instructions obtained by issuing the &#8220;man afterboot&#8221; command. Actually, quoting FAQ section 2.3, here is a list of the most useful man pages for new users: </p>
<p>     * [15]afterboot(8) &#8211; things to check after the first complete boot<br />
     * [16]boot(8) &#8211; system boot strapping procedures<br />
     * [17]passwd.conf(5) &#8211; format of the password configuration file<br />
     * [18]adduser_proc(8) &#8211; procedure for adding new users<br />
     * [19]adduser(8) &#8211; command for adding new users<br />
     * [20]vipw(8) &#8211; edit the pass word file<br />
     * [21]man(1) &#8211; display the on-line manual pages<br />
     * [22]sendbug(1) &#8211; send a problem report (PR) about OpenBSD to a<br />
       central support site.<br />
     * [23]disklabel(8) &#8211; Read and write disk pack label.<br />
     * [24]ifconfig(8) &#8211; configure network interface parameters.<br />
     * [25]route(8) &#8211; manually manipulate the routing tables.<br />
     * [26]netstat(1) &#8211; show network status.<br />
     * [27]reboot, halt(8) &#8211; Stopping and restarting the system.<br />
     * [28]shutdown(8) &#8211; close down the system at a given time.<br />
     * [29]boot_config(8) &#8211; how to change kernel configuration at boot</p>
<p>One of the first things you should do at this point is to add an unprivileged user and make him member of the wheel group. This is because, for security reasons, it is never a good idea to log in directly as root. The preferred way to gain root privileges is to login as a wheel member, and then use the &#8220;su -&#8221; command to gain root privileges.</p>
<p>OpenBSD will not prevent you from logging in directly as root, but will warn you every time against doing it.</p>
<p>Have fun!</p>
<p>Firewall and NAT rule sets<br />
This is a tricky one. Many people earn a good living just by knowing how to write firewall rule sets! Moreover, the whole packet filter and NAT code was completely rewritten from scratch in OpenBSD 3.0. It is now called &#8220;pf&#8221;, and is completely free of any external licensing strings so we will always have the latest, fully audited versions in future OpenBSD releases.<br />
Here are my own pf rules, in all their glory. They were heavily influenced by the various man pages and HOW-TO&#8217;s pertaining to &#8220;pf&#8221;. Be aware that they might be either too restrictive, or not enough, depending on your context. My philosophy about this is to disallow everything by default, and only open whatever is known to be useful. This restrictive ruleset will prevent ftp from working correctly, from the firewall itself. However, the ftp proxy currently available will work correctly for client machines located on the intranet. </p>
<p>Don&#8217;t forget to send me your tips for better rules&#8230; Thanks!</p>
<p>/etc/nat.conf<br />
nat on tun0 from 192.168.1.0/24 to any -> tun0<br />
rdr on ne1 proto tcp from any to any port 21 -> 127.0.0.1 port 8081</p>
<p>/etc/pf.conf<br />
#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
# PF ruleset, 11 dec. 2001<br />
#<br />
# Liberally adapted from the pf man page, the OpenBSD &#8220;Network How-To&#8221;,<br />
# and my own rulesets.<br />
#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
# Definitions<br />
Ext = &#8220;tun0&#8243;            # External interface<br />
Int = &#8220;ne1&#8243;             # Internal interface<br />
Loop = &#8220;lo0&#8243;            # Loopback interface<br />
IntNet=&#8221;192.168.1.0/24&#8243; # Internal network</p>
<p>NoRoute = &#8220;{ 127.0.0.1/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 255.255.255.255/32 }&#8221;</p>
<p>InServicesTCP = &#8220;{ ssh, smtp, auth, http, https, pop3 }&#8221;<br />
#InServicesUDP = &#8220;{ domain }&#8221;<br />
OutServicesTCP = &#8220;{ http, https, smtp, pop3, whois, domain, ssh, telnet, ftp, ftp-data, nntp, auth, ntp }&#8221;<br />
OutServicesUDP = &#8220;{ ntp, domain }&#8221;</p>
<p>XMMS = &#8220;{ 6000, 7500, 8000, 8004, 8044, 8034, 8052, 8038, 8010, 8400, 8014, 8026, 8048, \<br />
          8002, 8024, 8028, 8080 }&#8221;<br />
RealAudio = &#8220;{ 554, 7070, 8080 }&#8221;</p>
<p>#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
# Clean up fragmented and abnormal packets<br />
# By default in pf, packets which contain IP options are blocked. Good.<br />
scrub in on { $Ext, $Int } all<br />
#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
# Defaults<br />
# block and log everything<br />
block             out log on $Ext           all<br />
block             in  log on $Ext           all<br />
block return-rst  out log on $Ext proto tcp all<br />
block return-rst  in  log on $Ext proto tcp all<br />
block return-icmp out log on $Ext proto udp all<br />
block return-icmp in  log on $Ext proto udp all</p>
<p>block in  quick inet6 all<br />
block out quick inet6 all<br />
#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
# loopback packets left unmolested<br />
pass in quick on $Loop all<br />
pass out quick on $Loop all<br />
#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
# Immediate blocks<br />
# fuzz any &#8216;nmap&#8217; attempt<br />
block in log quick on $Ext inet proto tcp from any to any flags FUP/FUP<br />
block in log quick on $Ext inet proto tcp from any to any flags SF/SFRA<br />
block in log quick on $Ext inet proto tcp from any to any flags /SFRA</p>
<p># don&#8217;t allow anyone to spoof non-routeable addresses<br />
block in log quick on $Ext from $NoRoute to any<br />
block out log quick on $Ext from any to $NoRoute</p>
<p># silently drop broadcasts (cable modem noise)<br />
block in quick on $Ext from any to 255.255.255.255<br />
#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
# PASS rules</p>
<p># ALL  &#8212; we don&#8217;t normally do that. For debugging only.<br />
#pass out quick on $Ext all keep state</p>
<p># pass in data mode connections for ftp-proxy running on this host.<br />
pass in quick on $Ext inet proto tcp from any to any port > 49151 flags S/SA keep state</p>
<p># ICMP<br />
pass out     quick on $Ext inet proto icmp all icmp-type 8 code 0 keep state<br />
pass in  log quick on $Ext inet proto icmp all icmp-type 8 code 0 keep state</p>
<p># Services we provide to the outside world<br />
#pass in quick on $Ext inet proto udp from any to any port $InServicesUDP keep state<br />
pass in quick on $Ext inet proto tcp from any to any port $InServicesTCP flags S/SA keep state</p>
<p># Standard services we want to access in the world<br />
pass out quick on $Ext inet proto udp from any to any port $OutServicesUDP keep state<br />
pass out quick on $Ext inet proto tcp from any to any port $OutServicesTCP flags S/SA modulate state</p>
<p># Special services<br />
pass out quick on $Ext inet proto tcp from any to any port $XMMS flags S/SA modulate state<br />
pass out quick on $Ext inet proto tcp from any to any port $RealAudio flags S/SA modulate state<br />
IMPORTANT: Note that the &#8220;rdr&#8221; rule in the NAT file refers to the INTERNAL network interface. Its purpose is to redirect all ftp-data requests from the intranet to be redirected to the ftp-proxy on the firewall. Then the ftp-proxy channels those into ports 49152-65535, and outputs them on the internet. This is why we have this hole in the firewall starting at port 49152. I know, it is in the IN direction, but that is how passive ftp works&#8230; It is quite a broken protocol.<br />
That&#8217;s it! Nothing too painful, as you see. Since pf is a stateful inspection firewall, we can keep our ingress rules to a strict minimum. Notice the sheer elegance of the ruleset, with all services defined at once in a single IN or OUT rule. </p>
<p>One last thing: in order to automagically enable your firewall when the link comes up, you can put the following lines in the /etc/ppp/ppp.linkup file. Notice the extra space in front of each &#8220;!&#8221; character:</p>
<p>MYADDR:<br />
 ! sh -c &#8220;/sbin/ifconfig pflog0 up&#8221;<br />
 ! sh -c &#8220;/sbin/pfctl -e -l tun0 -F all -O aggressive -R /etc/pf.conf -N /etc/nat.conf&#8221;</p>
<p>The FTP proxy<br />
If you want tight security, and no FTP available on your intranet, simply remove the hole at 49152, and the &#8220;rdr&#8221; command in the file &#8220;nat.conf&#8221;. However, if you want to be able to use FTP from the intranet, then you must keep those, as well as enable the &#8220;ftp-proxy&#8221; service in inetd. Simply add this line to inetd.conf : </p>
<p>8081            stream  tcp     nowait  root    /usr/libexec/ftp-proxy  ftp-proxyDon&#8217;t forget that you still won&#8217;t be able to do FTP&#8217;ing from the firewall itself, when the packet filtering is enabled. Hopefully, it is very easy to temporarily disable pf with the command &#8220;pfctl -d&#8221;, and later re-enable it with the command &#8220;pfctl -e&#8221;. This comes in handy when we install packages from ftp.openbsd.org with the command &#8220;pkg_add&#8221;. </p>
<p>We are confident that ftp-proxy will improve with time and eventually dynamically manipulate the state tables of the firewall in order to open/close needed connections on-the-fly. </p>
<p>Addinc stuff to /etc/rc.local<br />
This is where our custom startup instructions go. Those things are started while the kernel is in secure level 1. If you need anything started in a lower security level, modify /etc/rc.securelevel instead. In order to start up PPPoE correctly, I added this at the end of my /etc/rc.local : </p>
<p>ifconfig ne0 up<br />
route flush<br />
ppp -ddial pppoe</p>
<p>This starts PPP, PPPoE, the firewall and the NAT translator (because the firewall and the NAT are started automatically in the ppp.linkup file). If you&#8217;re curious, you can reboot at this point, and confirm that you have a fully firewalled internet access:</p>
<p>pcreal# ifconfig -a<br />
lo0: flags=8009 mtu 33224<br />
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0&#215;5<br />
        inet6 ::1 prefixlen 128<br />
        inet 127.0.0.1 netmask 0xff000000<br />
lo1: flags=8008 mtu 33224<br />
ne0: flags=8863 mtu 1500<br />
        media: Ethernet autoselect (10baseT)<br />
        inet6 fe80::240:f4ff:fe2b:190d%ne0 prefixlen 64 scopeid 0&#215;1<br />
ne1: flags=8863 mtu 1500<br />
        media: Ethernet autoselect (10baseT)<br />
        inet 192.168.1.2 netmask 0xffffff00 broadcast 192.168.1.255<br />
        inet6 fe80::240:f4ff:fe2b:16b1%ne1 prefixlen 64 scopeid 0&#215;2<br />
pflog0: flags=141 mtu 33224<br />
sl0: flags=c010 mtu 296<br />
sl1: flags=c010 mtu 296<br />
ppp0: flags=8010 mtu 1500<br />
ppp1: flags=8010 mtu 1500<br />
tun0: flags=8011 mtu 1492<br />
        inet 65.92.185.97 &#8211;> 65.92.185.1 netmask 0xffffffff<br />
tun1: flags=10 mtu 3000<br />
enc0: flags=0<> mtu 1536<br />
bridge0: flags=0<> mtu 1500<br />
bridge1: flags=0<> mtu 1500<br />
vlan0: flags=0<> mtu 1500<br />
vlan1: flags=0<> mtu 1500<br />
gre0: flags=8010 mtu 1450<br />
gif0: flags=8010 mtu 1280<br />
gif1: flags=8010 mtu 1280<br />
gif2: flags=8010 mtu 1280<br />
gif3: flags=8010 mtu 1280</p>
<p>pcreal# pfctl -sr<br />
@0 scrub in on ne1 all<br />
@1 scrub in on tun0 all<br />
@2 block out log on tun0 all<br />
@3 block in log on tun0 all<br />
@4 block return-rst out log on tun0 proto tcp all<br />
@5 block return-rst in log on tun0 proto tcp all<br />
@6 block return-icmp out log on tun0 proto udp all<br />
@7 block return-icmp in log on tun0 proto udp all<br />
@8 block in quick inet6 all<br />
@9 block out quick inet6 all<br />
@10 pass in quick on lo0 all<br />
@11 pass out quick on lo0 all<br />
@12 block in log quick on tun0 inet proto tcp all flags FPU/FPU<br />
@13 block in log quick on tun0 inet proto tcp all flags FS/FSRA<br />
@14 block in log quick on tun0 inet proto tcp all flags /FSRA<br />
@15 block in log quick on tun0 inet from 255.255.255.255/32 to any<br />
@16 block in log quick on tun0 inet from 10.0.0.0/8 to any<br />
@17 block in log quick on tun0 inet from 172.16.0.0/12 to any<br />
@18 block in log quick on tun0 inet from 192.168.0.0/16 to any<br />
@19 block in log quick on tun0 inet from 127.0.0.1/8 to any<br />
@20 block out log quick on tun0 inet from any to 255.255.255.255/32<br />
@21 block out log quick on tun0 inet from any to 10.0.0.0/8<br />
@22 block out log quick on tun0 inet from any to 172.16.0.0/12<br />
@23 block out log quick on tun0 inet from any to 192.168.0.0/16<br />
@24 block out log quick on tun0 inet from any to 127.0.0.1/8<br />
@25 block in quick on tun0 inet from any to 255.255.255.255/32<br />
@26 pass in quick on tun0 inet proto tcp from any to any port > 49151 flags S/SA keep state<br />
@27 pass out quick on tun0 inet proto icmp all icmp-type echoreq code 0 keep state<br />
@28 pass in log quick on tun0 inet proto icmp all icmp-type echoreq code 0 keep state<br />
@29 pass in quick on tun0 inet proto tcp from any to any port = pop3 flags S/SA keep state<br />
@30 pass in quick on tun0 inet proto tcp from any to any port = https flags S/SA keep state<br />
@31 pass in quick on tun0 inet proto tcp from any to any port = www flags S/SA keep state<br />
@32 pass in quick on tun0 inet proto tcp from any to any port = auth flags S/SA keep state<br />
@33 pass in quick on tun0 inet proto tcp from any to any port = smtp flags S/SA keep state<br />
@34 pass in quick on tun0 inet proto tcp from any to any port = ssh flags S/SA keep state<br />
@35 pass out quick on tun0 inet proto udp from any to any port = domain keep state<br />
@36 pass out quick on tun0 inet proto udp from any to any port = ntp keep state<br />
@37 pass out quick on tun0 inet proto tcp from any to any port = ntp flags S/SA modulate state<br />
@38 pass out quick on tun0 inet proto tcp from any to any port = auth flags S/SA modulate state<br />
@39 pass out quick on tun0 inet proto tcp from any to any port = nntp flags S/SA modulate state<br />
@40 pass out quick on tun0 inet proto tcp from any to any port = ftp-data flags S/SA modulate state<br />
@41 pass out quick on tun0 inet proto tcp from any to any port = ftp flags S/SA modulate state<br />
@42 pass out quick on tun0 inet proto tcp from any to any port = telnet flags S/SA modulate state<br />
@43 pass out quick on tun0 inet proto tcp from any to any port = ssh flags S/SA modulate state<br />
@44 pass out quick on tun0 inet proto tcp from any to any port = domain flags S/SA modulate state<br />
@45 pass out quick on tun0 inet proto tcp from any to any port = whois flags S/SA modulate state<br />
@46 pass out quick on tun0 inet proto tcp from any to any port = pop3 flags S/SA modulate state<br />
@47 pass out quick on tun0 inet proto tcp from any to any port = smtp flags S/SA modulate state<br />
@48 pass out quick on tun0 inet proto tcp from any to any port = https flags S/SA modulate state<br />
@49 pass out quick on tun0 inet proto tcp from any to any port = www flags S/SA modulate state<br />
&#8230;<br />
@72 pass out quick on tun0 inet proto tcp from any to any port = 6000 flags S/SA modulate state<br />
@73 pass out quick on tun0 inet proto tcp from any to any port = 8080 flags S/SA modulate state<br />
@74 pass out quick on tun0 inet proto tcp from any to any port = 7070 flags S/SA modulate state<br />
@75 pass out quick on tun0 inet proto tcp from any to any port = 554 flags S/SA modulate state</p>
<p>pflogd and tcpdump<br />
With the new pf firewall code comes a new way to log firewalled packets and look at them. The log is actually taken care of by a separate daemon ( pflogd ) which should be started in &#8220;ppp.linkup&#8221; and killed in &#8220;ppp.linkdown&#8221;. This daemon puts its data in a special log file ( /var/log/pflog ) which is not directly human readable, for performance reasons. To get a dump of the file, simply issue the command &#8220;tcpdump -n -e -ttt -r /var/log/pflog&#8221;, or , if you want a real-time display of the logs, simply issue &#8220;tcpdump -n -e -ttt -i pflog0&#8243;. </p>
<p>The Dynamic DNS<br />
Dynamic DNS is a wonderful thing. Basically, you just go to a dyndns provider like those nice people and 10 minutes later you have your very own domain, for free. In order to make that domain dynamically follow your IP address changes, you must use a special client program which must be called whenever your IP changes. </p>
<p>Until recently I liked ddup, but now i use ipcheck. The latter is truly compliant with all of dyndns&#8217;s client specification, and maintains its state automatically in system files. You will have to install the python package if you use &#8220;ipcheck&#8221;. Also, you&#8217;ll need your user ID and password from the dyndns provider.</p>
<p>One more advice: it is perfectly acceptable to have more than one domain pointing at the same IP address. Remember this when choosing one or more domain names&#8230;</p>
<p>Keeping your xDSL link alive 24/7<br />
xDSL connections are very reliable, but ISP&#8217;s are not <img src='http://www.evanjiang.net.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  For many reasons unfathomable, you will sometimes lose your connection. There are many methods of re-establishing that connection automatically, and i&#8217;ll describe here the one i use. </p>
<p>The Method<br />
Make sure you initialise ppp with the &#8220;-ddial&#8221; command, and NOT the &#8220;-background&#8221; command&#8230;</p>
<p>The automatic restart of the ppp link is handled by ppp itself (using the &#8220;-ddial&#8221; command), which is quite handy. This leaves us with the dyndns updates, which are performed intelligently by ipcheck.py . An easy way of doing it is to create an executable file named &#8220;do_ipcheck&#8221; which contains this:</p>
<p>#!/bin/sh<br />
/usr/local/sbin/ipcheck.py -q -d /etc/ipcheck -i tun0  -w Username Password DomainName1,DomainName2with your own Username, Password and Domain names, of course. Then, all you have to do is to add the following line to crontab:</p>
<p>*/5     *       *       *       *       /usr/local/sbin/do_ipcheckAlso, don&#8217;t forget to create the directory /etc/ipcheck and make sure your /etc/ppp/ppp.linkup file looks like this:</p>
<p>MYADDR:<br />
 ! sh -c &#8220;/sbin/ifconfig pflog0 up&#8221;<br />
 ! sh -c &#8220;/sbin/pfctl -e -l tun0 -F all -O aggressive -R /etc/pf.conf -N /etc/nat.conf&#8221;<br />
 ! sh -c &#8220;/usr/local/sbin/ResetNTP.sh&#8221;<br />
 !bg sh -c &#8220;/usr/local/sbin/do_ipcheck&#8221;<br />
You can call &#8220;do_ipcheck&#8221; from &#8220;ppp.linkup&#8221; &#8230; however, you must use the special &#8220;!bg&#8221; construct, in order to instruct ppp to fork it in the background. Nasty stuff happens if you don&#8217;t use &#8220;!bg&#8221; here. Big thanks to Dan for this update!</p>
<p>This setup should garantee the proper restart of the firewall &#038; ipnat each time the ppp link is brought up again.</p>
<p>Apache<br />
Now would be a good time to install your htdocs directory. The way i like to do this is to mount a read-only NFS file system over the current htdocs. This is easily accomplished by adding a line like this to your /etc/fstab : </p>
<p>192.168.1.1:/usr/local/Apache/htdocs /var/www/htdocs nfs ro  Moreover, the web logs are kept in /var/www/logs. Interesting stuff.</p>
<p>We are in full virus season and i&#8217;m sure your log files will fill up as fast as mine with useless garbage, once your Apache is up. In order to remove some clutter, you can filter out the virus attacks and channel them to a specialized attack_log file. Simply insert the following lines into your /var/www/conf/httpd.conf file: </p>
<p>SetEnvIf Request_URI &#8220;^/default.ida&#8221; attacks # For Code Red<br />
SetEnvIf Request_URI &#8220;^/scripts&#8221; attacks # For nimda<br />
SetEnvIf Request_URI &#8220;^/c/winnt&#8221; attacks # &#8230; ditto all the way down<br />
SetEnvIf Request_URI &#8220;^/_mem_bin&#8221; attacks<br />
SetEnvIf Request_URI &#8220;^/_vti_bin&#8221; attacks<br />
SetEnvIf Request_URI &#8220;^/MSADC&#8221; attacks<br />
SetEnvIf Request_URI &#8220;^/msadc&#8221; attacks<br />
SetEnvIf Request_URI &#8220;^/d/winnt&#8221; attacks</p>
<p>CustomLog /var/www/logs/access_log combined env=!attacks<br />
CustomLog /var/www/logs/attack_log combined env=attacks<br />
This will send all virus-related requests to &#8220;attack_log&#8221;, while still logging other activities normally in access_log.</p>
<p>Named<br />
Someone (Chavous P. Camp, thanks!) sent me advice on optimizing &#8220;named&#8221; for faster throughput. He recommends to add two lines to the &#8220;/var/named/named.boot&#8221; file:</p>
<p>options forward-only<br />
forwarders ip.addresses.of.ISPs.nameservers.separated.by.spacesThis forces named to always use the same servers for dns. If your ISP&#8217;s servers are always on fixed IP adresses, then it works well. However, ISP&#8217;s who force you to use PPPoE will also sometimes change dynamically the DNS servers allocated to you (in &#8220;/etc/resolv.conf&#8221;, automatically created by ppp at startup). In that case, there is no garantee that the name servers you hardwire as forwarders will always be available.</p>
<p>Removing IPv6 related errors<br />
The GENERIC OpenBSD kernel comes precompiled with IP v6 support. This is the reason why you might see many &#8220;/bsd: tun0: not multicast capable, IPv6 not enabled&#8221; error messages in your logs. Those messages are completely harmless and do not alter the performance of your system. However, should you want to get rid of them, you can simply remove IPv6 support from your kernel by modifying &#8220;/usr/src/sys/conf/GENERIC&#8221; and removing the &#8220;option INET6&#8243; line. Then recompile your kernel in the usual way. Thanks Chavous for this info!</p>
<p>Setting permissions of scripts &#038; config files<br />
Another excellent suggestion from Chavous. Scripts and config files with passwords should have their permissions changed to 500 (for scripts) or 400 (for config files), for greater security. This includes &#8220;ppp.conf&#8221;, &#8220;do_ipcheck&#8221;, etc&#8230;</p>
<p>The NTP daemon<br />
The ntpd daemon is not installed by default. However, you can download it as a package, and install it with the pkg_add command. Since you have internet connectivity by now, you can download &#038; install it in a single command:</p>
<p>pkg_add ftp://ftp.openbsd.org/pub/OpenBSD/3.0/packages/i386/ntp-4.1.71.tgz Moreover, you will need a valid /etc/ntp.conf file:</p>
<p>pcreal# cat /etc/ntp.conf<br />
server 128.100.102.201<br />
driftfile /etc/ntp.driftFeel free to use any other atomic time server if you want. Also, the drift file will be created &#038; maintained automagically.</p>
<p>Important tip from Chavous:<br />
=========================================<br />
I found my ntp server would refuse to synchronize after a reboot because it<br />
had no route to the time server.  This was, of course, because PPPoE is<br />
loaded AFTER ntp, and sometimes the PPPoE negotiation after a reboot takes a<br />
few seconds.</p>
<p>Anyway, here is something you might want to add as a suggestion:</p>
<p>Turn ntpd OFF in the rc.conf file<br />
add this line to your ppp.linkup file &#8211; AFTER the firewall initialization</p>
<p> ! sh -c &#8220;/etc/ppp/ResetNTP.sh&#8221;</p>
<p>That script should then contain:</p>
<p>#!/bin/sh<br />
if [ -f /var/run/ntpd.pid ]; then<br />
        kill `cat /var/run/ntpd.pid`<br />
        rm -f /var/run/ntpd.pid<br />
fi<br />
/usr/local/sbin/ntpd -p /var/run/ntpd.pid</p>
<p>(as I have said before, remind your readers that this script is executed as<br />
root and should therefore be chmod 444 or less)</p>
<p>This kills the NTP daemon (if it exists) and restarts it.  On boot, it would<br />
not be restarted, but what if the link went down for a while? The ntp daemon<br />
would give up and stop sending queries because it couldn&#8217;t get a route to<br />
host.</p>
<p>REALLY, the ntp daemon SHOULD NOT stop querying the server just because it<br />
can&#8217;t get a route to the host, but it seems to be written as such now<br />
anyway.  I haven&#8217;t tested the ntp daemon over a long period of time (more<br />
than about a day) so I don&#8217;t know if it just gives up for some arbitrarily<br />
long period (MORE than a day) and then tries again. I seriously doubt it<br />
does, because a day is a LONG time.  This workaround isn&#8217;t ideal, because<br />
for time consistency, one would want the time server to stay running at all<br />
times.  According to the ntpd documentation, ntpd tends to become more<br />
accurate the longer it runs.</p>
<p>Chavous<br />
=========================================</p>
<p>Sendmail<br />
If you have followed all the steps of the recipe so far, your sendmail should be configured &#038; ready to receive mail from the internet, however you should know a few more things about this. First, if you want your gateway to receive mail for more than one domain, you must make sure the all fully qualified domains are setup as aliases for your host in the file /etc/hosts.</p>
<p>The mail popper<br />
All ingress mail is received &#038; kept on the gateway untill some POP client on the intranet gets it. I use the &#8220;popa3d&#8221; server package because it is written with security in mind. It is now part of the main OpenBSD 3.0 distribution, so you don&#8217;t have to download it as a separate package. Simply enable it in the file /etc/inetd.conf and you should be up &#038; running. </p>
<p>The installed packages<br />
Just to do a quick check, here are the packages i have installed on my system:</p>
<p>pcreal# pkg_info<br />
gmp-3.1.1          library for arbitrary precision arithmetic<br />
python-2.1.1       interpreted object-oriented programming language<br />
ntp-4.1.71         network time protocol implementation<br />
libiconv-1.7       character set conversion library<br />
gettext-0.10.40    GNU gettext<br />
mhash-0.8.9        strong hash library<br />
libtool-1.3.5p3    generic shared library support script<br />
postgresql-7.1.3   PostgreSQL RDBMS<br />
libmcrypt-2.4.15   interface to access block/stream encryption algorithms<br />
c-client-4.40p1    University of Washington&#8217;s c-client mail access routines<br />
php4-4.0.6p1-gettext-imap-mhash-no_x11-mcrypt-postgresql server-side HTML-embedded scripting language</p>
<p>The Secure Shell<br />
The secure shell looks &#038; feels exactly like telnet, except that all communication between the client and the server is encrypted. It is the only possible way to access your gateway, because the telnet daemon is disabled by default. Usage is very simple: just like telnet! </p>
<p>[real@pcreal Projects]$ ssh 192.168.1.2<br />
real@192.168.1.2&#8242;s password:<br />
Warning: Remote host denied X11 forwarding.<br />
Last login: Sun Nov  5 12:58:08 2000 from 192.168.1.1<br />
OpenBSD 2.7 (GENERIC) #1: Thu Nov  2 16:05:11 GMT 2000</p>
<p>pcreal:real {39}</p>
<p>Once you are logged in as an unprivileged user, member of the wheel group, you can use su to gain superuser privileges:</p>
<p>pcreal:real {39} su -<br />
Password:<br />
Terminal type? [nxterm]<br />
pcreal#</p>
<p>The log files<br />
There are many log files of high interest maintained automatically by your gateway. It is usually convenient to look at them with the &#8220;tail -f&#8221; command. The files i look at often are: </p>
<p>/var/log/messages<br />
/var/log/maillog<br />
/var/log/secure<br />
/var/www/logs/access_log</p>
<p>Moreover, you can grab interesting info about the blocked packets on your firewall with the &#8220;ipmon&#8221; utility.</p>
<p>There are many other log files available for all kinds of things. Dig around to find more about them.</p>
<p>Installing IPSEC<br />
Dave Cook has kindly provided us with a good description of how to install IPSEC on your OpenBSD boxen: file:///H:/OPENBSD/ipsec.pdf, in PDF (Acrobat) format. Be aware that it is a largish file (440K), and it might take some time for your Acrobat reader to load afterwards, so don&#8217;t hit the link repeatedly, it won&#8217;t make things load faster&#8230; <img src='http://www.evanjiang.net.cn/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Apply the security patches!<br />
Security patches are published there. APPLY THEM RELIGIOUSLY!<br />
It is not really difficult, but you will need a copy of the complete, original source tree of the distribution. The compressed source archives are to be found with the distribution files. These are the 3.0 source files:</p>
<p>      src.tar.gz      64447 Kb    Tue May  1 16:18:00 2001 Unix Tape Archive<br />
      srcsys.tar.gz   13837 Kb    Tue May  1 16:18:00 2001 Unix Tape ArchiveThey total about 80 MB. Once you have them, simply unpack them to &#8216;/usr/src&#8217; and &#8216;/usr/src/sys&#8217;. The latter is the kernel proper.</p>
<p>Once you have your source tree, you can start downloading the patches, and apply them. Usually, all the currently published patches are availble in a single file. For 3.0, it is there. After that, simply watch the patch page from time to time, to keep updated.</p>
<p>Patches are either applied to an application (in &#8216;/usr/src&#8217;), or to the kernel ( in &#8216;/usr/src/sys&#8217;). Since all kernel patches should be installed, the thing i do is to apply all the kernel patches in one session, then i recompile my kernel once.</p>
<p>The applications you don&#8217;t use (e.g. &#8216;X11&#8242;, for example) don&#8217;t have to be patched &#038; recompiled.</p>
<p>Reboot and enjoy!<br />
You should be able to ssh into your new gateway from any machine on the intranet. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/845.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Redhat  tar 自动备份和恢复脚本 （RHEL4）</title>
		<link>http://www.evanjiang.net.cn/archives/684.html</link>
		<comments>http://www.evanjiang.net.cn/archives/684.html#comments</comments>
		<pubDate>Wed, 04 Mar 2009 10:14:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[redhat linux]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[redhat  备份脚本]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=684</guid>
		<description><![CDATA[<p>自动备份脚本
#!/bin/bash
# df -k
#Filesystem           1K-blocks      Used Available Use% Mounted on
#/dev/sda2            113852040  10113912  97954732  10% /
#/dev/sda1             [...]]]></description>
			<content:encoded><![CDATA[<p>自动备份脚本<br />
#!/bin/bash<br />
# df -k<br />
#Filesystem           1K-blocks      Used Available Use% Mounted on<br />
#/dev/sda2            113852040  10113912  97954732  10% /<br />
#/dev/sda1               790588     24680    725748   4% /boot<br />
#none                   1028008         0   1028008   0% /dev/shm<br />
#/dev/sda5             19362784  10617104   7762104  58% /export/home<br />
#<br />
# to show how to set crontab<br />
# [root@ad12 log]# crontab -l<br />
# SHELL=/bin/bash<br />
# 30 18 * * *       /usr/local/william.w/backup-1.sh >> /usr/local/william.w/backup.log 2>&#038;1<br />
#<br />
# to avoid the error: TERM environment variable not set.<br />
TERM=linux<br />
export TERM<br />
cd /<br />
clear<br />
echo<br />
echo<br />
echo =====================================<br />
echo this tool is used to backup the MMSC<br />
echo =====================================<br />
# to get the IP<br />
IP1=`ifconfig | grep &#8220;inet addr:&#8221; | grep -v &#8220;inet addr:127.0.0.1&#8243; | awk -F: &#8216;{printf $2}&#8217;`<br />
IP2=${IP1%% *}<br />
echo the server IP is $IP2<br />
# to get the date<br />
DATE=`date +%Y-%m-%d-%H`-tar<br />
echo today is ${DATE%-*}<br />
# to make a file folder to store the backp files, but if it was already exsit, just to overwirite it.<br />
mkdir /export/home/$DATE 2> /dev/null<br />
echo /export/home/$DATE has already exsited or been made.<br />
echo and backup file will be backuped in this folder.<br />
echo<br />
# all backup files using tar file have been located in /export/home, and below command just sum the backup files and show them in the list.<br />
NUM=`ls /export/home/ | grep tar | wc -l`<br />
echo now we have $NUM tar folder, they are all under /export/home/<br />
echo =================<br />
ls -tr /export/home/ | grep tar<br />
echo =================<br />
# to caculate the used disk space for /export/home<br />
USEDISK=`df -k |sed -n &#8216;/export/&#8217;p  | awk &#8216;{print $5}&#8217; |sed &#8216;s/\%//&#8217;`<br />
        if [ $USEDISK -gt 85 ]<br />
        then<br />
        echo USEDISK is $USEDISK%<br />
        echo WARNNIG: have no enough space to backup!<br />
        exit;<br />
        fi<br />
<span id="more-684"></span><br />
echo USEDISK is $USEDISK%<br />
        if [ $USEDISK -gt 65 ]<br />
                then<br />
                echo &#8220;***************************&#8221;<br />
                echo &#8216;USEDISK is lager than 65!!!&#8217;<br />
                if [ $NUM -gt 2 ]<br />
                        then<br />
                        echo &#8220;***************************&#8221;<br />
                        echo there are $NUM tar folders:<br />
                        ls -tr /export/home/ | grep tar<br />
                        echo &#8220;*****************************************&#8221;<br />
                        # if the used disk space is beyond 65% and the number of tar-format-backup-file-folder is bigger than 2, we would delete these folders to keep the number to be less or equate 2<br />
                        DIFF=`expr $NUM &#8211; 2`<br />
                        # the number of file folders that would be deleted is $DIFF, and they would be deleted in below circle.<br />
                        for dir in `ls -tr /export/home/ | grep tar | head -n $DIFF`<br />
                                do<br />
                                        DISKSPACE=`df -k |sed -n &#8216;/export/&#8217;p  | awk &#8216;{print $5}&#8217; |sed &#8216;s/\%//&#8217;`<br />
                                        if [ $DISKSPACE -le 65 ]<br />
                                        then<br />
                                                echo now USEDISK is $DISKSPACE%, and it is OK<br />
                                                break;<br />
                                        fi<br />
#                                        line = $dir;<br />
                                        echo &#8220;`ls -tr /export/home/ | grep tar | head -n 1` will be deleted soon&#8230;&#8221;<br />
                                        echo &#8230;<br />
                                        rm -fr /export/home/$dir;<br />
                                        echo &#8220;$dir has been deleted successfully&#8221;<br />
                                echo &#8220;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;&#8221;<br />
                                done<br />
                        echo &#8220;********************************&#8221;<br />
                fi<br />
        fi<br />
echo<br />
echo &#8220;==========Begin to tar==============&#8221;<br />
echo now below file folder would be tared:<br />
# just show the list of file folder that would be backuped, and folder name has been add with &#8220;/&#8221; becuase this RHEL4.0 X86-64 does not show the root path.<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
ls / | grep -v -e proc -e mnt -e media -e lost+found -e export| sed &#8216;s/\([ ]\{1,\}\)/\1\//g;s/^./\/&#038;/g&#8217;<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
echo tar is working now&#8230;<br />
echo please waiting&#8230;&#8230;.<br />
# prepare to show the file name, and the backup file name is $DATE/$RNAME-$IP3-$DAY.tar.gz locating at /export/home/$DATE/<br />
# to backup all root file folders,  but donot include /proc, /mnt, /media/, and /export<br />
# all the display infomation would not show by  >&#038; /dev/null<br />
# all error information would not show by 2> /dev/null<br />
IP3=`echo $IP2 | awk -F. &#8216;{printf $3&#8243;.&#8221;$4}&#8217;`<br />
DAY=`echo $DATE| awk -F- &#8216;{printf $2$3$4}&#8217;`<br />
RNAME=`hostname | awk -F. &#8216;{printf $1}&#8217;`<br />
tar -zcvPf /export/home/$DATE/$RNAME-$IP3-$DAY.tar.gz 2> /dev/null $(ls / | grep -v -e proc -e mnt -e media -e lost+found -e export)  >&#038; /dev/null<br />
echo now backup is successful.<br />
echo the file is /export/home/$DATE/$RNAME-$IP3-$DAY.tar.gz<br />
echo &#8220;==================================End to tar=========================&#8221;<br />
echo<br />
# to list the backup folders<br />
echo Summary of backup files:<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
echo the img backup:<br />
ls -t /export/home/ | grep img<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
echo the tar backup:<br />
ls -t /export/home/ | grep tar<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
echo other files:<br />
ls -t /export/home/ | grep -v tar |grep -v img<br />
echo =================================<br />
USEDISK1=`df -k |sed -n &#8216;/export/&#8217;p  | awk &#8216;{print $5}&#8217; |sed &#8216;s/\%//&#8217;`<br />
echo before backup the USEDISK is $USEDISK%<br />
echo at last the USEDISK is $USEDISK1%<br />
echo =================================</p>
<p>自动恢复脚本<br />
#!/bin/bash<br />
cd /<br />
clear<br />
echo<br />
echo<br />
echo<br />
echo =====================================<br />
echo this tool is used to restore the MMSC<br />
echo =====================================<br />
echo<br />
echo this restore command must be like   &#8220;#/export/home/restore.sh   backup-file-folder&#8221;<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
echo for example:<br />
echo &#8220;#/export/home/restore.sh 2008-04-01-00-tar&#8221;<br />
echo<br />
# to get the date<br />
DATE=`date +%Y-%m-%d-%H`-tar<br />
echo today is ${DATE%-*}<br />
# to get the IP<br />
IP1=`ifconfig | grep &#8220;inet addr:&#8221; | grep -v &#8220;inet addr:127.0.0.1&#8243; | awk -F: &#8216;{printf $2}&#8217;`<br />
IP2=${IP1%% *}<br />
IP3=`echo $IP2 | awk -F. &#8216;{printf $3&#8243;.&#8221;$4}&#8217;`<br />
echo the server IP is $IP2<br />
RNAME=`hostname | awk -F. &#8216;{printf $1}&#8217;`<br />
echo the server name is $RNAME<br />
# to get the path of the backup file, and it is /export/home/$1/<br />
# to get the name of the backup file, and it is $RNAME-$IP3-$DAY.tar.gz<br />
echo the restored folder and file are:<br />
DAY=`echo $1| awk -F- &#8216;{printf $2$3$4}&#8217;`<br />
echo /export/home/$1/$RNAME-$IP3-$DAY.tar.gz<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
echo please wait&#8230;&#8230;<br />
# to restore the backup files under root path<br />
cd /<br />
tar -zxvPf /export/home/$1/$RNAME-$IP3-*.tar.gz  2> /dev/null -C / >&#038; /dev/null<br />
echo backup is successful<br />
echo &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
echo</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/684.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mysql备份脚本</title>
		<link>http://www.evanjiang.net.cn/archives/682.html</link>
		<comments>http://www.evanjiang.net.cn/archives/682.html#comments</comments>
		<pubDate>Wed, 04 Mar 2009 10:10:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=682</guid>
		<description><![CDATA[<p>#!/bin/sh
#
# Copyright (C), 2008 bug All Rights Reserved
# Title       : Database Backup Script
# Author      : BUG
# File        : db_bak.sh
# Version     : 1.1.0
# Date        :
# Email  [...]]]></description>
			<content:encoded><![CDATA[<p>#!/bin/sh<br />
#<br />
# Copyright (C), 2008 bug All Rights Reserved<br />
# Title       : Database Backup Script<br />
# Author      : BUG<br />
# File        : db_bak.sh<br />
# Version     : 1.1.0<br />
# Date        :<br />
# Email       :<br />
# License     : General Public License (GPL) v2<br />
# Description : Database Backup Script<br />
#</p>
<p>initial() {<br />
    echo -en &#8220;\33[2J"<br />
    echo -en "\33[0;0H"<br />
    echo -en "\33[32m"<br />
    echo "------------------------------------------------------------"<br />
    echo "---                Database Backup Script                ---"<br />
    echo "------------------------------------------------------------"<br />
    echo -en "\33[37m"<br />
    stty -echo<br />
    umask 077<br />
    mysqln=`echo 'show databases;' | /usr/local/mysql/bin/mysql -psjldafhkg | sed -n '3,$p'`<br />
    mysqlu="root"<br />
    mysqlp="********"<br />
    binpath="/usr/local/mysql/bin"<br />
    dstpath="/pri/bak/sql_bak/"<br />
    runuser=`ps aux | grep $$ | sed -n "1p" | awk '{ print $1 }'`<br />
    mkdir -p $dstpath/`date +%y%m%d`<br />
    exec 3>>$dstpath/`date +%y%m%d`/db_bak.log<br />
}</p>
<p>initial</p>
<p>echo -e "\n[`date +%y/%m/%d\ %H:%M:%S`] Database Backup Script start by $runuser PID:$$&#8221; >&#038;3</p>
<p>if [ -f "$dstpath/`date +%y%m%d`/lock" ]<br />
then<br />
    echo -e &#8220;\33[33mIt's has completed by `cat $dstpath/\`date +%y%m%d\`/lock`!!!\33[37m"<br />
    echo "[`date +%y/%m/%d\ %H:%M:%S`] It&#8217;s has completed by `cat $dstpath/\`date +%y%m%d\`/lock`!!!&#8221; >&#038;3<br />
else<br />
    echo -e &#8220;Database\tExport\tCompress\tSql\tTgz\tRate&#8221;<br />
    echo -e &#8220;\33[32m------------------------------------------------------------\33[37m"<br />
    cd $dstpath/`date +%y%m%d`<br />
    for db in $mysqln<br />
    do<br />
    echo -n "$db"<br />
    $binpath/mysqldump --opt -u$mysqlu -p$mysqlp $db > $dstpath/`date +%y%m%d`/$db.sql 2> /dev/null<br />
    RETVAL1=$?<br />
    if [ $RETVAL1 -eq 0 ]<br />
    then<br />
    sqlsize=`du -k $db.sql | cut -f1`<br />
    echo -n &#8220;[`date +%y/%m/%d\ %H:%M:%S`]&#8221; >&#038;3<br />
    echo -n &#8220;$db&#8221; | awk &#8216;{printf &#8221; %-17s&#8221;, $1}&#8217; >&#038;3<br />
    echo -n &#8220;OK  &#8221; >&#038;3<br />
    echo -en &#8220;\r\t\t  \33[32mOK\33[37m\t"<br />
    tar -czvf $db.tgz $db.sql > /dev/null 2>&#038;1<br />
        RETVAL2=$?<br />
        if [ $RETVAL2 -eq 0 ]<br />
        then<br />
        tgzsize=`du -k $db.tgz | cut -f1`<br />
        echo &#8220;OK&#8221; >&#038;3<br />
        rm -f $dstpath/`date +%y%m%d`/$db.sql<br />
        echo -en &#8221;   \33[32mOK\33[37m"<br />
        echo -en "\33[33m"<br />
        echo -en "$sqlsize" | awk '{printf "%12sKB", $1}'<br />
        echo -en "$tgzsize" | awk '{printf "%6sKB", $1}'<br />
        echo "$sqlsize $tgzsize" | awk '{printf "%8.0f%",$2/$1*100}'<br />
        echo -e "\33[37m"<br />
        else<br />
        echo "Compress fail return $RETVAL2" >&#038;3<br />
        echo -e "  \33[31mfail\33[37m"<br />
        fi<br />
    else<br />
    echo -n "[`date +%y/%m/%d\ %H:%M:%S`]&#8221; >&#038;3<br />
    echo -n &#8220;$db&#8221; | awk &#8216;{printf &#8221; %-17s &#8220;, $1}&#8217; >&#038;3<br />
    echo &#8220;Export fail return $RETVAL1&#8243; >&#038;3<br />
    echo -en &#8220;\r\t\t   \33[31mfail\33[37m&#8221;<br />
    fi<br />
    done<br />
    echo &#8220;`date +%H:%M:%S`&#8221;>$dstpath/`date +%y%m%d`/lock<br />
fi</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/682.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>linux下的bash与sh 详解以及实例</title>
		<link>http://www.evanjiang.net.cn/archives/668.html</link>
		<comments>http://www.evanjiang.net.cn/archives/668.html#comments</comments>
		<pubDate>Wed, 04 Mar 2009 09:45:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[debian linux]]></category>
		<category><![CDATA[redhat linux]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[suse linux]]></category>
		<category><![CDATA[linux下的bash与sh]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=668</guid>
		<description><![CDATA[<p>关于bash与sh的话题（限于一般linux），以下个人的一些总结及理解，有理解错误的地方还望指点</p>
<p>1、bash的POSIX标准</p>
<p>在一般的linux系统当中（如redhat），
使用sh调用执行脚本相当于打开了bash的POSIX标准模式
（等效于bash的 &#8211;posix 参数）</p>
<p>一般的，sh是bash的“子集”
（不是子集的部分，具体区别见下的“Things sh has that bash does not”）</p>
<p>例子：</p>
<p>[wwy@sf-watch test]$ cat t2.sh
#!/bin/bash
diff 




</p>
<p>2、调用相关：</p>
<p>在脚本的调用方面（interactive、login相关），bash与sh也是存在差异
以下是详细说明（假如被调用执行的脚本名字叫xxx.sh）</p>
<p>BASH：</p>
<p>1、交互式的登录shell （bash –il xxx.sh）
载入的信息：
/etc/profile
~/.bash_profile（ ->  ~/.bashrc  ->  /etc/bashrc）
~/.bash_login
~/.profile</p>
<p>2、非交互式的登录shell （bash –l xxx.sh）
载入的信息：
/etc/profile
~/.bash_profile （ ->  ~/.bashrc  ->  /etc/bashrc）
~/.bash_login
~/.profile
$BASH_ENV</p>
<p>3、交互式的非登录shell （bash –i xxx.sh）
载入的信息：
~/.bashrc （ ->  /etc/bashrc）</p>
<p>4、非交互式的非登录shell （bash xxx.sh）
载入的信息：
$BASH_ENV</p>
<p>SH：</p>
<p>1、交互式的登录shell
载入的信息：
/etc/profile
~/.profile</p>
<p>2、非交互式的登录shell
载入的信息：
/etc/profile
~/.profile</p>
<p>3、交互式的非登录shell
载入的信息：
$ENV</p>
<p>4、非交互式的非登录shell
载入的信息：
nothing</p>
<p>由此可以看出，最主要的区别在于相关配置文件的是否载入，
而这些配置的是否载入，也就导致了很多默认选项的差异
（具体请仔细查看~/.bash_profile 等文件）</p>
<p>如：</p>
<p>[wangweiyu@ComSeOp ~]$ grep ulimit /etc/profile
ulimit -S -c unlimited > /dev/null 2>&#038;1</p>
<p>即，如果/etc/profile没有被载入，则不会产生core dump</p>
<p>3、关于ssh</p>
<p>非常值得一提的是，使用ssh远程执行命令，
远端sshd进程通过“bash [...]]]></description>
			<content:encoded><![CDATA[<p>关于bash与sh的话题（限于一般linux），以下个人的一些总结及理解，有理解错误的地方还望指点</p>
<p>1、bash的POSIX标准</p>
<p>在一般的linux系统当中（如redhat），<br />
使用sh调用执行脚本相当于打开了bash的POSIX标准模式<br />
（等效于bash的 &#8211;posix 参数）</p>
<p>一般的，sh是bash的“子集”<br />
（不是子集的部分，具体区别见下的“Things sh has that bash does not”）</p>
<p>例子：</p>
<p>[wwy@sf-watch test]$ cat t2.sh<br />
#!/bin/bash<br />
diff <(echo xxx) <(echo yyy) </p>
<p>[wwy@sf-watch test]$ bash -x ./t2.sh # 使用bash 调用，不会出问题<br />
+ diff /dev/fd/63 /dev/fd/62<br />
++ echo xxx<br />
++ echo yyy<br />
1c1<br />
< xxx<br />
---<br />
> yyy<br />
[wwy@sf-watch test]$ sh ./t2.sh    # 而用sh调用，报错如下<br />
./t2.sh: line 3: syntax error near unexpected token `(&#8216;<br />
./t2.sh: line 3: `diff <(echo xxx) <(echo yyy)'<br />
[wwy@sf-watch test]$ echo $?<br />
2<br />
<span id="more-668"></span></p>
<p>但是，在我们的linux系统中，sh是bash的一个软链接：</p>
<p>[wangweiyu@ComSeOp mon]$ which sh<br />
/bin/sh<br />
[wangweiyu@ComSeOp mon]$ ls -l /bin/sh<br />
lrwxrwxrwx  1 root root 4 Mar 21  2007 /bin/sh -> bash</p>
<p>那为什么上面的例子中还会出现问题呢？原因在于：<br />
bash程序执行，当“$0”是“sh”的时候，<br />
则要求下面的代码遵循一定的规范，当不符合规范的语法存在时，则会报错，<br />
所以可以这样理解，<br />
“sh”并不是一个程序，而是一种标准（POSIX），<br />
这种标准，在一定程度上（具体区别见下面的“Things bash has that sh does not”）保证了脚本的跨系统性（跨UNIX系统）</p>
<p>下面的内容详细的说明了bash与sh在语法等方面的具体差异（引自Bash FAQ）：</p>
<p>Things bash has that sh does not:</p>
<p>        long invocation options<br />
        [+-]O invocation option<br />
        -l invocation option<br />
        `!&#8217; reserved word to invert pipeline return value<br />
        `time&#8217; reserved word to time pipelines and shell builtins<br />
        the `function&#8217; reserved word<br />
        the `select&#8217; compound command and reserved word<br />
        arithmetic for command: for ((expr1 ; expr2; expr3 )); do list; done<br />
        new $&#8217;&#8230;&#8217; and $&#8221;&#8230;&#8221; quoting<br />
        the $(&#8230;) form of command substitution<br />
        the $(<filename) form of command substitution, equivalent to<br />
                $(cat filename)<br />
        the ${#param} parameter value length operator<br />
        the ${!param} indirect parameter expansion operator<br />
        the ${!param*} prefix expansion operator<br />
        the ${param:offset[:length]} parameter substring operator<br />
        the ${param/pat[/string]} parameter pattern substitution operator<br />
        expansions to perform substring removal (${p%[%]w}, ${p#[#]w})<br />
        expansion of positional parameters beyond $9 with ${num}<br />
        variables: BASH, BASH_VERSION, BASH_VERSINFO, UID, EUID, REPLY,<br />
                   TIMEFORMAT, PPID, PWD, OLDPWD, SHLVL, RANDOM, SECONDS,<br />
                   LINENO, HISTCMD, HOSTTYPE, OSTYPE, MACHTYPE, HOSTNAME,<br />
                   ENV, PS3, PS4, DIRSTACK, PIPESTATUS, HISTSIZE, HISTFILE,<br />
                   HISTFILESIZE, HISTCONTROL, HISTIGNORE, GLOBIGNORE, GROUPS,<br />
                   PROMPT_COMMAND, FCEDIT, FIGNORE, IGNOREEOF, INPUTRC,<br />
                   SHELLOPTS, OPTERR, HOSTFILE, TMOUT, FUNCNAME, histchars,<br />
                   auto_resume<br />
        DEBUG trap<br />
        ERR trap<br />
        variable arrays with new compound assignment syntax<br />
        redirections: <>, &#038;>, >|, <<<, [n]<&#038;word-, [n]>&#038;word-<br />
        prompt string special char translation and variable expansion<br />
        auto-export of variables in initial environment<br />
        command search finds functions before builtins<br />
        bash return builtin will exit a file sourced with `.&#8217;<br />
        builtins: cd -/-L/-P, exec -l/-c/-a, echo -e/-E, hash -d/-l/-p/-t.<br />
                  export -n/-f/-p/name=value, pwd -L/-P,<br />
                  read -e/-p/-a/-t/-n/-d/-s/-u,<br />
                  readonly -a/-f/name=value, trap -l, set +o,<br />
                  set -b/-m/-o option/-h/-p/-B/-C/-H/-P,<br />
                  unset -f/-v, ulimit -i/-m/-p/-q/-u/-x,<br />
                  type -a/-p/-t/-f/-P, suspend -f, kill -n,<br />
                  test -o optname/s1 == s2/s1 < s2/s1 > s2/-nt/-ot/-ef/-O/-G/-S<br />
        bash reads ~/.bashrc for interactive shells, $ENV for non-interactive<br />
        bash restricted shell mode is more extensive<br />
        bash allows functions and variables with the same name<br />
        brace expansion<br />
        tilde expansion<br />
        arithmetic expansion with $((&#8230;)) and `let&#8217; builtin<br />
        the `[[...]]&#8217; extended conditional command<br />
        process substitution<br />
        aliases and alias/unalias builtins<br />
        local variables in functions and `local&#8217; builtin<br />
        readline and command-line editing with programmable completion<br />
        command history and history/fc builtins<br />
        csh-like history expansion<br />
        other new bash builtins: bind, command, compgen, complete, builtin,<br />
                                 declare/typeset, dirs, enable, fc, help,<br />
                                 history, logout, popd, pushd, disown, shopt,<br />
                                 printf<br />
        exported functions<br />
        filename generation when using output redirection (command >a*)<br />
        POSIX.2-style globbing character classes<br />
        POSIX.2-style globbing equivalence classes<br />
        POSIX.2-style globbing collating symbols<br />
        egrep-like extended pattern matching operators<br />
        case-insensitive pattern matching and globbing<br />
        variable assignments preceding commands affect only that command,<br />
                even for builtins and functions<br />
        posix mode and strict posix conformance<br />
        redirection to /dev/fd/N, /dev/stdin, /dev/stdout, /dev/stderr,<br />
                /dev/tcp/host/port, /dev/udp/host/port<br />
        debugger support, including `caller&#8217; builtin and new variables<br />
        RETURN trap<br />
        the `+=&#8217; assignment operator</p>
<p>Things sh has that bash does not:<br />
        uses variable SHACCT to do shell accounting<br />
        includes `stop&#8217; builtin (bash can use alias stop=&#8217;kill -s STOP&#8217;)<br />
        `newgrp&#8217; builtin<br />
        turns on job control if called as `jsh&#8217;<br />
        $TIMEOUT (like bash $TMOUT)<br />
        `^&#8217; is a synonym for `|&#8217;<br />
        new SVR4.2 sh builtins: mldmode, priv</p>
<p>Implementation differences:<br />
        redirection to/from compound commands causes sh to create a subshell<br />
        bash does not allow unbalanced quotes; sh silently inserts them at EOF<br />
        bash does not mess with signal 11<br />
        sh sets (euid, egid) to (uid, gid) if -p not supplied and uid < 100<br />
        bash splits only the results of expansions on IFS, using POSIX.2<br />
                field splitting rules; sh splits all words on IFS<br />
        sh does not allow MAILCHECK to be unset (?)<br />
        sh does not allow traps on SIGALRM or SIGCHLD<br />
        bash allows multiple option arguments when invoked (e.g. -x -v);<br />
                sh allows only a single option argument (`sh -x -v' attempts<br />
                to open a file named `-v', and, on SunOS 4.1.4, dumps core.<br />
                On Solaris 2.4 and earlier versions, sh goes into an infinite<br />
                loop.)<br />
        sh exits a script if any builtin fails; bash exits only if one of<br />
                the POSIX.2 `special' builtins fails</p>
<p>
<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
</p>
<p>2、调用相关：</p>
<p>在脚本的调用方面（interactive、login相关），bash与sh也是存在差异<br />
以下是详细说明（假如被调用执行的脚本名字叫xxx.sh）</p>
<p>BASH：</p>
<p>1、交互式的登录shell （bash –il xxx.sh）<br />
载入的信息：<br />
/etc/profile<br />
~/.bash_profile（ ->  ~/.bashrc  ->  /etc/bashrc）<br />
~/.bash_login<br />
~/.profile</p>
<p>2、非交互式的登录shell （bash –l xxx.sh）<br />
载入的信息：<br />
/etc/profile<br />
~/.bash_profile （ ->  ~/.bashrc  ->  /etc/bashrc）<br />
~/.bash_login<br />
~/.profile<br />
$BASH_ENV</p>
<p>3、交互式的非登录shell （bash –i xxx.sh）<br />
载入的信息：<br />
~/.bashrc （ ->  /etc/bashrc）</p>
<p>4、非交互式的非登录shell （bash xxx.sh）<br />
载入的信息：<br />
$BASH_ENV</p>
<p>SH：</p>
<p>1、交互式的登录shell<br />
载入的信息：<br />
/etc/profile<br />
~/.profile</p>
<p>2、非交互式的登录shell<br />
载入的信息：<br />
/etc/profile<br />
~/.profile</p>
<p>3、交互式的非登录shell<br />
载入的信息：<br />
$ENV</p>
<p>4、非交互式的非登录shell<br />
载入的信息：<br />
nothing</p>
<p>由此可以看出，最主要的区别在于相关配置文件的是否载入，<br />
而这些配置的是否载入，也就导致了很多默认选项的差异<br />
（具体请仔细查看~/.bash_profile 等文件）</p>
<p>如：</p>
<p>[wangweiyu@ComSeOp ~]$ grep ulimit /etc/profile<br />
ulimit -S -c unlimited > /dev/null 2>&#038;1</p>
<p>即，如果/etc/profile没有被载入，则不会产生core dump</p>
<p>3、关于ssh</p>
<p>非常值得一提的是，使用ssh远程执行命令，<br />
远端sshd进程通过“bash –c”的方式来执行命令（即“非交互式的非登录shell”）<br />
所以这一点，和登录之后再在本地执行执行命令，就存在了一定的差异</p>
<p>如：</p>
<p>[wangweiyu@ComSeOp ~]$ ssh wangweiyu@127.0.0.1 &#8216;echo $-&#8217;<br />
wangweiyu@127.0.0.1&#8242;s password:<br />
hBc<br />
[wangweiyu@ComSeOp ~]$ echo $-<br />
himBH<br />
[wangweiyu@ComSeOp ~]$ ssh wangweiyu@127.0.0.1 &#8216;echo $0&#8242;<br />
wangweiyu@127.0.0.1&#8242;s password:<br />
bash<br />
[wangweiyu@ComSeOp ~]$ echo $0<br />
-bash</p>
<p>注：<br />
“$-” 中含有“i”代表“交互式shell”<br />
“$0”的显示结果为“-bash”，bash前面多个“-”，代表“登录shell”<br />
没有“i“和“-”的，是“非交互式的非登录shell”</p>
<p>另外还有一点，虽然ssh远程执行的命令是“非交互式的非登录shell”，<br />
但在执行命令之前，ssh的那一次登录本身是“交互式的登录shell”，所以其会先载入“~/.bash_profile”</p>
<p>如：<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
[wangweiyu@ComSeOp ~]$ cat .bashrc<br />
# .bashrc<br />
# User specific aliases and functions<br />
# Source global definitions<br />
if [ -f /etc/bashrc ]; then<br />
        . /etc/bashrc<br />
fi<br />
echo &#8216;xxx&#8217; # 随便输出一些字符</p>
<p>[wangweiyu@ComSeOp ~]$ ssh wangweiyu@127.0.0.1 &#8216;echo $-&#8217;<br />
wangweiyu@127.0.0.1&#8242;s password:<br />
xxx # .bashrc 被执行<br />
hBc </p>
<p>这一点，衍生出一个关于scp的问题，scp在传输数据之前，会先进行一次ssh登录，<br />
而当.bashrc文件有输出的时候，则会导致scp失败！原因是解析返回的数据包出现混乱</p>
<p>如：</p>
<p>[wangweiyu@ComSeOp ~]$ cat .bashrc<br />
# .bashrc<br />
# User specific aliases and functions<br />
# Source global definitions<br />
if [ -f /etc/bashrc ]; then<br />
        . /etc/bashrc<br />
fi<br />
echo &#8216;xxx&#8217; # 随便输出一些字符<br />
[wangweiyu@ComSeOp ~]$ scp file wangweiyu@127.0.0.1:/tmp<br />
wangweiyu@127.0.0.1&#8242;s password:<br />
xxx # 输出xxx，随后scp失败<br />
[wangweiyu@ComSeOp ~]$ echo $?<br />
1<br />
[wangweiyu@ComSeOp ~]$ ls /tmp/<br />
[wangweiyu@ComSeOp ~]$</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/668.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>简单的shell备份脚本</title>
		<link>http://www.evanjiang.net.cn/archives/439.html</link>
		<comments>http://www.evanjiang.net.cn/archives/439.html#comments</comments>
		<pubDate>Sat, 21 Feb 2009 04:13:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[shell 脚本备份]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=439</guid>
		<description><![CDATA[<p>现：每周一对指定目录进行打包上传FTP，周二至周日做更新备份上传；</p>
<p>#!/bin/sh
backup_dir=&#8221;/var/tmp/shell/&#8221;
DAT=`date &#124; awk &#8216;{print $1}&#8217;`
if [ $DAT = 'Mon' ]
then
   filename=&#8221;`date +%G%m%d`.tar&#8221;
    if [ -f $backup_dir$filename ]
        then
          rm -f $backup_dir$filename &#124;&#124;  echo &#8220;The backup is failure,please check&#8221; &#038;&#038; exit
    [...]]]></description>
			<content:encoded><![CDATA[<p>现：每周一对指定目录进行打包上传FTP，周二至周日做更新备份上传；</p>
<p>#!/bin/sh<br />
backup_dir=&#8221;/var/tmp/shell/&#8221;<br />
DAT=`date | awk &#8216;{print $1}&#8217;`<br />
if [ $DAT = 'Mon' ]<br />
then<br />
   filename=&#8221;`date +%G%m%d`.tar&#8221;<br />
    if [ -f $backup_dir$filename ]<br />
        then<br />
          rm -f $backup_dir$filename ||  echo &#8220;The backup is failure,please check&#8221; &#038;&#038; exit<br />
       else<br />
          tar cvf $backup_dir$filename /var/tmp/tmp ||  echo &#8220;The backup is failure,please check&#8221; &#038;&#038; exit<br />
          echo &#8220;Backup succeed&#8221;<br />
    fi<br />
else<br />
<span id="more-439"></span><br />
   date=`date +%w`<br />
   aa=`expr $date &#8211; 1 `<br />
   bb=&#8221;`date +%G%m%d`&#8221;<br />
   cc=`expr $bb &#8211; $aa`<br />
   filename=&#8221;$cc.tar&#8221;<br />
         t1=`date +%d`<br />
         t2=`expr $t1 &#8211; 1 `<br />
         yesterday=`date +%Y\/%m\/`$t2<br />
        tar -N &#8220;$yesterday&#8221; -cvf  $backup_dir$filename /var/tmp/tmp<br />
      echo &#8220;update&#8221;<br />
fi<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
#ftp-put<br />
host=&#8217;x.x.x.x&#8217;<br />
user=&#8217;test&#8217;<br />
passwd=&#8217;pass&#8217;<br />
mode=&#8217;bin&#8217;<br />
echo &#8220;Backup starting, please wait&#8230;&#8221;<br />
ftp -i -n <<!<br />
open $host<br />
user $user $passwd<br />
$mode<br />
mput $filename<br />
bye<br />
!<br />
echo &#8220;Backup finished&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/439.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Solaris 系统管理 &#8211; 运行状态的种类和关机命令的区别</title>
		<link>http://www.evanjiang.net.cn/archives/414.html</link>
		<comments>http://www.evanjiang.net.cn/archives/414.html#comments</comments>
		<pubDate>Tue, 17 Feb 2009 06:39:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[sun unix]]></category>
		<category><![CDATA[solaris 系统管理  运行状态 关机命令]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=414</guid>
		<description><![CDATA[<p>§1    Solaris 系统管理简介</p>
<p>§1.1 系统管理员的职责</p>
<p>★熟悉shell</p>
<p>ü         常用的shell命令</p>
<p>ü         常用的Bourne shell命令</p>
<p>ü         常用的C shell命令</p>
<p>ü         常用的Korn shell命令</p>
<p>★用户和组管理</p>
<p>ü         添加用户</p>
<p>ü [...]]]></description>
			<content:encoded><![CDATA[<p>§1    Solaris 系统管理简介</p>
<p>§1.1 系统管理员的职责</p>
<p>★熟悉shell</p>
<p>ü         常用的shell命令</p>
<p>ü         常用的Bourne shell命令</p>
<p>ü         常用的C shell命令</p>
<p>ü         常用的Korn shell命令</p>
<p>★用户和组管理</p>
<p>ü         添加用户</p>
<p>ü         删除用户</p>
<p>ü         更改用户信息</p>
<p>ü         创建删除组</p>
<p> <span id="more-414"></span></p>
<p>★角色管理</p>
<p>ü         针对特殊任务授权超级用户权限</p>
<p>ü         创建修改删除角色</p>
<p>★文件系统管理</p>
<p>ü         文件系统的类型</p>
<p>ü         加载移除文件系统</p>
<p>ü         文件系统一致性检查</p>
<p>ü         备份恢复文件和文件系统</p>
<p>ü         创建cache文件系统</p>
<p>★设备管理</p>
<p>ü         理解设备自动配置</p>
<p>ü         使用DVD-ROM设备</p>
<p>ü         使用磁带</p>
<p>ü         格式化操盘</p>
<p>ü         磁盘使用监控</p>
<p>ü         服务访问技巧</p>
<p>ü         设置双向modem.</p>
<p>★管理系统</p>
<p>ü         查找系统信息</p>
<p>ü         创建本地邮件别名</p>
<p>ü         配置其他的交换空间</p>
<p>ü         管理时间和日期</p>
<p>★打印管理</p>
<p>ü         安装打印服务器和客户端</p>
<p>ü         使用打印命令</p>
<p>★认识文件访问问题</p>
<p>ü         通过查找path来坚定问题</p>
<p>ü         通过权限和所有来解决问题</p>
<p>ü         通过网络定位问题</p>
<p>本书不包含安装系统软件,安装第3方软件,配置管理网络服务,配置邮件服务,添加删除硬件,安全管理和账号,系统监控和网络性能等.</p>
<p>      §1.2 超级用户</p>
<p>超级用户的UID是0,su到超级用户的log在: /var/adm/sulog, 如果需要使用环境变量,使用su –</p>
<p>      §1.3 用户之间通信</p>
<p>ü         登陆时的信息显示: /etc/motd</p>
<p>ü         发送消息给单个用户: write ,要在线的才可以发送</p>
<p>       比如: bash-2.03# write meil</p>
<p>meil is logged on more than one place.</p>
<p>You are connected to &#8220;pts/2&#8243;.</p>
<p>Other locations are:</p>
<p>pts/3</p>
<p>good Afternoon</p>
<p>bash-2.03#</p>
<p>ü         发送消息给所有用户    wall</p>
<p>ü         发送消息给网络用户    rwall</p>
<p>ü         Email</p>
<p>      §1.4 启动关闭系统</p>
<p>需要关键的情况如下:</p>
<p>·         Turning off system power.</p>
<p>·         Installing a new release.</p>
<p>·         Preparing for a power outage.</p>
<p>·         Adding hardware to a system.</p>
<p>·         Performing maintenance on a file system.</p>
<p>§1.5选择初始状态</p>
<p>Table 1. System Init States</p>
<p>Init State</p>
<p>Function</p>
<p>0</p>
<p>Power-down state.</p>
<p>S, or s</p>
<p>Single-user state. All file systems mounted.</p>
<p>1</p>
<p>Administrative state. All file systems mounted and user logins allowed.</p>
<p>2</p>
<p>Multiuser state (resources not exported). All daemons are running except the NFS server daemons.</p>
<p>3</p>
<p>Multiuser state. NFS resource-sharing available.</p>
<p>4<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
Alternative multiuser state (currently unused).</p>
<p>5</p>
<p>Power-down state. Shut down the operating system so that it is safe to turn off power to the system. If possible, turn off power on systems that support this feature.</p>
<p>6</p>
<p>Reboot. Shut down the system to init state 0 and then reboot to the multiuser state defined in the inittab file.</p>
<p>/etc/inittab定义的重要内容如下:</p>
<p>·         The default run level for the system.</p>
<p>·         The processes to start, monitor, and restart if they terminate.</p>
<p>·         Actions to take when the system enters a new run level.</p>
<p>它的字段如下:</p>
<p>Field</p>
<p>Description</p>
<p>id</p>
<p>A unique identifier for the entry.</p>
<p>rstate</p>
<p>A list of run levels to which this entry applies.</p>
<p>action</p>
<p>How the process specified in the process field is to be run. Possible values include initdefault, sysinit, boot, bootwait, wait, and respawn.</p>
<p>process</p>
<p>The command to execute.</p>
<p>比如:</p>
<p>bash-2.03# vi /etc/inittab</p>
<p>&#8220;/etc/inittab&#8221; 17 lines, 1081 characters</p>
<p>ap::sysinit:/sbin/autopush -f /etc/iu.ap</p>
<p>ap::sysinit:/sbin/soconfig -f /etc/sock2path</p>
<p>fs::sysinit:/sbin/rcS sysinit           >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>is:3:initdefault:</p>
<p>p3:s1234:powerfail:/usr/sbin/shutdown -y -i5 -g0 >/dev/msglog 2<>/dev/msglog</p>
<p>sS:s:wait:/sbin/rcS                     >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>s0:0:wait:/sbin/rc0                     >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>s1:1:respawn:/sbin/rc1                  >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>s2:23:wait:/sbin/rc2                    >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>s3:3:wait:/sbin/rc3                     >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>s5:5:wait:/sbin/rc5                     >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>s6:6:wait:/sbin/rc6                     >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>fw:0:wait:/sbin/uadmin 2 0              >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>of:5:wait:/sbin/uadmin 2 6              >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>rb:6:wait:/sbin/uadmin 2 1              >/dev/msglog 2<>/dev/msglog </dev/console</p>
<p>sc:234:respawn:/usr/lib/saf/sac -t 300</p>
<p>co:234:respawn:/usr/lib/saf/ttymon -g -h -p &#8220;`uname -n` console login: &#8221; -T sun -d /dev/console -l console -m ldterm,ttcompat</p>
<p>       init的执行脚本sbin中,</p>
<p>bash-2.03# ls /sbin/rc*</p>
<p>/sbin/rc0  /sbin/rc1  /sbin/rc2  /sbin/rc3  /sbin/rc5  /sbin/rc6  /sbin/rcS</p>
<p>       控制文件在/etc/init.d中,它们连接到/etc/rc*.d, 其下面的文件K开头的表示kill, S开头的表示start</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/414.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>有用的shell命令</title>
		<link>http://www.evanjiang.net.cn/archives/412.html</link>
		<comments>http://www.evanjiang.net.cn/archives/412.html#comments</comments>
		<pubDate>Tue, 17 Feb 2009 06:30:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[shell 命令]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=412</guid>
		<description><![CDATA[<p>sort ad.txt &#124; uniq -u > ad_net.txt</p>
<p>例如，你ad.txt 有许多重重的数据，要处理一下，就可以用这个命令将多余的，重复的数据清除掉，只保持唯一的一条数据记录。。。</p>
]]></description>
			<content:encoded><![CDATA[<p>sort ad.txt | uniq -u > ad_net.txt</p>
<p>例如，你ad.txt 有许多重重的数据，要处理一下，就可以用这个命令将多余的，重复的数据清除掉，只保持唯一的一条数据记录。。。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/412.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vi 编辑器使用手册</title>
		<link>http://www.evanjiang.net.cn/archives/354.html</link>
		<comments>http://www.evanjiang.net.cn/archives/354.html#comments</comments>
		<pubDate>Thu, 05 Feb 2009 13:58:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[vi 使用]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=354</guid>
		<description><![CDATA[<p>&#8220;To me, vi is Zen.
To use vi is to practice zen.
Every command is a koan.
Profound to the user,
unintelligible to the uninitiated.
You discover truth every time you use it.&#8221;
&#8211;reddy@lion.austin.com
&#8220;对我来说，vi就是禅。
用vi就是坐禅。
每一个命令就是一个心印
对皈依者意义深远
对不了解者不可捉摸
每一次使用都会有新的发现&#8221;</p>
<p>VI是所有*NIX类系统都内置的一个命令行文本编辑软件，功能强大，命令繁多。初学时很难上手，但是一旦你熟悉之后，相信你不会再想使用其他的编辑软件。</p>
<p>本篇假定你已经熟悉VI的一些基本命令，如：
vi httpd.conf #打开一个名为httpd.conf的文档，如果不存在，将在当前目录下创建此文档；
输入“：wq”：存盘推出命令。
输入“：q！”：不存盘，强制推出
ESC：在命令模式与输入模式之间切换
i，I或者o等：插入文本命令&#8230;&#8230;..

VI之一：光标移动篇</p>
<p>这里我们先学习一下如何在一篇打开的文档中进行光标移动。</p>
<p>1. 方向键h,j,k,l.
h: 将光标向左移动一个字符
j: 将光标向下移动一个字符
k: 将光标向上移动一个字符
l: 将光标向右移动一个字符</p>
<p>这四个键相当于方向键,另设它们的好处是:你的手指不必离开正常的输入位置</p>
<p>2. 按字符移动的命令
fx: 移动光标至当前行下一个x字符处;使用;来重复上一次的f移动
tx: 同fx，但是移动光标至x字符前，而不是x字符上
Fx：通fx，但反方向移动








w:前移光标至下一个单词第一字符
W:前移光标至下一个长单词第一字符
e: 前移光标至下一个单词最后字符
E: 前移光标至下一个长单词最后字符
b: 前一单词第一字符
B: 前一长单词第一字符
(vi 按空格或标点符号分隔单词,按空格或新行来分隔长单词)</p>
<p>(: 到句首
): 到句尾</p>
<p>0: 到行首
^: 到行首第一字符
$: 到行尾</p>
<p>{: 到段首
}: 到段尾</p>
<p>*: 读取光标当前所在位置的字符,并将向前移动至下一个同样的字符
#: 和*功能相同,但反方向移动光标</p>
<p>Ctrl+F: 向前滚屏
Ctrl+B: 向后滚屏
H,M,L: 移动光标至屏幕的顶端,中间,底端</p>
<p>G: [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;To me, vi is Zen.<br />
To use vi is to practice zen.<br />
Every command is a koan.<br />
Profound to the user,<br />
unintelligible to the uninitiated.<br />
You discover truth every time you use it.&#8221;<br />
&#8211;reddy@lion.austin.com<br />
&#8220;对我来说，vi就是禅。<br />
用vi就是坐禅。<br />
每一个命令就是一个心印<br />
对皈依者意义深远<br />
对不了解者不可捉摸<br />
每一次使用都会有新的发现&#8221;</p>
<p>VI是所有*NIX类系统都内置的一个命令行文本编辑软件，功能强大，命令繁多。初学时很难上手，但是一旦你熟悉之后，相信你不会再想使用其他的编辑软件。</p>
<p>本篇假定你已经熟悉VI的一些基本命令，如：<br />
vi httpd.conf #打开一个名为httpd.conf的文档，如果不存在，将在当前目录下创建此文档；<br />
输入“：wq”：存盘推出命令。<br />
输入“：q！”：不存盘，强制推出<br />
ESC：在命令模式与输入模式之间切换<br />
i，I或者o等：插入文本命令&#8230;&#8230;..<br />
<span id="more-354"></span><br />
VI之一：光标移动篇</p>
<p>这里我们先学习一下如何在一篇打开的文档中进行光标移动。</p>
<p>1. 方向键h,j,k,l.<br />
h: 将光标向左移动一个字符<br />
j: 将光标向下移动一个字符<br />
k: 将光标向上移动一个字符<br />
l: 将光标向右移动一个字符</p>
<p>这四个键相当于方向键,另设它们的好处是:你的手指不必离开正常的输入位置</p>
<p>2. 按字符移动的命令<br />
fx: 移动光标至当前行下一个x字符处;使用;来重复上一次的f移动<br />
tx: 同fx，但是移动光标至x字符前，而不是x字符上<br />
Fx：通fx，但反方向移动<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
w:前移光标至下一个单词第一字符<br />
W:前移光标至下一个长单词第一字符<br />
e: 前移光标至下一个单词最后字符<br />
E: 前移光标至下一个长单词最后字符<br />
b: 前一单词第一字符<br />
B: 前一长单词第一字符<br />
(vi 按空格或标点符号分隔单词,按空格或新行来分隔长单词)</p>
<p>(: 到句首<br />
): 到句尾</p>
<p>0: 到行首<br />
^: 到行首第一字符<br />
$: 到行尾</p>
<p>{: 到段首<br />
}: 到段尾</p>
<p>*: 读取光标当前所在位置的字符,并将向前移动至下一个同样的字符<br />
#: 和*功能相同,但反方向移动光标</p>
<p>Ctrl+F: 向前滚屏<br />
Ctrl+B: 向后滚屏<br />
H,M,L: 移动光标至屏幕的顶端,中间,底端</p>
<p>G: 移动光标至文档最后一行<br />
numG: 移动光标至第num行<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
/text: 从光标处开始,向前搜索&#8221;text&#8221;字串<br />
?text: 同上,但搜索方向相反</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/354.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>分享mail服务器mysql数据库备份脚本</title>
		<link>http://www.evanjiang.net.cn/archives/252.html</link>
		<comments>http://www.evanjiang.net.cn/archives/252.html#comments</comments>
		<pubDate>Fri, 16 Jan 2009 07:54:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[mail]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[shell 备份脚本 mysql]]></category>

		<guid isPermaLink="false">http://www.hunttech.com.cn/wpblog/?p=252</guid>
		<description><![CDATA[<p>功能：备份mysql数据库中mail的数据库数据,并用gz压缩，先备份到本地，然后自动上传到指定的ftp服务器,备份日志email到指定的邮箱
</p>

?View Code SHELL[root@mail cron.daily]# cat mailmysql_backup_ftp
#!/bin/bash
#Mysql Autobackup Shell
&#160;
#DB env
dbuser=root
dbpasswd=root
dbserver=localhost
dbname=extmail
#dbopt=--opt
backupdir=/home/mysql-backup/
&#160;
#FTP 0 is disable,1 is enable
copytoftp=1
ftpserver=10.1.1.8
ftpuser=admin
ftppasswd=admin
fileprefix=extmail
dumpfilename=$backupdir`date +%F`.sql
newfile=$fileprefix-`date +%F`.gz
keepdays=16
&#160;
#Backup log
logfile=/tmp/mysqldump.log
logtmp=/tmp/mysqldump.tmp
&#160;
#mail 0 is diable,1 is enable
mailenable=1
mailaddress=ruochen0926@hotmail.com
&#160;
#Backup script
#===============================================
if [ ! -d $backupdir ]
then
        echo &#34;$backupdir is not exist, then make ...&#34; &#38;gt; $logfile
        mkdir -p $backupdir
fi
echo [...]]]></description>
			<content:encoded><![CDATA[<p>功能：备份mysql数据库中mail的数据库数据,并用gz压缩，先备份到本地，然后自动上传到指定的ftp服务器,备份日志email到指定的邮箱<br />
<span id="more-252"></span></p>

<div class="wp_codebox_msgheader wp_codebox_hide"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p252code2'); return false;">View Code</a> SHELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2522"><td class="code" id="p252code2"><pre class="shell" style="font-family:monospace;">[root@mail cron.daily]# cat mailmysql_backup_ftp
#!/bin/bash
#Mysql Autobackup Shell
&nbsp;
#DB env
dbuser=root
dbpasswd=root
dbserver=localhost
dbname=extmail
#dbopt=--opt
backupdir=/home/mysql-backup/
&nbsp;
#FTP 0 is disable,1 is enable
copytoftp=1
ftpserver=10.1.1.8
ftpuser=admin
ftppasswd=admin
fileprefix=extmail
dumpfilename=$backupdir`date +%F`.sql
newfile=$fileprefix-`date +%F`.gz
keepdays=16
&nbsp;
#Backup log
logfile=/tmp/mysqldump.log
logtmp=/tmp/mysqldump.tmp
&nbsp;
#mail 0 is diable,1 is enable
mailenable=1
mailaddress=ruochen0926@hotmail.com
&nbsp;
#Backup script
#===============================================
if [ ! -d $backupdir ]
then
        echo &quot;$backupdir is not exist, then make ...&quot; &amp;gt; $logfile
        mkdir -p $backupdir
fi
echo &quot;start====================================&amp;gt;&quot;&amp;gt;$logfile
echo &quot;Beginning backup `date '+%F %T'`&quot; &amp;gt;&amp;gt;$logfile
echo &quot;Delete $keepdays days ago files ...&quot; &amp;gt;&amp;gt;$logfile
find $backupdir -name $fileprefix* -mtime +$keepdays -fls $logtmp -exec rm {} \;
echo &quot;Deleted Backup File Is :&quot;&amp;gt;&amp;gt;$logfile
cat $logtmp &amp;gt;&amp;gt;$logfile
echo &quot;Delete old file Success!&quot; &amp;gt;&amp;gt;$logfile
if [ -f $backupdir$newfile ]
then
echo &quot;$newfile backup exist, backup stop ...&quot; &amp;gt;&amp;gt;$logfile
else
        if [ -z $dbpasswd ]
        then
#        mysqldump -u$dbuser -h$dbserver $dbopt $dbname &amp;gt;$dumpfilename
        /usr/bin/mysqldump -u$dbuser -h$dbserver $dbopt $dbname &amp;gt;$dumpfilename
        else
#        /opt/lampp/bin/mysqldump -u$dbuser -p$dbpasswd -h$dbserver $dbopt $dbname | gzip &amp;gt; /opt/apache/mysqlbackup/$newfile
        /usr/bin/mysqldump -u$dbuser -p$dbpasswd -h$dbserver $dbopt $dbname | gzip &amp;gt; $backupdir/$newfile
        fi
#        tar czvf $backupdir$newfile $dumpfilename &amp;gt;&amp;gt;$logfile 2&amp;gt;&amp;amp;1
#        gzip $dumpfilename  $newfile  &amp;gt;&amp;gt;$logfile 2&amp;gt;&amp;amp;1
        echo &quot;$backupdir$newfile Backup Success!&quot; &amp;gt;&amp;gt;$logfile
        rm -fr $dumpfilename
&nbsp;
if [ $copytoftp = 1 ];  then
        if [ -z $ftpserver ];then
        echo &quot;Ftp Server not set,Copy to Ftp Failed ...&quot; &amp;gt;&amp;gt;$logfile
        exit 1
        elif [ -z $ftpuser ];then
        echo &quot;Ftp user not set, Copy to Ftp Failed ...&quot; &amp;gt;&amp;gt;$logfile
        exit 2
        elif [ -z $ftppasswd ]; then
        echo &quot;Ftp password not set, Copy to Ftp Failed ...&quot; &amp;gt;&amp;gt;$logfile
        exit 3
        else
        echo &quot;Start copy to Ftp server ....&quot; &amp;gt;&amp;gt; $logfile
ftp -n&amp;lt;&amp;gt;$logfile
echo &quot;End=======================================|&quot;&amp;gt;&amp;gt;$logfile
fi
&nbsp;
if [ $mailenable=1 ];
    then
      mail -s &quot;Mail Server Mysql Backup Status&quot; $mailaddress&amp;lt;$logfile
fi</pre></td></tr></table></div>

<p>
<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/252.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WEB服务端故障监控及恢复脚本</title>
		<link>http://www.evanjiang.net.cn/archives/133.html</link>
		<comments>http://www.evanjiang.net.cn/archives/133.html#comments</comments>
		<pubDate>Fri, 19 Dec 2008 13:43:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[www]]></category>
		<category><![CDATA[web服务器 监控 脚本]]></category>

		<guid isPermaLink="false">http://www.hunttech.com.cn/wpblog/?p=133</guid>
		<description><![CDATA[<p> </p>
<p>为过好中秋，给所有WEB Server前端机器加了个脚本，运行良好，特奉献给广大的linux系统管理员同志：）</p>
<p>一，首先构建判断WEB Server是否正常的html测试文件及虚拟主机配置:</p>
<p>在Apache添加：health.mydomain.com 的虚拟主机，指到/web/php：</p>
<p> </p>
<p>&#60;VirtualHost *&#62;</p>
<p>    ServerName health.mydomain.com</p>
<p>    DocumentRoot /web/php/</p>
<p>    ErrorLog /dev/null</p>
<p>    CustomLog /dev/null combined</p>
<p>&#60;/VirtualHost&#62;</p>
<p></p>
<p> </p>
<p>hosts文件加入:</p>
<p>xxx.xxx.xxx.xxx        health.mydomain.com</p>
<p> </p>
<p> </p>
<p>在/web/php新建一html用来判断apache是否正常:</p>
<p> </p>
<p>文件名 health.html</p>
<p> </p>
<p> </p>
<p>&#60;html&#62;</p>
<p>&#60;head&#62;</p>
<p>&#60;title&#62;WEBSERVEROK&#60;/title&#62;</p>
<p>&#60;/head&#62;</p>
<p>&#60;body&#62;</p>
<p>&#60;/body&#62;</p>
<p>&#60;/html&#62;</p>
<p> </p>
<p> </p>
<p> 








 </p>
<p>二，编写脚本，并输出监控日志到/var/log/health.log:</p>
<p> </p>
<p>三，加到服务器每隔5分钟运行的cron:</p>
<p> </p>
<p>*/5 * * * * root /web/health.sh</p>
<p> </p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; /web/health.sh &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p> </p>
<p>#!/bin/bash</p>
<p> </p>
<p>#The WEB Server Status Check and Repair Script.</p>
<p> </p>
<p>#(C)  Zoey Last Date:2008-09-12</p>
<p> </p>
<p> </p>
<p>TMP=/tmp/health.html</p>
<p>HEALTH=&#8221;WEBSERVEROK&#8221;</p>
<p>REQUEST_APACHE=http://health.mydomain.com:81/health.html</p>
<p>REQUEST_SQUID=http://health.mydoamin.com:80/health.html</p>
<p>LOGDATE=&#8221;$(date +%F) $(date +%T) $HOSTNAME &#8221;</p>
<p>LOGFILE=/var/log/health.log</p>
<p>export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin</p>
<p> </p>
<p>[ ! -f $LOGFILE ] &#38;&#38; touch $LOGFILE</p>
<p> </p>
<p>function Check_Status()</p>
<p>{</p>
<p> </p>
<p>local RETRY=1</p>
<p>local SUCCESS=0</p>
<p> </p>
<p>while [ $RETRY [...]]]></description>
			<content:encoded><![CDATA[<p> </p>
<p>为过好中秋，给所有WEB Server前端机器加了个脚本，运行良好，特奉献给广大的linux系统管理员同志：）</p>
<p>一，首先构建判断WEB Server是否正常的html测试文件及虚拟主机配置:</p>
<p>在Apache添加：health.mydomain.com 的虚拟主机，指到/web/php：</p>
<p> </p>
<p>&lt;VirtualHost *&gt;</p>
<p>    ServerName health.mydomain.com</p>
<p>    DocumentRoot /web/php/</p>
<p>    ErrorLog /dev/null</p>
<p>    CustomLog /dev/null combined</p>
<p>&lt;/VirtualHost&gt;</p>
<p><span id="more-133"></span></p>
<p> </p>
<p>hosts文件加入:</p>
<p>xxx.xxx.xxx.xxx        health.mydomain.com</p>
<p> </p>
<p> </p>
<p>在/web/php新建一html用来判断apache是否正常:</p>
<p> </p>
<p>文件名 health.html</p>
<p> </p>
<p> </p>
<p>&lt;html&gt;</p>
<p>&lt;head&gt;</p>
<p>&lt;title&gt;WEBSERVEROK&lt;/title&gt;</p>
<p>&lt;/head&gt;</p>
<p>&lt;body&gt;</p>
<p>&lt;/body&gt;</p>
<p>&lt;/html&gt;</p>
<p> </p>
<p> </p>
<p> <br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
 </p>
<p>二，编写脚本，并输出监控日志到/var/log/health.log:</p>
<p> </p>
<p>三，加到服务器每隔5分钟运行的cron:</p>
<p> </p>
<p>*/5 * * * * root /web/health.sh</p>
<p> </p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; /web/health.sh &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p> </p>
<p>#!/bin/bash</p>
<p> </p>
<p>#The WEB Server Status Check and Repair Script.</p>
<p> </p>
<p>#(C)  Zoey Last Date:2008-09-12</p>
<p> </p>
<p> </p>
<p>TMP=/tmp/health.html</p>
<p>HEALTH=&#8221;WEBSERVEROK&#8221;</p>
<p>REQUEST_APACHE=http://health.mydomain.com:81/health.html</p>
<p>REQUEST_SQUID=http://health.mydoamin.com:80/health.html</p>
<p>LOGDATE=&#8221;$(date +%F) $(date +%T) $HOSTNAME &#8221;</p>
<p>LOGFILE=/var/log/health.log</p>
<p>export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin</p>
<p> </p>
<p>[ ! -f $LOGFILE ] &amp;&amp; touch $LOGFILE</p>
<p> </p>
<p>function Check_Status()</p>
<p>{</p>
<p> </p>
<p>local RETRY=1</p>
<p>local SUCCESS=0</p>
<p> </p>
<p>while [ $RETRY -le 3 ]; do </p>
<p> </p>
<p>        [ -f $TMP ] &amp;&amp; rm -f $TMP</p>
<p> </p>
<p>        curl $2 &gt; $TMP 2&gt;&amp;1</p>
<p> </p>
<p>        STATUS=$(egrep -o &#8220;$HEALTH&#8221; $TMP)</p>
<p> </p>
<p>        if [ x$STATUS = x ]; then</p>
<p>                echo &#8220;${LOGDATE}$1 检查失败重新检查 $1 第 $RETRY 次，重试&#8230;&#8221; &gt;&gt; $LOGFILE</p>
<p>                let RETRY=$RETRY+1</p>
<p>                sleep 2</p>
<p>                continue</p>
<p>        fi</p>
<p> </p>
<p>        if [ $STATUS = "$HEALTH" ]; then </p>
<p>                echo &#8220;${LOGDATE}$1 工作正常!&#8221; &gt;&gt; $LOGFILE</p>
<p>                SUCCESS=1</p>
<p>                break</p>
<p>                else </p>
<p>                echo &#8220;${LOGDATE}$1 检查失败重新检查 $1 第 $RETRY 次，重试&#8230;&#8221; &gt;&gt; $LOGFILE</p>
<p>                let RETRY=$RETRY+1</p>
<p>                sleep 2</p>
<p>        fi</p>
<p> </p>
<p>done</p>
<p> </p>
<p>if [ $SUCCESS -eq 0 ]; then</p>
<p>        let FC=$RETRY-1</p>
<p>        echo &#8220;${LOGDATE}重复 $FC 次检查 $1 状态失败，准备重新启动 $1!&#8221; &gt;&gt; $LOGFILE</p>
<p>        RETURN=0</p>
<p>else</p>
<p>        RETURN=1</p>
<p>fi</p>
<p> </p>
<p>rm -f $TMP</p>
<p> </p>
<p>}</p>
<p> </p>
<p>Check_Status Apache $REQUEST_APACHE</p>
<p> </p>
<p>if [ $RETURN -eq 0 ]; then</p>
<p> </p>
<p>        PID=$(ps -ef | grep httpd | sed &#8216;/grep/d&#8217; | wc -l)</p>
<p> </p>
<p>        if [ $PID -ge 1 ]; then </p>
<p> </p>
<p>                echo &#8220;${LOGDATE} 发现 Apache 进程存在，杀死并重新启动&#8230;&#8221; &gt;&gt; $LOGFILE</p>
<p>                HTTP_PID=$(ps -ef | grep httpd | sed &#8216;/grep/d&#8217; | awk &#8216;{print $2}&#8217;)</p>
<p>                kill -9 $HTTP_PID &gt; /dev/null 2&gt;&amp;1</p>
<p>                service httpd start &gt; /dev/null 2&gt;&amp;1</p>
<p> </p>
<p>        else</p>
<p> </p>
<p>                service httpd start &gt; /dev/null 2&gt;&amp;1</p>
<p> </p>
<p>        fi</p>
<p>                sleep 2</p>
<p> </p>
<p>        PID=$(ps -ef | grep httpd | sed &#8216;/grep/d&#8217; | wc -l)</p>
<p> </p>
<p>        if [ $PID -ge 1 ]; then</p>
<p> </p>
<p>                echo &#8220;${LOGDATE}重新启动 Apache 成功!&#8221; &gt;&gt; $LOGFILE</p>
<p>        else</p>
<p>                echo &#8220;${LOGDATE}重新启动 Apache 失败!&#8221; &gt;&gt; $LOGFILE</p>
<p>#               此处添加启动失败报警（以后完成)</p>
<p> </p>
<p>        fi</p>
<p>fi</p>
<p> </p>
<p>Check_Status SQUID $REQUEST_SQUID</p>
<p> </p>
<p>if [ $RETURN -eq 0 ]; then</p>
<p> </p>
<p>        PID=$(ps ax | grep &#8220;(squid)&#8221; | sed &#8216;/grep/d&#8217; | wc -l)</p>
<p> </p>
<p>        if [ $PID -ge 1 ]; then</p>
<p> </p>
<p>                echo &#8220;${LOGDATE} 发现 SQUID 进程存在，杀死并重新启动&#8230;&#8221; &gt;&gt; $LOGFILE</p>
<p>                SQUID_PID=$(ps -ef | grep &#8220;(squid)&#8221; | sed &#8216;/grep/d&#8217; awk &#8216;{print $2}&#8217;)</p>
<p>                kill -9 $SQUID_PID &gt; /dev/null 2&gt;&amp;1</p>
<p>                service squid start &gt; /dev/null 2&gt;&amp;1</p>
<p> </p>
<p>        else</p>
<p> </p>
<p>                service squid start &gt; /dev/null 2&gt;&amp;1</p>
<p> </p>
<p>        fi</p>
<p> </p>
<p>                sleep 2</p>
<p> </p>
<p>        PID=$(ps ax | grep &#8220;(squid)&#8221; | sed &#8216;/grep/d&#8217; | wc -l)</p>
<p> </p>
<p>        if [ $PID -ge 1 ]; then</p>
<p> </p>
<p>                echo &#8220;${LOGDATE}重新启动 SQUID 成功!&#8221; &gt;&gt; $LOGFILE</p>
<p>        else</p>
<p> </p>
<p>                echo &#8220;${LOGDATE}重新启动 SQUID 失败!&#8221; &gt;&gt; $LOGFILE</p>
<p>#               此处添加启动失败报警 (以后完成)</p>
<p> </p>
<p>        fi</p>
<p>fi</p>
<div></div>
<p>
<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/133.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
