日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

nginx basic auth配置踩坑记

發布時間:2025/3/19 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 nginx basic auth配置踩坑记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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 | MD52a | 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 utilimport ("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支持的對密碼加密的字符串。

總結

以上是生活随笔為你收集整理的nginx basic auth配置踩坑记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。