您好,登錄后才能下訂單哦!
nginx的basic auth配置由ngx_http_auth_basic_module模塊提供,對HTTP Basic Authentication協(xié)議進(jìn)行了支持,用戶可通過該配置設(shè)置用戶名和密碼對web站點(diǎn)進(jìn)行簡單的訪問控制。
basic auth配置示例:
location / { auth_basic "closed site"; auth_basic_user_file conf/htpasswd; }
說明:
踩坑的地方就是這個密碼,官方文檔里對支持的密碼類型進(jìn)行了說明:
使用htpasswd或者openssl passwd命令生成的密碼固然可以使得配置生效,nginx能夠正常地進(jìn)行密碼安全校驗,如果密碼類型不支持, 則nginx或報錯:
crypt_r() failed (22: Invalid argument)
但是因為業(yè)務(wù)的需要,我們要用代碼生成nginx的配置并下發(fā)配置到每個云主機(jī)中,之后拉起nginx進(jìn)程。項目代碼使用go語言編寫,所以需要找一個對應(yīng)的函數(shù)或者庫生成nginx支持的密碼。
go語言生成nginx支持的密碼
在進(jìn)行自動生成密碼開發(fā)之前,思考了一下大概有三種方案可以實現(xiàn):
首先,第一種方式是不太可取的,因為需要強(qiáng)依賴服務(wù)器環(huán)境,所以直接pass。下面看第二種和第三種方式的具體實現(xiàn)。
直接調(diào)用系統(tǒng)函數(shù)crypt()
Linux的crypt函數(shù)有兩個參數(shù),函數(shù)定義為:
char *crypt(const char *key, const char *salt);
其中參數(shù)key為需要加密的內(nèi)容,salt參數(shù)有兩種類型:
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"方式直接調(diào)用c語言的庫函數(shù),下面是封裝crypt函數(shù)的具體實現(xiàn):
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 }
生成密碼的具體實現(xiàn):
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) }
經(jīng)過實測,上述通過調(diào)用crypt函數(shù)生成nginx支持的加密密碼實際可用,但是需要注意的是如果密碼長度超過8位,則salt參數(shù)只能選擇$id$salt$encrypted類型,在測試過程中就是因為踩了這點(diǎn)坑導(dǎo)致nginx只能校驗密碼的前8位,無語。
因為在編寫go代碼過程中調(diào)用了C函數(shù)庫,這種方式也需要依賴服務(wù)器所處環(huán)境,因此最好的方式是采用go標(biāo)準(zhǔn)庫中的函數(shù)對密碼進(jìn)行加密。
使用crypto函數(shù)庫
go的crypto標(biāo)準(zhǔn)庫封裝了很多中加密算法,采用SHA加密算法進(jìn)行密碼加密的代碼如下:
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) }
測試過程中通過調(diào)用GetSha()函數(shù)生成了對密碼加密的字符串,但是直接配置在nginx的conf/htpasswd文件中,reload nginx配置后測試驗證密碼是否生效,結(jié)果還是報錯,原來如前文所述,SHA加密的密碼必須帶有“{SHA}”前綴才可以,再次修改配置后經(jīng)過驗證,成功地用代碼生成了nginx支持的對密碼加密的字符串。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。