分类: BSD
2006-06-13 11:41:48
FreeBSD全能服务器安装手册之域名服务器篇之DNS(数据库)篇
#################################下载并解压缩安装包################################
cd /usr/ports/dns/bind9
//下载bind9.3.1
make fetch
cd /usr/ports/distfiles/
//解压缩bind9.3.*
tar zxvf bind-9.3.*.tar.gz
chown -R root:wheel bind-9.3.*
###############################生成mysqldb.c文件##################################
cd /usr/ports/distfiles/bind-9.3.*/bin/named/
//生成mysqldb.c 注意:必须采用touch命令生成文件,因为有些时候用其他命令生成的文件是不能被程序识别的。
touch mysqldb.c
//编辑mysqldb.c
/* 增加以下内容(此为mysqldb.c的原版文档亦可从以下连接直*)*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "mysqldb.h"
static dns_sdbimplementation_t *mysqldb = NULL;
struct dbinfo {
MYSQL *mysql;
char *database;
char *table;
char *host;
char *user;
char *passwd;
};
static void
mysqldb_destroy(const char *zone, void *driverdata, void **dbdata);
/*
* Canonicalize a string before writing it to the database.
* "dest" must be an array of at least size 2*strlen(source) + 1.
*/
static void
quotestring(const char *source, char *dest) {
while (*source != 0) {
if (*source == '\'')
*dest++ = '\'';
*dest++ = *source++;
}
*dest++ = 0;
}
/*
* Connect to the database.
*/
static isc_result_t
db_connect(struct dbinfo *dbi) {
dbi->mysql = mysql_init(0);
if (!mysql_real_connect(dbi->mysql, dbi->host, dbi->user, dbi->passwd, dbi->database, 0, NULL, 0))
return (ISC_R_FAILURE);
return (ISC_R_SUCCESS);
}
/*
* Check to see if the connection is still valid. If not, attempt to
* reconnect.
*/
static isc_result_t
maybe_reconnect(struct dbinfo *dbi) {
if (dbi->mysql != NULL)
return (ISC_R_SUCCESS);
return (db_connect(dbi));
}
/*
* This database operates on absolute names.
*
* Queries are converted into SQL queries and issued synchronously. Errors
* are handled really badly.
*/
static isc_result_t
mysqldb_lookup(const char *zone, const char *name, void *dbdata,
dns_sdblookup_t *lookup)
{
isc_result_t result;
struct dbinfo *dbi = dbdata;
MYSQL_RES *res;
MYSQL_ROW row;
char str[1500]="";
char *canonname;
UNUSED(zone);
canonname = isc_mem_get(ns_g_mctx, strlen(name) * 2 + 1);
if (canonname == NULL)
return (ISC_R_NOMEMORY);
quotestring(name, canonname);
snprintf(str, sizeof(str),
"SELECT TTL,RDTYPE,RDATA FROM %s WHERE lower(NAME) = lower('%s')", dbi->table, canonname);
isc_mem_put(ns_g_mctx, canonname, strlen(name) * 2 + 1);
result = maybe_reconnect(dbi);
if (result != ISC_R_SUCCESS)
return (result);
if (mysql_query(dbi->mysql, str)) {
return (ISC_R_FAILURE);
}
if (!(res = mysql_store_result(dbi->mysql))) {
return (ISC_R_NOTFOUND);
}
while ((row = mysql_fetch_row(res))) {
char *ttlstr = row[0];
char *type = row[1];
char *data = row[2];
dns_ttl_t ttl;
char *endp;
ttl = (ttlstr) ? strtol(ttlstr, &endp, 10) : 86400;
if (*endp != '\0') {
mysql_free_result(res);
return (DNS_R_BADTTL);
}
result = dns_sdb_putrr(lookup, type, ttl, data);
if (result != ISC_R_SUCCESS) {
mysql_free_result(res);
return (ISC_R_FAILURE);
}
}
mysql_free_result(res);
return (ISC_R_SUCCESS);
}
/*
* Issue an SQL query to return all nodes in the database and fill the
* allnodes structure.
*/
static isc_result_t
mysqldb_allnodes(const char *zone, void *dbdata, dns_sdballnodes_t *allnodes) {
struct dbinfo *dbi = dbdata;
MYSQL_RES *res;
MYSQL_ROW row;
isc_result_t result;
char str[1500]="";
UNUSED(zone);
snprintf(str, sizeof(str),
"SELECT TTL,NAME,RDTYPE,RDATA FROM %s ORDER BY NAME",
dbi->table);
result = maybe_reconnect(dbi);
if (result != ISC_R_SUCCESS)
return (result);
mysql_select_db(dbi->mysql,dbi->database);
if (mysql_query(dbi->mysql, str)) {
return (ISC_R_FAILURE);
}
if (!(res = mysql_store_result(dbi->mysql))) {
return (ISC_R_NOTFOUND);
}
while ((row = mysql_fetch_row(res))) {
char *ttlstr = row[0];
char *name = row[1];
char *type = row[2];
char *data = row[3];
dns_ttl_t ttl;
char *endp;
ttl = (ttlstr) ? strtol(ttlstr, &endp, 10) : 86400;
if (*endp != '\0') {
mysql_free_result(res);
return (DNS_R_BADTTL);
}
result = dns_sdb_putnamedrr(allnodes, name, type, ttl, data);
if (result != ISC_R_SUCCESS) {
mysql_free_result(res);
return (ISC_R_FAILURE);
}
}
mysql_free_result(res);
return (ISC_R_SUCCESS);
}
/*
* Create a connection to the database and save any necessary information
* in dbdata.
*
* argv[0] is the name of the database
* argv[1] is the name of the table
* argv[2] (if present) is the name of the host to connect to
* argv[3] (if present) is the name of the user to connect as
* argv[4] (if present) is the name of the password to connect with
*/
static isc_result_t
mysqldb_create(const char *zone, int argc, char **argv,
void *driverdata, void **dbdata)
{
struct dbinfo *dbi;
isc_result_t result;
UNUSED(zone);
UNUSED(driverdata);
if (argc < 2)
return (ISC_R_FAILURE);
dbi = isc_mem_get(ns_g_mctx, sizeof(struct dbinfo));
if (dbi == NULL)
return (ISC_R_NOMEMORY);
dbi->mysql = NULL;
dbi->database = NULL;
dbi->table = NULL;
dbi->host = NULL;
dbi->user = NULL;
dbi->passwd = NULL;
#define STRDUP_OR_FAIL(target, source)\
do {\
target = isc_mem_strdup(ns_g_mctx, source);\
if (target == NULL) {\
result = ISC_R_NOMEMORY;\
goto cleanup;\
}\
} while (0);
STRDUP_OR_FAIL(dbi->database, argv[0]);
STRDUP_OR_FAIL(dbi->table, argv[1]);
if (argc > 2)
STRDUP_OR_FAIL(dbi->host, argv[2]);
if (argc > 3)
STRDUP_OR_FAIL(dbi->user, argv[3]);
if (argc > 4)
STRDUP_OR_FAIL(dbi->passwd, argv[4]);
result = db_connect(dbi);
if (result != ISC_R_SUCCESS)
goto cleanup;
*dbdata = dbi;
return (ISC_R_SUCCESS);
cleanup:
mysqldb_destroy(zone, driverdata, (void **)&dbi);
return (result);
}
/*
* Close the connection to the database.
*/
static void
mysqldb_destroy(const char *zone, void *driverdata, void **dbdata) {
struct dbinfo *dbi = *dbdata;
UNUSED(zone);
UNUSED(driverdata);
if (dbi->mysql != NULL)
mysql_close(dbi->mysql);
if (dbi->database != NULL)
isc_mem_free(ns_g_mctx, dbi->database);
if (dbi->table != NULL)
isc_mem_free(ns_g_mctx, dbi->table);
if (dbi->host != NULL)
isc_mem_free(ns_g_mctx, dbi->host);
if (dbi->user != NULL)
isc_mem_free(ns_g_mctx, dbi->user);
if (dbi->passwd != NULL)
isc_mem_free(ns_g_mctx, dbi->passwd);
if (dbi->database != NULL)
isc_mem_free(ns_g_mctx, dbi->database);
isc_mem_put(ns_g_mctx, dbi, sizeof(struct dbinfo));
}
/*
* Since the SQL database corresponds to a zone, the authority data should
* be returned by the lookup() function. Therefore the authority() function
* is NULL.
*/
static dns_sdbmethods_t mysqldb_methods = {
mysqldb_lookup,
NULL, /* authority */
mysqldb_allnodes,
mysqldb_create,
mysqldb_destroy
};
/*
* Wrapper around dns_sdb_register().
*/
isc_result_t
mysqldb_init(void) {
unsigned int flags;
flags = 0;
return (dns_sdb_register("mysql", &mysqldb_methods, NULL, flags,
ns_g_mctx, &mysqldb));
}
/*
* Wrapper around dns_sdb_unregister().
*/
void
mysqldb_clear(void) {
if (mysqldb != NULL)
dns_sdb_unregister(&mysqldb);
}
####################################################################################
#############################生成mysqldb.h文件#####################################
cd /usr/ports/distfiles/bind-9.3.*/bin/named/include/
touch mysqldb.h
ee mysqldb.h
#include
isc_result_t mysqldb_init(void);
void mysqldb_clear(void);
###############################改变文件的运行权限###################################
chmod 755 /usr/ports/distfiles/bind-9.3.*/bin/named/mysqldb.c
chmod 755 /usr/ports/distfiles/bind-9.3.*/bin/named/include/mysqldb.h
#################################修改Makefile.in####################################
ee /usr/ports/distfiles/bind-9.3.*/bin/named/Makefile.in
从26行开始
# Add database drivers here.
#
DBDRIVER_OBJS =
DBDRIVER_SRCS =
DBDRIVER_INCLUDES =
DBDRIVER_LIBS =
改成
DBDRIVER_OBJS = mysqldb.@O@
DBDRIVER_SRCS = mysqldb.c
DBDRIVER_INCLUDES = -I'/usr/local/include/mysql'
DBDRIVER_LIBS = -L'/usr/local/lib/mysql' -lmysqlclient
#################################修改main.c ####################################
ee /usr/ports/distfiles/bind-9.3.*/bin/named/main.c
添加
#include
################################注册mysqldb_init();################################
寻找: register
* Add calls to register sdb drivers here.
*/
/* xxdb_init(); */
mysqldb_init();
ns_server_create(ns_g_mctx, &ns_g_server);
寻找: unregister
################################注册mysqldb_clear();################################
/*
* Add calls to unregister sdb drivers here.
*/
/* xxdb_clear(); */
mysqldb_clear();
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
ISC_LOG_NOTICE, "exiting");
ns_log_shutdown();
#################################安装bind9.3.2######################################
cd /usr/ports/distfiles/bind-9.3.*
./configure
make
make install
make clean
#################################配置bind9.3.2######################################
/usr/local/sbin/rndc-confgen > /etc/namedb/rndc.conf
cd /etc/namedb
tail -n10 rndc.conf | head -n9 | sed -e s/#\ //g >> named.conf
###############################建立bind数据库######################################
mysql -uroot -ppassword
CREATE DATABASE bind9;
GRANT select,insert,update,delete,create,drop ON bind9.* TO bind9user@localhost IDENTIFIED BY 'password';
use bind9;
CREATE TABLE mydomain (
name varchar(255) default NULL,
ttl int(11) default NULL,
rdtype varchar(255) default NULL,
rdata varchar(255) default NULL
) TYPE=MyISAM;
###############################插入事例数据文件#####################################
INSERT INTO mydomain VALUES ('mydomain.com', 259200, 'SOA', 'mydomain.com. 200309181 28800 7200 86400 28800');
INSERT INTO mydomain VALUES ('mydomain.com', 259200, 'NS', 'ns0.mydomain.com.');
INSERT INTO mydomain VALUES ('mydomain.com', 259200, 'NS', 'ns1.mydomain.com.');
INSERT INTO mydomain VALUES ('mydomain.com', 259200, 'MX', '10 mail.mydomain.com.');
INSERT INTO mydomain VALUES ('w0.mydomain.com', 259200, 'A', '192.168.1.1');
INSERT INTO mydomain VALUES ('w1.mydomain.com', 259200, 'A', '192.168.1.2');
INSERT INTO mydomain VALUES ('mydomain.com', 259200, 'Cname', 'w0.mydomain.com.');
INSERT INTO mydomain VALUES ('mail.mydomain.com', 259200, 'Cname', 'w0.mydomain.com.');
INSERT INTO mydomain VALUES ('ns0.mydomain.com', 259200, 'Cname', 'w0.mydomain.com.');
INSERT INTO mydomain VALUES ('ns1.mydomain.com', 259200, 'Cname', 'w1.mydomain.com.');
INSERT INTO mydomain VALUES ('', 259200, 'Cname', 'w0.mydomain.com.');
INSERT INTO mydomain VALUES ('ftp.mydomain.com', 259200, 'Cname', 'w0.mydomain.com.');
#############################在named.conf中加入主域################################
ee /var/named/etc/namedb/named.conf
zone "mydomain.com" {
type master;
notify no;
database "mysql bind9 mydomain localhost bind9user password";
};
%%%%%%%%%%%%删除或注释掉DNS服务器的监听地址%%%%%%
ee /var/named/etc/namedb/named.conf
删除
20 listen-on { 127.0.0.1; };
注释掉
// listen-on { 127.0.0.1; };
rndc reload
(由于bind9在默认的情况下只是给自己,所以要去除监听地址listen-on { 127.0.0.1; };)
%%%%%%%%%%%%%设置本机DNS服务器地址%%%% %%%%%%%%%%%%
ee /etc/resolv.conf
添加
nameserver 127.0.0.1
nameserver 211.98.2.4
nameserver 202.99.104.68
nameserver 202.99.96.68
nameserver 202.102.128.68
nameserver 202.103.0.117
nameserver 202.103.44.5
(所以选这么多DNS是考虑到了冗余设计防止万一出错)
###################################停止系统默认的bind###############################
mv /usr/sbin/named /usr/sbin/named.dist
mv /usr/sbin/rndc /usr/sbin/rndc.dist
mv /usr/sbin/dnssec-keygen /usr/sbin/dnssec-keygen.dist
mv /usr/sbin/dnssec-signzone /usr/sbin/dnssec-signzone.dist
mv /usr/sbin/named-checkconf /usr/sbin/named-checkconf.dist
mv /usr/sbin/named-checkzone /usr/sbin/named-checkzone.dist
mv /usr/sbin/rndc-confgen /usr/sbin/named-checkzone.dist
##################################启用新安装的bind###################################
ln -s /usr/local/sbin/named /usr/sbin
ln -s /usr/local/sbin/rndc /usr/sbin
ln -s /usr/local/sbin/dnssec-keygen /usr/sbin
ln -s /usr/local/sbin/dnssec-signzone /usr/sbin
ln -s /usr/local/sbin/named-checkconf /usr/sbin
ln -s /usr/local/sbin/named-checkzone /usr/sbin
ln -s /usr/local/sbin/rndc-confgen /usr/sbin
ln -s /var/named/etc/namedb/rndc.conf /etc/rndc.conf
####################################运行bind########################################
/usr/local/sbin/named -gc /etc/namedb/named.conf &
####################################测试bind运行情况################################
www# nslookup
> w1.mydomain.com
Server: 127.0.0.1
Address: 127.0.0.1#53
Name: w1.mydomain.com
Address: 192.168.1.2
>
%%%%%%%%%%%%使DNS服务器和系统一起启动%%%%%%%%
touch /usr/local/etc/rc.d/named.sh
ee /usr/local/etc/rc.d/named.sh
增加
/usr/local/sbin/named -gc /etc/namedb/named.conf &
chmod 755 named.sh
############################设置系统服务启动顺序#####################################
cd /usr/local/etc/rc.d/
mv webmin.sh 001.webmin.sh
mv mysql.-server.sh 002.mysql.-server.sh
mv apache.sh 003.apache.sh
mv named.sh 004.named.sh
%%%%%%%%%%%%%%%%%%%%%删除无用启动脚本%%%%%%%%%%%%%%%%%%%%
rm webmin.sh
rm mysql.-server.sh
rm apache.sh
rm named.sh