为Visual SVN Server添加认证用户IP功能

为Visual SVN Server添加认证用户IP功能

背景

内网环境下,某位大佬觉得Visual SVN Server的安全性不够,要求用户只能在指定的一个或几个IP上登录???

方案

内网环境下,Visual SVN Server使用https进行通信,有两种可以实现IP与用户绑定:

  • 做一个网关,用户访问SVN时,都通过网关进行访问,然后就可以在网关上进行IP与用户名校验了。由于使用的是https通信,网关配置https并转发到SVN Server比较麻烦,网关方式不进行实现。
  • 写一个apache module,在处理请求之前进行拦截校验

从SVN请求中提取用户名

SVN的每次请求都会带有AuthorizationHeader参数,其内容就是使用Base64编码的用户名和密码,其格式为:“Basic Base64(用户名:密码)”。因此,只需要解析Authorization字段就可以获取到用户名。无论是使用添加网关还是添加apache module,都比较容易取得Authorization参数。

主要实现

apache module实际上是一个动态库,apache httpd在启动的时候会动态加载该动态库,加载配置参数后正式进行工作,以下是主要模块的主要代码:

#include <stdio.h>
#include <http_protocol.h>
#include <httpd.h>
#include <http_config.h>
#include <apr_want.h>
#include <ap_config.h>
#include <apr_base64.h>
#include "host_bind_filter/host_bind_filter.h"

module AP_MODULE_DECLARE_DATA auth_host_bind_module;

static int auth_host_bind_handler(request_rec *r) {
    int len = 0;
    char* user = NULL;
    const char* authorization = apr_table_get(r->headers_in, "Authorization");
    // Basic Base64(用户名:密码)
    if(authorization != NULL && (authorization = strstr(authorization, "Basic ")) != NULL) {
        authorization += 6;// 跳过 "Basic ",然后进行base64解密

        len = apr_base64_decode_len(authorization);
        user = (char*)malloc(len);
        apr_base64_decode(user, authorization);
        // 通过user_host_filter函数进行用户名IP校验,其实现完整Demo.
        int res = user_host_filter(user, r->useragent_ip);
        free(user);
        show_request("host=%s, ip=%s", r->useragent_host, r->useragent_ip);
        if (res != 0) { // 如果校验不通过时,直接截断HTTP调用链
            ap_rprintf(r, "user cannot log in on the host[%s]", r->useragent_ip); // 写入返回信息
            return OK; // 返回OK,请求就截断了
        }
    } 

    return DECLINED; // 没有authorization参数或校验通过时,返回DECLINED,请求会继续进行,让Visual SVN Server处理。
}

static void register_hooks(apr_pool_t *p) {
    ap_hook_handler(auth_host_bind_handler, NULL, NULL, APR_HOOK_REALLY_FIRST); // APR_HOOK_REALLY_FIRST 表示在最前面进行IP认证处理。
}

typedef struct context_host_filename_config {
    char filename[1024];
} context_host_filename_config;

/* 读取设置字符串方法 */
static const char *set_context_host_filename(cmd_parms *cmd,
                                       void *mconfig,
                                       const char *name)
{
    context_host_filename_config *conf = (context_host_filename_config *) mconfig;
    strcpy_s(conf->filename, sizeof(conf->filename), name);
    load_context_host(name); // 加载用户IP绑定表,更好的方式是通过读取数据库来进行校验,这里使用cvs文件来绑定
    return NULL;
}

static const command_rec auth_context_host_filename_cmd[] =
        {
                AP_INIT_TAKE1("HostBindFileName", set_context_host_filename,   NULL, OR_FILEINFO,
                              "set HostBindFileName."),
                { NULL }
        };

/* init per dir */
static void *create_context_host_filename_config(apr_pool_t *p, char *d)
{
    context_host_filename_config *conf = (context_host_filename_config *)apr_pcalloc(p, sizeof(*conf));
    if(conf == NULL) return NULL;
    memset(conf->filename, 0, sizeof(conf->filename));
    return conf;
}

/* module structure */
module AP_MODULE_DECLARE_DATA
auth_host_bind_module = {
        STANDARD20_MODULE_STUFF,
        create_context_host_filename_config, /* dir config creater */
        NULL,                                /* dir merger — default is to override */
        NULL,                                /* server config */
        NULL,                                /* merge server configs */
        auth_context_host_filename_cmd,      /* command apr_table_t */
        register_hooks                       /* register hooks */
};

模块使用

  1. 编译成功后,将生成的mod_auth_host_bind.dll重命名为mod_auth_host_bind.so,将其拷贝到${svn_root}/bin目录中, ${svn_root}为Visrual SVN Server的安装目录,默认路径为:C:\Program Files\VisualSVN Server

  2. 修改${svn_root}/conf/httpd.conf配置文件,在第一个LoadModule***上方添加一行:

LoadModule auth_host_bind_module bin/mod_auth_host_bind.so
  1. 修改${svn_root}/conf/httpd.conf配置文件,在<Location />节点下添加绑定文件配置:
<Location />
  AuthName "VisualSVN Server"
  AuthType Basic
  AuthBasicProvider file
  AuthUserFile "E:/Repositories/htpasswd"
  HostBindFileName "E:/Repositories/HostBind.csv" # 这是添加的,其他的保持不变
  Require valid-user
</Location>
  1. 配置完成后,重启一下SVN Server服务
  2. HostBind.csv文件结构
    每一行作为一条记录,其格式为:用户名,IP绑定IP地址。允许一个用户绑定多个IP,同一个用户添加多行即可实现。

示例:

D00371,192.168.1.103
D00371,192.168.1.102

最后

Apache Module完整Demo源码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值