5.8.7. 使用安全连接

MySQL支持 MySQL客户端和服务器之间的安全 (加密的 )连接所使用的安全套接字层 (SSL)协议。本节讨论如何使用 SSL连接。还描述了在 Windows中设置 SSH的方法。

MySQL的标准配置倾向于尽可能快,因此默认情况不使用加密连接。使用该协议会使客户端/服务器协议慢得多。对数据进行加密非常耗CPU,需要计算机多做许多工作,会延迟MySQL的其它任务。对于需要通过加密连接提供安全的应用程序,可以保证额外的计算。

MySQL允许在连接前启用加密。你可以根据具体应用程序的需求选择普通未加密连接或安全加密SSL连接。

5.8.7.1. SSL基本概念

要想理解 MySQL如何使用 SSL,需要解释一些基本 SSLX509概念。熟悉的人们可以跳过该部分。

默认情况下,MySQL在客户端和服务器之间使用未加密的连接。这说明可以访问网络的部分人可以看到你的通信,并看到发送和接收的数据。他们甚至可以更改在客户端和服务器之间传递的数据。要想提高安全性,当调用客户端程序时,你可以通过--compress选项压缩客户端/服务器之间的通信。但是,这样并不能阻挡住顽固的攻击者。

当你需要以安全方式在网络中传递信息时,未加密的连接是不可接受的。加密是使任何数据不可读的方法。事实上,今天的许多惯例需要加密算法提供更加安全的要素。它们应能抵抗各种已知的攻击,例如更改加密消息的顺序或两次重放数据。

SSL是一种使用不同的加密算法确保从公用网接收到的数据是可信的协议。它具有检测数据更改、丢失或重放的机制。SSL还包括使用 X509标准提供身份认证的算法。

使用X509,可以识别Internet上的某些人。通常用于电子商务应用程序中。按照基本概念,应有某种称之为“认证机构(CA)的机构,可以向请求者分发电子证书。证书依赖非对称加密算法,有两个加密密钥(公共密钥和私人密钥)。认证持有者可以向其它方出示证书来证明身份。证书包括持有者的公共密钥。只能使用对应的私人密钥对含该公共密钥的加密数据进行解密,私人密钥由证书持有者拥有。

如果你需要关于SSLX509、或加密的详细信息,使用Internet搜索引擎来搜索你感兴趣的关键字。

5.8.7.2. 需求(OpenSSL)

要想在MySQL服务器和客户端程序之间使用SSL连接,系统必须能够支持OpenSSL。如果用支持内嵌式yaSSLMySQL版本,不要读该节,但应阅读5.8.7.3节,“使用yaSSL”

要想获得安全的MySQL连接,必须:

1.    安装OpenSSL库。我们已经测试了带OpenSSL 0.9.6MySQL。如果你需要OpenSSL,请访问http://www.openssl.org

2.    配置MySQL,用--with-vio--with-openssl选项运行configure脚本。

3.    确保升级了授权表,使mysql.user表内包含SSL相关列。如果 授权表是从MySQL 4.0.0之前的版本升级,这很重要。升级过程见2.10.2节,“升级授权表”

4.    要想检查是否运行的mysqld服务器支持OpenSSL,应检查have_openssl系统变量的值:

5.            mysql> SHOW VARIABLES LIKE 'have_openssl';
6.            +---------------+-------+
7.            | Variable_name | Value |
8.            +---------------+-------+
9.            | have_openssl  | YES   |
10.        +---------------+-------+

如果值为YES,服务器支持OpenSSL连接。

5.8.7.3. 使用yaSSL

使用MySQL的内嵌式yaSSL支持,可以很容易地使用安全连接。不需要安装OpenSSL和执行5.8.7.2节,“需求(OpenSSL)”中的步骤。并且,MySQLyaSSL使用相同的许可模型。

当前,在以下平台上支持yaSSL

·         Linux/x86-64 Red Hat Enterprise 3.0

·         Linux RHAS21 Itanium-2,带gcc,静态链接

·         Linux Itanium-2,带gcc

·         Windows

当从源码构建MySQL时如果你想要启用yaSSL,应这样配置MySQL

./configure --with-yassl=yes

要想启动MySQL服务器支持yaSSL,使用支持OpenSSL的相同的选项,并识别建立安全连接需要的证书:

shell> mysqld --ssl-ca=cacert.pem \
       --ssl-cert=server-cert.pem \
       --ssl-key=server-key.pem

·         --ssl-ca识别认证机构证书。

·         --ssl-cert识别服务器证书。

·         --ssl-key识别客户证书。

要想用yaSSL支持建立与MySQL服务器的安全连接,应这样启动客户端:

shell> mysql --ssl-ca=cacert.pem \
       --ssl-cert=server-cert.pem \
       --ssl-key=server-key.pem

换句话说,选项与服务器的相同,并且认证机构证书必须相同。

要想从应用程序建立安全连接,调用mysql_real_connect()之前,应使用mysql_ssl_set()API函数来设置相应认证选项。参见25.2.3.64节,“mysql_ssl_set()”

5.8.7.4. 为MySQL设置SSL证书

下面是一个为 MySQ设置 SSL证书的例子:
DIR=`pwd`/openssl
PRIV=$DIR/private
 
mkdir $DIR $PRIV $DIR/newcerts
cp /usr/share/ssl/openssl.cnf $DIR
replace ./demoCA $DIR -- $DIR/openssl.cnf
 
# Create necessary files: $database, $serial and $new_certs_dir
# directory (optional)
 
touch $DIR/index.txt
echo "01" > $DIR/serial
 
#
# Generation of Certificate Authority(CA)
#
 
openssl req -new -x509 -keyout $PRIV/cakey.pem -out $DIR/cacert.pem \
    -config $DIR/openssl.cnf
 
# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# ................++++++
# .........++++++
# writing new private key to '/home/monty/openssl/private/cakey.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL admin
# Email Address []:
 
#
# Create server request and key
#
openssl req -new -keyout $DIR/server-key.pem -out \
    $DIR/server-req.pem -days 3600 -config $DIR/openssl.cnf
 
# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# ..++++++
# ..........++++++
# writing new private key to '/home/monty/openssl/server-key.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL server
# Email Address []:
#
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:
 
#
# Remove the passphrase from the key (optional)
#
 
openssl rsa -in $DIR/server-key.pem -out $DIR/server-key.pem
 
#
# Sign server cert
#
openssl ca  -policy policy_anything -out $DIR/server-cert.pem \
    -config $DIR/openssl.cnf -infiles $DIR/server-req.pem
 
# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Enter PEM pass phrase:
# Check that the request matches the signature
# Signature ok
# The Subjects Distinguished Name is as follows
# countryName           :PRINTABLE:'FI'
# organizationName      :PRINTABLE:'MySQL AB'
# commonName            :PRINTABLE:'MySQL admin'
# Certificate is to be certified until Sep 13 14:22:46 2003 GMT
# (365 days)
# Sign the certificate? [y/n]:y
#
#
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated
 
#
# Create client request and key
#
openssl req -new -keyout $DIR/client-key.pem -out \
    $DIR/client-req.pem -days 3600 -config $DIR/openssl.cnf
 
# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# .....................................++++++
# .............................................++++++
# writing new private key to '/home/monty/openssl/client-key.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL user
# Email Address []:
#
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:
 
#
# Remove a passphrase from the key (optional)
#
openssl rsa -in $DIR/client-key.pem -out $DIR/client-key.pem
 
#
# Sign client cert
#
 
openssl ca  -policy policy_anything -out $DIR/client-cert.pem \
    -config $DIR/openssl.cnf -infiles $DIR/client-req.pem
 
# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Enter PEM pass phrase:
# Check that the request matches the signature
# Signature ok
# The Subjects Distinguished Name is as follows
# countryName           :PRINTABLE:'FI'
# organizationName      :PRINTABLE:'MySQL AB'
# commonName            :PRINTABLE:'MySQL user'
# Certificate is to be certified until Sep 13 16:45:17 2003 GMT
# (365 days)
# Sign the certificate? [y/n]:y
#
#
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated
 
#
# Create a my.cnf file that you can use to test the certificates
#
 
cnf=""
cnf="$cnf [client]"
cnf="$cnf ssl-ca=$DIR/cacert.pem"
cnf="$cnf ssl-cert=$DIR/client-cert.pem"
cnf="$cnf ssl-key=$DIR/client-key.pem"
cnf="$cnf [mysqld]"
cnf="$cnf ssl-ca=$DIR/cacert.pem"
cnf="$cnf ssl-cert=$DIR/server-cert.pem"
cnf="$cnf ssl-key=$DIR/server-key.pem"
echo $cnf | replace " " '
' > $DIR/my.cnf

 

要想测试SSL连接,按下面方法启动服务器,其中$DIR是示例my.cnf选项文件安装的路径名:

shell> MySQLd --defaults-file=$DIR/my.cnf &

然后使用相同的选项文件调用客户端程序:

shell> MySQL --defaults-file=$DIR/my.cnf

如果你有MySQL源码分发版,还可以修改前面的my.cnf文件来指向SSL目录中的示范证书和密钥文件来测试你的设置。

5.8.7.5. SSL GRANT 选项

MySQL可以检查X509证书的属性和基于用户名和密码的通用鉴定方法。要想为MySQL账户指定SSL相关选项,使用GRANT语句的REQUIRE子句。参见13.5.1.3节,“GRANT和REVOKE语法”

有多种可能来限制一个账户的连接类型:

·         如果账户没有SSLX509需求,如果用户名和密码合法,允许未加密的连接。但是,如果客户有正确的证书和密钥文件,在客户选项中可以使用加密连接。

·         REQUIRE SSL选项限制服务器只允许该账户的SSL加密连接。请注意如果有ACL记录允许非SSL连接,该选项会被忽略。

·                  mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
·                     -> IDENTIFIED BY 'goodsecret' REQUIRE SSL;

·         REQUIRE X509表示客户必须有合法证书但确切的证书、分发者和主体不重要。唯一的需求是应可以被某个CA认证机构验证它的签名。

·                mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
·                    -> IDENTIFIED BY 'goodsecret' REQUIRE X509;

·         REQUIRE ISSUER 'issuer'限制连接企图,即客户必须出示CA 'issuer'签发的合法X509证书。如果客户出示了一个合法证书,但是是由不同的分发者签发,服务器拒绝连接。使用X509证书表示要加密,因此不需要SSL选项。

·                mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
·                    -> IDENTIFIED BY 'goodsecret'
·                    -> REQUIRE ISSUER '/C=FI/ST=Some-State/L=Helsinki/
·                       O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com';

请注意ISSUER值应做为单一字符串输入。

·         REQUIRE SUBJECT 'subject' 限制连接企图,即客户必须出示主题为'subject'的合法X509证书。如果客户出示了一个合法证书,但是有不同的主题,服务器拒绝连接。

·                mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
·                    -> IDENTIFIED BY 'goodsecret'
·                    -> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
·                       O=MySQL demo client certificate/
       CN=Tonu Samuel/Email=tonu@example.com';

请注意SUBJECT值应做为单一字符串输入。

·         REQUIRE CIPHER 'cipher'用来确保使用足够强的密码和密钥长度。如果使用旧的短加密密钥算法,SSL本身可能很弱。使用该选项,我们可以索取确切的加密方法来连接。

·                mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
·                    -> IDENTIFIED BY 'goodsecret'
    -> REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA';

REQUIRE子句中,可以结合使用SUBJECTISSUERCIPHER选项:

mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
    -> IDENTIFIED BY 'goodsecret'
    -> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
       O=MySQL demo client certificate/
       CN=Tonu Samuel/Email=tonu@example.com'
    -> AND ISSUER '/C=FI/ST=Some-State/L=Helsinki/
       O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com'
    -> AND CIPHER 'EDH-RSA-DES-CBC3-SHA';

请注意SUBJECTISSUER值应做为单一字符串输入。

MySQL 5.1,REQUIRE选项之间可以选用AND关键字。

选项的顺序不重要,但任何选项不能用两次。

5.8.7.6. SSL命令行选项

下面列出了规定 SSL、证书文件和密钥文件使用的选项。它们可以位于命令行中或选项文件中。

·         --ssl

对于服务器,该选项规定该服务器允许SSL连接。对于客户端程序,它允许客户使用SSL连接服务器。单单该选项不足以使用SSL连接。还必须指定--ssl-ca--ssl-cert--ssl-key选项。

通常从反向使用该选项表示不应使用SSL。要想实现,将选项指定为--skip-ssl--ssl=0

请注意使用--ssl需要SSL连接。例如,如果编译的服务器或客户不支持SSL,则使用普通的未加密的连接。

确保使用SSL连接的安全方式是使用含REQUIRE SSL子句的GRANT语句在服务器上创建一个账户。然后使用该账户来连接服务器,服务器和客户端均应启用SSL支持。

·         --ssl-ca=file_name

含可信SSL CA的清单的文件的路径。

·         --ssl-capath=directory_name

包含pem格式的可信SSL CA证书的目录的路径。

·         --ssl-cert=file_name

SSL证书文件名,用于建立安全连接。

·         --ssl-cipher=cipher_list

允许的用于SSL加密的密码的清单。cipher_list的格式与OpenSSL ciphers命令相同。

示例:--ssl-cipher=ALL:-AES:-EXP

·         --ssl-key=file_name

SSL密钥文件名,用于建立安全连接。

5.8.7.7. 用SSH以远程方式从Windows连接到MySQL

本节说明如何用 SSH安全连接到远程 MySQL服务器 (David Carlson <dcarlson@mplcommcom> )

1.    Windows主机上安装SSH客户端。作为用户,我所发现的最好的非免费客户端来自http://www.vandyke.com/SecureCRT。另一个选则是http://www.f-secure.com/f-secure。你还可以从http://directory.google.com/Top/Computers/Security/Products_and_Tools/Cryptography/SSH/Clients/Windows/ Google找到一些免费客户端。

2.    启动Windows SSH客户端。设置Host_Name = yourmysqlserver_URL_or_IP。设置userid=your_userid以便登录服务器。此userid值可以与你的MySQL账户的用户名不相同。

3.    设置端口映射。可以进行远程映射(设置local_port: 3306, remote_host: yourmysqlservername_or_ip, remote_port: 3306)或本地映射(设置port: 3306, host: localhost, remote port: 3306)

4.    进行保存,否则下次需要重设。

5.    刚创建的SSH会话登录服务器。

6.    Windows机器上启动相应ODBC应用程序(例如Access)

7.    Windows中创建一个新的文件按照常用方法通过ODBC驱动程序链接MySQL,不同的是要为MySQL服务器输入localhost,而不是yourmysqlservername

你应有使用SSH加密的ODBC连接到MySQL

关注编程学问公众号