nginx basic auth配置踩坑记

2023-11-07

nginx的basic auth配置由ngx_http_auth_basic_module模块提供,对HTTP Basic Authentication协议进行了支持,用户可通过该配置设置用户名和密码对web站点进行简单的访问控制。

basic auth配置示例:

location / {
    auth_basic           "closed site";
    auth_basic_user_file conf/htpasswd;
}

说明:

  • auth_basic可设置为off或其它字符串,为off时表示不开启密码验证
  • auth_basic_user_file 为包含用户名和密码的文件,文件内容如elastic:YsEm9Tb4.RwB6

踩坑的地方就是这个密码,官方文档里对支持的密码类型进行了说明:

  • 采用系统函数crypt()加密的密码;可通过htpasswd命令或者openssl passwd命令生成
  • 通过Apache提供的基于MD5的变种加密算法(apr1),同样可通过htpasswd或者openssl passwd命令生成
  • 以“{scheme}data”格式表示的加密后的密码,RFC
    2307中有对该格式的密码标准进行了说明。其中scheme指的是加密算法,nginx支持的scheme有PLAIN, SHA,
    SSHA算法。

使用htpasswd或者openssl passwd命令生成的密码固然可以使得配置生效,nginx能够正常地进行密码安全校验,如果密码类型不支持, 则nginx或报错:

crypt_r() failed (22: Invalid argument)

但是因为业务的需要,我们要用代码生成nginx的配置并下发配置到每个云主机中,之后拉起nginx进程。项目代码使用go语言编写,所以需要找一个对应的函数或者库生成nginx支持的密码。

go语言生成nginx支持的密码

在进行自动生成密码开发之前,思考了一下大概有三种方案可以实现:

  • 项目服务器上安装htpasswd工具或openssl, 通过代码执行本地命令生成加密密码
  • 直接调用Linux系统函数crypt()加密密码
  • 使用go标准库crypto加密密码

首先,第一种方式是不太可取的,因为需要强依赖服务器环境,所以直接pass。下面看第二种和第三种方式的具体实现。

直接调用系统函数crypt()

Linux的crypt函数有两个参数,函数定义为:

char *crypt(const char *key, const char *salt);

其中参数key为需要加密的内容,salt参数有两种类型:

  • 长度为2的字符串,取值范围为[a-zA-Z0-9./],如果超过两位会被忽略,并且只能支持最长8位的key,如果key超过8位,则8位之后的会被忽略
  • $id$salt$encrypted 格式,用于支持其它的加密算法, id表示算法类型,具体取值有:

    ID  | Method
       ─────────────────────────────────────────────
       1   | MD5
       2a  | Blowfish (not in mainline glibc; added in some
           | Linux distributions)
       5   | SHA-256 (since glibc 2.7)
       6   | SHA-512 (since glibc 2.7)
    

go语言中可以通过import "C"方式直接调用c语言的库函数,下面是封装crypt函数的具体实现:

package crypt

/*
#define _GNU_SOURCE
#include <unistd.h>
*/
import "C"

import (
    "sync"
    "unsafe"
)

var (
    mu sync.Mutex
)


func Crypt(pass, salt string) (string, error) {
    c_pass := C.CString(pass)
    defer C.free(unsafe.Pointer(c_pass))

    c_salt := C.CString(salt)
    defer C.free(unsafe.Pointer(c_salt))

    mu.Lock()
    c_enc, err := C.crypt(c_pass, c_salt)
    mu.Unlock()

    if c_enc == nil {
        return "", err
    }
    defer C.free(unsafe.Pointer(c_enc))

    return C.GoString(c_enc), err
}

生成密码的具体实现:

func main() {
    des, err := crypt.Crypt("Elastic123", "in")
    if err != nil {
        fmt.Errorf("error:", err)
        return
    }

    sha512, err := crypt.Crypt("Elastic123", "$6$SomeSaltSomePepper$")
    if err != nil {
        fmt.Errorf("error:", err)
        return
    }

    fmt.Println("des:", des)
    fmt.Println("SHA512:", sha512)
}

经过实测,上述通过调用crypt函数生成nginx支持的加密密码实际可用,但是需要注意的是如果密码长度超过8位,则salt参数只能选择$id$salt$encrypted类型,在测试过程中就是因为踩了这点坑导致nginx只能校验密码的前8位,无语。

因为在编写go代码过程中调用了C函数库,这种方式也需要依赖服务器所处环境,因此最好的方式是采用go标准库中的函数对密码进行加密。

使用crypto函数库

go的crypto标准库封装了很多中加密算法,采用SHA加密算法进行密码加密的代码如下:

package util

import (
    "crypto/sha1"
    "encoding/base64"
)

func GetSha(password string) string {
    s := sha1.New()
    s.Write([]byte(password))
    passwordSum := []byte(s.Sum(nil))
    return base64.StdEncoding.EncodeToString(passwordSum)
}

测试过程中通过调用GetSha()函数生成了对密码加密的字符串,但是直接配置在nginx的conf/htpasswd文件中,reload nginx配置后测试验证密码是否生效,结果还是报错,原来如前文所述,SHA加密的密码必须带有“{SHA}”前缀才可以,再次修改配置后经过验证,成功地用代码生成了nginx支持的对密码加密的字符串。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

nginx basic auth配置踩坑记 的相关文章

随机推荐

  • UI自动化截图之chrome&Firefox篇

    在web的UI自动化中 小伙伴们经常遇到的一个问题是 IE的截屏非常好实现 一个save screenshot即可满足 而chrome和Firefox的全屏截图就让人很是头疼了 今天作者来给大家分享下自己实例中使用的chrome和Firef
  • Python/练习题

    1 执行 Python 脚本的两种方式 交互方式 命令行 Windows操作系统下 快捷键cmd 输入 python 启动交互式python解释器 文件方式 python文件 2 简述位 字节的关系 一个二进制位是计算机里最小表示单元 一个
  • 《第1阶段》——边界值分析法

    Video Number 091820 学习时间 4月23日 091820 边界值分析法 对输入或输出的边界值进行测试的一种黑盒测试设计方法 通常是作为等价类划分法的补充 这种情况下 其测试用例来自等价类的边界 不是从某等价类中随便挑一个作
  • quasar在axios.js中使用响应拦截器不能正常跳转解决

    问题描述 提示 这里描述具体问题 在quasar框架中的 src boot axios js中使用router push 无效 router index js import route from quasar wrappers import
  • 最近用matplotlib绘制了一张天气折线图,分享给大家

    usr bin env python coding utf 8 作者 志在星空 时间 2022 04 04 19 38 文件名 绘制折线图 py 软件 PyCharm import matplotlib pylab as pyl impor
  • 机器学习中的范数规则化之(一)L0、L1与L2范数

    机器学习中的范数规则化之 一 L0 L1与L2范数 zouxy09 qq com http blog csdn net zouxy09 今天我们聊聊机器学习中出现的非常频繁的问题 过拟合与规则化 我们先简单的来理解下常用的L0 L1 L2和
  • 某验滑块js逆向 - 底图还原

    注 本篇博客仅供学习使用 请勿用做其他商业用途 如有侵权 请联系本菜鸟 前段时间本小菜鸟研究了某验的点选类型验证码 今天开始研究他们的另一类验证码 滑块 先直接上流程 和点选的步骤基本相同 1 请求gt register slide off
  • 【Linux】shell的简单模拟实现

    目录 一 大概思路 二 命令行显示及获取用户输入命令 三 分析命令 四 创建子进程执行命令 五 导入环境变量 六 源码 总结 前言 我们已经接触了很长时间的Linux 我们对shell特别的好奇 正好前面我们学习了shell的运行原理 以及
  • Ambari——大数据平台的搭建利器(一)

    Ambari是hadoop分布式集群配置管理工具 是由hortonworks主导的开源项目 它已经成为apache基金会的孵化器项目 已经成为hadoop运维系统中的得力助手 引起了业界和学术界的关注 Ambari采用的不是一个新的思想和架
  • matlab系统稳定性仿真实验,基于Matlab的电力系统暂态稳定仿真实验与分析

    基于Matlab的电力系统暂态稳定仿真实验与分析 第29卷第4期2010年4月 实验室研究与探索 RESEARCHANDEXPLORATIONINLABORATORY Vol 29No 4Apr 2010 Matlab 1引言 长期以来 电
  • vue2与vue3的区别

    1 vue2和vue3双向数据绑定原理发生了改变 vue2 的双向数据绑定是利用ES5 的一个 API Object definePropert 对数据进行劫持 结合 发布订阅模式的方式来实现的 vue3 中使用了 es6 的 ProxyA
  • glTexSubImage2D的使用详解

    Name glTexSubImage2D glTextureSubImage2D specify a two dimensional texture subimage C Specification void glTexSubImage2D
  • LeetCode第3题解析

    给定一个字符串 请你找出其中不含有重复字符的 最长子串 的长度 示例 1 输入 abcabcbb 输出 3 解释 因为无重复字符的最长子串是 abc 所以其长度为 3 示例 2 输入 bbbbb 输出 1 解释 因为无重复字符的最长子串是
  • 【洛谷 P1170】兔八哥与猎人 题解(数学+辗转相除法)

    兔八哥与猎人 题目描述 兔八哥躲藏在树林旁边的果园里 果园有 M N M times N M N 棵树 组成一个 M M M 行
  • 本地从0搭建Stable Diffusion WebUI及错误记录

    从0开始搭建本地Stable Diffusion WebUI环境 一 环境配置 1 使用的电脑配置 系统 Windows10 处理器 英特尔 i7 内存 24GB 显卡 NVIDIA GTX 1060 6GB 2 镜像源 阿里云 清华大学
  • MySql 简介

    目录 数据存取演变历史 数据库软件应用史 数据库的本质 数据库的分类 1 关系型数据库 关系型数据库有哪些 2 非关系型数据库 非关系型数据库有哪些 MySQL简介 基本使用 系统服务制作 密码相关操作 SQL与NoSQL 数据库的概念 数
  • Spring Junit 单元测试@Test 报错 ServletContext找不到 No qualifying bean of type javax.servlet.ServletContext

    Spring Junit 单元测试 Test 报错 ServletContext找不到 No qualifying bean of type javax servlet ServletContext found for dependency
  • 微信小程序画布详解

    有的时候需要插入动画 这时就需要用到画布 接下来浅谈一下画布的功能和用法吧 wxml代码
  • Log Structured Merge Trees(LSM) 原理(LSM 算法的原理是什么?)

    十年前 谷歌发表了 BigTable 的论文 论文中很多很酷的方面之一就是它所使用的文件组织方式 这个方法更一般的名字叫 Log Structured Merge Tree LSM是当前被用在许多产品的文件结构策略 HBase Cassan
  • nginx basic auth配置踩坑记

    nginx的basic auth配置由ngx http auth basic module模块提供 对HTTP Basic Authentication协议进行了支持 用户可通过该配置设置用户名和密码对web站点进行简单的访问控制 basi