Golang обратный прокси с несколькими приложениями
Я хочу обслуживать два или более веб-приложений, работающих в виртуальной машине (разные порты и некоторое время в разных каталогах под одним и тем же портом) с хост-машины, и потому что мне нужно, чтобы пользователь вошел в систему, прежде чем он сможет получить доступ к этим приложениям, я не могу использовать статический прокси-сервер, такой как Nginx или Apache.
вот моя ситуация :
192.168.1.1 : есть IP хоста
192.168.1.2: является ли VM ip
внутри VM у меня есть это :
192.168.1.2 / owncloud: адрес owncloud
192.168.1.2: 8080: другое приложение
192.168.1.2:8888 : 3-е приложение
Я хочу иметь это:
192.168.1.1 / app1 --> 192.168.1.2 / owncloud
192.168.1.1 / app2 --> 192.168.1.2: 8080
192.168.1.1 / app2 --> 192.168.1.2: 8888
Я попытался использовать golang httputil.ReverseProxy для достижения этой маршрутизации, но без особого успеха: мой код на основе этой работы : суть
package main
import(
"log"
"net/url"
"net/http"
"net/http/httputil"
)
func main() {
remote, err := url.Parse("http://192.168.1.2:8080")
if err != nil {
panic(err)
}
proxy := httputil.NewSingleHostReverseProxy(remote)
http.HandleFunc("/app2", handler(proxy))
err = http.ListenAndServe(":80", nil)
if err != nil {
panic(err)
}
}
func handler(p *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
log.Println(r.URL)
r.URL.Path = "/"
p.ServeHTTP(w, r)
}
}
Edit:
Я изменил ip-адрес vm: 192.168.1.2 не 192.168.1.1
3 ответов
вам лучше сделать это по имени хоста, а не по URL. например!--2-->
owncloud.domain.com -> IP 192.168.1.2,
app2.domain.com -> IP 192.168.1.3
Если вы еще не знали, имя хоста - это просто заголовок HTTP-запроса (Host: domain.com), поэтому вы можете иметь несколько имен хостов на IP (Apache называет это "именованными виртуальными хостами").
преимущество использования имен хостов, а не URL-адресов заключается в том, что веб-приложение на другом конце не знает о URL-адресах, которые вы добавляете, но должны соблюдать их, поэтому вы можете столкнуться с проблемами с URL-адресами написано веб-приложение не работает против URL-адресов, ожидаемых обратным прокси-сервером. Где в качестве прокси на основе имени хоста должны работать, поскольку большинство веб-приложений не переписывают доменное имя. (это огромное обобщение, хотя некоторые веб-приложения позволят вам добавить адрес прокси - сервера, но обычно вы столкнетесь с меньшими проблемами с именами хостов)
самая большая проблема заключается в настройке поддоменов на сервере имен. Я предполагаю, что ваши поставщики registra / DNS позволяют создавать поддомены бесплатно (большинство должно), но если вы используете что-то вроде динамического DNS с этим работает от вашего домашнего широкополосного соединения, то вы столкнетесь с проблемами, и вам придется купить свое собственное доменное имя с поддоменами CNAME'ED на ваш динамический DNS-адрес (или использовать платную учетную запись с динамическими DNS-провайдерами, если они предлагают поддомены).
и последнее, если вы смотрите в owncloud, то вы также можете взглянуть на Pydio (формально AjaxExplore). Они оба имеют разные сильные и слабые стороны, но по моему личному мнению Pydio-лучший продукт.
сделать карту, как это
hostTarget = map[string]string{
"app1.domain.com": "http://192.168.1.2/owncloud",
"app2.domain.com": "http://192.168.1.2:8080",
"app3.domain.com": "http://192.168.1.2:8888",
}
использовать httputil.ReverseProxy
построить свой обработчик
type baseHandle struct{}
func (h *baseHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
host := r.Host
if target, ok := hostTarget[host]; ok {
remoteUrl, err := url.Parse(target)
if err != nil {
log.Println("target parse fail:", err)
return
}
proxy := httputil.NewSingleHostReverseProxy(remoteUrl)
proxy.ServeHTTP(w, r)
return
}
w.Write([]byte("403: Host forbidden " + host))
}
ListenAndServe
h := &baseHandle{}
http.Handle("/", h)
server := &http.Server{
Addr: ":8080",
Handler: h,
}
log.Fatal(server.ListenAndServe())
вы можете кэшировать httputil.ReverseProxy
на Глобальной карте, в файле выше.
здесь SSLDocker проект видел, чтобы соответствовать вам лучше всего.
передача неправильного IP-адреса обратному прокси-серверу. Должен быть ваш VM 192.168.1.2
.
на docs
NewSingleHostReverseProxy returns a new ReverseProxy that rewrites URLs to the scheme, host, and base path provided in target.