| 安全 |
所有用户都可以用passwd -s看自己口令属性,超级用户可以看别人。
显示格式如下:
name status mm/dd/yy min max warn
status PS有口令,LK锁定,NP无口令
mm/dd/yy 口令最后一次被改变的时间
min 单位为天。下次更改的口令的最短时限。
/etc/default/passwd中定义了MINWEEKS
max 口令有效的最长时限。
MAXWEEKS is found in /etc/default/passwd and is set to NULL.
warn 在口令过期前多少天开始提醒用户
passwd -e jhli Change the login shell.
passwd -g jhli Change the gecos (finger) information.
passwd -h jhli Change the home directory.
passwd -f jhli 强迫用户下次更改口令
passwd -l jhli 锁定用户
passwd -d jhli 删除口令后不会给出password:提示,而口令为空的时候依旧会出现这个提示,还需要按一次回车。
-n min 如果min比max大,则用户无法自己修改口令。
-w warn
-x max 把max设置成-1,则用户口令永不过期。若设置成0,则强迫用户下次登录时更改口令,然后该用户口令过期功能被关闭。
passwd -a -s 显示所有用户口令属性
/etc/default/passwd文件是个配置文件,
MAXWEEKS=
MINWEEKS=
PASSLENGTH=
WARNWEEKS=
PASSLENGTH=6表明口令至少6个字符,口令超过8个字符的时候只有前8个字符有意义。值得注意的是,su和rlogin的时候,只要安全检查通过并不理会LK状态。所以如果发现这些LK用户拥有过shell进程,那就要好好检查安全问题了。
/etc/dialups列出了需要额外的拨号口令的终端设备全称路径名。
该文件应该是root属主,并且chmod 600
/etc/d_passwd格式如下login-shell:password:
/dev/pts/4
/dev/pts/5
/dev/pts/6
/dev/pts/7
/usr/bin/sh:!@#$%^&*:
/usr/bin/csh:!@#$%^&*:
/sbin/sh:!@#$%^&*:
效果如下,jhli使用/usr/bin/csh。
登录成功后可以用tty命令确认自己使用哪个终端。
login: jhli
Password:
Dialup Password:
各个操作系统可能有细微差别,请man dialups、man d_passwd。
同时提醒大家的是,man可能是没有得到更新的早期的man,实践出来的效果才是真的。
在Linux系统中,有三个主要的日志子系统:
连接时间日志--由多个程序执行,把纪录写入到/var/log/wtmp和/var/run/utmp,login等程序更新wtmp和utmp文件,使系统管理员能够跟踪谁在何时登录到系统。
进程统计--由系统内核执行。当一个进程终止时,为每个进程往进程统计文件(pacct或acct)中写一个纪录。进程统计的目的是为系统中的基本服务提供命令使用统计。
错误日志--由syslogd(8)执行。各种系统守护进程、用户程序和内核通过syslog(3)向文件/var/log/messages报告值得注意的事件。另外有许多UNIX程序创建日志。像HTTP和FTP这样提供网络服务的服务器也保持详细的日志。
常用的日志文件如下:
access-log 纪录HTTP/web的传输
acct/pacct 纪录用户命令
aculog 纪录MODEM的活动
btmp 纪录失败的纪录
lastlog 纪录最近几次成功登录的事件和最后一次不成功的登录
messages 从syslog中记录信息(有的链接到syslog文件)
sudolog 纪录使用sudo发出的命令
sulog 纪录使用su命令的使用
syslog 从syslog中记录信息(通常链接到messages文件)
utmp 纪录当前登录的每个用户
wtmp 一个用户每次登录进入和退出时间的永久纪录
xferlog 纪录FTP会话
utmp、wtmp和lastlog日志文件是多数重用UNIX日志子系统的关键--保持用户登录进入和退出的纪录。有关当前登录用户的信息记录在文件utmp中;登录进入和退出纪录在文件wtmp中;最后一次登录文件可以用lastlog命令察看。数据交换、关机和重起也记录在wtmp文件中。所有的纪录都包含时间戳。这些文件(lastlog通常不大)在具有大量用户的系统中增长十分迅速。例如wtmp文件可以无限增长,除非定期截取。许多系统以一天或者一周为单位把wtmp配置成循环使用。它通常由cron运行的脚本来修改。这些脚本重新命名并循环使用wtmp文件。通常,wtmp在第一天结束后命名为wtmp.1;第二天后wtmp.1变为wtmp.2等等,直到wtmp.7。
每次有一个用户登录时,login程序在文件lastlog中察看用户的UID。如果找到了,则把用户上次登录、退出时间和主机名写到标准输出中,然后login程序在lastlog中纪录新的登录时间。在新的lastlog纪录写入后,utmp文件打开并插入用户的utmp纪录。该纪录一直用到用户登录退出时删除。utmp文件被各种命令文件使用,包括who、w、users和finger。
下一步,login程序打开文件wtmp附加用户的utmp纪录。当用户登录退出时,具有更新时间戳的同一utmp纪录附加到文件中。wtmp文件被程序last和ac使用。
具体命令
wtmp和utmp文件都是二进制文件,他们不能被诸如tail命令剪贴或合并(使用cat命令)。用户需要使用who、w、users、last和ac来使用这两个文件包含的信息。
who:who命令查询utmp文件并报告当前登录的每个用户。Who的缺省输出包括用户名、终端类型、登录日期及远程主机。例如:who(回车)显示
chyang pts/0 Aug 18 15:06
ynguo pts/2 Aug 18 15:32
ynguo pts/3 Aug 18 13:55
lewis pts/4 Aug 18 13:35
ynguo pts/7 Aug 18 14:12
ylou pts/8 Aug 18 14:15
如果指明了wtmp文件名,则who命令查询所有以前的纪录。命令who /var/log/wtmp将报告自从wtmp文件创建或删改以来的每一次登录。
w:w命令查询utmp文件并显示当前系统中每个用户和它所运行的进程信息。例如:w(回车)显示:3:36pm up 1 day, 22:34, 6 users, load average: 0.23, 0.29, 0.27。
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
chyang pts/0 202.38.68.242 3:06pm 2:04 0.08s 0.04s -bash
ynguo pts/2 202.38.79.47 3:32pm 0.00s 0.14s 0.05 w
lewis pts/3 202.38.64.233 1:55pm 30:39 0.27s 0.22s -bash
lewis pts/4 202.38.64.233 1:35pm 6.00s 4.03s 0.01s sh /home/users/
ynguo pts/7 simba.nic.ustc.e 2:12pm 0.00s 0.47s 0.24s telnet mail
ylou pts/8 202.38.64.235 2:15pm 1:09m 0.10s 0.04s -bash
users:users用单独的一行打印出当前登录的用户,每个显示的用户名对应一个登录会话。如果一个用户有不止一个登录会话,那他的用户名将显示相同的次数。例如:users(回车)显示:chyang lewis lewis ylou ynguo ynguo
last:last命令往回搜索wtmp来显示自从文件第一次创建以来登录过的用户。例如:
chyang pts/9 202.38.68.242 Tue Aug 1 08:34 - 11:23 (02:49)
cfan pts/6 202.38.64.224 Tue Aug 1 08:33 - 08:48 (00:14)
chyang pts/4 202.38.68.242 Tue Aug 1 08:32 - 12:13 (03:40)
lewis pts/3 202.38.64.233 Tue Aug 1 08:06 - 11:09 (03:03)
lewis pts/2 202.38.64.233 Tue Aug 1 07:56 - 11:09 (03:12
如果指明了用户,那么last只报告该用户的近期活动,例如:last ynguo(回车)显示:
ynguo pts/4 simba.nic.ustc.e Fri Aug 4 16:50 - 08:20 (15:30)
ynguo pts/4 simba.nic.ustc.e Thu Aug 3 23:55 - 04:40 (04:44)
ynguo pts/11 simba.nic.ustc.e Thu Aug 3 20:45 - 22:02 (01:16)
ynguo pts/0 simba.nic.ustc.e Thu Aug 3 03:17 - 05:42 (02:25)
ynguo pts/0 simba.nic.ustc.e Wed Aug 2 01:04 - 03:16 1+02:12)
ynguo pts/0 simba.nic.ustc.e Wed Aug 2 00:43 - 00:54 (00:11)
ynguo pts/9 simba.nic.ustc.e Thu Aug 1 20:30 - 21:26 (00:55)
ac:ac命令根据当前的/var/log/wtmp文件中的登录进入和退出来报告用户连结的时间(小时),如果不使用标志,则报告总的时间。例如:ac(回车)显示:total 5177.47
ac -d(回车)显示每天的总的连结时间
Aug 12 total 261.87
Aug 13 total 351.39
Aug 14 total 396.09
Aug 15 total 462.63
Aug 16 total 270.45
Aug 17 total 104.29
Today total 179.02
ac -p (回车)显示每个用户的总的连接时间
ynguo 193.23
yucao 3.35
rong 133.40
hdai 10.52
zjzhu 52.87
zqzhou 13.14
liangliu 24.34
total 5178.24
lastlog:lastlog文件在每次有用户登录时被查询。可以使用lastlog命令来检查某特定用户上次登录的时间,并格式化输出上次登录日志/var/log/lastlog的内容。它根据UID排序显示登录名、端口号(tty)和上次登录时间。如果一个用户从未登录过,lastlog显示\"**Never logged**。注意需要以root运行该命令,例如:
rong 5 202.38.64.187 Fri Aug 18 15:57:01 +0800 2000
dbb **Never logged in**
xinchen **Never logged in**
pb9511 **Never logged in**
xchen 0 202.38.64.190 Sun Aug 13 10:01:22 +0800 2000
另外,可一加一些参数,例如,last -u 102将报告UID为102的用户;last -t 7表示限制上一周的报告。
进程统计
UNIX可以跟踪每个用户运行的每条命令,如果想知道昨晚弄乱了哪些重要的文件,进程统计子系统可以告诉你。它对还跟踪一个侵入者有帮助。与连接时间日志不同,进程统计子系统缺省不激活,它必须启动。在Linux系统中启动进程统计使用accton命令,必须用root身份来运行。Accton命令的形式accton file,file必须先存在。先使用touch命令来创建pacct文件:touch /var/log/pacct,然后运行accton: accton /var/log/pacct。一旦accton被激活,就可以使用lastcomm命令监测系统中任何时候执行的命令。若要关闭统计,可以使用不带任何参数的accton命令。
lastcomm命令报告以前执行的文件。不带参数时,lastcomm命令显示当前统计文件生命周期内纪录的所有命令的有关信息。包括命令名、用户、tty、命令花费的CPU时间和一个时间戳。如果系统有许多用户,输入则可能很长。下面的例子:
crond F root ?? 0.00 secs Sun Aug 20 00:16
promisc_check.s S root ?? 0.04 secs Sun Aug 20 00:16
promisc_check root ?? 0.01 secs Sun Aug 20 00:16
grep root ?? 0.02 secs Sun Aug 20 00:16
tail root ?? 0.01 secs Sun Aug 20 00:16
sh root ?? 0.01 secs Sun Aug 20 00:15
ping S root ?? 0.01 secs Sun Aug 20 00:15
ping6.pl F root ?? 0.01 secs Sun Aug 20 00:15
sh root ?? 0.01 secs Sun Aug 20 00:15
ping S root ?? 0.02 secs Sun Aug 20 00:15
ping6.pl F root ?? 0.02 secs Sun Aug 20 00:15
sh root ?? 0.02 secs Sun Aug 20 00:15
ping S root ?? 0.00 secs Sun Aug 20 00:15
ping6.pl F root ?? 0.01 secs Sun Aug 20 00:15
sh root ?? 0.01 secs Sun Aug 20 00:15
ping S root ?? 0.01 secs Sun Aug 20 00:15
sh root ?? 0.02 secs Sun Aug 20 00:15
ping S root ?? 1.34 secs Sun Aug 20 00:15
locate root ttyp0 1.34 secs Sun Aug 20 00:15
accton S root ttyp0 0.00 secs Sun Aug 20 00:15
进程统计的一个问题是pacct文件可能增长的十分迅速。这时需要交互式的或经过cron机制运行sa命令来保持日志数据在系统控制内。sa命令报告、清理并维护进程统计文件。它能把/var/log/pacct中的信息压缩到摘要文件/var/log/savacct和/var/log/usracct中。这些摘要包含按命令名和用户名分类的系统统计数据。sa缺省情况下先读它们,然后读pacct文件,使报告能包含所有的可用信息。sa的输出有下面一些标记项:
avio--每次执行的平均I/O操作次数
cp--用户和系统时间总和,以分钟计
cpu--和cp一样
k--内核使用的平均CPU时间,以1k为单位
k*sec--CPU存储完整性,以1k-core秒
re--实时时间,以分钟计
s--系统时间,以分钟计
tio--I/O操作的总数
u--用户时间,以分钟计
例如:
842 173.26re 4.30cp 0avio 358k
2 10.98re 4.06cp 0avio 299k find
9 24.80re 0.05cp 0avio 291k ***other
105 30.44re 0.03cp 0avio 302k ping
104 30.55re 0.03cp 0avio 394k sh
162 0.11re 0.03cp 0avio 413k security.sh*
154 0.03re 0.02cp 0avio 273k ls
56 31.61re 0.02cp 0avio 823k ping6.pl*
2 3.23re 0.02cp 0avio 822k ping6.pl
35 0.02re 0.01cp 0avio 257k md5sum
97 0.02re 0.01cp 0avio 263k initlog
12 0.19re 0.01cp 0avio 399k promisc_check.s
15 0.09re 0.00cp 0avio 288k grep
11 0.08re 0.00cp 0avio 332k awk
用户还可以根据用户而不是命令来提供一个摘要报告。例如sa -m显示如下:
885 173.28re 4.31cp 0avk
root 879 173.23re 4.31cp 0avk
alias 3 0.05re 0.00cp 0avk
qmailp 3 0.01re 0.00cp 0avk
Syslog设备
Syslog已被许多日志函数采纳,它用在许多保护措施中--任何程序都可以通过syslog 纪录事件。Syslog可以纪录系统事件,可以写到一个文件或设备中,或给用户发送一个信息。它能纪录本地事件或通过网络纪录另一个主机上的事件。
Syslog设备依据两个重要的文件:/etc/syslogd(守护进程)和/etc/syslog.conf配置文件,习惯上,多数syslog信息被写到/var/adm或/var/log目录下的信息文件中(messages.*)。一个典型的syslog纪录包括生成程序的名字和一个文本信息。它还包括一个设备和一个优先级范围(但不在日之中出现)。
每个syslog消息被赋予下面的主要设备之一:
LOG_AUTH--认证系统:login、su、getty等
LOG_AUTHPRIV--同LOG_AUTH,但只登录到所选择的单个用户可读的文件中
LOG_CRON--cron守护进程
LOG_DAEMON--其他系统守护进程,如routed
LOG_FTP--文件传输协议:ftpd、tftpd
LOG_KERN--内核产生的消息
LOG_LPR--系统打印机缓冲池:lpr、lpd
LOG_MAIL--电子邮件系统
LOG_NEWS--网络新闻系统
LOG_SYSLOG--由syslogd(8)产生的内部消息
LOG_USER--随机用户进程产生的消息
LOG_UUCP--UUCP子系统
LOG_LOCAL0~LOG_LOCAL7--为本地使用保留
Syslog为每个事件赋予几个不同的优先级:
LOG_EMERG--紧急情况
LOG_ALERT--应该被立即改正的问题,如系统数据库破坏
LOG_CRIT--重要情况,如硬盘错误
LOG_ERR--错误
LOG_WARNING--警告信息
LOG_NOTICE--不是错误情况,但是可能需要处理
LOG_INFO--情报信息
LOG_DEBUG--包含情报的信息,通常旨在调试一个程序时使用
syslog.conf文件指明syslogd程序纪录日志的行为,该程序在启动时查询配置文件。该文件由不同程序或消息分类的单个条目组成,每个占一行。对每类消息提供一个选择域和一个动作域。这些域由tab隔开:选择域指明消息的类型和优先级;动作域指明syslogd接收到一个与选择标准相匹配的消息时所执行的动作。每个选项是由设备和优先级组成。当指明一个优先级时,syslogd将纪录一个拥有相同或更高优先级的消息。所以如果指明\"crit\",那所有标为crit、alert和emerg的消息将被纪录。每行的行动域指明当选择域选择了一个给定消息后应该把他发送到哪儿。例如,如果想把所有邮件消息纪录到一个文件中,如下:
#Log all the mail messages in one place
mail.* /var/log/maillog
其他设备也有自己的日志。UUCP和news设备能产生许多外部消息。它把这些消息存到自己的日志(/var/log/spooler)中并把级别限为\"err\"或更高。例如:
# Save mail and news errors of level err and higher in aspecial file.
uucp,news.crit /var/log/spooler
当一个紧急消息到来时,可能想让所有的用户都得到。也可能想让自己的日志接收并保存。
#Everybody gets emergency messages, plus log them on anther machine
*.emerg *
*.emerg @linuxaid.com.cn
alert消息应该写到root和tiger的个人账号中:
#Root and Tiger get alert and higher messages
*.alert root,tiger
有时syslogd将产生大量的消息。例如内核(\"kern\"设备)可能很冗长。用户可能想把内核消息纪录到/dev/console中。下面的例子表明内核日志纪录被注释掉了:
#Log all kernel messages to the console
#Logging much else clutters up the screen
#kern.* /dev/console
用户可以在一行中指明所有的设备。下面的例子把info或更高级别的消息送到/var/log/messages,除了mail以外。级别\"none\"禁止一个设备:
#Log anything(except mail)of level info or higher
#Don\'t log private authentication messages!
*.info:mail.none;autHPriv.none /var/log/messages
在有些情况下,可以把日志送到打印机(或者通过网络送到root的邮箱、日志服务器、每天更换的磁带机甚至光盘刻录机),这样网络入侵者怎么修改日志都没有用了。通常要广泛纪录日志。Syslog设备是一个攻击者的显著目标。一个为其他主机维护日志的系统对于防范服务器攻击特别脆弱,因此要特别注意。
有个小命令logger为syslog(3)系统日志文件提供一个shell命令接口,使用户能创建日志文件中的条目。用法:logger 例如:logger This is a test!
它将产生一个如下的syslog纪录:Aug 19 22:22:34 tiger: This is a test!
注意不要完全相信日志,因为攻击者很容易修改它的。
程序日志
许多程序通过维护日志来反映系统的安全状态。su命令允许用户获得另一个用户的权限,所以它的安全很重要,它的文件为sulog。同样的还有sudolog。另外,想Apache有两个日志:access_log和error_log。
其他日志工具
chklastlog
ftp://coast.cs.purdue.edu/pub/tools/unix/chklastlog/
chkwtmp
ftp://coast.cs.purdue.edu/pub/tools/unix/chkwtmp/
dump_lastlog
ftp://coast.cs.purdue.edu/pub/tools/unix/dump_lastlog.Z
spar
ftp://coast.cs.purdue.edu/pub/tools/unix/TAMU/
Swatch
http://www.lomar.org/komar/alek/pres/swatch/cover.html
Zap
ftp://caost.cs.purdue.edu/pub/tools/unix/zap.tar.gz
日志分类方法
http://csrc.nist.gov/nissc/1998/proceedings/paperD1.pdf
uucico作为登录外壳启动时,将得到远程系统名和所在系统的登录名,并在USERFILE文件中找到匹配login和sys的行。如果该行含有call_back标志c,uucico将不传送文件,连接断开,调用远程系统(即,任何系统可以告诉本系统它的名是xyz,于是本系统挂起,调用实际的xyz执行文件传输),若无c,uucico将执行远程系统请求的文件传送,被传送的文件名被假定为以path_name开头的。
用户需要了解以下几点:
·如果远程系统使用的登录名未列于USERFILE的登录域中,uucico将拒绝允许其他系统做任何事,并挂起。
·如果系统名未列于sys域中,uucico将使用USERFILE中有匹配的登录名和空系统名的第一行,如:nuucp,/usr/spool/uucppublic应用到作为nuucp登录的所有系统。cbuucp,c将迫使作为cbuucp登录的所有系统自己执行文件传输的请求。若调用系统名不匹配sys系统中的任何一个,并且无空入口项,uucico也将拒绝做任何事。
·若两个机器都设置了call_back标志,传送文件的请求决不会被执行,两个系统会一直互相调用,直到两个系统中的一个取消call_back时,才能进行文件传送。
·如果一个用户的登录名列于USERFILE文件的login域中,则当调用本系统的uucico为该用户传送文件时,uucico只传送至path_name指定的目录中的文件。空登录名用于所有未明确列于USERFILE文件中的用户进行登录。所以pat,/usr/pat只允许pat传送/usr/pat目录结构中的文件。/usr/spool/uucppublic/tmp其他用户仅允许传送目录/usr/spool/uucppublic和/tmp中的文件。不要允许uucico将文件拷进/出到除了/usr/spool/uucppublic目录以外的其他任何目录,否则可能会有人用下面的命令拷贝走本系统的重要信息:
uucpyoursys!/etc/passwdto-creep
系统管理员可允许登录用户执行netnews(rnews)的命令或远程打印命令(lp),但决不允许用户执行拷贝文件到标准输出的命令,如cat命令或网络命令uucp,否则这些人只需在他们自己的系统上敲入:
uux"yoursys!uucpyoursys!/etc/passwd(outside!~/passwd)"
然后就可等待本系统发送出命令文件。
UID和GID的5号通常留给uucp,由于uucico具有管理登录的SUID许可,因此nuucp帐户的UID和GID应当用其他值。
uucp用/usr/spool/uucp目录存放工作文件。文件名以C.开头的文件是送到其他系统的命令文件,含有在其他系统上拷入(/出)数据和执行命令的请求。文件名以D.开头的文件用作C.文件的数据文件。文件名以X.开头的文件是来自其他系统的远程执行请求,由uuxqt解释。文件名以TM.开始的文件是从其他系统传送数据到本系统过程中uucp所使用的暂存文件。
XQTDIR是uuxqt用于执行X.文件的目录。LOGFILE可有助于管理uucp的安全,它含有执行uucp请求成功与否的信息。系统管理员可时常查看该文件,了解有哪些系统正登录本系统执行uucp请求,是什么请求,特别要检查这些请求是否试图做不允许的操作。
小组就像登录用户一样可以有口令。如果/etc/group文件入口项的第二个域为非空,则将被认为是加密口令,newgrp命令将要求用户给出口令,然后将口令加密,再与该域的加密口令比较。给小组建立口令一般不是个好方法。第一,如果小组内共享文件,而某人猜中小组口令,则该组的所有用户的文件就可能泄密:其次,管理小组口令很费事,因为对于小组没有类似的passwd命令。可用/usr/lib/makekey生成一个口令写入/etc/group。
以下情况必须建立新组:
·可能要增加新用户,该用户不属于任何一个现有的小组。
·有的用户可能时常需要独自为一个小组。
·有的用户可能有一个SGID程序,需要独自为一个小组。
·有时可能要安装运行SGID的软件系统,该软件系统需要建立一个新组。
要增加一个新组,必须编辑该文件,为新组加一个入口项。由于用户登录时,系统从/etc/passwd文件中取GID,而不是从/etc/group中取GID,所以group文件和口令文件应当具有一致性。对于一个用户的小组,UID和GID应当是相同的。多用户小组的GID应当不同于任何用户的UID,一般为5位数,这样在查看/etc/passwd文件时,就可根据5位数据的GID识别多用户小组,这将减少增加新组和新用户时可能产生的混淆。
#!/bin/sh
#
# ----------------------------------------------------------------------------
# Last modified by Gerhard Mourani: 04-25-2000
# ----------------------------------------------------------------------------
# Copyright (C) 1997, 1998, 1999 Robert L. Ziegler
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for educational, research, private and non-profit purposes,
# without fee, and without a written agreement is hereby granted.
# This software is provided as an example and basis for individual firewall
# development. This software is provided without warranty.
#
# Any material furnished by Robert L. Ziegler is furnished on an
# "as is" basis. He makes no warranties of any kind, either expressed
# or implied as to any matter including, but not limited to, warranty
# of fitness for a particular purpose, exclusivity or results obtained
# from use of the material.
# ----------------------------------------------------------------------------
#
# Invoked from /etc/rc.d/init.d/firewall.
# chkconfig: - 60 95
# description: Starts and stops the IPCHAINS Firewall \
# used to provide Firewall network services.
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
if [ ${NETWORKING} = "no" ]
then
exit 0
fi
if [ ! -x /sbin/ipchains ]; then
exit 0
fi
# See how we were called.
case "$1" in
start)
echo -n "Starting Firewalling Services: "
# Some definitions for easy maintenance.
# ----------------------------------------------------------------------------
# EDIT THESE TO SUIT YOUR SYSTEM AND ISP.
EXTERNAL_INTERFACE="eth0" # Internet connected interface
LOOPBACK_INTERFACE="lo" # Your local naming convention
IPADDR="my.ip.address" # Your IP address
ANYWHERE="any/0" # Match any IP address
NAMESERVER_1="my.name.server.1" # Everyone must have at least one
NAMESERVER_2="my.name.server.2" # Your secondary name server
MY_ISP="my.isp.address.range/24" # ISP NOC address range
SMTP_SERVER="my.smtp.server" # Your Mail Hub Server.
SYSLOG_SERVER="syslog.internal.server" # Your syslog internal server
SYSLOG_CLIENT="sys.int.client.range/24" # Your syslog internal client range
LOOPBACK="127.0.0.0/8" # Reserved loopback address range
CLASS_A="10.0.0.0/8" # Class A private networks
CLASS_B="172.16.0.0/12" # Class B private networks
CLASS_C="192.168.0.0/16" # Class C private networks
CLASS_D_MULTICAST="224.0.0.0/4" # Class D multicast addresses
CLASS_E_RESERVED_NET="240.0.0.0/5" # Class E reserved addresses
BROADCAST_SRC="0.0.0.0" # Broadcast source address
BROADCAST_DEST="255.255.255.255" # Broadcast destination address
PRIVPORTS="0:1023" # Well known, privileged port range
UNPRIVPORTS="1024:65535" # Unprivileged port range
# ----------------------------------------------------------------------------
# SSH starts at 1023 and works down to 513 for
# each additional simultaneous incoming connection.
SSH_PORTS="1022:1023" # range for SSH privileged ports
# traceroute usually uses -S 32769:65535 -D 33434:33523
TRACEROUTE_SRC_PORTS="32769:65535"
TRACEROUTE_DEST_PORTS="33434:33523"
# ----------------------------------------------------------------------------
# Default policy is DENY
# Explicitly accept desired INCOMING OUTGOING connections
# Remove all existing rules belonging to this filter
ipchains -F
# Clearing all current rules and user defined chains
ipchains -X
# Set the default policy of the filter to deny.
# Don't even bother sending an error message back.
ipchains -P input DENY
ipchains -P output DENY
ipchains -P forward DENY
# ----------------------------------------------------------------------------
# LOOPBACK
# Unlimited traffic on the loopback interface.
ipchains -A input -i $LOOPBACK_INTERFACE -j ACCEPT
ipchains -A output -i $LOOPBACK_INTERFACE -j ACCEPT
# ----------------------------------------------------------------------------
# Network Ghouls
# Deny access to jerks
# /etc/rc.d/rc.firewall.blocked contains a list of
# ipchains -A input -i $EXTERNAL_INTERFACE -s address -j DENY
# rules to block from any access.
# Refuse any connection from problem sites
#if [ -f /etc/rc.d/rc.firewall.blocked ]; then
# . /etc/rc.d/rc.firewall.blocked
#fi
# ----------------------------------------------------------------------------
# SPOOFING BAD ADDRESSES
# Refuse spoofed packets.
# Ignore blatantly illegal source addresses.
# Protect yourself from sending to bad addresses.
# Refuse spoofed packets pretending to be from the external address.
ipchains -A input -i $EXTERNAL_INTERFACE -s $IPADDR -j DENY -l
# Refuse packets claiming to be to or from a Class A private network
ipchains -A input -i $EXTERNAL_INTERFACE -s $CLASS_A -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -d $CLASS_A -j DENY -l
ipchains -A output -i $EXTERNAL_INTERFACE -s $CLASS_A -j REJECT -l
ipchains -A output -i $EXTERNAL_INTERFACE -d $CLASS_A -j REJECT -l
# Refuse packets claiming to be to or from a Class B private network
ipchains -A input -i $EXTERNAL_INTERFACE -s $CLASS_B -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -d $CLASS_B -j DENY -l
ipchains -A output -i $EXTERNAL_INTERFACE -s $CLASS_B -j REJECT -l
ipchains -A output -i $EXTERNAL_INTERFACE -d $CLASS_B -j REJECT -l
# Refuse packets claiming to be to or from a Class C private network
# ipchains -A input -i $EXTERNAL_INTERFACE -s $CLASS_C -j DENY -l
# ipchains -A input -i $EXTERNAL_INTERFACE -d $CLASS_C -j DENY -l
# ipchains -A output -i $EXTERNAL_INTERFACE -s $CLASS_C -j REJECT -l
# ipchains -A output -i $EXTERNAL_INTERFACE -d $CLASS_C -j REJECT -l
# Refuse packets claiming to be from the loopback interface
ipchains -A input -i $EXTERNAL_INTERFACE -s $LOOPBACK -j DENY -l
ipchains -A output -i $EXTERNAL_INTERFACE -s $LOOPBACK -j REJECT -l
# Refuse broadcast address SOURCE packets
ipchains -A input -i $EXTERNAL_INTERFACE -s $BROADCAST_DEST -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -d $BROADCAST_SRC -j DENY -l
# Refuse Class D multicast addresses (in.h) (NET-3-HOWTO)
# Multicast is illegal as a source address.
# Multicast uses UDP.
ipchains -A input -i $EXTERNAL_INTERFACE -s $CLASS_D_MULTICAST -j DENY -l
# Refuse Class E reserved IP addresses
ipchains -A input -i $EXTERNAL_INTERFACE -s $CLASS_E_RESERVED_NET -j DENY -l
# refuse addresses defined as reserved by the IANA
# 0.*.*.*, 1.*.*.*, 2.*.*.*, 5.*.*.*, 7.*.*.*, 23.*.*.*, 27.*.*.*
# 31.*.*.*, 37.*.*.*, 39.*.*.*, 41.*.*.*, 42.*.*.*, 58-60.*.*.*
# 65-95.*.*.*, 96-126.*.*.*, 197.*.*.*, 201.*.*.* (?), 217-223.*.*.*
ipchains -A input -i $EXTERNAL_INTERFACE -s 1.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 2.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 5.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 7.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 23.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 27.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 31.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 37.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 39.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 41.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 42.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 58.0.0.0/7 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 60.0.0.0/8 -j DENY -l
#65: 01000001 - /3 includes 64 - need 65-79 spelled out
ipchains -A input -i $EXTERNAL_INTERFACE -s 65.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 66.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 67.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 68.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 69.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 70.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 71.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 72.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 73.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 74.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 75.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 76.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 77.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 78.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 79.0.0.0/8 -j DENY -l
#80: 01010000 - /4 masks 80-95
ipchains -A input -i $EXTERNAL_INTERFACE -s 80.0.0.0/4 -j DENY -l
# 96: 01100000 - /4 makses 96-111
ipchains -A input -i $EXTERNAL_INTERFACE -s 96.0.0.0/4 -j DENY -l
#126: 01111110 - /3 includes 127 - need 112-126 spelled out
ipchains -A input -i $EXTERNAL_INTERFACE -s 112.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 113.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 114.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 115.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 116.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 117.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 118.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 119.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 120.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 121.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 122.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 123.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 124.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 125.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 126.0.0.0/8 -j DENY -l
#217: 11011001 - /5 includes 216 - need 217-219 spelled out
ipchains -A input -i $EXTERNAL_INTERFACE -s 217.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 218.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 219.0.0.0/8 -j DENY -l
#223: 11011111 - /6 masks 220-223
ipchains -A input -i $EXTERNAL_INTERFACE -s 220.0.0.0/6 -j DENY -l
# ----------------------------------------------------------------------------
# ICMP
# To prevent denial of service attacks based on ICMP bombs, filter
# incoming Redirect (5) and outgoing Destination Unreachable (3).
# Note, however, disabling Destination Unreachable (3) is not
# advisable, as it is used to negotiate packet fragment size.
# For bi-directional ping.
# Message Types: Echo_Reply (0), Echo_Request (8)
# To prevent attacks, limit the src addresses to your ISP range.
#
# For outgoing traceroute.
# Message Types: INCOMING Dest_Unreachable (3), Time_Exceeded (11)
# default UDP base: 33434 to base+nhops-1
#
# For incoming traceroute.
# Message Types: OUTGOING Dest_Unreachable (3), Time_Exceeded (11)
# To block this, deny OUTGOING 3 and 11
# 0: echo-reply (pong)
# 3: destination-unreachable, port-unreachable, fragmentation-needed, etc.
# 4: source-quench
# 5: redirect
# 8: echo-request (ping)
# 11: time-exceeded
# 12: parameter-problem
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 0 -d $IPADDR -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 3 -d $IPADDR -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 4 -d $IPADDR -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 11 -d $IPADDR -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 12 -d $IPADDR -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $MY_ISP 8 -d $IPADDR -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 0 -d $MY_ISP -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 3 -d $MY_ISP -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 4 -d $ANYWHERE -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 8 -d $ANYWHERE -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 12 -d $ANYWHERE -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 11 -d $MY_ISP -j ACCEPT
# ----------------------------------------------------------------------------
# UDP INCOMING TRACEROUTE
# traceroute usually uses -S 32769:65535 -D 33434:33523
ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
-s $MY_ISP $TRACEROUTE_SRC_PORTS \
-d $IPADDR $TRACEROUTE_DEST_PORTS -j ACCEPT -l
ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
-s $ANYWHERE $TRACEROUTE_SRC_PORTS \
-d $IPADDR $TRACEROUTE_DEST_PORTS -j DENY -l
# ----------------------------------------------------------------------------
# DNS server
# ----------
# DNS: full server
# server/client to server query or response
ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
-s $ANYWHERE $UNPRIVPORTS \
-d $IPADDR 53 -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p udp \
-s $IPADDR 53 \
-d $ANYWHERE $UNPRIVPORTS -j ACCEPT
# DNS client Zone Transfers (53)
# ---------------
ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
-s $NAMESERVER_1 53 \
-d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p udp \
-s $IPADDR $UNPRIVPORTS \
-d $NAMESERVER_1 53 -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y \
-s $NAMESERVER_1 53 \
-d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp \
-s $IPADDR $UNPRIVPORTS \
-d $NAMESERVER_1 53 -j ACCEPT
# ----------------------------------------------------------------------------
# TCP accept only on selected ports
# ---------------------------------
# ------------------------------------------------------------------
# SSH server (22)
# ---------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp \
-s $ANYWHERE $UNPRIVPORTS \
-d $IPADDR 22 -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp ! -y \
-s $IPADDR 22 \
-d $ANYWHERE $UNPRIVPORTS -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp \
-s $ANYWHERE $SSH_PORTS \
-d $IPADDR 22 -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp ! -y \
-s $IPADDR 22 \
-d $ANYWHERE $SSH_PORTS -j ACCEPT
# ------------------------------------------------------------------
# AUTH server (113)
# -----------------
# Reject, rather than deny, the incoming auth port. (NET-3-HOWTO)
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp \
-s $ANYWHERE \
-d $IPADDR 113 -j REJECT
# ------------------------------------------------------------------
# SYSLOG server (514)
# -----------------
# Provides full remote logging. Using this feature you're able to
# control all syslog messages on one host.
# ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
# -s $SYSLOG_CLIENT \
# -d $IPADDR 514 -j ACCEPT
# SYSLOG client (514)
# -----------------
# ipchains -A output -i $EXTERNAL_INTERFACE -p udp \
# -s $IPADDR 514 \
# -d $SYSLOG_SERVER 514 -j ACCEPT
# ------------------------------------------------------------------
# SMTP server (25)
# ----------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp \
-s $ANYWHERE $UNPRIVPORTS \
-d $IPADDR 25 -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp ! -y \
-s $IPADDR 25 \
-d $ANYWHERE $UNPRIVPORTS -j ACCEPT
# SMTP client (25)
# ----------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y \
-s $ANYWHERE 25 \
-d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp \
-s $IPADDR $UNPRIVPORTS \
-d $ANYWHERE 25 -j ACCEPT
# ------------------------------------------------------------------
# IMAP server (143)
# -----------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp \
-s $ANYWHERE $UNPRIVPORTS \
-d $IPADDR 143 -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp ! -y \
-s $IPADDR 143 \
-d $ANYWHERE $UNPRIVPORTS -j ACCEPT
# POP server (110)
# -----------------
# ipchains -A input -i $EXTERNAL_INTERFACE -p tcp \
# -s $ANYWHERE $UNPRIVPORTS \
# -d $IPADDR 110 -j ACCEPT
# ipchains -A output -i $EXTERNAL_INTERFACE -p tcp ! -y \
# -s $IPADDR 110 \
# -d $ANYWHERE $UNPRIVPORTS -j ACCEPT
# ------------------------------------------------------------------
# OUTGOING TRACEROUTE
# -------------------
ipchains -A output -i $EXTERNAL_INTERFACE -p udp \
-s $IPADDR $TRACEROUTE_SRC_PORTS \
-d $ANYWHERE $TRACEROUTE_DEST_PORTS -j ACCEPT
# ----------------------------------------------------------------------------
# Enable logging for selected denied packets
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp \
-d $IPADDR -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
-d $IPADDR $PRIVPORTS -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
-d $IPADDR $UNPRIVPORTS -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 5 -d $IPADDR -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 13:255 -d $IPADDR -j DENY -l
# ----------------------------------------------------------------------------
;;
stop)
echo -n "Shutting Firewalling Services: "
# Remove all existing rules belonging to this filter
ipchains -F
# Delete all user-defined chain to this filter
ipchains -X
# Reset the default policy of the filter to accept.
ipchains -P input ACCEPT
ipchains -P output ACCEPT
ipchains -P forward ACCEPT
;;
status)
status firewall
;;
restart|reload)
$0 stop
$0 start
;;
*)
echo "Usage: firewall {start|stop|status|restart|reload}"
exit 1
esac
exit 0
Now, make this script executable and change its default permissions:
[root@deep] /#chmod 700 /etc/rc.d/init.d/firewall
[root@deep] /#chown 0.0 /etc/rc.d/init.d/firewall
Create the symbolic rc.d links for your Firewall with the command:
[root@deep] /#chkconfig --add firewall
[root@deep] /#chkconfig --level 345 firewall on
Now, your firewall rules are configured to use System V init (System V init is in charge of starting all the normal processes that need to run at boot time) and it will be automatically started each time if your server reboot.
To manually stop the firewall on your system, use the following command:
[root@deep] /# /etc/rc.d/init.d/firewall stop
Shutting Firewalling Services: [ OK ]
To manually start the firewall on your system, use the following command:
[root@deep] /# /etc/rc.d/init.d/firewall start
Starting Firewalling Services: [ OK ]
If you don't want some services listed in the firewall rules files for the Web Server that I make ON by default, comment them out with a "#" at the beginning of the line. If you want some other services that I commented out with a "#", then remove the "#" at the beginning of those lines.
Create the firewall script file, touch /etc/rc.d/init.d/firewall on your Web Server and add:
#!/bin/sh
#
# ----------------------------------------------------------------------------
# Last modified by Gerhard Mourani: 04-25-2000
# ----------------------------------------------------------------------------
# Copyright (C) 1997, 1998, 1999 Robert L. Ziegler
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for educational, research, private and non-profit purposes,
# without fee, and without a written agreement is hereby granted.
# This software is provided as an example and basis for individual firewall
# development. This software is provided without warranty.
#
# Any material furnished by Robert L. Ziegler is furnished on an
# "as is" basis. He makes no warranties of any kind, either expressed
# or implied as to any matter including, but not limited to, warranty
# of fitness for a particular purpose, exclusivity or results obtained
# from use of the material.
# ----------------------------------------------------------------------------
#
# Invoked from /etc/rc.d/init.d/firewall.
# chkconfig: - 60 95
# description: Starts and stops the IPCHAINS Firewall \
# used to provide Firewall network services.
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
if [ ${NETWORKING} = "no" ]
then
exit 0
fi
if [ ! -x /sbin/ipchains ]; then
exit 0
fi
# See how we were called.
case "$1" in
start)
echo -n "Starting Firewalling Services: "
# Some definitions for easy maintenance.
# ----------------------------------------------------------------------------
# EDIT THESE TO SUIT YOUR SYSTEM AND ISP.
EXTERNAL_INTERFACE="eth0" # Internet connected interface
LOOPBACK_INTERFACE="lo" # Your local naming convention
IPADDR="my.ip.address" # Your IP address
ANYWHERE="any/0" # Match any IP address
NAMESERVER_1="my.name.server.1" # Everyone must have at least one
NAMESERVER_2="my.name.server.2" # Your secondary name server
MY_ISP="my.isp.address.range/24" # ISP NOC address range
SMTP_SERVER="my.smtp.server" # Your Mail Hub Server.
SYSLOG_SERVER="syslog.internal.server" # Your syslog internal server
SYSLOG_CLIENT="sys.int.client.range/24" # Your syslog internal client range
LOOPBACK="127.0.0.0/8" # Reserved loopback address range
CLASS_A="10.0.0.0/8" # Class A private networks
CLASS_B="172.16.0.0/12" # Class B private networks
CLASS_C="192.168.0.0/16" # Class C private networks
CLASS_D_MULTICAST="224.0.0.0/4" # Class D multicast addresses
CLASS_E_RESERVED_NET="240.0.0.0/5" # Class E reserved addresses
BROADCAST_SRC="0.0.0.0" # Broadcast source address
BROADCAST_DEST="255.255.255.255" # Broadcast destination address
PRIVPORTS="0:1023" # Well known, privileged port range
UNPRIVPORTS="1024:65535" # Unprivileged port range
# ----------------------------------------------------------------------------
# SSH starts at 1023 and works down to 513 for
# each additional simultaneous incoming connection.
SSH_PORTS="1022:1023" # range for SSH privileged ports
# traceroute usually uses -S 32769:65535 -D 33434:33523
TRACEROUTE_SRC_PORTS="32769:65535"
TRACEROUTE_DEST_PORTS="33434:33523"
# ----------------------------------------------------------------------------
# Default policy is DENY
# Explicitly accept desired INCOMING OUTGOING connections
# Remove all existing rules belonging to this filter
ipchains -F
# Clearing all current rules and user defined chains
ipchains -X
# Set the default policy of the filter to deny.
# Don't even bother sending an error message back.
ipchains -P input DENY
ipchains -P output DENY
ipchains -P forward DENY
# ----------------------------------------------------------------------------
# LOOPBACK
# Unlimited traffic on the loopback interface.
ipchains -A input -i $LOOPBACK_INTERFACE -j ACCEPT
ipchains -A output -i $LOOPBACK_INTERFACE -j ACCEPT
# ----------------------------------------------------------------------------
# Network Ghouls
# Deny access to jerks
# /etc/rc.d/rc.firewall.blocked contains a list of
# ipchains -A input -i $EXTERNAL_INTERFACE -s address -j DENY
# rules to block from any access.
# Refuse any connection from problem sites
#if [ -f /etc/rc.d/rc.firewall.blocked ]; then
# . /etc/rc.d/rc.firewall.blocked
#fi
# ----------------------------------------------------------------------------
# SPOOFING BAD ADDRESSES
# Refuse spoofed packets.
# Ignore blatantly illegal source addresses.
# Protect yourself from sending to bad addresses.
# Refuse spoofed packets pretending to be from the external address.
ipchains -A input -i $EXTERNAL_INTERFACE -s $IPADDR -j DENY -l
# Refuse packets claiming to be to or from a Class A private network
ipchains -A input -i $EXTERNAL_INTERFACE -s $CLASS_A -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -d $CLASS_A -j DENY -l
ipchains -A output -i $EXTERNAL_INTERFACE -s $CLASS_A -j REJECT -l
ipchains -A output -i $EXTERNAL_INTERFACE -d $CLASS_A -j REJECT -l
# Refuse packets claiming to be to or from a Class B private network
ipchains -A input -i $EXTERNAL_INTERFACE -s $CLASS_B -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -d $CLASS_B -j DENY -l
ipchains -A output -i $EXTERNAL_INTERFACE -s $CLASS_B -j REJECT -l
ipchains -A output -i $EXTERNAL_INTERFACE -d $CLASS_B -j REJECT -l
# Refuse packets claiming to be to or from a Class C private network
# ipchains -A input -i $EXTERNAL_INTERFACE -s $CLASS_C -j DENY -l
# ipchains -A input -i $EXTERNAL_INTERFACE -d $CLASS_C -j DENY -l
# ipchains -A output -i $EXTERNAL_INTERFACE -s $CLASS_C -j REJECT -l
# ipchains -A output -i $EXTERNAL_INTERFACE -d $CLASS_C -j REJECT -l
# Refuse packets claiming to be from the loopback interface
ipchains -A input -i $EXTERNAL_INTERFACE -s $LOOPBACK -j DENY -l
ipchains -A output -i $EXTERNAL_INTERFACE -s $LOOPBACK -j REJECT -l
# Refuse broadcast address SOURCE packets
ipchains -A input -i $EXTERNAL_INTERFACE -s $BROADCAST_DEST -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -d $BROADCAST_SRC -j DENY -l
# Refuse Class D multicast addresses (in.h) (NET-3-HOWTO)
# Multicast is illegal as a source address.
# Multicast uses UDP.
ipchains -A input -i $EXTERNAL_INTERFACE -s $CLASS_D_MULTICAST -j DENY -l
# Refuse Class E reserved IP addresses
ipchains -A input -i $EXTERNAL_INTERFACE -s $CLASS_E_RESERVED_NET -j DENY -l
# refuse addresses defined as reserved by the IANA
# 0.*.*.*, 1.*.*.*, 2.*.*.*, 5.*.*.*, 7.*.*.*, 23.*.*.*, 27.*.*.*
# 31.*.*.*, 37.*.*.*, 39.*.*.*, 41.*.*.*, 42.*.*.*, 58-60.*.*.*
# 65-95.*.*.*, 96-126.*.*.*, 197.*.*.*, 201.*.*.* (?), 217-223.*.*.*
ipchains -A input -i $EXTERNAL_INTERFACE -s 1.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 2.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 5.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 7.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 23.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 27.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 31.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 37.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 39.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 41.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 42.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 58.0.0.0/7 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 60.0.0.0/8 -j DENY -l
#65: 01000001 - /3 includes 64 - need 65-79 spelled out
ipchains -A input -i $EXTERNAL_INTERFACE -s 65.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 66.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 67.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 68.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 69.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 70.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 71.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 72.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 73.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 74.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 75.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 76.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 77.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 78.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 79.0.0.0/8 -j DENY -l
#80: 01010000 - /4 masks 80-95
ipchains -A input -i $EXTERNAL_INTERFACE -s 80.0.0.0/4 -j DENY -l
# 96: 01100000 - /4 makses 96-111
ipchains -A input -i $EXTERNAL_INTERFACE -s 96.0.0.0/4 -j DENY -l
#126: 01111110 - /3 includes 127 - need 112-126 spelled out
ipchains -A input -i $EXTERNAL_INTERFACE -s 112.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 113.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 114.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 115.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 116.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 117.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 118.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 119.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 120.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 121.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 122.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 123.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 124.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 125.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 126.0.0.0/8 -j DENY -l
#217: 11011001 - /5 includes 216 - need 217-219 spelled out
ipchains -A input -i $EXTERNAL_INTERFACE -s 217.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 218.0.0.0/8 -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -s 219.0.0.0/8 -j DENY -l
#223: 11011111 - /6 masks 220-223
ipchains -A input -i $EXTERNAL_INTERFACE -s 220.0.0.0/6 -j DENY -l
# ----------------------------------------------------------------------------
# ICMP
# To prevent denial of service attacks based on ICMP bombs, filter
# incoming Redirect (5) and outgoing Destination Unreachable (3).
# Note, however, disabling Destination Unreachable (3) is not
# advisable, as it is used to negotiate packet fragment size.
# For bi-directional ping.
# Message Types: Echo_Reply (0), Echo_Request (8)
# To prevent attacks, limit the src addresses to your ISP range.
#
# For outgoing traceroute.
# Message Types: INCOMING Dest_Unreachable (3), Time_Exceeded (11)
# default UDP base: 33434 to base+nhops-1
#
# For incoming traceroute.
# Message Types: OUTGOING Dest_Unreachable (3), Time_Exceeded (11)
# To block this, deny OUTGOING 3 and 11
# 0: echo-reply (pong)
# 3: destination-unreachable, port-unreachable, fragmentation-needed, etc.
# 4: source-quench
# 5: redirect
# 8: echo-request (ping)
# 11: time-exceeded
# 12: parameter-problem
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 0 -d $IPADDR -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 3 -d $IPADDR -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 4 -d $IPADDR -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 11 -d $IPADDR -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 12 -d $IPADDR -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $MY_ISP 8 -d $IPADDR -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 0 -d $MY_ISP -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 3 -d $MY_ISP -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 4 -d $ANYWHERE -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 8 -d $ANYWHERE -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 12 -d $ANYWHERE -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p icmp \
-s $IPADDR 11 -d $MY_ISP -j ACCEPT
# ----------------------------------------------------------------------------
# UDP INCOMING TRACEROUTE
# traceroute usually uses -S 32769:65535 -D 33434:33523
ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
-s $MY_ISP $TRACEROUTE_SRC_PORTS \
-d $IPADDR $TRACEROUTE_DEST_PORTS -j ACCEPT -l
ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
-s $ANYWHERE $TRACEROUTE_SRC_PORTS \
-d $IPADDR $TRACEROUTE_DEST_PORTS -j DENY -l
# ----------------------------------------------------------------------------
# DNS forwarding, caching only nameserver (53)
# --------------------------------------------
# server to server query or response
# Caching only name server only requires UDP, not TCP
ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
-s $NAMESERVER_1 53 \
-d $IPADDR 53 -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p udp \
-s $IPADDR 53 \
-d $NAMESERVER_1 53 -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
-s $NAMESERVER_2 53 \
-d $IPADDR 53 -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p udp \
-s $IPADDR 53 \
-d $NAMESERVER_2 53 -j ACCEPT
# DNS client (53)
# ---------------
ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
-s $NAMESERVER_1 53 \
-d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p udp \
-s $IPADDR $UNPRIVPORTS \
-d $NAMESERVER_1 53 -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
-s $NAMESERVER_2 53 \
-d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p udp \
-s $IPADDR $UNPRIVPORTS \
-d $NAMESERVER_2 53 -j ACCEPT
# TCP client to server requests are allowed by the protocol
# if UDP requests fail. This is rarely seen. Usually, clients
# use TCP as a secondary nameserver for zone transfers from
# their primary nameservers, and as hackers.
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y \
-s $NAMESERVER_1 53 \
-d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp \
-s $IPADDR $UNPRIVPORTS \
-d $NAMESERVER_1 53 -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y \
-s $NAMESERVER_2 53 \
-d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp \
-s $IPADDR $UNPRIVPORTS \
-d $NAMESERVER_2 53 -j ACCEPT
# ----------------------------------------------------------------------------
# TCP accept only on selected ports
# ---------------------------------
# ------------------------------------------------------------------
# SSH server (22)
# ---------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp \
-s $ANYWHERE $UNPRIVPORTS \
-d $IPADDR 22 -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp ! -y \
-s $IPADDR 22 \
-d $ANYWHERE $UNPRIVPORTS -j ACCEPT
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp \
-s $ANYWHERE $SSH_PORTS \
-d $IPADDR 22 -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp ! -y \
-s $IPADDR 22 \
-d $ANYWHERE $SSH_PORTS -j ACCEPT
# ------------------------------------------------------------------
# HTTP server (80)
# ----------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp \
-s $ANYWHERE $UNPRIVPORTS \
-d $IPADDR 80 -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp ! -y \
-s $IPADDR 80 \
-d $ANYWHERE $UNPRIVPORTS -j ACCEPT
# ------------------------------------------------------------------
# HTTPS server (443)
# ------------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp \
-s $ANYWHERE $UNPRIVPORTS \
-d $IPADDR 443 -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp ! -y \
-s $IPADDR 443 \
-d $ANYWHERE $UNPRIVPORTS -j ACCEPT
# ------------------------------------------------------------------
# SYSLOG server (514)
# -----------------
# Provides full remote logging. Using this feature you're able to
# control all syslog messages on one host.
# ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
# -s $SYSLOG_CLIENT \
# -d $IPADDR 514 -j ACCEPT
# SYSLOG client (514)
# -----------------
# ipchains -A output -i $EXTERNAL_INTERFACE -p udp \
# -s $IPADDR 514 \
# -d $SYSLOG_SERVER 514 -j ACCEPT
# ------------------------------------------------------------------
# AUTH server (113)
# -----------------
# Reject, rather than deny, the incoming auth port. (NET-3-HOWTO)
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp \
-s $ANYWHERE \
-d $IPADDR 113 -j REJECT
# ------------------------------------------------------------------
# SMTP client (25)
# ----------------
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y \
-s $SMTP_SERVER 25 \
-d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp \
-s $IPADDR $UNPRIVPORTS \
-d $SMTP_SERVER 25 -j ACCEPT
# ------------------------------------------------------------------
# FTP server (20, 21)
# -------------------
# incoming request
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp \
-s $ANYWHERE $UNPRIVPORTS \
-d $IPADDR 21 -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp ! -y \
-s $IPADDR 21 \
-d $ANYWHERE $UNPRIVPORTS -j ACCEPT
# PORT MODE data channel responses
#
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp ! -y \
-s $ANYWHERE $UNPRIVPORTS \
-d $IPADDR 20 -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp \
-s $IPADDR 20 \
-d $ANYWHERE $UNPRIVPORTS -j ACCEPT
# PASSIVE MODE data channel responses
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp \
-s $ANYWHERE $UNPRIVPORTS \
-d $IPADDR $UNPRIVPORTS -j ACCEPT
ipchains -A output -i $EXTERNAL_INTERFACE -p tcp ! -y \
-s $IPADDR $UNPRIVPORTS \
-d $ANYWHERE $UNPRIVPORTS -j ACCEPT
# ------------------------------------------------------------------
# OUTGOING TRACEROUTE
# -------------------
ipchains -A output -i $EXTERNAL_INTERFACE -p udp \
-s $IPADDR $TRACEROUTE_SRC_PORTS \
-d $ANYWHERE $TRACEROUTE_DEST_PORTS -j ACCEPT
# ----------------------------------------------------------------------------
# Enable logging for selected denied packets
ipchains -A input -i $EXTERNAL_INTERFACE -p tcp \
-d $IPADDR -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
-d $IPADDR $PRIVPORTS -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -p udp \
-d $IPADDR $UNPRIVPORTS -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 5 -d $IPADDR -j DENY -l
ipchains -A input -i $EXTERNAL_INTERFACE -p icmp \
-s $ANYWHERE 13:255 -d $IPADDR -j DENY -l
# ----------------------------------------------------------------------------
;;
stop)
echo -n "Shutting Firewalling Services: "
# Remove all existing rules belonging to this filter
ipchains -F
# Delete all user-defined chain to this filter
ipchains -X
# Reset the default policy of the filter to accept.
ipchains -P input ACCEPT
ipchains -P output ACCEPT
ipchains -P forward ACCEPT
;;
status)
status firewall
;;
restart|reload)
$0 stop
$0 start
;;
*)
echo "Usage: firewall {start|stop|status|restart|reload}"
exit 1
esac
exit 0
Now, make this script executable and change its default permissions:
[root@deep] /# chmod 700 /etc/rc.d/init.d/firewall
[root@deep] /# chown 0.0 /etc/rc.d/init.d/firewall
Create the symbolic rc.d links for your Firewall with the following command:
[root@deep] /# chkconfig --add firewall
[root@deep] /# chkconfig --level 345 firewall on
Now, your firewall rules are configured to use System V init (System V init is in charge of starting all the normal processes that need to run at boot time) and it will be automatically started each time your server reboots.
To manually stop the firewall on your system, use the following command:
[root@deep] /# /etc/rc.d/init.d/firewall stop
&n