发新话题
打印

FreeBSD下构建安全的Web服务器

FreeBSD下构建安全的Web服务器

::目录::
1 r: O+ J" e. ~2 L' G8 V& @; G5 T+ a/ |: B: v
序言
! x/ f% c6 A5 S: b2 l' I) C3 @8 o4 X- @
一、系统和服务程序的安装 1 f( F% h& o1 C  p. r* O! d
1. 系统安装
( \- P2 g6 a+ {- F; c2. 服务程序安装
. X6 z4 M" X; B* c
: z3 S  k' u7 ?& U二、系统安全设置
/ ?7 {0 n) w' O; t# e1. 用户控制 + Q8 ]  e/ T+ }' n1 g
2. 文件访问控制
& u$ a/ F, {5 {( ]5 M- I% _3. 系统服务和端口控制
. m2 E1 K' {% M6 y4. 日志管理和控制 + k6 }' Z$ j" Y0 E% X3 c) ]
5. 文件指纹检测 # s0 R/ p/ v4 a; J/ T7 D7 c' b, L
6. 系统指纹泄露和防范
3 B9 j2 }) J* L7. 系统内核安全
$ X/ }% u* H/ o) i9 u8. 系统安全优化 $ R. [/ X' W3 |' k3 C/ C

4 V3 v+ ]% y3 N! Q3 ^' ]三、服务程序的安全设置
9 t7 ~% x1 @) w2 W' S0 n3 p1. Apache安全设置
/ G, r7 z" D2 a2. PHP安全设置
$ c! R& z6 J+ ?  m/ m; r3. Mysql安全设置 4 [4 b: d/ m+ U" A0 k2 M# n4 Q
4. vsFTPd安全设置 1 I: U% Y+ Q3 B' B: @5 u* e8 P& ~) p: C
5. SSH的安全设置 8 ?. r9 X9 l8 m% e4 H7 U

  n+ K- M" \3 ~5 ]' K' F四、防火墙的安装和设置
6 H% ?9 Q* {/ j  |; D( P7 o7 _1. 安装ipfw - P) R. o4 W& K
2. 配置ipfw
8 b0 Q3 d% j1 Y6 F
  J- b( _4 K# M2 Q+ K4 r五、Unix/Linux上的后门技术和防范
1 P; @  a3 i+ A' |/ u9 Z4 }8 G1. 帐号后门
# ]3 m- C" O  Q9 t  x5 r2. shell后门
0 L1 J$ r6 K0 G( P4 `3. cron服务后门
! o3 {# a+ ]# W' I4. rhosts后门
- C$ ~/ m; r& y) E% p6 J5. Login后门
$ \) v5 Q" s3 S8 ?! f2 C6. Bind后门 1 v# G& Q$ @; J* p% m1 u8 Y2 m0 ^4 f
7. 服务后门
9 Z! t* L0 {( d3 j6 j/ ]& U8. rootkit后门 * Y8 C6 G7 Y4 w  C9 ^
9. 内核后门
+ R# \5 f: Y" n10. 其他后门
/ ^- E5 y+ H" a& {
1 V1 i0 y4 L8 N  t( q4 j六、结束语
6 G$ Q$ j& R2 M% ]( m+ t& R1 z" I- X1 v* A$ p
附录

TOP

三、 服务程序的安全设置

3 i* s/ t9 V( H- J& B" F

6 Q3 a: T8 F/ O* s7 K- r5 \到这里就是本文的重点所在了,我们将花费比较多的文字进行描述,当然,所以描述不一定是非常正确的,也希望能够对你有一些帮助。我们系统默认是运行了包括Apache、Mysql、vsFTPd,SSH等服务,我们以下进行一一讲解。 1 H. S( u6 a. f8 i4 `
; S# q2 d" C8 `
1 N2 R( P4 q" B
1. Apache的安全设置 & c5 B. J: w! C# F

; R( K' Q  ^/ [+ |$ t$ AApache的核心设置就是在 httpd.conf 里面,我们安装的Apache的目录是在 /usr/local/apache2/ 下,那么我们的配置文件就是在 /usr/local/apache2/conf/httpd.conf ,如果你是使用ports等安装的,配置文件应该是在/etc或/usr/local/etc目录下。使用ee或者vi打开配置文件:
- q  q' j: [6 U" w9 \# ee /usr/local/apache2/conf/httpd.conf
# U' `5 ~. T- V( s% }下面我们就要进行比较多的安全设置了,基本的服务、端口、主目录等等设置就不说了,只讲与安全有关的设置。   p- O& @  e8 h

# G$ j6 J, X! t; O+ G. _(1)指定运行Apache服务的用户和组
8 r* j" ^7 Q' d1 v) C这是比较重要的,因为权限是继承的,如果运行Apache服务的用户权限太高,那么很可能使得入侵者通过WebShell等就会对系统构成严重威胁。一般我们运行Apache的是nobody用户和nobody组。在httpd.conf的250-275行之间找到User和Group选项,比如我们默认设置如下(去掉了注释信息):
* V3 {" t4 X8 U6 _. A& w: i7 k<IfModule !mpm_winnt.c>;
3 [* r7 K6 `! P<IfModule !mpm_netware.c>;
& e! y* W' Y( `5 {+ V8 Q4 W: R- `User nobody ' u0 B2 c7 Y$ Z1 s* ~/ @
Group #-1
: k& T; k0 ~+ Q: ?9 a</IfModule>;
7 f2 M" V1 p+ B* Y</IfModule>;
: W* m8 m5 U! y4 ]: W1 M& I/ w" i8 Z; J
(2) Apache的日志文件
9 w; T' Y* Y3 z6 p* f2 S1 B% |Apache的日志文件是非常重要的,可以发现apache的运行状况和访问情况,对于判断入侵等有重要帮助。它的默认选项是:
$ M. a5 T# Z3 x; A& ?/ s7 g# 错误日志存放目录,默认是存放在apache安装目录的logs下 1 c- B2 D0 ]! E2 h0 M7 n0 S
ErrorLog logs/error_log 6 L' Y/ v! ?1 x! r/ V
# 日志记录的级别,级别有debug, info, notice, warn, error, crit等,默认是“warn”级别 1 ]" ~% P# M7 N- ^5 B1 A
LogLevel warn . v! i3 ]/ i2 G) L  g5 T7 Z6 M
# 访问日志记录的格式,每一种格式都有不同的内容,根据你的需要进行定制,以获取最多访问信息 4 p& K& |9 H7 c& K
LogFormat "%h %l %u %t \"%r\" %>;s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined . _2 J* u; S4 a1 X5 A
LogFormat "%h %l %u %t \"%r\" %>;s %b" common 0 f) o1 L- n3 W' W# G/ D) T- k$ @
LogFormat "%{Referer}i ->; %U" referer
+ H# ^2 J. l5 T8 C) ?LogFormat "%{User-agent}i" agent
! L$ L' K2 ?: m& U0 N* |# 使用上面格式的那一种,默认是使用common 8 ?6 U! @& t: q# ^: e% ^
CustomLog logs/access_log common
" ?  t( M( e' R- Y; ]1 t* k* s8 A7 @1 ?8 K
文件格式预定义的格式内容: : L( P8 x- L6 n9 d2 B1 R
%a 远程用户IP
1 G* f3 V5 r/ |%A 本地httpd服务器的ip & Z0 b5 M* ~- d) c1 |. U3 X
%f 传送的文件名 + I$ M3 p$ @' Q; C/ P8 p
%h 远程主机
; I# E2 T. W* }3 i5 k%m 请求方式 ) N7 K$ r. T, v, ^# |3 P- M6 A5 w
%l identd给出的远程名 - B; M" X+ [+ j& n, b' X8 K# a
%p 连接的httpd端口号
7 F0 J6 X% l: @+ [8 U6 [%P 请求的httpd进程 $ f+ Z- O- o" j
%t 时间
( t9 M5 Y! @$ T$ n3 m%T 服务请求时间 2 [8 ?2 [% u8 Y& W7 ~
你可以定制自己的日志格式,然后通过CustomLog logs/access_log common来进行调用。 3 Y+ W- @4 f& a& h) y1 [
- a/ w7 s1 d0 E: K
注意,日志文件是由运行Apache的用户进行打开的,要注意该文件的安全,防止被黑客改写或者删除。
3 u; m/ k- }* j, a# A% [5 ~; c* c" O/ v' U5 r! V' l4 D
(3) Apache服务信息显示控制
  L. g: m" E" Y0 E在配置文件中有个选项是控制是否显示apache版本信息、主机名称、端口、支持的cgi等信息的: ) S4 Y# n- o: A" p9 s
ServerSignature On ) M- k# \* }+ r- b. u0 u/ q
默认为On,那么将显示所有信息:
( a. C* g4 B, |1 v. w0 n  i我故意访问一个不存在的文件:http://www.target.com/404.html ' j) Z2 Q" S( C7 [  h2 v+ P
那么就会在给的错误提示中显示如下信息: $ ?2 {3 W/ H3 m! A9 ~
Apache/2.0.53 (Unix) PHP/4.3.11 Server at target.com Port 80
+ h: o( Q% R7 w- g9 B9 Z2 Z) L) J( h/ }# t; i* r! A
所有Apache和PHP的信息暴露无遗,这是很不安全的。当然同时还有Off和EMail选项,Off将不显示任何信息,EMail将显示管理员的邮箱地址,建议设为Off或者EMail,这样能够避免泄漏Apache服务器的信息给黑客。
1 ]8 o9 A1 g5 E9 n1 t3 W9 L+ B# G2 n' K) |1 w6 Z5 e3 k2 q. a
(4) 目录浏览
0 v9 V" N+ A* ?在httpd.conf中可以设置apache能够对一些没有索引文件的网页目录进行目录浏览:
# }% n# f; C) V  e- ~# z$ g<Directory />; 2 o6 l' k- I; [& F/ B; a
    Options Indexes FollowSymLinks
! U7 O, H; h6 }6 W, G    AllowOverride None
8 \* S( x- ^+ l</Directory>;
3 w7 t( J7 S4 T. l这是不合适也不安全的,建议不需要目录浏览:
+ `" o8 B. \9 ?+ X<Directory />; 6 ~% d, L  b2 p" e$ w  q
    Options FollowSymLinks
! f. c5 I! c( k* E4 J    AllowOverride None
/ G* V: E( L& f* f3 R0 z) @</Directory>; " ?6 {# o: s! a) D9 Y& D( z

- ~; E9 n) j! W) o. W( b& n+ C(5) 用户主页 " v6 n5 j  c( q/ g8 Z$ q; O
设置httpd.conf中的: # j- C) I  \' J
UserDir public_html
9 y. m$ {- [+ ]  K' G5 l能够使得每个使用系统的用户在自己的主目录下建立 public_html 目录后就能够把自己的网页放进该目录,然后通过:
! H6 [) z! ~% v8 u; k0 Fhttp://www.target.com/~用户名/网页 就能够显示自己的网页,这是不安全的,而且对于我们服务器来讲,这没有必要,所以我们直接关闭该功能:
2 Q/ p5 n2 [0 q) Y# vUserDir disabled / {3 ^! d4 w# o
或者把该内容改名,改成 一个黑客比较不容易猜到的文件名,比如:
1 [- a% {' t  ^3 c' d1 UUserDir webserver_public_htmlpath
7 F. D0 Z" Z) K9 E# f* X也可以只允许部分用户具有该功能:
. B  D6 R/ a0 i' ~3 R# x- k+ RUserDir enabled user1 user2 user3 % X6 r& q  S* J
, P4 g$ n# E- ?2 A
(6) CGI执行目录
( `' N+ B" n! _' F( T如果你的apache要执行一些perl等cgi程序,那么就要设置一下选项: ; f  |. H% o$ W5 q8 f
ScriptAlias /cgi-bin/ "/usr/local/apache/cgi-bin/" # b  u! a0 r! l
但是这也给了黑客利用一些不安全的cgi程序来进行破坏,所以如果你不需要cgi的话,建议关闭该选项: ! s2 k$ Z  A# K0 `9 g" Y
#ScriptAlias /cgi-bin/ "/usr/local/apache/cgi-bin/" ( \5 I- M0 B/ n# F- p6 L
% z, L% p$ R( w0 N% `
(7) 控制PHP脚本只能访问指定目录 " [7 h. u0 P& Q2 i' @9 @
在httpd.conf添加如下内容:
5 |& j, S% O+ @+ z& T& ~- m; tphp_admin_value open_basedir /usr/www ) D6 d) E8 A9 b0 e6 W  x# a, F0 [
后面的路径是你需要PHP脚本能够访问的目录,如果PHP脚本想要访问其他目录将出项错误提示。 1 C( Z* t; V; e0 H! c
! I5 c$ ?; I' Z8 m/ g" C: J
(8) 目录访问控制 (未完) + c1 t* s8 Q, R" r3 p1 z
这项内容最复杂,同时涉及的东西也比较多,我只能简单说一下,不清楚请参考其他文章。 ! y! R  R9 T: H9 M6 W6 a" O1 n
比如下面的内容: / v3 b& y, T$ `6 |4 s, V
<Directory />;
  @1 a( D+ f6 U3 ~    Options FollowSymLinks & g  f5 \9 b$ P2 k
    AllowOverride None 5 o' s# y3 J! h$ ?+ W& {
</Directory>; . K: b  i( W7 T
就是允许访问每一个目录,里面设置的是允许执行的动作,一般包含的动作有:Options、AllowOverride、Order、Allow、Deny。
2 J' a' q6 k6 c6 S5 YOptions是只对指定目录及其子目录能够执行的操作,Indexes、Includes、FollowSymLinks、ExecCGI、MultiViews、None、All等操作。
3 h8 ]0 O" M: m$ M! YAllowOverride是指定目录访问的权限,当然也可以通过 AccessFileName文件指定的 .htaccess 来控制。它的操作有:None、All、Options、FileInfo、AuthConfit、Limit等。 # {7 i1 t' T! Y/ t, W8 Z% q' Y' B
Order、Allow、Deny三个指令必须配合来控制目录访问权限。Order指定检查次序的规则,比如Order Allow, Deny,表示先按Allow检查,如果不匹配再按Deny进行检查。Order Deny, Allow ,表示先按Deny规则检查,如果不满足条件,再按Allow进行检查。
7 P1 [' |5 d* l5 |8 K- T9 c
' Q: v% S- m  p* o& N. J控制目录访问权限的文件
2 r" [; s) M6 R1 N3 V) g默认在Unix平台下能够使用 .htaccess 来对目录权限进行规则定义,但是这是不安全的,建议关闭,默认的选项:
  ]) ~+ d" W' y1 Q" CAccessFileName .htaccess
; \* g, Z+ ~* `% g# r1 h+ ~- V6 ^建议设成:
4 V; M2 p( n7 z! [, Y#AccessFileName .htaccess 3 B" v8 [) `" F' k
全部目录权限定义使用httpd.conf中的定义,不使用 .htaccess。 4 t$ [" O: i% M4 \/ v/ X9 V
/ a- W) B6 ~& H( i0 v' i1 K1 Q2 o) K) r
(9) 用户访问认证 # a' X' {1 t/ \( n
这个技术非常重要,能够控制一些非法用户访问本内容。假设我们的网站: http://www.target.com/admin 是我们的后台管理目录,我不允许一些非法用户进行访问,那么我就必须设定对该目录访问是需要验证的。
" c& ]; T+ }' f. r先在httpd.conf中加入要进行访问认证的目录:
4 s3 ^2 z! ]* k<Directory "/usr/www/admin">;
' V  z( U! L4 ^" K7 i2 ]: C8 qauthtype basic 1 N/ o9 j* g  d3 N- L. |
authname "Private" 2 m3 R( T7 i# V; r7 f' f
authuserfile /usr/local/apache/bin/admin.dat 6 `- j9 R2 ?! q1 f$ A8 Q5 W
require user login_user
7 A- Y* o  o$ g. z9 ^" d( H; nOptions Indexes FollowSymlinks MultiViews
4 I% P7 y& [* C8 T1 P$ O2 FAllowOverride None : g7 I; f0 y6 y2 J
</Directory>;
# a8 e. W/ [/ \; o上面我们就设置了我们的 /usr/www/admin目录是必须进行认证才能访问的,接着我们设置访问密码:
  t) _4 P& ?' V# /usr/local/apahche/bin/htpasswd -c /usr/local/apache/bin/admin.dat login_name ) y. a7 S- q( s9 V6 r
New password: *****
; N; Q' h; y, q6 h0 DRe-type new password: ***** 7 E% ]: {( O" L1 \, I& |- b) `
Adding password for user login_name , `8 u- G9 l0 Q6 D) @% v' a% {

. H* H+ \  J' s7 {. K8 T" h那么下次任何用户访问http://www.target.com/admin目录的时候就需要输入用户名login_name和你设置的密码。
7 `7 N% Z2 n# b! Q( P* J/ R1 H$ j* e# ^" f3 J7 c
0 B+ G+ M0 b$ }
2. PHP安全设置
0 L, A3 h- r6 n, i) I1 P! X
- u- @" A7 Q7 K! S* N# h0 oPHP本身再老版本有一些问题,比如在 php4.3.10和php5.0.3以前有一些比较严重的bug,所以推荐使用新版。另外,目前闹的轰轰烈烈的SQL Injection也是在PHP上有很多利用方式,所以要保证安全,PHP代码编写是一方面,PHP的配置更是非常关键。
( D5 k, X/ W. _( C% e我们php手手工安装的,php的默认配置文件在 /usr/local/apache2/conf/php.ini,我们最主要就是要配置php.ini中的内容,让我们执行php能够更安全。 # Q6 D9 P) \7 }' O6 v
整个PHP中的安全设置主要是为了防止phpshell和SQL Injection的攻击,一下我们慢慢探讨。我们先使用任何编辑工具打开/etc/local/apache2/conf/php.ini,如果你是采用其他方式安装,配置文件可能不在该目录。
1 ]' O7 Q9 V" l: x; M
8 [: z4 _. \( `7 R. ^7 d(1) 打开php的安全模式
$ p: R! o1 m: o$ L7 g! zphp的安全模式是个非常重要的内嵌的安全机制,能够控制一些php中的函数,比如system(),同时把很多文件操作函数进行了权限控制,也不允许对某些关键文件的文件,比如/etc/passwd,但是默认的php.ini是没有打开安全模式的,我们把它打开:
  y1 ~9 x' K* ?" w! X, lsafe_mode = on - X; c: A5 n8 }6 b

8 y+ A7 g; c8 o4 g% V(2) 用户组安全 , [& R3 G+ D. j3 ~' s* H8 b
当safe_mode打开时,safe_mode_gid被关闭,那么php脚本能够对文件进行访问,而且相同组的用户也能够对文件进行访问。 " U1 b! C- y( O) I( N/ w
建议设置为:
$ j, m* ^- ^3 j8 C  ~: @0 [safe_mode_gid = off
1 m1 i( n8 \" {# A) W3 ~5 R如果不进行设置,可能我们无法对我们服务器网站目录下的文件进行操作了,比如我们需要对文件进行操作的时候。
1 O5 T' Y4 V  n+ P& _9 x! x9 p' L$ s( a! v4 v. `, o
(3) 安全模式下执行程序主目录
" ~  J; H+ ?5 I0 l5 C如果安全模式打开了,但是却是要执行某些程序的时候,可以指定要执行程序的主目录:
+ P- F. R# L6 R; Csafe_mode_exec_dir = /usr/bin
" c0 z6 L( }& e( O6 m0 S一般情况下是不需要执行什么程序的,所以推荐不要执行系统程序目录,可以指向一个目录,然后把需要执行的程序拷贝过去,比如: ( g7 x" q5 H0 q, Z2 ~$ ]
safe_mode_exec_dir = /tmp/cmd + f3 Y0 h) ]1 ^1 v" A
但是,我更推荐不要执行任何程序,那么就可以指向我们网页目录:
' Q' b6 N" J: Q  `' W- fsafe_mode_exec_dir = /usr/www
7 `; @9 G1 A+ |% E4 z# n4 h2 M: X- J2 G" r
(4) 安全模式下包含文件
' F4 |% W3 p' F  I如果要在安全模式下包含某些公共文件,那么就修改一下选项:
* z2 O$ F; }: g. h# T! Msafe_mode_include_dir = /usr/www/include/
# X+ V( N  m: z0 a1 A其实一般php脚本中包含文件都是在程序自己已经写好了,这个可以根据具体需要设置。 6 U5 {6 F& _, M) o1 a, t/ g

" y" h0 x3 H+ P# T3 C6 X; I( J3 R(5) 控制php脚本能访问的目录 & X  T' `' {; V- y3 F2 t) O
使用open_basedir选项能够控制PHP脚本只能访问指定的目录,这样能够避免PHP脚本访问/etc/passwd等文件,一定程度上限制了phpshell的危害,我们一般可以设置为只能访问网站目录: # y% t1 S) [" E) ~0 s
open_basedir = /usr/www
8 b1 z( F$ ]  j9 A- ~2 H& O/ K. ~1 A; C& ~9 `5 ^! V
(6) 关闭危险函数
3 m7 i$ |2 c1 w/ G  r! [* l1 @如果打开了安全模式,那么函数禁止是可以不需要的,但是我们为了安全还是考虑进去。比如,我们觉得不希望执行包括system()等在那的能够执行命令的php函数,或者能够查看php信息的phpinfo()等函数,那么我们就可以禁止它们:
# y. F/ u( ^; T( ?8 ddisable_functions = system,passthru,exec,shell_exec,popen,phpinfo , f/ C8 ]: M; l5 i& c
如果你要禁止任何文件和目录的操作,那么可以关闭很多文件操作
5 k$ \6 m5 Z8 I+ }disable_functions = chdir,chroot,dir,getcwd,opendir,readdir,scandir,fopen,unlink,delete,copy,mkdir,rmdir,rename,file,file_get_contents,fputs,fwrite,chgrp,chmod,chown 1 R5 ?9 i2 R' X& b9 S
以上只是列了部分不叫常用的文件处理函数,你也可以把上面执行命令函数和这个函数结合,就能够抵制大部分的phpshell了。
+ F* W4 o: `4 l0 N  ~" K5 H4 g" u" [' z; W( @
(7) 关闭PHP版本信息在http头中的泄漏
# K2 V  F0 S) n9 O6 m我们为了防止黑客获取服务器中php版本的信息,可以关闭该信息斜路在http头中: 5 m8 C! H; U8 P2 w: h. s
expose_php = Off / r6 d: h* B! D
比如黑客在 telnet www.target.com 80 的时候,那么将无法看到PHP的信息。 . {$ T/ [/ ~- ^( _( x6 d

2 g6 m  Q9 C7 y8 G(8) 关闭注册全局变量
' E7 V( k* C  f/ I( _8 D0 b: }, x在PHP中提交的变量,包括使用POST或者GET提交的变量,都将自动注册为全局变量,能够直接访问,这是对服务器非常不安全的,所以我们不能让它注册为全局变量,就把注册全局变量选项关闭:
; ?( d  P/ g* h2 [7 t4 \- {register_globals = Off
7 B4 E: c9 x9 P- s/ F当然,如果这样设置了,那么获取对应变量的时候就要采用合理方式,比如获取GET提交的变量var,那么就要用$_GET['var']来进行获取,这个php程序员要注意。
# X0 h2 d. f8 a% n4 {' z% @/ C. l+ r  s0 C+ {
(9) 打开magic_quotes_gpc来防止SQL注入
! N7 Y4 [- t3 j5 tSQL注入是非常危险的问题,小则网站后台被入侵,重则整个服务器沦陷,所以一定要小心。php.ini中有一个设置: ) s1 r8 E: b+ d, M  n
magic_quotes_gpc = Off % }' B  O2 t* i* N1 T
这个默认是关闭的,如果它打开后将自动把用户提交对sql的查询进行转换,比如把 ' 转为 \'等,这对防止sql注射有重大作用。所以我们推荐设置为: 5 ?3 ?% k# z6 ]4 Z
magic_quotes_gpc = On ' W0 Y7 z# P5 o
8 L+ W1 Y* J2 P- `2 U
(10) 错误信息控制 , h4 j2 T1 @; n
一般php在没有连接到数据库或者其他情况下会有提示错误,一般错误信息中会包含php脚本当前的路径信息或者查询的SQL语句等信息,这类信息提供给黑客后,是不安全的,所以一般服务器建议禁止错误提示:
& U4 b) \+ l% c  X0 q) Rdisplay_errors = Off
. R. O: s% c. j: L- O$ _如果你却是是要显示错误信息,一定要设置显示错误的级别,比如只显示警告以上的信息: 1 S; P* m* b  }1 X/ V3 l
error_reporting = E_WARNING & E_ERROR
% o( s( R" f2 q" [, z  w当然,我还是建议关闭错误提示。
: w) H2 ]4 \! S$ D# c& d/ V+ T
2 k0 S  ]3 M* U- k  @(11) 错误日志 + D: `; z% U/ Z7 K" `! {6 k, [
建议在关闭display_errors后能够把错误信息记录下来,便于查找服务器运行的原因: & V5 t2 J; G) [  ^
log_errors = On % j0 Q9 }* }, k* k: F2 L$ T
同时也要设置错误日志存放的目录,建议根apache的日志存在一起:
' s- I# d7 v4 }: O; z7 H. Ferror_log = /usr/local/apache2/logs/php_error.log 1 F+ y; @3 Z. G" u  X, D
注意:给文件必须允许apache用户的和组具有写的权限。   v7 p+ `! }$ G3 Q+ J

8 N2 I1 H; T: e. I4 t, ~
! P2 Z, ~0 T- u" u/ T+ R2 P# L3. Mysql的安全设置 $ b% L9 Z! ^: z# x2 {% g

7 o# @2 Z& C4 H! a1 `我们把Mysql安装在 /usr/local/mysql目录下,我们必须建立一个用户名为mysql,组为mysql的用户来运行我们的mysql,同时我们把它的配置文件拷贝到 /etc目录下:
8 D* H8 G, n5 K' a2 q& Z5 ?# cp suport-files/my-medium.cnf /etc/my.cnf
+ ~" s0 B9 p" G) achown root:sys /etc/my.cnf 8 ^3 C. B6 h# r- F0 v3 B: l! f
chmod 644 /etc/my.cnf
6 N+ h% c6 q" p3 g$ @1 t& a
) n0 h# P5 Q) S' V" |+ O# F$ Z使用用户mysql来启动我们的mysql:
2 s3 N8 ?9 ]- T, ~, c) ~# /usr/local/mysql/bin/mysqld_safe -user=mysql & ( H' ]1 P1 |% O% l! P% i& ^; D. ^* G

0 z5 Y" V0 Q% ^2 \- D' ?(1) 修改root用户的的口令
4 R" G- h6 _& @$ b7 l! L* S" x缺省安装的mysql是没有密码的,所以我们要修改,以防万一。下面采用三种方式来修改root的口令。
+ X6 Y3 }4 {6 i: d% k" d' b3 v
! W0 |6 o% E) |% U*  用mysqladmin命令来改root用户口令
" U0 |/ n( \" W+ C1 z  T8 j# mysqladmin -uroot password test 5 \& T$ \* g: ]+ a: b
这样,MySQL数据库root用户的口令就被改成test了。(test只是举例,我们实际使用的口令一定不能使用这种易猜的弱口令)   \9 G# I" ]. O. }6 U  ^
4 y3 C  x9 [; [/ B: F4 O5 d
*  用set password修改口令:   ^5 x/ w) w/ }5 N& A( Q
mysql>; set password for root@localhost=password('test'); * y6 Y% T$ U7 E: M+ _, {
这时root用户的口令就被改成test了。
) ^; F) N: A. `& y/ j$ b
4 A. e' c' C, C9 G6 R*  直接修改user表的root用户口令     . f6 m2 A( Q( L2 q) h& m" r0 s
mysql>; use mysql;
* G: {% y2 r3 j) p- ^mysql>; update user set password=password('test') where user='root'; 1 `; m/ \" }6 x( P
mysql>; flush privileges; : m" s& o4 A2 y0 i1 F
5 G, p$ m# Z, I8 ?
这样,MySQL数据库root用户的口令也被改成test了。其中最后一句命令flush privileges的意思是强制刷新内存授权表,否则用的还是缓冲中的口令,这时非法用户还可以用root用户及空口令登陆,直到重启MySQL服务器。 # i) o2 d- b7 i2 Y9 \! G" |
7 E5 [2 ^# Z3 r
(2) 删除默认的数据库和用户 ( k* D  |2 J# B1 t6 G5 S8 y
我们的数据库是在本地,并且也只需要本地的php脚本对mysql进行读取,所以很多用户不需要。mysql初始化后会自动生成空用户和test库,这会对数据库构成威胁,我们全部删除。
$ D& {9 L& V: c. X我们使用mysql客户端程序连接到本地的mysql服务器后出现如下提示:
- a0 W) O* s, M) l5 `. K! G' zmysql>; drop database test; 5 Z; v' p2 q0 P- Z! M/ M
mysql>; use mysql;
0 V9 j+ b/ K* L$ `7 d* p  gmysql>; delete from db; 4 G; ^. v- h. Y0 T# y
mysql>; delete from user where not(host="localhost" and user="root"); ) P- `% K4 L! g6 _% b# y
mysql>; flush privileges;
) d% h6 ?4 B8 h4 k% u6 N! E7 o- m' ]5 \3 U3 N: E4 i; s; ?# w
(3) 改变默认mysql管理员的名称 4 n/ G; r  g  H; o+ ]  a
这个工作是可以选择的,根据个人习惯,因为默认的mysql的管理员名称是root,所以如果能够修改的话,能够防止一些脚本小子对系统的穷举。我们可以直接修改数据库,把root用户改为"admin"
, R+ y; `4 q) c2 P. g9 nmysql>; use mysql;
8 T. d% z4 Q, @/ [3 N+ j- _mysql>; update user set user="admin" where user="root";
# z: P* z4 A5 ?: nmysql>; flush privileges; 7 q0 V2 c3 c! _
4 R4 R2 w# E+ |: f# h$ A
(4) 提高本地安全性
2 c2 o: o- _0 G$ b. P& o提高本地安全性,主要是防止mysql对本地文件的存取,比如黑客通过mysql把/etc/passwd获取了,会对系统构成威胁。mysql对本地文件的存取是通过SQL语句来实现,主要是通过Load DATA LOCAL INFILE来实现,我们能够通过禁用该功能来防止黑客通过SQL注射等获取系统核心文件。
3 H+ i5 t: F- v  e6 W+ D; ~禁用该功能必须在 my.cnf 的[mysqld]部分加上一个参数:
- k$ |( H$ r1 X: C( G* ^set-variable=local-infile=0 , v/ U" e& L% ^9 `7 Y$ Q

% w/ {( B  r" C(5) 禁止远程连接mysql
5 T3 B+ J/ D  w& ~* r5 q因为我们的mysql只需要本地的php脚本进行连接,所以我们无需开socket进行监听,那么我们完全可以关闭监听的功能。 9 ^- Z# t7 U4 q0 c
有两个方法实现: , g; j) a' Y/ E6 U' s# _" S% }6 B' x
* 配置my.cnf文件,在[mysqld]部分添加 skip-networking 参数
( U6 {; q, ^- k3 F, U; C* F* mysqld服务器中参数中添加 --skip-networking 启动参数来使mysql不监听任何TCP/IP连接,增加安全性。如果要进行mysql的管理的话,可以在服务器本地安装一个phpMyadmin来进行管理。 . _4 h# O$ D1 v, I& s, }
' b, h6 B: Z- q3 ?7 y
(6) 控制数据库访问权限 . z* _! Z; s7 }6 @+ k
对于使用php脚本来进行交互,最好建立一个用户只针对某个库有 update、select、delete、insert、drop table、create table等权限,这样就很好避免了数据库用户名和密码被黑客查看后最小损失。 / ~5 x4 z$ B$ _  h# j1 j
比如下面我们创建一个数据库为db1,同时建立一个用户test1能够访问该数据库。
/ W- I. [; s/ n! t$ Smysql>; create database db1; 4 y: j4 E3 K/ m
mysql>; grant select,insert,update,delete,create,drop privileges on db1.* to test1@localhost identified by 'admindb'; 3 f: ^5 d" k4 j8 }0 c5 V9 O
以上SQL是创建一个数据库db1,同时增加了一个test1用户,口令是admindb,但是它只能从本地连接mysql,对db1库有select,insert,update,delete,create,drop操作权限。 , x$ c# E: S( C! Q5 p, x

6 ]- w/ Y9 o5 G/ f(7) 限制一般用户浏览其他用户数据库
2 b0 b' t/ F% {- O4 D如果有多个数据库,每个数据库有一个用户,那么必须限制用户浏览其他数据库内容,可以在启动MySQL服务器时加--skip-show-database 启动参数就能够达到目的。 1 A: H3 D& u( ?0 e4 h! a/ D1 }" d

4 t6 F) M  X. ?/ H(8) 忘记mysql密码的解决办法 ) x: P3 h3 S& x
如果不慎忘记了MySQL的root密码,我们可以在启动MySQL服务器时加上参数--skip-grant-tables来跳过授权表的验证 (./safe_mysqld --skip-grant-tables &),这样我们就可以直接登陆MySQL服务器,然后再修改root用户的口令,重启MySQL就可以用新口令登陆了。
: J5 r! a; F, U5 k; N
% z1 }& s) M+ b(9) 数据库文件的安全
, k, Q# ~* P# V3 Q: F+ E我们默认的mysql是安装在/usr/local/mysql目录下的,那么对应的数据库文件就是在/usr/local/mysql/var目录下,那么我们要保证该目录不能让未经授权的用户访问后把数据库打包拷贝走了,所以要限制对该目录的访问。
# M6 O, ~: M% ?我们修改该目录的所属用户和组是mysql,同时改变访问权限: ! U6 N$ c' l' B: ^8 V% ^
# chown -R mysql.mysql /usr/local/mysql/var
1 d; s/ H9 J. V- B! |# chmod -R go-rwx /usr/local/mysql/var
5 J! f$ b( b! Z6 ~( e0 ]( n, v% C# I( c8 U7 V
(10) 删除历史记录 ' w0 Z* K& W% b1 w8 V* H
执行以上的命令会被shell记录在历史文件里,比如bash会写入用户目录的.bash_history文件,如果这些文件不慎被读,那么数据库的密码就会泄漏。用户登陆数据库后执行的SQL命令也会被MySQL记录在用户目录的.mysql_history文件里。如果数据库用户用SQL语句修改了数据库密码,也会因.mysql_history文件而泄漏。所以我们在shell登陆及备份的时候不要在-p后直接加密码,而是在提示后再输入数据库密码。
( {; K: v( ]; N7 X7 K( o: n1 P另外这两个文件我们也应该不让它记录我们的操作,以防万一。 3 {$ k6 e3 r; ~2 C2 m* e. G' g
# rm .bash_history .mysql_history
( ?, q  r; c+ H6 ~% o/ q% ~* k# ln -s /dev/null .bash_history , _% {( v1 p! c, E* n; `4 R/ U
# ln -s /dev/null .mysql_history
0 p: m( ?# h! h. S3 u. k: t4 }4 b# q. P& b# ]( `5 m% Y
(11) 其他
$ X; ]- O/ C; K  z- z另外还可以考虑使用chroot等方式来控制mysql的运行目录,更好的控制权限,具体可以参考相关文章。 3 y. Z& Y5 n: m; J
( w: O* ^) v- r/ `: Z) s# ^

' y5 X& o# x) y8 o/ C4. vsFTPd安全设置  
$ y. |' V% e$ j3 I1 Q: x7 n) ?" r4 {1 d& n+ T9 J  H: B1 p: X% ?
vsFTPd是一款非常著名的ftp daemon程序,目前包括Redhat.com在内很多大公司都在使用,它是一款非常安全的程序,因为它的名字就叫:Very Secure FTP Daemon (非常安全的FTP服务器)。 . T& v3 m* l9 a7 d. Z
vsftpd设置选项比较多,涉及方方面面,我们下面主要是针对安全方面进行设置。
$ p8 \3 N. {9 W  U' x+ I& o目前我们的需求就是使用系统帐户同时也作为是我们的FTP帐户来进行我们文件的管理,目前假设我只需要一个帐户来更新我的网站,并且我不希望该帐户能够登陆我们的系统,比如我们的网站的目录是在/usr/www下面,那么我们新建一个用户ftp,它的主目录是/usr/www,并且它的shell是/usr/sbin/nologin,就是没有shell,防止该用户通过ssh等登陆到系统。
! x# R% ~2 }' M  x4 g* M
: j5 }( g( h2 \' F下面在进行系统详尽的设置,主要就是针对vsftpd的配置文件vsftpd.conf文件的配置。 9 f7 v+ _6 n7 i7 p9 Z/ ~+ K
7 |' ~: ]* L' B/ D& N' `$ n
(1) 禁止匿名用户访问, 我们不需要什么匿名用户,直接禁止掉: $ M. E. j3 G) Z  p' o. F- q9 ]- o
anonymous_enable=NO  & O9 }8 g5 p* @# k

2 n5 b4 h* h% G% S) h7 U! T( ?+ o, b(2) 允许本地用户登陆,因为我们需要使用ftp用户来对我们网站进行管理: 3 t, A2 Y' ~' z: Z. i) E+ F
local_enable=YES ( K/ C' }% M' }8 y

3 f9 j$ J* s" q$ m5 S. P(3) 只允许系统中的ftp用户或者某些指定的用户访问ftp,因为系统中帐户众多,不可能让谁都访问。
- p) D: r' j6 A- [  D打开用户文件列表功能: # Y: ~# Y, n0 b6 ]& H% o
userlist_enable=YES
1 T7 q6 p- G, ~! D4 k* X3 [只允许用户文件列表中的用户访问ftp: ; U+ }, P0 ^* \6 x. v/ V
userlist_deny=NO  
  j" E8 K+ o+ e% G用户名文件列表路径:
& K+ L, g* `$ E$ l  cuserlist_file=/etc/vsftpd.user_list  8 o) P9 J! k# B. @7 C/ w

, }5 Y) |# h9 T2 H' D5 p) \然后在/etc下建立文件 vsftpd.user_list 文件,一行一个,把用户ftp加进去,同时也可以加上你允许访问的系统帐户名。 ! N& X# U* E; }/ m
0 a. u8 }  N' X" D; Q! P1 W
(4) 禁止某些用户登陆ftp: / {; M, u+ V* C' `. N( N) b
pam_service_name=vsftpd  
2 o" U* ]: x* M  B) J' z指出VSFTPD进行PAM认证时所使用的PAM配置文件名,默认值是vsftpd,默认PAM配置文件是/etc/pam.d/vsftpd。  " k0 S, L; Q# L- b, ]
5 h; @( z; ?! Q+ w
/etc/vsftpd.ftpusers  
' T+ f2 ~2 E0 o2 j# h1 kVSFTPD禁止列在此文件中的用户登录FTP服务器,用户名是一行一个。这个机制是在/etc/pam.d/vsftpd中默认设置的。
& T/ [( u/ c0 Z8 Q, V
5 t: k+ Q2 R8 R* d! o8 w这个功能和(3)里的功能有点类似,他们俩能结合使用,那样就最好了。
8 T/ ?/ k* [$ O* s# z5 c/ b7 g" Y8 _7 Z1 v" j3 n- Y
(5) 把本地用户锁定在自己的主目录,防止转到其他目录,比如把/etc/passwd给下载了: 2 |, D% _" S( D8 p, t. X
chroot_local_users=NO
0 T; I7 y7 b* z9 z: B& C- tchroot_list_enable=YES  6 Z4 S4 L9 v/ a1 C$ E  t
chroot_list_file=/etc/vsftpd.chroot_list . B( ]& z$ h5 u8 Z) v& h  t
然后在/etc下建立vsftpd.chroot_list文件,里面把我们要限制的本地帐户加进去,一行一个,我们加上ftp,防止它登陆到系统。
$ l3 l: a& D: v# g  D( |
& {3 |" u( C8 I- x% J(6) 隐藏文件真实的所有用户和组信息,防止黑客拿下ftp后查看更多系统用户信息:
2 A( l$ {( R' o4 D5 \( ihide_ids=YES
9 g+ h9 z5 V4 M0 {* N+ i2 S" L/ ~9 D; I: v7 M3 d, ]
(7) 取消ls -R命令,节省资源,因为使用该命令,在文件列表很多的时候将浪费大量系统资源:
( t9 R5 `' H( k9 Y' `ls_recurse_enable=NO  
0 ~( n3 i7 F# c
1 Z2 }  B- {/ X* G(8) 上传文件的默认权限,设置为022: 3 m- {3 @4 T$ W2 ?. L0 Z" l
local_umask=022 7 r& J7 R' X! m2 y
如果要覆盖删除等,还要打开:
, Y( c4 Y  h$ X/ q( m  S+ O) Ewrite_enable=YES 6 d$ `- H6 x& }! K- ~7 X; T, ?

2 r* R& K' ^& |: n6 _(9) ftp的banner信息,为了防止黑客获取更多服务器的信息,设置该项: 6 z1 A) Y; q% D4 @) R. j4 }, c
ftpd_banner=banner string
/ Z9 h( C2 ^1 t. ]把后面的banner string设为你需要的banner提示信息,为了安全,建议不要暴露关于vsFTPd的任何信息。
9 D6 r' c% J: f$ H/ O3 I6 i9 Q$ f另外,如果你的信息比较多的话,可以设置为提示信息是读取一个文件中的信息:
8 l; H5 M& o) F: |- o$ ubanner_file=/directory/vsftpd_banner_file  
( @" a3 z) _  Q
8 [2 U& x* z; [: E(10) 打开日志功能: : R! D. E, d! B* e4 l3 J; @1 N: X
xferlog_enable=YES
4 G& J$ `$ t3 g" R0 I同时设置日志的目录: # l( p) B" y* c8 R% E! ^
xferlog_file=/var/log/vsftpd.log
3 c0 G1 {* i; D$ Z' c: i启用详细的日志记录格式:
# k. y2 E4 G' a' rxferlog_enable=YES  ; N8 f6 I' t2 u  Q3 u# P) p
  Y3 w6 N  W: \6 w
(11) 如果打开虚用户功能等,那么建议关闭本地用户登陆:
0 l  s. x: _: f. @7 a( }1 \. Glocal_enable=NO  
7 k* J  d+ t- k3 D4 v, S
5 m' V" i( o5 J9 @8 r& f) {6 y1 v2 Q* k2 ]$ t- H
vsFTPd还有很多安全设置,毕竟人家的名字就是:Very Secure FTP Daemon,反正它的溢出漏洞什么的是很少的,如果要更安全,建议按照自己的需要设置vsftpd,设置的好,它绝对是最安全的。 $ \( [0 ?5 i: e9 V: Y$ o5 d
3 }- G7 q# g- H! T
2 _7 S/ T+ ]! s& |4 g
5. SSH安全设置
4 r4 E2 w* E+ B+ ]* M
. K  X. s9 l3 U8 N, z5 ]' oSSH是一个基于SSL的安全连接远程管理的服务程序,主要出现就是为了解决telnet、rlogin、rsh等程序在程序交互过程中存在明文传输易被监听的问题而产生的,目前基本上是推荐使用ssh来代替telnet、rlogin、rsh等远程管理服务。
- B( t  [+ ^, n+ W/ _: Dssh能够直接在windows平台下通过Secure SSH Client等客户端工具进行连接管理,目前最流行的服务器端就是OpenSSH程序,目前最新版本是OpenSSH4.0版,详细可以参考www.openssh.com网站。
# s$ u  E/ f, U3 o7 ?* EOpenSSH在FreeBSD下已经集成安装了,FreeBSD5.3下的OpenSSH版本是3.8.1,建议ports升级到4.0。 5 _$ r* }  A5 Q4 r9 R
, r' ^" Y1 I1 v. z
$ A3 T7 E5 g4 ]+ W. a  V$ |
主要的安全配置文件是/etc/ssh/sshd_config文件,我们编辑该文件。 4 Z0 I+ \2 A; Z9 W
' J- F( S$ V( T. k1 h+ G
(1) 使用protocol 2代替protocol 1,SSH2更加安全,可以防止攻击者通过修改携带的版本banner来劫持(hijacking)启动会话进程并降低到protocol 1。注释掉protocol 2,1 改用下面语句代替: 6 y  L& _8 d" A. z& ~: }
protocol 2  ) r+ j0 t/ ^: J8 ]' g& k

* T3 X  \$ z) R2 @3 K& I5 O(2) 合理设置最大连接数量, 防止DOS攻击  4 `) n4 [. E$ c4 S9 x) W
' @& d% n% d7 M
  MaxStartups 5:50:10  " T: U* Y" u% Y
' U' K# g( S4 _: Y! Q: ^0 D/ Q" L
(3)关闭X11forwording ,防止会话劫持 / U' y. q. L/ D9 I: N" G
8 u) D2 j' Z3 E  X: M7 W
  X11Forwarding no  
2 [' i3 ^$ Z  e& p
6 L- R$ p( N; C# [: H8 Q4 _6 r6 B: `(4)建议不使用静态密码,而使用DSA 或RSA KEY,修改如下内容可以关闭使用密码认证:  0 k! k0 k" m9 x* Z# |" b% M
% _* v0 j( b" \' k" N5 N; U
  PasswordAuthentication no  
" y, M( o. v) v& P: V+ h* A2 ]( Z9 c1 t, N" X# l* k7 t
(5)可以限制某个组或光是单个用户访问shell  
' e% o; l( C. T7 F
3 `( i/ x3 _  g0 u$ O. B  AllowGroups wheel  ! b% G) f- a  Z* g; C+ R9 l0 u
或者
2 ~/ R7 ^9 l: m$ k, p: m  AllowUsers heiyeluren  
! F; n' Z" a0 Y* S, q6 ?7 c2 |" j  v6 R, r& l
(6) 限制root用户登陆,主要是为了防止暴力破解 4 K! b- V& a( F$ b" c

3 W& x# c* s$ }9 }, G, Z    PermitRootLogin no
, ]1 \" f. f9 F0 T/ W9 O- D  V: H- Y, r
(7) 不允许口令为空的用户登陆
4 }! j1 g7 _4 M$ P% ?6 ?     
) w6 I3 T* X0 p; V( o) o. ]3 Q    PermitEmptyPasswords no
+ k2 Q/ O8 Z% g( D# |' F
: l8 k  \" C7 l6 a( u(8)使用TCP wrappers来限制一些访问,修改/etc/hosts.allow文件,注释掉"ALL : ALL : allow",增加如下内容:  5 E/ ^( N& L3 a5 ^8 E1 q. p

. N) A% p6 z4 O$ H+ o0 K* z  sshd:localhost:allow  
3 `1 |' \) B- L# q+ @  sshd:friendlcomputer:allow  
' p+ s$ d- u: _8 U' W8 Y7 R% r# y+ p# I  sshd:all : deny  ' F6 Y! x, w+ F, V2 x. y
* A9 d$ b2 T) O  v2 P$ F8 |# l
  #相关命令:  
' c$ o% n* j( |  #chsh -s /sbin/nologin user

TOP

四、防火墙的安装和设置


  b9 [5 [9 L3 B& \7 d3 H; x& B: u, h/ I, j3 R. \: Y* v
FreeBSD自带有一个基于包过滤的防火墙--ipfw,虽然功能没有专业防火墙那么强大,但是应付一个Web站点的安全还是足够的,所以我们决定选用该防火墙来保护我们的Web服务器。 ( [7 X' v0 K5 r/ Q3 Y: O

* V. F: k' b% }8 K. ~+ z; b1 ]0 }/ G+ I; E' o
1. 安装ipfw   V) d; |" ?( o/ Z% m' i" x% `* v
" D# k7 }& E& k# B, W4 x
IPFW 的主要部分是在内核中运行的, 因此会需要在FreeBSD内核配置文件中添加部分选项。(注意,如果你没有安装FreeBSD核心源代码,是无法进入以下目录的,所以运行之前一定要先安装内核源代码)我们先进入内核配置文件:
) Z. n# Y9 G) T  [* V: ~9 w# cd /sys/i386/conf    T+ j5 }- U/ ~6 u# ~* r
# cp GENERIC ./kernel_fw 6 R1 A9 F6 w+ O" H

) k6 F/ x, {2 a打开内核配置文件:
0 u& z+ J/ p3 W) P  N% c# ee ./kernel_fw ; ~/ G- I* N, a

' p9 }& q6 U9 F3 Q0 ~添加四个选项,不需要后面的注释信息: 6 U! z; c# e' n8 N- S
options IPFIREWALL # 将包过滤部分的代码编译进内核。 4 l* x3 t' X/ e2 ~7 P; T
options IPFIREWALL_VERBOSE  
0 A& y: W$ |! i0 o% b  T# 启用通过syslogd记录的日志。如果没有指定这个选项,即使您在过滤规则中指定记录包, 也不会真的记录它们 6 y- N+ o8 q% @" q% d
options IPFIREWALL_VERBOSE_LIMIT=10  
/ D. O( e1 T- O6 J( W# 限制通过 syslogd(8) 记录的每项包规则的记录条数。在恶劣的环境中如果您想记录防火墙的活动, 而又不想由于 syslog 洪水一般的记录而导致拒绝服务攻击, 那么这个选项将会很有用。
" t4 ?$ a# x: V5 foptions IPFIREWALL_DEFAULT_TO_ACCEPT  
* U( D2 Y6 F0 ]0 k# 这将把默认的规则动作从 ``deny'' 改为 ``allow''。这可以防止在没有配置防火墙之前使用启用过 IPFIREWALL 支持的内核重启时把自己锁在外面。 另外, 如果您经常使用 ipfw(8) 来解决一些问题时它也非常有用。 尽管如此,在使用时应该小心, 因为这将使防火墙敞开, 并改变它的行为。 5 [& `2 f; z; Z+ X3 T
% U) t( E# Y+ k8 ]
2 }+ k  ?- t2 [1 l
编译内核: , T5 v3 G" A/ e1 z! P' N# E5 K
# /usr/sbin/config kernel_fw
0 j$ J7 H3 O1 e3 I  e" L# cd ../compile/kernel_fw (注意你的版本,如果是低于5.0的版本用../../compile/kernel_fw) 1 d5 l: @, E8 G
# make depend  
- w5 B! {) Y( W4 i8 l5 m# make  + e. |" e; J$ @4 H! g" q* V
# make install  
5 Q; [. r/ e+ P6 e# g
. P+ C4 U5 D) p# a3 I重启系统。注意,我们没有选择options IPFIREWALL_DEFAULT_TO_ACCEPT该选项,就是说默认系统启动后是打开防火墙的,并且防火墙默认是不允许任何连接的(deny from any to any),所以一定要在本地操作,否则你将被“锁在门外”,如果你选择了该选项则可以使用ssh等连接不受影响,不过这相对不安全。 : _. A6 T" D# Z/ v

: d& o& f" K8 o& E  D7 w9 [1 O. g
( @, _& {% C* G4 [9 ~. T; b: F2. 配置ipfw * f7 R/ ?4 C/ R# e" e8 E) a1 l6 G

8 {2 W% ]6 m9 N: q: c2 I1 ?7 j2 Y如果配置普通情况下的规则,使用命令配置的模式: 8 P6 R. U4 R& q! G3 o. C
ipfw的配置命令:ipfw [-N] 命令 [编号] 动作 [log(日志)] 协议 地址 [其它选项]
/ W0 d$ A/ b! @4 I" y例如: ; {6 H1 o1 a, r7 u& v/ b: a- \
# ipfw add allow tcp from any to 10.10.10.1 80 #允许外界访问我的web服务
2 e3 R2 [& @, F4 }$ N# ipfw add allow tcp from any to 10.10.10.1 21 #允许外面访问我的ftp服务
$ p4 Y/ d  _6 P; C- d, K2 ~# ipfw add allow tcp from any to 10.10.10.1 22 #允许外界访问我的ssh服务 . @7 W; ]4 I# t2 [

& V7 A2 i  L' X/ M如果使用规则包的形式,那么查看下面内容。
3 v  M" {7 P$ i% u系统启动后,我们还要配置rc.conf文件来运行我们的防火墙: , @5 G# o, u* N7 q
# ee /etc/rc.conf
" K0 l" o- A, L! ^& Z0 N4 i
+ s3 K2 x" \0 h- ]0 u/ |# ^; u加入如下内容: 8 N% v- e  \( ?2 I$ e; O7 t
gateway_enable="YES" # 启动网关  
: r* G2 e7 P, Pfirewall_enable="YES" # 激活firewall防火墙  
& b: M# p- l3 O! W( r3 Tfirewall_script="/etc/rc.firewall" # firewall防火墙的默认脚本  . J, p; O. w, p/ F$ C) B- t
firewall_type="/etc/ipfw.conf" # firewall自定义脚本  
2 i& z: x$ z6 [% [6 g( H+ d2 Afirewall_quiet="NO" # 起用脚本时,是否显示规则信息。现在为“NO”假如你的防火墙脚本已经定型,那么就可以把这里设置成“YES”了。  9 B  C9 ?# C: {2 F4 V
firewall_logging_enable="YES" # 启用firewall的log记录。  ( i8 E4 U% S5 S% y
: j6 p& }+ g8 `: B' z
设置完成后我们再编辑/etc/syslog.conf文件:
9 w: k  P; @* i" p# ee /etc/syslog.conf
, \6 _  g% ~' o' \0 J加入以下行:  
& ^0 x/ ^# f& |7 Z+ `' x) I!ipfw  . H! l! Z' L7 V: T
*.*                 /var/log/ipfw.log  
: a) l! q% f* H) r, ~$ L' z% |; f1 z& J" V% f
现在到了最重要的编辑规则包了:
0 ~+ Y4 C5 t/ a9 f, k# }# ee /etc/ipfw.conf ) [; ?1 P0 J9 d+ _/ U+ n
我们添加一下规则:(注意 10.10.10.1是我们服务器的IP) $ H9 g# \& R! N- ]( F: N6 l
! g# T9 o& y. C$ u
######### TCP ########## ; s! j# f3 x7 S) \/ d/ |
add 00001 deny log ip from any to any ipopt rr  
0 q1 I' m5 A% L* U* @* f9 _4 Radd 00002 deny log ip from any to any ipopt ts  
* A. E) @: W* |" I5 Yadd 00003 deny log ip from any to any ipopt ssrr  4 p+ ^: V7 ?. d+ Q  M. Z' b
add 00004 deny log ip from any to any ipopt lsrr  
/ C' i. c# Q7 [: Y$ K+ C/ U& {add 00005 deny tcp from any to any in tcpflags syn,fin  
! ~' j2 l6 k0 G8 \, Z# T# 这5行是过滤各种扫描包  - y2 o" R& ~& R5 f. V

1 u2 h& ^. K4 [! `) R1 kadd 10001 allow tcp from any to 10.10.10.1 80 in  # 向整个Internet开放http服务。  
- N( N3 ]3 r, d/ qadd 10002 allow tcp from any to 10.10.10.1 21 in  # 向整个Internet开放ftp服务。  
; ~* x2 Q; G* c: ]& ?' c# c5 Jadd 10000 allow tcp from 1.2.3.4 to 10.10.10.1 22 in  
) N6 ]5 u* t; S9 ?' ]" E# 向Internet的xx.xx.xx.xx这个IP开放SSH服务。也就是只信任这个IP的SSH登陆。
* _9 u0 d, ]+ Q# }( W# 如果你登陆服务器的IP不固定,那么就要设为:add 10000 allow tcp from any to 10.10.10.1 22 in ) G3 g/ K5 H4 }
3 o  e+ ?; D5 E) e0 ~
add 19997 check-state  
7 M3 U- Q/ ^9 Z' tadd 19998 allow tcp from any to any out keep-state setup  
4 V* a, w+ g, ]& ~7 U% y% Jadd 19999 allow tcp from any to any out #这三个组合起来是允许内部网络访问出去,如果想服务器自己不和Internet进行tcp连接出去,可以把19997和19998去掉。(不影响Internet对服务器的访问)    M0 n# s0 y/ R6 U0 S: l
7 U, h. p9 x* H# q6 {1 u! o% _
########## UDP ##########
$ [8 R4 D, R4 K( K2 b; T" yadd 20001 allow udp from any 53 to 10.10.10.1 # 允许其他DNS服务器的信息进入该服务器,因为自己要进行DNS解析嘛~  
  U9 ?; `3 S+ \: m& Uadd 29999 allow udp from any to any out # 允许自己的UDP包往外发送。  
7 \1 G" D+ A4 o: _
' d% x% b. i9 B! v$ A$ x' Q0 R  E8 ]########## ICMP ######### 7 l3 {* X! T( U: d6 O3 F
add 30000 allow icmp from any to any icmptypes 3  
. [8 U6 ~( S7 M& J0 R- X$ Jadd 30001 allow icmp from any to any icmptypes 4  
0 F$ m6 K& W7 P% m% U7 aadd 30002 allow icmp from any to any icmptypes 8 out  5 j& R4 O7 C4 N, U# ~5 @: e
add 30003 allow icmp from any to any icmptypes 0 in  7 r/ O; ~7 R  }* h9 M( l
add 30004 allow icmp from any to any icmptypes 11 in
3 {; l* I3 K6 O#允许自己ping别人的服务器。也允许内部网络用router命令进行路由跟踪。  + W( g: L% |$ u. ?6 k+ p
3 l& ]  f" h; _, I- O9 V5 ~
3 j% z; d+ N+ }& \& D; b

6 A; o$ C; O8 ^; M: E- @/ G

五、Unix/Linux上的后门技术和防范


  Q1 G7 F( D# ~  v( B2 Q9 m3 e' W
对黑客来讲,入侵一个系统只是万里长征的开始,最主要的是长期占有一个肉鸡(傀儡机),所以,后门技术往往非常重要。对于我们来讲,总是处于被动的地位,百密一疏,总有没有做到位的地方,谁都不能保证自己的系统是绝对安全的,所以不能避免我们可能会被入侵。黑客入侵后肯定会留后门,当然,除了那些高手,境界非常高,入侵只是为了测试或者技术挑战,对于一般黑客来讲,入侵之后留个后门是很重要的,我们要防范,当然就要了解常用的后门技术,下面就简单的讲将在Unix/Linux系统中比较常见的后门技术。
3 S) Z5 K/ K  }, X6 s* ?5 T% c- [/ ^9 [
1. 帐号后门
: D" l* L6 Q9 J3 q' W  D( `" Z0 b- e$ n
最普通和原始的后门技术,一般就是在系统中添加一个管理员帐户。 + t4 U) n+ T% v% |& j$ K
# echo "heiyeluren:*:0:0::/root:/bin/sh" >;>; /etc/passwd  
, h6 X; D/ H; X. s) F0 L# echo "heiyeluren::0:0::0:0::/root:/bin/sh" >;>; /etc/shadow + A& s% W' i. _
给系统增加一个 uid和gid都为0(root)的帐号,无口令。 ; O: \9 d; }9 c5 k( p
FreeBSD的密码是存储在 /etc/master.passwd里面的,那么后面的命令就应该改成: 3 }  m) o. E* c" L3 s, b, H8 C* A
# echo "heiyeluren:::::::::" >;>; /etc/master.passwd
# w+ i& R+ f: Q也可以使用程序来实现: 9 b& u" c3 X/ V1 f
/* Add super user */
7 X. H8 C! B  E/ _#include "stdio.h"
/ L/ G. ~1 ^  {( ~#define PASSWD_PATH "/etc/passwd" 3 n* }3 a2 f* y
#define SHADOW_PATH "/etc/master.passwd"
' y+ D: z) s  Q( F- R8 hmain()   b8 Q9 K0 I3 ]6 s. h
{ % v3 p/ B4 }+ ~: Q4 O
FILE *fd; , ]3 x6 k* P5 J* |/ p. z) M6 ~0 C
fd = fopen(PASSWD_PATH, "a+"); * t: g: p# d% x! y" j6 J3 a7 X
fprintf(fd, "heiyeluren:*:0:0::/root:/bin/sh\n");
4 q; @. {) j6 N3 ifclose(fd); 6 t7 f" V$ B# a( {' A
fd = fopen(SHADOW_PATH, "a+"); 6 S3 C; `: |- ^
fprintf(fd, "heiyeluren::0:0::0:0::/root:/bin/sh\n"); * y) Y, @/ z) _# ]
fclose(fd); ( o+ O: `' G' i' K3 R: z' O6 i
}
) w( h# R+ _+ S* o5 d' }# gcc -o adduser adduser.c 3 H3 U  ^& T& S# {; R1 y- y
# ./adduser
9 V7 L; e# C# [: ]5 T, \这种方法比较傻,一般比较容易发现,特别是系统帐户不多的时候。也有的用户名起的比较迷惑人,比如起个r00t的用户名,uid和gid都是0,这样如果不注意,可能就会被蒙混过关了。
, U; |! i, m) w& {' Q
+ v8 _% w$ K) v2 v( {" Q* 防范方法: - b4 \* \* ?/ {! J& _' w+ s6 n
这种方法虽然比较容易发现,但是我们还是要防范,要多注意观察系统的帐户情况,本来我们系统帐户就不多,检查起来比较方便,另外也要注意那些比较少使用的帐户是不是被更改过,比如默认的帐户有bind,它的shell是 /usr/sbin/nologin,就是不能登陆的,但是黑客入侵后把它改了,比如改为/bin/csh,那么对方就能登陆了,但是你确不知道。所以最好办法是把/etc/passwd另外备份一份,不定期的检查,同时把/etc/passwd和/etc/master.passwd设为只有root才能查看。
& P: z4 t; ~6 G/ c4 P8 V) B, U) h- [

4 D- U: q: b1 x1 q* @4 C0 H2. shell后门 0 g: S% w3 S' p  v# t7 E/ _

9 Q3 x. T* x; D# N' ^) G: A$ q这个比较常用,也比较流行。一般就是把root执行的shell程序通过setuid的形式把shell程序拷贝到其他能够执行的地方,然后只要用小权限用户执行该shell就能够直接获取root权限。
$ X* U7 K$ n) T' W比如: 8 F4 M2 h; u5 X- A( i, f
# cp /bin/sh /tmp/.backdoor
7 z3 P/ P* E: Y1 c# chown root:root /tmp/.backdoor . G/ x6 q1 m- Q' k: E
# chmod +s /tmp/.backdoor
$ y: z6 Z& m" `9 ~& q( i& Z$ `这样只是把sh复制了,如果你喜欢其他shell,比如ksh、csh也可以,具体你看各个不同的操作系统而定。你就可以把那个加了s标记的shell程序放到任何目录,最好是深一点,不容易被人发现的地方,比如/usr/local/share/man之类的目录,然后你使用小权限用户登陆后执行该shell就可以了,比如我们上面复制的shell,我们只要用小权限用户登陆后执行: " i( D3 x/ _) t0 Y& m
$ /tmp/.backdoor : a5 N6 E9 m. o( N* T
#  
! `( [" I9 g& w. N4 D$ U+ ?& d7 k就可以了,当然,如何获得小权限用户,你可以使用暴力破解一些帐户,或者自己创建一个小权限的帐户。
" h& L  }0 R  _3 d
* X9 Y- V2 U5 T4 m+ q9 O* 防范方法: + K4 V; T+ i# H
首先给各个主要目录加上我们上面说的文件指纹校验,知道某个目录下有什么文件,如果多出了可疑文件可以仔细检查。还有使用find命令来查找有没有危险的root suid程序:
( ?% X8 Q0 J! O! n, Y& }4 Efind / -type f (-perm -4000 -o -perm -2000 ) -print
* ~  n8 f& L7 g8 ?) Z, Z
1 [& r( i# P8 O; U! e: ^) V6 e% z6 e
3. Crontab服务后门 ) F* R, w: x  F& R& R4 W
, _4 D* d% [5 w8 n. R! E' O
crontab命令就相当于windows下的at命令,定期执行某些任务。对黑客来讲,比如定期建立一个帐户,然后过多久就删除,这样管理员永远看不到系统中有后门,这样是非常保险的。。
% _* @; o  j$ d# R  O/ W" q' N( M1 [6 e# l0 i' S5 h
* 防范方法:   _3 |  P9 O$ y/ F% i
cron的服务默认是存储在 /var/spool/crontab/root目录下,定期检查cron服务,看是否有异常的任务在执行,或者如果你不使用cron的话,直接关闭掉它。
2 j( B2 Q8 ]% s1 r) C) j: u8 [7 E1 {; s) m  W

5 a; I  f/ b# w6 X3 n& l; l# z$ V4. rhosts后门
3 a2 F$ n& B+ n
6 `* p5 R0 G) [3 {# K! zRhosts文件常常被黑客利用来制作后门,如果系统开了rlogin、rexec等r的服务,因为象rlogin这样的服务是基于rhosts文件里的主机名使用简单的认证方法,所以黑客只要将.rhosts文件设置成"++",那么就允许任何人从任何地方使用该用户名,无须口令登陆513端口的rlogin服务就行。而且r之类的服务没有日志能力,不容易被发现。 & ^5 Y" K6 t! q1 P( X4 p1 q+ Y) x
实现方法: : {! o4 n) k* c$ y7 I9 l
# echo "++" >; /usr/heiyeluren/.rhosts
7 G: J5 P1 ~% J  o, a# rlogin -l heiyeluren localhost
+ O6 @' P! Z  A8 D" {- @这样就不需要任何密码,直接输入用户名heiyeluren就登陆到了系统。
- D% f/ s7 I5 K8 y8 |6 S( U  c+ m
* 防范办法:
' N4 O) _& g* s. h) q  F8 k6 i1 e不要使用rlogin等服务,同时也不推荐使用telnet等服务,因为telnetd等守护进程溢出漏洞一堆,而且在数据传输过程中是没有加密的,很容易被嗅探,建议使用ssh等经过安全加密的服务来替代。
5 ?, l) l' G* o  z: R3 G% Q5 S
! \$ U4 z4 v; A9 F& I, e: q% d4 {
" o$ N+ o. B- t  u# \: `5. Login后门
8 y/ ?& d8 k7 @! H& u
. S/ \% m( n) G' jlogin程序通常用来对telnet来的用户进行口令验证. 入侵者获取login的原代码并修改使它在比较输入口令与存储口令时先检查后门口令. 如果用户敲入后门口令,它将忽视管理员设置的口令让你长驱直入。
) M% s, }- p- [- A
& h5 i5 @) D( v8 J( v3 V0 K6 k* 防范方法: % G' h; c( ~$ _1 _8 f0 e% s
一般针对这类后门,一般都是使用"string"命令搜索login程序中是否有中是否有密码等字符串来进行检查。如果密码经过加密,那么就对login文件进行指纹记录和MD5值的记录,觉得异常时进行检测。 # z- t( A4 X2 K9 P

3 \+ p" |, C4 w9 i! k2 H% N$ T; @
: c( K" {) c! h! t! V& v6. Bind后门
% W! j7 A$ `2 f; L1 N7 I2 Z" L( s; A( Y4 Q; R) ~
就是通过常用的网络连接协议 TCP/UDP/ICMP 来建立连接的后门,这个在Windows下可是轰轰烈烈。
# D. w9 h$ n8 u9 ?: J比较普遍的有TCP协议的后门都是写一段程序开一个指定的端口进行监听,然后从客户端进行连接后登陆系统。也有黑客为了隐蔽使用UDP协议来连接。icmp后门也常见,一般是。有时候可能bind后门跟服务后门结合,黑客通过自己写的bind后门来替换inetd中的服务。 + ]" ]& m/ @$ o

1 N' D+ _1 ?: B( S8 F2 A5 x4 B" d* 防范方法:
9 B: ]  G; e+ b4 \& r5 n% D经常使用netstat命令检查有没有非法的端口打开,最好直接用防火墙屏蔽除了正常访问的端口之外的端口。对于ping后门的话,直接在防火墙上禁止ping服务器
& ~& [0 c: N* \$ q4 ]* l
: {) |, Y) u* |+ A+ U: P6 l' B$ i  I- m+ N; X8 r8 u6 H
7. 服务后门
8 A/ {) C$ E% l/ b* w! O
; d! i$ g4 K& _# f3 V一般是替换或者添加服务来实现后门。比如在 /etc/inetd.conf 中添加或者替换某个服务来运行自己的后门程序,或者在某些服务中加入自己的后门代码。如果是替换服务的话,该服务必须不被使用,而且不容易发现。如果是自己添加的服务,那么必须在/etc/services中设置对应的服务和端口才能使用。 & ?$ i: E4 C: J$ r% H
8 c3 p$ H$ X: Z* ]
* 防范方法: 9 i0 e8 H& E  G; `
经常检查服务,最好备份 /etc/inetd.conf 、/etc/services等文件,同时在FreeBSD下也要时常检查 /usr/loca/etc/rc.d 下面的脚本是否是合法的并且是否那些脚本里面有没有启动非法程序。如果是在服务程序中添加自己的代码,那么就要对文件的指纹进行校验,比如md5值看是否匹配。 & r: r* E  J% c2 q  J

* u- R, d) J" @3 W3 W' B( O8 t- k- k* K0 t- F' d
8. rootkit后门 & O8 f1 y  }0 d- Q) e

" _! {% [0 {1 q4 nrootkit后门一般是替换管理员使用的工具,比如ls、ps、netstat、who等常用文件,把那些程序替换成被黑客加了特殊代码的程序,那样就能达到控制的效果。而且现在已经有很多现成能下载使用的rootkit。
- z6 j7 c2 L. e: h6 e( j$ ~( K* E' u( }! R1 W6 `! b# J
* 防范方法: ) Z, s9 O" [7 {! E- {
按照我们前面的方法,给每个文件建立系统指纹档案和md5校验值,如果觉得不对劲的时候查看文件指纹是否匹配,有没有别修改过,就知道是否着了rootkit的道。 / e; r4 l; d- s% {1 t/ a
, n6 `4 A6 G" \+ t+ y
; n7 q- y8 D) E! z! W9 P) Q8 _9 C
9. 内核后门
7 ?( U7 Y2 w" W& f. b' z6 D- _7 c1 I+ `3 \3 ^
通过加载内核模块的方式来加载后门,比较复杂。一般内核后门都是针对操作系统而言的,不同的操作系统内核模块设置编写方法都不一样,一般不通用。内核后门一般无法通过md5校验等来判断,所有基本比较难发现,目前针对内核后门比较多的是Linux和Solaris下。 : l* r" }0 z; K. l* E/ K

- Z$ f$ o) j$ t+ e7 Y/ T/ m2 h* 防范方法:
2 v& A# d, X- HFreeBSD下通过我们上面讲的设置内核安全等级来控制加载内核模块。
. r1 _4 m; r0 E* M* i* k, [3 i; S
3 l6 }7 U' m; A, m  k# j. p
3 r* f6 y, T" _: @: z$ k10. 其他后门
8 ]$ P0 g! _1 x# [3 ~  T还有包括.forward等其他各类后门,另外很多后门可能是结合多种技术,比如把rootkit和内核后门结合在一起,实际过程中,黑克是会更难对付的。当然还有许多我们没有发现高手独门秘诀,这需要灵活检查,不过只要勤劳一点,安全会提升很多。
6 O  A# b: M6 y6 z& t- G: G8 {& |
3 h, [' z5 A5 q# z( \. h* l6 n! W& Q
% v+ Z3 c# Q2 u' L% X3 D" y

六、结束语

/ `0 k' }5 H* H9 V4 M
6 g: b! [. ]' Y6 P4 I: V
安全是一个整体,即使那么服务你设置的非常安全,但是不能保证永远安全,安全是动态的,必须不断的充实自己的知识,发现新漏洞、新技术。如果你需要更安全的系统,一定要自己有时常能够手工作入侵检测或者使用部分工具帮助你进行入侵检测。同时推荐你安装一些网络入侵检测系统(NIDS),比如Snort。
. b' z( Z( H: j' M我想这个题目真的有点大了,开始写的时候没有那种感觉,越做到后来越觉得想要说的很多,最后只能泛泛而谈了一下,虽然如此,也希望能够给在使用FreeBSD的网管和网络安全爱好者一点点的帮助,那就足够了。
$ g" w( Y" W) {* X
  ~: W7 T/ d, L2 @  i$ \感谢所有致力于开源世界安全研究和管理并且愿意共享自己学习心得的朋友!
1 q  {) [) K' ]( Y% j% x& f
/ \9 f& e$ a  Y  o/ v最后谢谢你能够耐心阅读本文。

TOP

路过,学习一下!' b7 m* f# g1 A. s

3 g2 c( R7 E3 j* }0 W( a1 H* X
8 x0 J6 R! C6 E) V3 t3 x" f
: g" A9 k! M0 h4 x2 H9 a! C# u/ V- ]
( f% f/ V1 ^" Y  z6 {

; r/ @6 f) l  S6 J  Qu88126u88.cn126油箱3158

TOP

发新话题