AMQPS connection via proxy

502 views
Skip to first unread message

Julien Vehent

unread,
Jul 20, 2014, 10:38:17 AM7/20/14
to golan...@googlegroups.com
Hi everyone,

I use github.com/streadway/amqp to manage connections from distributed
agents to a central rabbitmq cluster on the internet. Some agents are
blocked by a squid proxy that supports the CONNECT method. However,
CONNECT is a HTTP method, not supported by AMQP.

I could use the HTTP API of the rabbitmq management interface, or add a
rabbitmq server next to the agents that are blocked by the proxy. But
before I do that: does anyone know of a way to establish a TCP/TLS
connection through a proxy without relying on the HTTP CONNECT method?

Thanks,
Julien Vehent

Frits van Bommel

unread,
Jul 20, 2014, 11:01:59 AM7/20/14
to golan...@googlegroups.com, jul...@linuxwall.info

I know nothing about AMQP, but it looks like it has a DialConfig() function which accepts a Config parameter. The last field of that Config is this:
    // Dial returns a net.Conn prepared for a TLS handshake with TSLClientConfig,
    // then an AMQP connection handshake.
    // If Dial is nil, net.DialTimeout with a 30s connection and 30s read
    // deadline is used.
    Dial func(network, addr string) (net.Conn, error)

It shouldn't be hard to put a function in there that performs the HTTP CONNECT handshake and then returns the connection.

jul...@linuxwall.info

unread,
Jul 20, 2014, 3:30:11 PM7/20/14
to Frits van Bommel, golan...@googlegroups.com
On Sun 20.Jul'14 at 8:01:58 -0700, Frits van Bommel wrote:
> On Sunday, July 20, 2014 4:38:17 PM UTC+2, Julien Vehent wrote:
> > does anyone know of a way to establish a TCP/TLS
> > connection through a proxy without relying on the HTTP CONNECT method?
> >
> I know nothing about AMQP, but it looks like it has a DialConfig()
> It shouldn't be hard to put a function in there that performs the HTTP CONNECT handshake and then returns the connection.

Thanks Frits, that seem to be the correct direction indeed.
For future ref, I implemented the code below as an amqp.Config.Dial
function and it does the job.

- Julien

package main
import (
"bufio"
"fmt"
"net"
"time"
)
func main() {
target := "some.target.example.net:443"
proxy := "some.relay.example.com:3128"
conn, err := net.DialTimeout("tcp", proxy, 30*time.Second)
if err != nil {
panic(err)
}
// send a CONNECT request to the proxy
fmt.Fprintf(conn, "CONNECT "+target+" HTTP/1.1\r\nHost: "+target+"\r\n\r\n")
status, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
panic(err)
}
fmt.Printf("'%s'\n", status)
// 9th character in response should be "2"
// HTTP/1.0 200 Connection established
// ^
if status == "" || len(status) < 12 {
panic("invalid response")
}
if status[9] != '2' {
fmt.Println(status)
panic("invalid status")
}
fmt.Println("success")

// do tcp stuff with `conn`

err = conn.Close()
if err != nil {
panic(err)
}
}

Reply all
Reply to author
Forward
0 new messages