MySQL は先進的な非標準のセキュリティ/特権システムを持っています。
MySQL 特権システムの基本機能は、ホスト上のユーザ名に対しデータ ベースの select, insert, update そして delete 特権を与えることです。
拡張機能は匿名ユーザをもつ能力を含み、LOAD DATA INFILE
のような
MySQL 固有の機能を使用する許可を与えます。
SQL データベースのユーザ名(MySQL のような)は、UNIX ユーザで行う
ことはありません。便利のため、多くの MySQL クライアントは現在の
ユーザ名でログインを試みます。しかしこれは --user
スイッチで変更
できます。これは、全てのユーザに対しパスワードを持つことなしには、どんな
方法でもデータベースを安全にできないことを意味します。
MySQL では、ホストとユーザの組合せがユニークとして識別されます。 ユーザのことを考えずに、ホスト+ユーザを考えてください。全てがよりクリア になります。例えば、2つの異なるホストで(異なる特権を持つ) 'Robb' という 名前のユーザを MySQL では衝突無しに持つことができます。
MySQL 特権システムは確実に、各ユーザに許されていることを厳密に 行ないます。システムは、どのユーザ が どのホスト から どのデータベース に接続したかによって、異なる特権の許可を決定し ます。
あなたの特権はスクリプト mysqlaccess
でいつでもテストできます。こ
れは Yves Carlier が MySQL 配布に提供しました。 「何故 Access denied
エラーになるのか?」節参照
「MySQL をクラッカーに対して安全にする方法」節参照
全ての特権は3つのテーブルに置かれます。user
, host
そして
db
です。
user
テーブル内で承認される全てのものは、db
テーブル内にない全てのデー
タベースに有効です。この理由から、個々のデータベースごとに、ユーザ(スー
パーユーザは除く)の特権を許可することは賢いことです。
host
テーブルは主に ``安全な'' サーバのリストを維持します。TcX では
host
はローカルネットワーク上の全てのマシンのリストを含んでいます。
これは全ての特権が承認されてます。
接続するユーザの特権は次のアルゴリズムで計算されます:
Table | Sorted by |
host | ワイルドなしのホスト/ワイルドつきのホスト/空のホスト |
db | ワイルドなしのホスト/ワイルドつきのホスト/空のホスト |
user | ホスト/ユーザ |
host = ""
のエントリ。各ホスト中では、同じ規則を使用してユーザで
ソートします。最後に、db
テーブル内で同じ規則を使用して db でソー
トします。以下のステップでは、ソートされたテーブルを通して見て、
常に最初に見つけたものを使用します。
user
テーブルから最初に見つかったものを使用して、接続するユーザの
特権を獲得します。
これを特権のセット Priv と呼びます。
db
テーブルから最初に見つかったものを使用して、接続するユーザの特
権を獲得します。
db
テーブルに見つかったエントリが host = ""
の場合、
Priv と host
テーブル内の host からの特権を AND します。す
なわち両方が "Y" でない全ての特権を削除します。(host <> ""
の場合、
Priv は影響されません。この場合、host
は、少なくても部分的
に、接続するホストの名前に適合しなければなりません。したがって、この行内
に見つかった特権が接続ホストの情報に適合したとみなされます。)
user
テーブルから user についての特権を持つ Priv を OR (追
加)します。すなわち、user
内の "Y" である全ての特権を追加します。
mysqladmin
reload
をしなけれないけないことを覚えておいてください。
接続するユーザは特権 Priv のセットを得ます。
ソートと適合の例を示しましょう! user テーブルがこれを含んでいると仮定し
ます:
+-----------+----------+- | Host | User | ... +-----------+----------+- | % | root | ... | % | jeffrey | ... | localhost | root | ... | localhost | | ... +-----------+----------+-すると検索順は次になります:
localhost/any
行
に適合します。any/jeffrey
行ではありません。最初に見つかった適合
が使用されます!
もしアクセスの問題があった場合は、user テーブルを出力し、手動でソートして、ど
のように適合されるかを見てください。
ここで、'localhost', 'server.domain' そして 'whitehouse.gov' のホストか
ら接続が可能なユーザ 'custom' を追加する例を示します。彼はパスワード 'stupid'
を持つことを望みます。データベース 'bankaccount' は 'localhost' からだけ
使用でき、そして 'customer' データベースは全ての3つのホストから到達でき
ます。
shell> mysql mysql. mysql> insert into user (host,user,password) values('localhost','custom',password('stupid')); mysql> insert into user (host,user,password) values('server.domain','custom',password('stupid')); mysql> insert into user (host,user,password) values('whitehouse.gov','custom',password('stupid')); mysql> insert into db (host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv, Create_priv,Drop_priv) values ('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y'); mysql> insert into db (host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv, Create_priv,Drop_priv) values ('%','customers','custom','Y','Y','Y','Y','Y','Y');もちろん、xmysqladmin, mysql_webadmin, mysqladmin そして xmysql を使って も、特権テーブルへの値の挿入/変更/更新ができます。これらのユーティリティは Contrib ディレクトリ内に見つけることができます。
行の承認テーブルの特権は select, insert, update そして delete です。
テーブルとデータベースの特権は create と drop です。create と drop はテーブルとデータベースの両方に働きます。drop 権限を持つユーザは任意 のテーブルを削除できるため、これはデータベースの drop 権限と同じことです。
他の特権は(LOAD DATA INFILE
と SELECT INTO OUTFILE
のため
の)ファイルの使用と、管理コマンド shutdown, reload,
refresh, process の使用の権利を与えます。
特権システムは3つのテーブルに基づきます。
user
テーブル
user
テーブルは次の項目を持ちます:
Field | Type | Key | Default |
Host | char(60) | PRI | "" |
User | char(16) | PRI | "" |
Password | char(16) | - | "" |
Select_priv | enum('N','Y') | - | N |
Insert_priv | enum('N','Y') | - | N |
Update_priv | enum('N','Y') | - | N |
Delete_priv | enum('N','Y') | - | N |
Create_priv | enum('N','Y') | - | N |
Drop_priv | enum('N','Y') | - | N |
Reload_priv | enum('N','Y') | - | N |
Shutdown_priv | enum('N','Y') | - | N |
Process_priv | enum('N','Y') | - | N |
File_priv | enum('N','Y') | - | N |
db
テーブル
ホスト+ユーザが使用を許されるデータベースと、その人が各データベースでテー
ブルに行えることを含みます。db
テーブルは次の項目を持ちます:
Field | Type | Key | Default |
Host | char(60) | PRI | "" |
Db | char(64) | PRI | "" |
User | char(16) | PRI | "" |
Select_priv | enum('N','Y') | - | N |
Insert_priv | enum('N','Y') | - | N |
Update_priv | enum('N','Y') | - | N |
Delete_priv | enum('N','Y') | - | N |
Create_priv | enum('N','Y') | - | N |
Drop_priv | enum('N','Y') | - | N |
host
テーブル
db テーブル内に空の host エントリが見られるような大きなネットワークでだ
けに使用されます。これは、あなたのネットワーク内の全てのホストからユーザ
にデータベースを使用させたい場合、db テーブルのホスト名として '' を置く
べきであることを意味します。この場合 host
テーブルは、あなたのネッ
トワーク内の全てのホストのエントリを含むべきです。host
テーブルは
次の項目を持ちます:
Field | Type | Key | Default |
Host | char(60) | PRI | "" |
Db | char(64) | PRI | "" |
Select_priv | enum('N','Y') | - | N |
Insert_priv | enum('N','Y') | - | N |
Update_priv | enum('N','Y') | - | N |
Delete_priv | enum('N','Y') | - | N |
Create_priv | enum('N','Y') | - | N |
Drop_priv | enum('N','Y') | - | N |
%
と
_
を伴う文字列を含むことができます。これらの項目を空にすることは、'%'
を設定するのと同じことです。
localhost
, ホスト名, IP アドレスまたはワイルドカー
ドを伴う文字列です。db テーブル内の空の host は、host テーブル内の任意のホストを意味
します。host または user テーブル内の空の host は サーバにTCP 接続を生成
する任意のホストを意味します。
user
テーブル内に適合しないユーザは、名無しのユーザとして処理され
ます。
db
テーブルと OR されます。これはスーパーユーザだ
けが user テーブル内で全ての特権フラグを Y
に設定することが必要であるこ
とを意味します。
123.444.444.%
のようなエントリを使用できます。誰かがホスト
123.444.444.somwehere.com
という名前のホストによって、この設定を
馬鹿にする試みの可能性を回避するため、MySQL は数値とドットで始
まる全てのホスト名を許可しません。そのためあなたのホストが
1.2.foo.com
のような名前の場合、名前の適合で認められることはあり
ません。この場合は IP 番号を使用してください。
MySQL データベースに特権を追加するために:
現在のユーザが mysql db テーブルについての insert 特権と reload 特権を持ってい
ると仮定します。サーバ (mysqld) が実行されていないといけません。そうでな
い場合は、safe_mysqld --log &
で開始します。
> mysql mysql insert into user values ('%','monty',password('something'),'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y') ; insert into user (host,user,password) values('localhost','dummy','') ; insert into user values ('%','admin','','N','N','N','N','N','N','Y','N','Y','Y') ; quit > mysqladmin reload
これは3つの新しいユーザを作ります:
Monty
admin
mysqladmin reload
, mysqladmin
refresh
そして mysqladmin processlist
の使用だけが許されます。テーブル
db
を通して個々のデータベース特権が承認されます。
dummy
db
を通して個々のデータベース特権が承認される必要があります。
デフォルトの特権 (`scripts/mysql_install_db'内でセットされる) は
root に全てを行なえるようにします。全てのユーザは 'test' という名前また
は 'test_' で始まる名前の全てのデータベースで全てを行なうことができます。
通常のユーザは mysqladmin shutdown
または mysqladmin
processlist
は使用できません。他のユーザを追加する方法の例は、スクリプ
ト (`scripts/mysql_install_db') を参照してください。
特権テーブルは mysqladmin reload
で mysqld に読み込まれます。
ありがちな間違いは、パスワードが暗号化されて格納されることを忘れることで す。これは次のように指示されます:
INSERT INTO user VALUES ('%','jeffrey','bLa81m0','Y','Y','Y','N','N','N','N','N', 'N','N');
そして(もちろん)認証の変更を有効にするために mysqladmin reload
を
行ない、それからサーバに接続を試みます:
$ ./mysql -h sqlserver -u jeffrey -p bLa81m0 test Access denied
代わりにこれを試みて下さい:
INSERT INTO user VALUES ('%','jeffrey',password('bLa81m0'),'Y','Y','Y','N','N','N','N','N','N','N');
前と同じように、認証の変更を有効にするために mysqladmin reload
を
行ないます。
さあ、これでちゃんと働きます。
Access denied
エラーになるのか?mysql -u root test
の実行によってテストして
ください。これは普通はエラーになりません。mysql データベースディレクトリ
内にファイル 'user.ISD' があるかどうかでもチェックできます (普通は
install_dir/var/mysql/user.ISD)。
mysqladmin reload
を実行する必要があること
を忘れないで下さい。そうしないと古いテーブルが使われます!
--without-grant-tables
オプショ
ンで開始すべきです。そうすれば MySQL 承認テーブルを変更でき、スクリプ
ト mysqlaccess
を、あなたの承認が働くかどうかのチェックのために使
用できます。mysqladmin reload
は mysqld デーモンに新しい承認テーブルの
使用を開始するように知らせます。
mysql -u user database
または mysql -uuser -ppassword
database
で、特権の問題をテストしてください。-p と password の間には空
白がないことに注意してください。--password=your_password
構文でも
パスワードを与えられます!
mysql -u user database
でデータベースに接続を試みた時に、'Access
denied' エラーになる場合、'user' テーブルに問題があります。mysql -u root
mysql
と select * from user
を行なうことでこれをチェックしてくだ
さい。あなたのコンピュータのホスト名とあなたのユーザ名に適合する 'hostname'
と 'user' でのエントリが得られるべきです。クライアントとサーバが同じホス
ト上で実行されて、mysql に --host
オプションを使用せず、そして
MIT スレッドを使用していない場合は、'localhost' があなたのホスト名の同義
語です。
Access denied
エラーメッセージは、あなたが誰で、どこのホストから
ログインしようとしたか、そしてパスワードを使用したかどうかをあなたに教え
ます。通常 user
テーブル内に、エラーメッセージで得られたような、正確な
あなたのホストとユーザに適合する 1つのエントリを持つべきです。
mysql -u root test
が働くのに mysql -h your_hostname -u
root test
が 'Access denied' になる場合は、user テーブル内にあなたのホストの
正しい名前がありません。例えば、'user' テーブル内にホスト 'tcx' のエントリを持っ
ているけれども、DNS があなたのホスト名を 'tcx.subnet.se' と MySQL に知ら
せる場合、このエントリは働きません。'user' テーブル内にホストの IP のレコード
を追加することでテストしてください。もちろん、ワイルドカードのホスト (例
えば 'tcx%') を 'user' テーブルに追加することもできます (ただし % で終わるホス
ト名の使用はかなり危険です)。
mysql -u user database
がサーバマシン上で働き、mysql -h
host -u user datbase
が他のクライアントマシン上で働かない場合は、クライ
アントマシンが 'user' または 'db' テーブル内にありません。
mysql -u user test
が働くのに mysql -u user other_database
が働かない場合、other_database が 'db' テーブルにありません。
SELECT ... INTO OUTFILE
または LOAD DATA
SQL コマンドの使
用時に 'Access to database denied' になる場合、おそらく user テーブルにあなた
のための File_priv
特権セットがありません。
mysqld
デーモンを
--debug=d,general,query
で起動してください。これは接続しようとす
るホストとユーザの情報と、各コマンドについての情報を出力します。
「MySQL のデバッグ」節参照 。
mysqldump mysql
コマンドでテーブルをダンプできま
す。常に、あなたの問題は mysqlbug
スクリプトを使って投稿してくだ
さい。
Can't connect to local mySQL server
または Can't
connect ot MySQL server on some_hostname
になる場合、これはデーモン
mysqld が動いていないか、または間違ったソケットやポートに接続しようとし
たことを意味します。ソケット(通常は /tmp/mysql.sock)が存在するかチェック
するか、または telnet でそのポートに接続できるかを試してください:
telnet hostname 3306
。また mysqladmin version
でさらにいく
つかの情報を得ることもできます。
MySQL システムを安全にするためには、次のことを考えるべきです:
mysql_install_db
スクリプトを編集することで、または
MySQL root ユーザだけは次で変更できます。
mysql -u root -e "update user set password=password('new_password') where user='root'" mysql
SELECT INTO
OUTFILE
で作成される全てのファイルは全員に読み込み可能で生成され、既存
のファイルには上書きできません。
mysqld
への次のオプションはセキュリティに影響します:
--secure
get_hostbyname
から返される ip がオリジナルのホスト名に戻せるかど
うかをチェックします。これは、外の誰かが他のホストを真似てアクセスを得る
ことを難しくします。このオプションはいくつかの正しいホスト名チェックも追
加します。これは、時にチェックに長い時間がかかるため、デフォルトではオフ
にされています。
--skip-grant-tables
--skip-name-resolve
--skip-networking
Go to the first, previous, next, last section, table of contents.