随着网络的普及,基于网络的应用也越来越多。网络数据库就是其中之一。通过一台或几台服务器可以为很多客户提供服务,这种方式给人们带来了很多方便,但也给不法分子造成了可乘之机。由于数据都是通过网络传输的,这就可以在传输的过程中被截获,或者通过非常手段进入数据库。由于以上原因,数据库安全就显得十分重要。因此,本文就以上问题讨论了MySQL数据库在网络安全方面的一些功能。
! w, T4 g3 |0 k, K- e2 m( G帐户安全" \3 J3 }/ @' B8 G8 T4 M7 A
帐户是MySQL最简单的安全措施。每一帐户都由用户名、密码以及位置(一般由服务器名、IP或通配符)组成。如用户john从server1进行登录可能和john从server2登录的权限不同。/ Y& h0 I6 I, V3 C2 H# q3 [
MySQL的用户结构是用户名/密码/位置。这其中并不包括数据库名。下面的两条命令为database1和database2设置了SELECT用户权限。
/ \8 ~8 f; J$ z2 B( pGRANT SELECT ON database1.* to ‘abc’@‘server1’ IDENTIFIED BY ‘password1’;
3 `7 s% w) z# p: bGRANT SELECT ON database2.* to ‘abc’@‘server1’ IDENTIFIED BY ‘password2’;
4 k1 S1 Z4 z3 a6 j第一条命令设置了用户abc在连接数据库database1时使用password1。第二条命令设置了用户abc在连接数据库database2时使用password2。因此,用户abc在连接数据库database1和database2的密码是不一样的。" v2 u9 v4 C8 H; e/ x0 S4 }
上面的设置是非常有用的。如果你只想让用户对一个数据库进行有限的访问,而对其它数据库不能访问,这样可以对同一个用户设置不同的密码。如果不这样做,当用户发现这个用户名可以访问其它数据库时,那将会造成麻烦。' z2 J! T1 J* X
MySQL使用了很多授权表来跟踪用户和这些用户的不同权限。这些表就是在mysql数据库中的MyISAM表。将这些安全信息保存在MySQL中是非常有意义的。因此,我们可以使用标准的SQL来设置不同的权限。; k/ }" J& G* K1 [' ]! F. y
一般在MySQL数据库中可以使用3种不同类型的安全检查:
6 h6 j/ p2 k( s- [. `* c) w·登录验证
; P I# K" @! p7 H也就是最常用的用户名和密码验证。一但你输入了正确的用户名和密码,这个验证就可通过。, C2 B8 z9 Z1 `6 s5 W, h
·授权' L3 u8 S7 |# J3 \) n5 V
在登录成功后,就要求对这个用户设置它的具体权限。如是否可以删除数据库中的表等。
" _/ w. f% ]9 k7 p* ^: u ?; `1 p·访问控制( E. l- \5 h$ M! d* }7 d' L6 b) d
这个安全类型更具体。它涉及到这个用户可以对数据表进行什么样的操作,如是否可以编辑数据库,是否可以查询数据等等。4 r2 T& E0 v) x/ Q0 t" U$ e* S
访问控制由一些特权组成,这些特权涉及到所何使用和操作MySQL中的数据。它们都是布尔型,即要么允许,要么不允许。下面是这些特权的列表:% i6 A& e9 s- C8 l7 P4 R- t
·SELECT
" D- e0 ?1 D5 s n! u& xSELECT是设定用户是否可以使用SELECT来查询数据。如果用户没有这个特权,那么就只能执行一些简单的SELECT命令,如计算表达式(SELECT 1+2),或是日期转换(SELECT Unix_TIMESTAMP(NOW( )))等。
0 X2 c8 l4 g) Y8 Q·INSERT
3 F) I' X$ \2 |) ^9 Q& r·UPDATE4 n. M8 q* b! s/ \
·INDEX+ M& U! x3 s$ P$ j$ ^; d4 y
INDEX决定用户是否可以对表的索引进行设置。如果用户没有这个权限,那么将无法设置表中的索引。
, U+ o O4 f* I% O3 l; W·ALTER
" `7 ~9 t+ P. ?4 r' |. @·CREATE; I* ^" w+ h8 G( Z
·GRANT! a" V- x# U3 G) `0 V8 |
如果一个用户拥有这个GRANT权限,那么他就可以将自己的权限授给别的用户。也就是说,这个用户可以和其它用户共享自己的权限。' t4 G1 R! b# w
·REFERENCES
, j+ s' q+ x% H8 A% n有了REFERENCES权限,用户就可以将其它表的一个字段作为某一个表的外键约束。
2 h+ r I5 s0 _, ~除了以上的权限外,MySQL还有一些权限可以对整个MySQL进行操作。
) r/ ?! V1 H4 v8 E7 d·Reload
/ l9 z0 [- q! g3 [& f' s+ E. M8 U% H这个权限可以使用户有权执行各种FLUSH命令,如FLUSH TABLES, FLUSH STATUS等。
2 I" ` a% a' k) m3 u·Shutdown* e Z- n* I1 P% G0 D- ?
这个权限允许用户关闭MySQL V! ?6 [8 n2 j$ Y. k, c
·Process
5 O3 `$ k! N3 U* L通过这个权限,用户可以执行SHOW PROCESSLIST和KILL命令。这些命令可以查看MySQL的处理进程,可以通过这种方式查看SQL执行的细节。6 k7 V: U' c0 M3 O$ @
·File
+ N4 ~/ j8 R9 K. a: { e这个权限决定用户是否可以执行LOAD DATA INFILE命令。给用户这个权限要慎重,因为有这个权限的用户可以将任意的文件装载到表中,这样对MySQL是十分危险的。" P) D: u/ q4 I$ C/ `
·Super* ^$ }9 E" I. n/ u8 I L
这个权限允许用户终止任何查询(这些查询可能并不是这个用户执行的)。
" U4 i. W9 `5 [6 q2 t以上几种权限是非常危险的,在给用户授权限时要非常谨慎。7 Y' C3 x+ R8 T6 C, @" U% z3 L4 {
[NextPage]
" n+ |0 |9 \4 }MySQL中的SSL1 c, m' ?, T+ g" u
以上的帐户安全只是以普通的Socket进行数据传输的,这样非常不安全。因此,MySQL在4.1版以后提供了对SSL(Secure Scokets Layer)的支持。MySQL使用的是免费的OpenSSL库。( {0 k2 y. `; L, L0 }# m
由于MySQL的Linux版本一般都是随Linux本身一起发布,因此,它们默认时都不使用SSL进行传输数据。如果要打开SSL功能,需要对hava_openssl变量进行设置:
0 @* p9 W0 x7 a' ]8 B0 h1 Z( m' \5 bMySQL的Windows版本已经将OpenSSL加入了。也面的命令是查看你的MySQL是否打开了SSL功能。
0 W1 p# c8 ]3 J. \( }SHOW VARIABLES LIKE ‘have_openssl’;* U; Z7 t& i7 Z7 i" P/ S& n
+---------------+-------+6 o+ Z" q6 y" p" k# D/ W
| Variable_name | Value |" l( B6 ?' x0 U M% a k
+---------------+-------+% k: n) a7 ^# N9 p6 |* l; t3 L
| have_openssl | NO |3 I8 I& R9 \4 Q- Z2 V% ]4 u- S
+---------------+-------+' E( p$ @( b# S0 k9 y$ P! `
1 row in set (0.00 sec)
4 h' T, x5 h# s3 n$ u5 z% L8 t如果返回的是NO,那么说明你需要将OpenSSL编译进自己的MySQL
6 q2 [* L$ o$ J在有时你可能需要将用户名和密码进行加密传输。在这时可以使用下面GRANT命令:
! F/ M# d: G8 e% L9 q& FGRANT ALL PRIVILEGES ON ssl_only_db.* to ‘abc’@‘%’ IDENTIFIED BY “password!” REQUIRE SSL;" A5 p) r+ m( ?1 J* W m1 f: \, L
还可以通过 REQUIRE x509 选项进行SSL传输:
. V+ x1 m, z% k7 a: i/ Y/ vGRANT ALL PRIVILEGES ON ssl_only_db.* to ‘abc’@‘%’ IDENTIFIED BY “password!” REQUIRE x509;# }3 }" o" S3 b: I* Z Z0 V$ V' v! T
你还可以使用REQUIRE SUBJECT来指定一个特定的客户端证书来访问数据库。4 v% v) H* f8 q) m% Z
GRANT ALL PRIVILEGES ON ssl_only_db.* to ‘abc’@‘%’
$ ~ D* P; G' s$ _5 `0 cIDENTIFIED BY “password!”, h5 z& ]& q: h
REQUIRE SUBJECT “/C=US/ST=New York/L=Albany/O=Widgets Inc./CN=client-ray.& _& S& t4 q" s& F# J
example.com/emailAddress=raymond@example.com”;
5 c0 u! Q, H+ P9 N1 G4 t也许你并不关心使用的是什么客户许可,而仅仅关心的是你的证书。那么你可以使用REQUIRE ISSUER来实现:
# q" ] G0 a+ K1 J4 bGRANT ALL PRIVILEGES ON ssl_only_db.* to ‘abc’@‘%’ IDENTIFIED BY “password!”
h% D$ g3 l0 @$ SREQUIRE ISSUER “/C=US/ST=New+20York/L=Albany/O=Widgets Inc./CN=cacert.example.8 e/ Y. n) k. b' Q
com/emailAddress=admin@example.com”;
7 i* Q4 e, H; d. ^; |SSL还可以直接通过密码进行加密。可以使用REQUIRE CIPHER设置密码。
; B g: f" f8 [: bGRANT ALL PRIVILEGES ON ssl_only_db.* to ‘abc’@‘%’ IDENTIFIED BY “password!”
" B/ r. u2 V5 y" K9 }$ sREQUIRE CIPHER “EDH-RSA-DES-CBC3-SHA”;
7 `3 w3 C3 l4 ^! E上面使用了GRANT命令对用户权限进行设置。而这些信息都是保存在授权表中,这些表是安全系统的心脏。在这些表中保存了每一个用户和客户机所具有的权限。如果正确地操作这些表,将会对数据库的安全起到积极的作用,而如果使用不慎,将是非常危险的。
5 M, Q) L: L2 o# R! W: M下面让我们来看看MySQL中的最要的5个授权表。/ B! D. B+ B( m# ?0 E! Y0 V9 I
user
- s2 x7 P6 e8 @' y用户表保存了用户的权限和被加密的密码。这个表负责确定哪些用户和客户机可以连接到服务器上。) ?+ b* Y E" m% a6 Q& U- h
host7 u8 B0 X+ t3 b* i/ [3 f! b( ^" I
这个表为每一个客户机分配权限,它并不考虑用户的权限。MySQL在确定是否接收还是拒绝一个连接时,首先考虑的是user表。而使用GRANT或REVOKE命令并不影响host表,我们可以通过手工方式修改这个表中的内容。
. x9 x \9 i& @% Edb
$ j$ q. J/ i+ ?; L( i; P! fdb表保存了数据库层的权限信息。
6 ]/ E5 q0 R; Wtables_priv& h# c9 P* k9 ]$ o
这个表存储了表的权限信息。/ W6 p% U: ^9 g/ X+ Q9 s& d
columns_priv
+ [+ L! p$ j/ Z2 e; H! c" @这个表保存了单独列的权限信息。通过这个表,可以将操作某一列的权限授予一个用户。6 m# u. H2 H, o. g( n( S
[NextPage]3 i; [4 z" @! a" }
哈希加密3 D- v& K" g+ V% U D- ~
如果数据库保存了敏感的数据,如银行卡密码,客户信息等,你可能想将这些数据以加密的形式保存在数据库中。这样即使有人进入了你的数据库,并看到了这些数据,也很难获得其中的真实信息。# |+ z9 o, z5 B7 S
在应用程序的大量信息中,也许你只想交很小的一部分进行加密,如用户的密码等。这些密码不应该以明文的形式保存,它们应该以加密的形式保存在数据库中。一般情况下,大多数系统,这其中包括MySQL本身都是使用哈希算法对敏感数据进行加密的。- ? d' p. z4 ]
哈希加密是单向加密,也就是说,被加密的字符串是无法得到原字符串的。这种方法使用很有限,一般只使用在密码验证或其它需要验证的地方。在比较时并不是将加密字符串进行解密,而是将输入的字符串也使用同样的方法进行加密,再和数据库中的加密字符串进行比较。这样即使知道了算法并得到了加密字符串,也无法还原最初的字符串。银行卡密码就是采用的这种方式进行加密。
5 n$ I: |) F# j( iMySQL提供了4个函数用于哈希加密:PASSWORD, ENCRYPT, SHA1和MD5。下面让我们试一试这4个函数,看看会得到什么结果。我们以加密字符串“pa55word”为例进行说明:
7 e" p9 _, G- E3 C1 N$ B让我们先来看看MD5函数
- @. T7 W( Q% N$ B, tSELECT MD5(‘pa55word’);3 E1 m! d$ [- I) d2 }, v, U
+----------------------------------+
7 c" K- M) a: e+ _, M7 p" w9 d- V: W| MD5(‘pa55word’) |* | n- n1 Z+ v0 r4 W
+----------------------------------+
& H, O+ y* m/ @; h| a17a41337551d6542fd005e18b43afd4 |3 n2 R, P1 V. [3 A5 A* I& o/ m5 b
) q' c0 T/ e X& f' D7 x- g# B
+----------------------------------+
6 O' w! F& J! n7 o/ s* {5 c1 row in set (0.13 sec)8 T! a8 t9 n# {( ?6 a0 i. M, m
下面是PASSWORD函数2 @. D' `3 N' }7 r$ k* k2 k
SELECT PASSWORD(‘pa55word’);
& s( M, x! `6 L* u( W+----------------------+) g) k* |* }% o/ N- K3 B
| PASSWORD(‘pa55word’) |
' y' b: _. }, W z9 M+----------------------+* [6 [0 `0 X, M: q
| 1d35c6556b8cab45 |' V5 Y' r T: K$ _7 D3 u
+----------------------+
. b$ Z' v4 q( L2 s8 {1 row in set (0.00 sec)! a5 {7 v0 ^+ o% `9 H
下面是ENCRYPT函数
! C x0 F4 ^" k E# HSELECT ENCRYPT(‘pa55word’);
- |! z' F; f$ `6 l- e: }0 D+---------------------+
" _0 U9 N5 @; B; ]4 p. a, N| ENCRYPT(‘pa55word’) |$ O( A- d/ K7 e' L: ^, E
+---------------------+
% h3 z7 O! X. k# s| up2Ecb0Hdj25A |1 k5 m! w: J9 S
+---------------------+
) s: G3 m' G) K+ `1 row in set (0.17 sec)! n6 M! S+ ^* B% S
上面的每个函数都返回了一个加密后的字符串。为了区分加密字符串的大小写,最好在使用ENCRYPT生成加密字符串时,将这个字段定义成CHAR BINARY类型。4 n) ], |# d: g/ N: l# a3 i
上面列举了3种加密的方法,但我认为使用MD5加密是最好的。这是因为这样做可以将明文密码显示在处理列表中或是查询日志中,这样便于跟踪。如下面的INSERT语句使用插入了一条记录,其中的密码使用了MD5进行加密:( H! I2 ~9 M: _
INSERT INTO table1 (user, pw) VALUE (‘user1’, MD5(‘password1’))5 o7 H3 ]6 A# [& g# |
可以通过如下的语句进行密码验证:, F- b1 q8 c& B# u
SELECT * FROM table1 WHERE user = ‘user1’ AND pw = MD5(‘password1’)
" r k9 l2 ^# V, p哈希加密方法可以很好地对密码进行加密,使用了这种方法加密,密码将无法 恢复成明文。
. g* j' {' m3 I# B F( `/ y6 P& d9 `
|
|