guanzi September 22nd, 2020 at 09:53 pm

    zsh:no matches found 问题解决 解决方法: ~/.zshrc 文件加入: setopt no_nomatch 之后,更新配置 source ~/.zshrc

    guanzi September 22nd, 2020 at 09:40 pm

    //../ญ๊xian.gif  گگ罐گ 21:29:44
    @老虎会游泳 ping 命令

    //../ญ๊xian.gif  گگ罐گ 21:29:52
    安装包

    //../ญ๊xian.gif  گگ罐گ 21:29:54

    //../ญ๊xian.gif  گگ罐گ 21:29:58
    是什么

    //../ญ๊xian.gif  گگ罐گ 21:30:12

    老虎会游泳 21:30:34
    https://www.debian.org/distrib/packages#search_contents
    去这里找

    //../ญ๊xian.gif  گگ罐گ 21:33:21

    //../ญ๊xian.gif  گگ罐گ 21:33:35
    哪一个

    老虎会游泳 21:34:57
    apt list | grep 已安装 | grep ping

    //../ญ๊xian.gif  گگ罐گ 21:35:50
    怎么重新设置他

    //../ญ๊xian.gif  گگ罐گ 21:37:38
    我卸载重装了

    guanzi September 22nd, 2020 at 09:40 pm

    ss-tproxy stop; ss-tproxy flush-postrule; ss-tproxy flush-dnscache

    guanzi August 11th, 2020 at 04:52 pm

    @爱学习的UncleLI 执行这条命令可以修复声音问题:
    echo -e 'pcm.!default pulsenctl.!default pulse' | sudo tee /etc/asound.conf
    来自 https://www.youtube.com/watch?v=9K9b2tXLGrw

    guanzi August 10th, 2020 at 07:19 pm

    https://www.danieltufvesson.com/makeresolvedeb
    DaVinci Resolve视频编辑软件

    guanzi August 9th, 2020 at 08:37 pm
    guanzi August 6th, 2020 at 10:40 pm
    guanzi August 6th, 2020 at 10:40 pm
    guanzi August 3rd, 2020 at 08:36 am

    1 如何查看日志? 遇到问题不要慌,排查日志第一步。 # 系统实时日志 journalctl -n 100 -f # 搜索警告日志 journalctl | grep 'level=warning' # 根据可能关键词搜索 journalctl | grep 'Networking will not work' 或者 journalctl | grep 'IPv4'

    guanzi August 3rd, 2020 at 08:36 am

    2.如何解决问题? 从原因可以看到,IP转发被禁用,导致网络不通,那么如何开启内核IP转发呢,如下: 备注:解决问题其实最容易,根据自己的知识google就行了,找出原因往往才是最难的,这里就不详细说明了。 # 2.1 会话 echo 1 > /proc/sys/net/ipv4/ip_forward # 2.2 永久 vi /etc/sysctl.conf 添加如下代码: net.ipv4.ip_forward=1 # 2.3 检查 重启network服务 systemctl restart network 查看是否修改成功 sysctl net.ipv4.ip_forward

    guanzi July 31st, 2020 at 08:31 pm

    【活跃】猎人 20:16:55
    更建议debian 不是很建议centos

    【群主】疯子手机号888866 20:17:12
    因为容器会共享基础镜像的

    【群主】疯子手机号888866 20:17:22
    一个debian可能占用80M,你开10个还是80M

    【活跃】穴儿 20:18:44
    docker 咋保存啊 想换服务的时候复原。。。

    【群主】疯子手机号888866 20:19:16
    然而alpine因为缺少各种依赖,你在每个容器中安装依赖,这些东西不共享的,占用的空间你容器越多反而比debian更多。

    【群主】疯子手机号888866 20:19:58
    如果你只有golang程序可能alpine是最好的选择,因为golang基本都没啥依赖,如果是其他的话果断选个依赖包全的镜像

    【群主】疯子手机号888866 20:20:11
    比如aite.xyz的基础镜像就是golang:alpine

    【群主】疯子手机号888866 20:20:20
    但是php-fpm之类的我多选择了debian

    【群主】疯子手机号888866 20:20:30
    根据实际情况选择基础镜像,而不是啥都不知道就上alpine

    【群主】疯子手机号888866 20:20:41
    比如postgres的alpine镜像有locales区域问题

    guanzi July 28th, 2020 at 10:10 pm
    guanzi July 27th, 2020 at 12:56 am
    guanzi July 27th, 2020 at 12:54 am

    guanzi July 27th, 2020 at 12:31 am

    funsion 360
    实体建模

    guanzi July 25th, 2020 at 11:27 am

    Nordic Semiconductor nRF52832

    guanzi July 16th, 2020 at 05:54 pm

    占位符呀 不同的符号代表不同的类型
    bool string int float32 等 %s %d %t %f 等

    guanzi July 15th, 2020 at 11:04 pm

    王道长 22:02:48
    问个问题哈 md5.Sum() 我想用变量str来替换 md5,那这个函数该怎么写呢?

    北京-dotdotdot 22:11:53
    s:=fmt.Sprintf("%x",m)

    guanzi July 15th, 2020 at 09:18 pm


    mmmm

    guanzi July 12th, 2020 at 09:12 pm
    guanzi July 12th, 2020 at 09:12 pm

    گگ罐گ‮‮‮‮‮‮‮‮‮‮‮‮‮‮//./xian.
    克隆了.
    @گگ罐گ‮‮‮‮‮‮‮‮‮‮‮‮‮‮//./xian. 照着https://blog.csdn.net/qq_27637465/article/details/106531334写的
    用github action编译了个openssl 1.1.1g for android

    guanzi July 10th, 2020 at 11:17 am

    您查询的关键词仅在网页标题或指向此网页的链接中出现。
    如果打开速度慢,可以尝试快速版;如果想更新或删除快照,可以投诉快照。

    百度和网页 http://bbs.xiuno.com/thread-150118.htm 的作者无关,不对其内容负责。百度快照谨为网络故障时之索引,不代表被搜索网站的即时页面。
    插件
    首页
    程序发布
    安装
    BUG
    插件
    模板
    WEB开发
    XiunoPHP
    测试
    交流
    IP查询
    搜索
    登录
    插件
    LDAP活动目录认证插件

    LDAP活动目录认证插件 功能增强 文档教程
    1Bill 2019-1-20 2830

    由于公司业务发展需要,在原认证基础上增加LDAP认证。实现统一账户认证。

    目前公司已经把邮件、网盘、GIT、禅道、一些不能使用认证的应用比如(elasticsearch,netdata)通过nginx 的auth_request 与活动目录认证集成。

    现在分享下:这个插件,程序简单粗暴。

    至于 活动目录用户则是通过 shell脚本定时写入到数据库,保证用户信息同步。 这里就不提供了。

    欢迎大家一起交流。。。。

    LDAP配置信息采用 cache。

    通过 kv_get('ldap_settiings') 获取参数。

    新增模型: ./model/ldap.func.php

    <?php

    /**

    Created by PhpStorm.User: bill <benma9@qq.com>Date: 2019/1/20Time: 2:43 AM
    */

    /**

    返回配置参数@param string $key@return
    */

    function config_get($key)
    {

    global $ldap_config;
    $ldap_config=kv_get('ldap_settings');
    if($ldap_config) {
        return isset($ldap_config[$key])?$ldap_config[$key] : $value;
    }else {
        return '';
    }

    }

    /**

    Return true if the parameter is an empty string or a stringcontaining only whitespace, false otherwise@param string $p_var string to test@return bool@access public
    */

    function is_blank( $p_var ) {

    $p_var = trim( $p_var );
    $str_len = strlen( $p_var );
    if( 0 == $str_len ) {
        return true;
    }
    return false;

    }

    /**

    Connect and bind to the LDAP directory@param string $p_binddn@param string $p_password@return resource or false
    */

    function ldap_connect_bind( $p_binddn = '', $p_password = '' ) {

    if( !extension_loaded( 'ldap' ) ) {
        message(1,'请确认已经安装php-ldap?');
    }
    
    $t_ldap_server = config_get( 'ldap_server' );
    
    # Connect to LDAP server
    $t_ds = @ldap_connect( $t_ldap_server );
    
    if ( $t_ds !== false && $t_ds > 0 ) {
        $t_protocol_version = config_get( 'ldap_protocol_version' );
    
        if( $t_protocol_version > 0 ) {
            $t_result = @ldap_set_option( $t_ds, LDAP_OPT_PROTOCOL_VERSION, $t_protocol_version );
            if( !$t_result ) {
                echo ( $t_ds );
            }
        }
    
        # Set referrals flag.
        $t_follow_referrals = 0 == config_get( 'ldap_follow_referrals' );
        $t_result = @ldap_set_option( $t_ds, LDAP_OPT_REFERRALS, $t_follow_referrals );
        if( !$t_result ) {
            echo( $t_ds );
        }
    
        # If no Bind DN and Password is set, attempt to login as the configured
        #  Bind DN.
        if( is_blank( $p_binddn ) && is_blank( $p_password ) ) {
            $p_binddn = config_get( 'ldap_bind_dn', '' );
            $p_password = config_get( 'ldap_bind_passwd', '' );
        }
    
        if( !is_blank( $p_binddn ) && !is_blank( $p_password ) ) {
            $t_br = @ldap_bind( $t_ds, $p_binddn, $p_password );
        } else {
            # Either the Bind DN or the Password are empty, so attempt an anonymous bind.
            $t_br = @ldap_bind( $t_ds );
        }
    
    }
    
    return $t_ds;

    }

    /**

    Escapes the LDAP string to disallow injection.
    *@param string $p_string The string to escape.@return string The escaped string.
    */

    function ldap_escape_string( $p_string ) {

    $t_find = array( '\\', '*', '(', ')', '/', "\x00" );
    $t_replace = array( '\5c', '\2a', '\28', '\29', '\2f', '\00' );
    
    $t_string = str_replace( $t_find, $t_replace, $p_string );
    
    return $t_string;

    }

    /**

    Gets the value of a specific field from LDAP given the user nameand LDAP field name.
    *@todo Implement caching by retrieving all needed information in one query.@todo Implement logging to LDAP queries same way like DB queries.
    *@param string $p_username The user name.@param string $p_field The LDAP field name.@return string The field value or null if not found.
    */

    function ldap_get_field_from_username( $p_username, $p_field ) {

    $t_ldap_organization    = config_get( 'ldap_organization' );
    $t_ldap_root_dn         = config_get( 'ldap_root_dn' );
    $t_ldap_uid_field     = config_get( 'ldap_uid_field' );
    
    $c_username = ldap_escape_string( $p_username );
    
    # Bind
    $t_ds = @ldap_connect_bind();
    if ( $t_ds === false ) {
        return null;
    }
    
    # Search
    $t_search_filter        = "(&$t_ldap_organization($t_ldap_uid_field=$c_username))";
    $t_search_attrs         = array( $t_ldap_uid_field, $p_field, 'dn' );
    
    $t_sr = @ldap_search( $t_ds, $t_ldap_root_dn, $t_search_filter, $t_search_attrs );
    if ( $t_sr === false ) {
        ldap_unbind( $t_ds );
        return null;
    }
    
    # Get results
    $t_info = ldap_get_entries( $t_ds, $t_sr );
    if ( $t_info === false ) {
        return null;
    }
    
    # Free results / unbind
    ldap_free_result( $t_sr );
    ldap_unbind( $t_ds );
    
    # If no matches, return null.
    if ( count( $t_info ) == 0 ) {
        return null;
    }
    
    # Make sure the requested field exists
    if( is_array($t_info[0]) && array_key_exists( $p_field, $t_info[0] ) ) {
        $t_value = $t_info[0][$p_field][0];
    } else {
        return null;
    }
    
    return $t_value;

    }

    /**

    Authenticates an user via LDAP given the username and password.
    *@param string $p_username The user name.@param string $p_password The password.@return true: authenticated, false: failed to authenticate.
    */

    function ldap_authenticate_by_username( $p_username, $p_password ) {

        $c_username = ldap_escape_string( $p_username );
    
        $t_ldap_organization = config_get( 'ldap_organization' );
        $t_ldap_root_dn = config_get( 'ldap_root_dn' );
    
        $t_ldap_uid_field = config_get( 'ldap_uid_field', 'uid' );
        $t_search_filter = "(&$t_ldap_organization($t_ldap_uid_field=$c_username))";
        $t_search_attrs = array(
            $t_ldap_uid_field,
            'dn',
        );
    
        # Bind
        try {
            $t_ds = ldap_connect_bind();
        } catch  (Exception $e) {
            message(1,'活动目录设置参数可能不对,请检查?');
        }
    
        # Search for the user id
        $t_sr = ldap_search( $t_ds, $t_ldap_root_dn, $t_search_filter, $t_search_attrs );
        if ( $t_sr === false ) {
            ldap_unbind( $t_ds );
        }
    
        $t_info = @ldap_get_entries( $t_ds, $t_sr );
        if ( $t_info === false ) {
            ldap_free_result( $t_sr );
            ldap_unbind( $t_ds );
        }
    
        $t_authenticated = false;
    
        if ( $t_info['count'] > 0 ) {
            # Try to authenticate to each until we get a match
            for ( $i = 0; $i < $t_info['count']; $i++ ) {
                $t_dn = $t_info[$i]['dn'];
                # Attempt to bind with the DN and password
                if ( @ldap_bind( $t_ds, $t_dn, $p_password ) ) {
    
                    $t_authenticated = true;
                    break;
                }
            }
        }
    
        ldap_free_result( $t_sr );
        ldap_unbind( $t_ds );
    
    return $t_authenticated;

    }

    控制器

    覆盖 ./route/user.php (login部分重写,增加LDAP认证方法,LDAP认证不通过,则继续使用原认证),此模版会与 xn_mobile冲突,如有手机登录需求,请自行合并。

    elseif($action == 'login') {

    // hook user_login_get_post.php

    if($method == 'GET') {

      // hook user_login_get_start.php
    
      $referer = user_http_referer();
    
      $header['title'] = lang('user_login');
    
      // hook user_login_get_end.php
    
      include _include(APP_PATH.'view/htm/user_login.htm');
    

    } else if($method == 'POST') {

      // hook user_login_post_start.php

    // LDAP认证部分
    include APP_PATH.'plugin/socialbird_ldap/model/ldap.func.php';

    $email = param('email'); // 邮箱或者手机号 / email or mobile
    $password = param('password');
    empty($email) AND message('email', lang('email_is_empty'));

    if(is_email($email, $err)) {
    $_user = user_read_by_email($email);

    empty($_user) AND message('email', lang('email_not_exists'));
    } else {
    $_user = user_read_by_username($email);
    empty($_user) AND message('email', lang('username_not_exists'));
    }

    if (ldap_authenticate_by_username($_user['username'],$password))
    {
    user_update($_user['uid'], array('login_ip' => $longip, 'login_date' => $time, 'logins+' => 1));
    $uid = $_user['uid'];
    $_SESSION['uid'] = $uid;
    user_token_set($_user['uid']);
    message(0, lang('user_login_successfully'));
    }

    $password = md5($password);

    // LDAP认证结束,注释掉以下代码,
    // 同时覆盖 view/htm/user_login.html文件,
    // 注释掉 70行代码 //postdata.password = $.md5(postdata.password);
    // 防止密码 md5加密,活动目录认证则失败!
    // 账户同步脚本 可以联系作者 bill<benma9@qq.com> 获得。

    // $email = param('email'); // 邮箱或者手机号 / email or mobile
    // $password = param('password');
    // empty($email) AND message('email', lang('email_is_empty'));
    // if(is_email($email, $err)) {
    // $_user = user_read_by_email($email);
    // empty($_user) AND message('email', lang('email_not_exists'));
    // } else {
    // $_user = user_read_by_username($email);
    // empty($_user) AND message('email', lang('username_not_exists'));
    // }

      !is_password($password, $err) AND message('password', $err);
      $check = (md5($password.$_user['salt']) == $_user['password']);
      // hook user_login_post_password_check_after.php
      !$check AND message('password', lang('password_incorrect'));
    
      // 更新登录时间和次数
      // update login times
      user_update($_user['uid'], array('login_ip'=>$longip, 'login_date' =>$time , 'logins+'=>1));
    
      // 全局变量 $uid 会在结束后,在函数 register_shutdown_function() 中存入 session (文件: model/session.func.php)
      // global variable $uid will save to session in register_shutdown_function() (file: model/session.func.php)
      $uid = $_user['uid'];
    
      $_SESSION['uid'] = $uid;
    
      user_token_set($_user['uid']);
    
      // hook user_login_post_end.php
    
      // 设置 token,下次自动登陆。
    
      message(0, lang('user_login_successfully'));
    

    }
    管理: 覆盖./admin/index.php (login部分重写)

    if($action == 'login') {

    // hook admin_index_login_get_post.php
    
    if($method == 'GET') {
    
        // hook admin_index_login_get_start.php
    
        $header['title'] = lang('admin_login');
    
        include _include(ADMIN_PATH."view/htm/index_login.htm");
    
    } else if($method == 'POST') {
    
        // hook admin_index_login_post_start.php
    
        include APP_PATH.'plugin/socialbird_ldap/model/ldap.func.php';
    
        $password = param('password');
    
        if (!ldap_authenticate_by_username($user['username'],$password))
        {
            $password = md5($password);
    
            if(md5($password.$user['salt']) != $user['password']) {
                xn_log('password error. uid:'.$user['uid'].' - ******'.substr($password, -6), 'admin_login_error');
                message('password', lang('password_incorrect'));
            }
        }
    
        admin_token_set();
    
        xn_log('login successed. uid:'.$user['uid'], 'admin_login');
    
        // hook admin_index_login_post_end.php
    
        message(0, jump(lang('login_successfully'), '.'));
    
    }
    

    }
    模版view:

    覆盖 ./view/htm/user_login.htm ,注释掉70行,防止md5加密导致ldap认证无法通过

    覆盖 ./admin/view/htm/index_login.htm, 注释

    //postdata.password = $.md5(postdata.password);

    收藏 1
    收藏的用户(1) X
    正在加载信息~
    最新回复 (5)

    axiuno 2019-1-20
    引用 2楼
    nice

    senlo 2019-1-20
    引用 3楼
    优秀

    452010152 2019-1-20
    引用 4楼
    给力

    达无谓惧 2019-2-14
    引用 5楼
    特别感谢,近期正好有此方面的需要,但是目前在官方插件库里并没有看到此插件,请问能否提供一下下载路径吗?谢谢

    十品香茗爱观音 2019-3-1
    引用 6楼
    感谢楼主的无私分享,这个插件哪里可以下载呢?

    返回
    发新帖

    1Bill
    主题数
    1 帖子数
    1 精华数
    1 注册排名
    21369
    关键词
    搜索

    Powered by Xiuno BBS 4.0.4 - 北京若深科技有限公司
    Processed: 0.003, SQL: 8 / 京ICP备17008605号-1

    guanzi July 9th, 2020 at 07:21 pm
    guanzi July 6th, 2020 at 05:27 pm
    guanzi July 4th, 2020 at 12:34 pm

    hu60.cn

    guanzi July 4th, 2020 at 12:34 pm

    hu60.cn

    guanzi July 4th, 2020 at 12:33 pm

    guanzi July 4th, 2020 at 12:33 pm

    guanzi July 4th, 2020 at 12:33 pm

    guanzi June 13th, 2020 at 12:35 am

    guanzi June 13th, 2020 at 12:35 am

    guanzi June 13th, 2020 at 12:35 am

    guanzi June 13th, 2020 at 12:34 am
    guanzi June 13th, 2020 at 12:34 am
    guanzi June 13th, 2020 at 12:34 am
    guanzi June 13th, 2020 at 12:28 am

    天蓝的博客https://xn--rssy03h.cn/

    guanzi June 12th, 2020 at 11:20 am

    新的一天

联系方式

关于我

  • 来自南部的一个小城市,个性不张扬,讨厌随波逐流。