Golang обратный прокси с несколькими приложениями

StackOverflow https://stackoverflow.com//questions/21055182

  •  22-12-2019
  •  | 
  •  

Вопрос

Я хочу обслуживать два или более веб-приложений, запущенных в виртуальной машине (разные порта и некоторое время в другом каталоге под тем же портом) из хоста, и поскольку мне нужно войти в систему, прежде чем он сможет получить доступ к этим приложениям I не может использовать статический прокси, как Nginx или Apache.

Так вот моя ситуация:

192.168.1.1: IP-хост IP
192.168.1.2: VM IP

Внутри VM у меня есть это:

192.168.1.2/OwnCloud: Add Add Address
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 для достижения этой маршруты, но без особых успехов: Мой код основан на этой работе: Gist

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)
    }
}
.

<Сильные> Редактировать:
Я изменил IP-адрес VM: 192.168.1.2 не 192.168.1.1

Это было полезно?

Решение

Тебе лучше делать это по имени хоста, а не URL. например,

owncloud.domain.com -> IP 192.168.1.2,
app2.domain.com     -> IP 192.168.1.3
.

Если вы не знаете, имя хоста - это просто заголовка HTTP-запроса (хост: domain.com), поэтому вы можете иметь несколько хостов на iP (Apache вызывает это «именованные виртуальные хосты»).

Преимущество использования имена хостов, а не URL, заключается в том, что веб-приложение на другом конце не в курсе URL-адресов, которые вы префиксируете, но необходимо для чтения их, так что вы можете столкнуться с проблемами, написанными URL Веб-приложение, не работающее против URL, ожидаемых обратным прокси. Где в качестве прокси, основанные на хоте, на основании прокси должны работать большинство веб-приложений, не переписывают доменное имя. (Это огромное обобщение, хотя некоторые веб-приложения позволят вам добавить прокси-адрес - но обычно вы столкнулись с меньшими проблемами с именами хостов)

Самая большая проблема - настроить подгруппу на вашем сервере имени. Я предполагаю, что ваши поставщики регистрации Registra / DNS позволяют вам бесплатно создавать субдомены бесплатно (большинство), но если вы используете что-то вроде динамического DNS с этим, запустив свой домашний широкополосный соединение, то вы столкнетесь с проблемами и Чтобы купить свое собственное доменное имя с помощью CNAME поддоменов в ваш динамический 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))
}
.

Слушайте, сервис

h := &baseHandle{}
http.Handle("/", h)

server := &http.Server{
    Addr:    ":8080",
    Handler: h,
}
log.Fatal(server.ListenAndServe())
.

Вы можете кэшировать httputil.ReverseProxy в глобальной карте, Все в файле выше.

Вот a Ssldocker Проект, увиденный, чтобы соответствовать вам лучше всего.

Ваш прохождение неправильного IP на обратный прокси.Должен быть вашим VM GenaCodicCodcode.

в Документы

192.168.1.2

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top