Я хочу защитить REST API демона Docker с помощью обратного прокси-сервера Go. Я нашел эту статью очень актуальной. Я никогда не использовал Go, поэтому не знаю, как реализовать базовую аутентификацию для этого со статическим именем пользователя и паролем. Я перепробовал все возможные способы, которые мне удалось найти в Google, но ни один из них не работал у меня.
Не могли бы некоторые помочь добавить статическую аутентификацию basicAuth в следующий код, чтобы запрос, чтобы API демона Docker был доступен только в том случае, если запрос включает имя пользователя и пароль: https://github.com/ben-lab/blog-material/blob/master/golang-reverse-proxy-2/reverse-proxy.go
package main
import (
"fmt"
"io"
"log"
"net/http"
"time"
"github.com/tv42/httpunix"
)
func handleHTTP(w http.ResponseWriter, req *http.Request) {
fmt.Printf("Requested : %s\n", req.URL.Path)
u := &httpunix.Transport{
DialTimeout: 100 * time.Millisecond,
RequestTimeout: 1 * time.Second,
ResponseHeaderTimeout: 1 * time.Second,
}
u.RegisterLocation("docker-socket", "/var/run/docker.sock")
req.URL.Scheme = "http+unix"
req.URL.Host = "docker-socket"
resp, err := u.RoundTrip(req)
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
defer resp.Body.Close()
copyHeader(w.Header(), resp.Header)
w.WriteHeader(resp.StatusCode)
io.Copy(w, resp.Body)
}
func copyHeader(dst, src http.Header) {
for k, vv := range src {
for _, v := range vv {
dst.Add(k, v)
}
}
}
func main() {
server := &http.Server{
Addr: ":8888",
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { handleHTTP(w, r) }),
}
log.Fatal(server.ListenAndServe())
}
https://github.com/ben-lab/blog-material/blob/master/golang-reverse-proxy-2/reverse-proxy.go

Вот, можете скопировать логику из моего следующего маленького проекта.
В первую очередь вам нужен сервер для хранения пользователей (я использовал Redis).
Чем вам нужно 3 функции для пользователя
На этапе входа/регистрации вы создаете файл cookie, хэширующий имя пользователя/пароль, и устанавливаете файл cookie в таблицу Redis.
Затем вы проверяете каждый раз, когда вызывается API.
Не стесняйтесь копировать код, который вам нужен.
Открывайте тему, если что-то не понятно.
Вы можете получить доступ к базовым значениям заголовка аутентификации, вызвав BasicAuth() на вашем
req *http.Request object
нравиться:
user, pass, _ := req.BasicAuth()
Затем сравните пользователя и перейдите со статическими значениями, которые у вас есть.
https://golang.org/pkg/net/http/#Request.BasicAuth
Обновлять:
func handleHTTP(w http.ResponseWriter, req *http.Request) {
user, pass, _ := req.BasicAuth()
if user != "muuser" || pass != "mysecret" {
// you have to import "errors"
http.Error(w, errors.New("not authoized!!"), http. StatusUnauthorized)
return
}
fmt.Printf("Requested : %s\n", req.URL.Path)
u := &httpunix.Transport{
DialTimeout: 100 * time.Millisecond,
RequestTimeout: 1 * time.Second,
ResponseHeaderTimeout: 1 * time.Second,
}
u.RegisterLocation("docker-socket", "/var/run/docker.sock")
req.URL.Scheme = "http+unix"
req.URL.Host = "docker-socket"
resp, err := u.RoundTrip(req)
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
defer resp.Body.Close()
copyHeader(w.Header(), resp.Header)
w.WriteHeader(resp.StatusCode)
io.Copy(w, resp.Body)
}
не могли бы вы поделиться тем, как вызвать BasicAuth из объекта re *http.Request, поскольку я пытался посмотреть пример кода в Google, но не смог заставить его работать. заранее спасибо
Обновлен мой ответ, чтобы показать, как это сделать в вашем коде. Пожалуйста, не нужно импортировать "ошибки"
импортированные «ошибки», но не удалось выполнить сборку из-за следующей ошибки: reverse-proxy.go:17:31: невозможно использовать errors.New («не авторизовано!!») (ошибка типа) в качестве строки типа в аргументе для http.Error
это сработало как шарм, большое спасибо за помощь, приятель. Просто пришлось изменить: http.Error(w, errors.New("не авторизовано!!"), http.StatusUnauthorized) на http.Error(w, errors.New("не авторизовано!!").Error(), http.StatusUnauthorized)
Нужна еще одна помощь, не могли бы вы подсказать мне, как подключиться с помощью клиента Docker? Он отлично работает с curl, но не работает с клиентом docker. Я пробовал это, используя вход в докер, но я думаю, что получаю несанкционированную ошибку 401. Не могли бы вы помочь мне с этим тоже? Например, как я могу добавить учетные данные для этой команды? докер -H=127.0.0.1:8888 контейнер лс
Может попробовать -H=имя пользователя:пароль@127.0.0.1:8888
это здорово, спасибо, я обязательно попробую это. Я не очень хорошо разбираюсь в golang, не могли бы вы поделиться функцией, в которой можно использовать жестко закодированные имя пользователя и пароль. Мне не нужна регистрация пользователя и функция удаления, просто нужно защитить сквозной пароль. Спасибо большое за вашу помощь.