在2个FTP服务器之间进行代理以使用第3个服务器进行故障转移

时间:2018-10-29 06:57:40

标签: go proxy ftp

我在VDS#1(主要)上有第一台ftp服务器,有时可以通过托管禁用它。我们创建了第二个VDS#2(辅助),可以在无法访问VDS#1时帮助提高容错能力。 VDS#2始终具有与VDS#1相同的用户列表,包括用户名,密码和目录树。

当用户无法访问VDS#1时,我们希望将他们自动重定向到VDS#2。 我写了GOlang代码(下面的代码),但是它不能正常工作,我不知道为什么,我是FTP问题的新手。

Schematic view

你能帮我吗?也许有一种方法可以通过特殊的服务器响应或类似的方法轻松地重定向FTP请求? 谢谢大家!

func proxyConn(connection net.Conn) {

    defer connection.Close()

    remoteServer, remoteServerError := getActiveServer()
    if remoteServerError != nil {
        Error{}.PrintAndSave(remoteServerError.Error())
        return
    }

    remoteConnection, remoteError := net.DialTCP("tcp", nil, remoteServer)
    if remoteError != nil {
        Error{}.PrintAndSave(remoteError.Error())
        return
    }
    defer remoteConnection.Close()

    io.Copy(remoteConnection, connection)
    io.Copy(connection, remoteConnection)
}

func getActiveServer() (*net.TCPAddr, error) {

    connectedServerIndex := -1

    for ftpServerIndex, ftpServer := range FTP_SERVERS {
        connectedServer, serverError := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ftpServer, FTP_DEFAULT_PORT), CONNECTION_TIMEOUT)
        if serverError != nil {
            if ftpServerIndex == 0 {
                // Send e-mail "Server unreachable"
            }
        } else {
            connectedServerIndex = ftpServerIndex
            connectedServer.Close()
            break
        }
    }

    if connectedServerIndex == -1 {
        return nil, errors.New("active servers not found")
    }

    return net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", FTP_SERVERS[connectedServerIndex], FTP_DEFAULT_PORT))
}

func main() {

    localAddress, localAddressErr := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", LOCAL_ADDRESS, FTP_DEFAULT_PORT))
    if localAddressErr != nil {
        Error{}.PrintAndSave(localAddressErr.Error())
    }

    server, serverError := net.ListenTCP("tcp", localAddress)
    if serverError != nil {
        Error{}.PrintAndSave(serverError.Error())
        return
    }

    for {
        connection, connectionError := server.Accept()
        if connectionError != nil {
            Error{}.PrintAndSave(fmt.Sprintf("failed to accept listener: %v", connectionError))
        }

        go proxyConn(connection)
    }
}

0 个答案:

没有答案