Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有多个应用程序的Golang反向代理_Go_Proxy_Reverse Proxy_Pydio - Fatal编程技术网

具有多个应用程序的Golang反向代理

具有多个应用程序的Golang反向代理,go,proxy,reverse-proxy,pydio,Go,Proxy,Reverse Proxy,Pydio,我想从主机上为运行在VM中的两个或多个web应用程序(不同端口,有时在同一端口下的不同目录中)提供服务,因为我需要用户在访问这些应用程序之前进行登录,所以我不能使用像Nginx或Apache这样的静态代理 我的情况如下: 192.168.1.1:主机ip是否为 192.168.1.2:是虚拟机ip吗 在虚拟机内部,我有以下内容: 192.168.1.2/owncloud:owncloud地址 192.168.1.2:8080:另一个应用程序 192.168.1.2:8888:第三次应用 我想要这

我想从主机上为运行在VM中的两个或多个web应用程序(不同端口,有时在同一端口下的不同目录中)提供服务,因为我需要用户在访问这些应用程序之前进行登录,所以我不能使用像Nginx或Apache这样的静态代理

我的情况如下:

192.168.1.1:主机ip是否为
192.168.1.2:是虚拟机ip吗

在虚拟机内部,我有以下内容:

192.168.1.2/owncloud:owncloud地址
192.168.1.2:8080:另一个应用程序
192.168.1.2:8888:第三次应用

我想要这个:

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来实现此路由,但没有多大成功: 我的代码基于以下工作:

编辑:

我已更改vm ip地址:192.168.1.2而不是192.168.1.1

您将错误的ip传递给反向代理。应该是您的虚拟机的
192.168.1.2


NewSingleHostReverseProxy返回一个新的ReverseProxy,它将URL重写为目标中提供的方案、主机和基本路径。

您最好通过主机名而不是URL执行此操作。乙二醇

owncloud.domain.com -> IP 192.168.1.2,
app2.domain.com     -> IP 192.168.1.3
如果您还不知道,主机名只是一个HTTP请求头(Host:domain.com),因此每个IP可以有几个主机名(Apache称之为“命名虚拟主机”)

使用主机名而不是URL的好处是,另一端的web应用程序不知道您要添加前缀的URL,但需要遵守这些URL,因此您可能会遇到问题,web应用程序编写的URL与反向代理预期的URL不一致。其中,基于主机名的代理应该可以工作,因为大多数web应用不会重写域名。(虽然这是一个巨大的概括,一些web应用程序允许您添加代理地址,但通常情况下,您在主机名方面遇到的问题较少)

最大的问题是必须在名称服务器上设置子域。我假设您的注册/DNS提供商允许您免费创建子域(大多数应该),但如果您使用动态DNS之类的东西,并且在您的家庭宽带连接上运行此功能,那么您将遇到问题,并且必须购买您自己的域名,子域CNAME'ed到您的动态DNS地址(或者如果动态DNS提供商提供子域,则使用他们的付费帐户)

最后一件事,如果你正在研究自己的云,那么你可能还想看看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


这是一个最适合您的项目。

感谢您的回复:这里使用的ip地址不是我的真实配置。我已经修复了它。我相信,如果不将web应用程序修改为app1、app2……目录下的服务器,然后将它们与我的Golang程序挂接在e主机。我如何修改反向代理中的响应头?例如,如果我想修改“服务器”头。事实上,这是满足我需要的最佳解决方案。感谢您的帮助!我还应该说,就像您正在侦听端口80(从而以root身份运行此端口)一样然后,您还应该更改用户ID和组ID,以防发现并利用漏洞:
err=syscall.Setgid(daemon\u group\u ID);err=syscall.Setuid(daemon\u user\u ID)
h := &baseHandle{}
http.Handle("/", h)

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