MySQL数据库之关于nginx_auth_mysql认证模块
小标 2018-09-12 来源 : 阅读 924 评论 0

摘要:本文主要向大家介绍了MySQL数据库之关于nginx_auth_mysql认证模块 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助。

本文主要向大家介绍了MySQL数据库之关于nginx_auth_mysql认证模块 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助。

准备工作



下载nginx_auth_mysql的源代码

CentOS7服务器,nginx源码包(笔者使用nginx1.12.0稳定版)

支持nginx的编译环境,并安装有openssl开发包

存在libmysqlclient以及libmysqld动态库

安装流程记录
nginx_auth_mysql的源代码文件如下所示:

$ ls
config crypt_private.c  crypt_private.h  LICENSE  ngx_http_auth_mysql_module.c  README
查看一下config配置文件,其内容如下所示:

$ cat config.bak
ngx_addon_name=ngx_http_auth_mysql_module
HTTP_MODULES="$HTTP_MODULES ngx_http_auth_mysql_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_auth_mysql_module.c $ngx_addon_dir/crypt_private.c"
CORE_LIBS="$CORE_LIBS -lcrypto -lmysqlclient"
USE_MD5=YES
由上述配置文件的格式,可以看出是专门进行静态编译的第三方模块。由于在Nginx 1.9.11版本之后,已经支持以动态模块的方式来支持第三方扩展,并且由上述配置文件的内容,初步判定可以将其修改为动态模块的编译配置,因此这里将其编译为动态库,以供Nginx进行加载。

关于配置文件的修改以及动静模块的转换,参照如下两篇文章:

Converting Static Modules to Dynamic Modules

New Config Shell File

经过修改之后的config文件内容如下所示:

ngx_addon_name=ngx_http_auth_mysql_module
if test -n "$ngx_module_link"; then
        ngx_module_type=HTTP
        ngx_module_name=$ngx_addon_name
        ngx_module_srcs="$ngx_addon_dir/ngx_http_auth_mysql_module.c $ngx_addon_dir/crypt_private.c"
        ngx_module_incs="/usr/include/mysql" 
        ngx_module_libs="-lcrypto -lmysqlclient -lmysqld -L/usr/lib64/mysql"
        . auto/module
else
        HTTP_MODULES="$HTTP_MODULES ngx_http_auth_mysql_module"
        NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_auth_mysql_module.c $ngx_addon_dir/crypt_private.c"
        CORE_LIBS="$CORE_LIBS -lcrypto -lmysqlclient"
        USE_MD5=YES
fi
在编译的时候,添加上--add-dynamic-module选项,将模块添加进来。笔者这里使用的是--add-dynamic-module=/root/nginx-1.12.0/nginx_auth_mysql,其中的nginx_auth_mysql目录用于存放模块的源代码。

在进行编译的过程中,笔者遇到了如下错误:

/root/nginx-1.12.0/nginx_auth_mysql/ngx_http_auth_mysql_module.c: In function ‘ngx_http_auth_mysql_check_md5’:
/root/nginx-1.12.0/nginx_auth_mysql/ngx_http_auth_mysql_module.c:488:19: error: ‘MD5_DIGEST_LENGTH’ undeclared (first use in this function)
  u_char md5_str[2*MD5_DIGEST_LENGTH + 1];
                   ^
/root/nginx-1.12.0/nginx_auth_mysql/ngx_http_auth_mysql_module.c:488:19: note: each undeclared identifier is reported only once for each function it appears in
/root/nginx-1.12.0/nginx_auth_mysql/ngx_http_auth_mysql_module.c:489:9: error: unused variable ‘md5_digest’ [-Werror=unused-variable]
  u_char md5_digest[MD5_DIGEST_LENGTH]; 
         ^
/root/nginx-1.12.0/nginx_auth_mysql/ngx_http_auth_mysql_module.c:488:9: error: unused variable ‘md5_str’ [-Werror=unused-variable]
  u_char md5_str[2*MD5_DIGEST_LENGTH + 1];
从上面的报错结果来看,可以发现,是MD5_DIGEST_LENGTH没有定义,甚是奇怪……
经过排查,在ngx_http_auth_mysql_module.c文件里面,所引用的头文件当中,似乎确实并未包含MD5_DIGEST_LENGTH的定义,ngx_md5.h的全部内容如下所示:

$ cat ngx_md5.h

/*
 * Copyright (C) Igor Sysoev
 * Copyright (C) Nginx, Inc.
 */


#ifndef _NGX_MD5_H_INCLUDED_
#define _NGX_MD5_H_INCLUDED_


#include <ngx_config.h>
#include <ngx_core.h>


typedef struct {
    uint64_t  bytes;
    uint32_t  a, b, c, d;
    u_char    buffer[64];
} ngx_md5_t;


void ngx_md5_init(ngx_md5_t *ctx);
void ngx_md5_update(ngx_md5_t *ctx, const void *data, size_t size);
void ngx_md5_final(u_char result[16], ngx_md5_t *ctx);


#endif /* _NGX_MD5_H_INCLUDED_ */
通过对比一个老版本的nginx源代码,发现确实有所不同,下面的是老版本的nginx的头文件,可以看出,引用了openssl的md5头文件定义:

......
......
#if (NGX_HAVE_MD5)

#if (NGX_HAVE_OPENSSL_MD5_H)
#include <openssl/md5.h>
#else
#include <md5.h>
#endif
......
......
通过查阅md5头文件,得到其定义的值为16,因此,在nginx-1.12.0的ngx_md5.h里面,添加如下定义:

#define MD5_DIGEST_LENGTH 16
保存之后,重新编译,成功通过。
编译完成之后,在objs文件夹里面生成了所需要的模块:

$ ls objs/ | grep auth
ngx_http_auth_mysql_module_modules.c
ngx_http_auth_mysql_module_modules.o
ngx_http_auth_mysql_module.so
将ngx_http_auth_mysql_module.so拷贝到对应的模块目录里面,至此完成了初步的模块安装任务。

配置内容

在nginx.conf文件中的main段里面添加如下一行,代表需要加载该模块:

load_module modules/ngx_http_auth_mysql_module.so;
笔者使用默认主机/auth路径下的auth.html进行测试:

$ cat /opt/nginx/html/auth/auth.html 
<h1>auth page</h1>
在该模块的README文档中,详细介绍了模块使用的配置参数,如下所示:

== CONFIGURATION ==
It is activated by adding several configuration options:

auth_mysql_realm: HTTP basic authentiaction realm. Required.

auth_mysql_host: the host of the MySQL server. Default is 127.0.0.1.

auth_mysql_port: on which port to connect to the MySQL server. Default is 3306.

auth_mysql_user: username for connection to the MySQL server. Default is root.

auth_mysql_password: password for connection to the MySQL server. Default is empty.

auth_mysql_database: name of the database. Required.

auth_mysql_table: name of the table, which holds the user record.
You can have more than one table separated by comas. Default is users.

auth_mysql_user_column: name of the username column. Default is username.

auth_mysql_password_column: name of the password column. Default is password.

auth_mysql_conditions: Additional SQL conditions. They will be placed after and AND.
Default is empty string.

auth_mysql_group_table: name of the table, which holds the groups information.
You can have more than one table separated by comas. Default is the users table.

auth_mysql_group_column: name of the group name column. Default is name.

auth_mysql_group_conditions: Additional SQL conditions applied only in group queries.
They will be placed after an AND. Default is empty string.

auth_mysql_encryption_type: the format of the password field. Should be one of:



none: the password is stored in plaintext in the database;

md5: in the database is stored a md5 hash of the password;

phpass: a portable php hash of the password is stored. See:
//www.openwall.com/phpass/ for more information.
The default is md5.

auth_mysql_allowed_users: whitespace delimited list of allowed users.

auth_mysql_allowed_groups: whitespace delimited list of allowed groups.
If both allowed_users and allowed_groups are defined, either of them has to satisfied.

笔者这里使用mysql数据库创建认证用户的内容如下所示,创建nginx数据库,在nginx数据库里面添加一个nginx_auth的数据表,存放user字段和password字段,并且password字段用md5进行加密:

$ mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 3337
Server version: 5.5.44-MariaDB MariaDB Server

Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

Type ‘help;‘ or ‘\h‘ for help. Type ‘\c‘ to clear the current input statement.

MariaDB [(none)]> use nginx;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [nginx]> show tables;
+-----------------+
| Tables_in_nginx |
+-----------------+
| nginx_auth      |
+-----------------+
1 row in set (0.00 sec)

MariaDB [nginx]> select * from nginx_auth;
+------+----------------------------------+
| user | password                         |
+------+----------------------------------+
| tom  | d077f244ddf8r70e5ea758bd8352fcd8 |
+------+----------------------------------+
1 row in set (0.00 sec)
在nginx.conf配置文件当中使用的配置如下所示:

......
......
location /auth {
            root /opt/nginx/html;
            index auth.html;
            auth_mysql_realm "authentication";
            auth_mysql_host "192.168.5.181";
            auth_mysql_port "3306";
            auth_mysql_user "nginx";
            auth_mysql_password "nginx";
            auth_mysql_database "nginx";
            auth_mysql_table "nginx_auth";
            auth_mysql_user_column "user";
            auth_mysql_password_column "password";
            auth_mysql_encryption_type "md5";
        }
......
......
reload一下nginx,利用curl命令进行测试,得到的结果如下所示,可见模块正常运行:

$ curl -u tom:right_password //192.168.5.181/auth/
<h1>auth page</h1>


$ curl -u tom:wrong_password //192.168.5.181/auth/ 
<html>
<head><title>401 Authorization Required</title></head>
<body bgcolor="white">
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.12.0</center>
</body>
</html>


其他事项
在httpd上面使用的mod_auth_mysql模块,自带了aes加密算法,但是在nginx上面使用的此模块,默认却没有添加该项功能,不过该模块的作者在README中提到:



== WRITING A NEW ECNRYPTION TYPE ==
Add an entry in the ngx_http_auth_mysql_enctypes array. It has to be a struct
with two elements:

ngx_str_t id

The name under which it should be referenced in the config file



ngx_uint_t (*checker)(ngx_http_request_t *r, ngx_str_t sent_password, ngx_str_t actual_password)

A function, which given the request (mostly used for logging and memory allocation through its r->pool),
the password sent by the user and the password in the database has to determine whether they match.
If they match it should return NGX_OK, if they don’t it should return NGX_DECLINED. If other error
occures, it should log it and return NGX_ERR.
Currently salts aren‘t supported, but if there are schemes, which require them it is quite easy.

Questions/patches may be sent to Nikolay Bachiyski, nikolay@automattic.com

似乎只能等待牛人进行二次开发了......    

本文由职坐标整理并发布,希望对同学们学习MySQL有所帮助,更多内容请关注职坐标数据库MySQL数据库频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程