Golang http client through VPN (openVPN) / set network interfaceWebbased or Thick-client through VPN?Connecting to VPN through a custom clientHow to set HTTP headers (for cache-control)?authenticated http client requests from golangSetting HTTP headersHow to set headers in http get request?Setting up proxy for HTTP clientHow to set timeout for http.Get() requests in Golang?How to check if a network interface is a VPN in AndroidSpecify network interface for http request in Golang

What is the opposite of 'gravitas'?

Why escape if the_content isnt?

Why Were Madagascar and New Zealand Discovered So Late?

Integer addition + constant, is it a group?

How can I get through very long and very dry, but also very useful technical documents when learning a new tool?

Is a stroke of luck acceptable after a series of unfavorable events?

Overloading istream>> to read comma-separated input

Failed to fetch jessie backports repository

How to be diplomatic in refusing to write code that breaches the privacy of our users

Did Dumbledore lie to Harry about how long he had James Potter's invisibility cloak when he was examining it? If so, why?

How does it work when somebody invests in my business?

Short story about space worker geeks who zone out by 'listening' to radiation from stars

Valid Badminton Score?

How do scammers retract money, while you can’t?

Term for the "extreme-extension" version of a straw man fallacy?

I'm in charge of equipment buying but no one's ever happy with what I choose. How to fix this?

Opposite of a diet

Are student evaluations of teaching assistants read by others in the faculty?

India just shot down a satellite from the ground. At what altitude range is the resulting debris field?

How does the UK government determine the size of a mandate?

Class Action - which options I have?

Is `x >> pure y` equivalent to `liftM (const y) x`

How long to clear the 'suck zone' of a turbofan after start is initiated?

Pole-zeros of a real-valued causal FIR system



Golang http client through VPN (openVPN) / set network interface


Webbased or Thick-client through VPN?Connecting to VPN through a custom clientHow to set HTTP headers (for cache-control)?authenticated http client requests from golangSetting HTTP headersHow to set headers in http get request?Setting up proxy for HTTP clientHow to set timeout for http.Get() requests in Golang?How to check if a network interface is a VPN in AndroidSpecify network interface for http request in Golang













3















I have to make http requests through VPN. There is php code using cURL making what I need, nothing additional:



curl_setopt($cu, CURLOPT_INTERFACE, "tun0");


This interface from ifconfig:



 tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
inet 10.13.13.2 netmask 255.255.255.255 destination 10.13.13.1
inet6 fe80::80ee:132:d102:a52d prefixlen 64 scopeid 0x20<link>
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 100 (UNSPEC)


My go code (as I understand, I should bind to ip of tun0):



package main

import (
"io/ioutil"
"log"
"net"
"net/http"
"time"
)

func main()
httpTransport := &http.Transport
ief, err := net.InterfaceByName("tun0")
if err != nil
log.Fatal(err)

addrs, err := ief.Addrs()
if err != nil
log.Fatal(err)

tcpAddr := &net.TCPAddrIP: addrs[0].(*net.IPNet).IP
println(tcpAddr.String())
httpTransport.Dial = (&net.Dialer
Timeout: 20 * time.Second,
LocalAddr: tcpAddr,
).Dial

c := &http.Client
Transport: httpTransport,
Timeout: 30 * time.Second,


req, err := http.NewRequest(
http.MethodGet,
"http://example.com/",
nil,
)
if err != nil
log.Fatal(err)


resp, err := c.Do(req)
if err != nil
log.Fatal(err)

bytes, err := ioutil.ReadAll(resp.Body)
if err != nil
log.Fatal(err)

println(string(bytes))



So what I get :



10.13.13.2:0
2019/03/21 15:29:42 Get http://example.com/: dial tcp 10.13.13.2:0->93.184.216.34:80: i/o timeout
exit status 1


Php code with cUrl gets this page fast. I tried many times with Go code, so timeouts can do nothing. Any ideas how to replace that one PHP string in Go?



UPDATE



PHP code getting same page via tun0 and it's output:



<?php
$cu = curl_init();
curl_setopt($cu, CURLOPT_URL, "http://example.com");
curl_setopt($cu, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($cu, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($cu, CURLOPT_TIMEOUT, 30);
curl_setopt($cu, CURLOPT_INTERFACE, "tun0");
$result = curl_exec($cu);;
curl_close($cu);
echo $result . PHP_EOL;


Output:



<!doctype html>
<html>
<head>
<title>Example Domain</title>

<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;


div
width: 600px;
margin: 5em auto;
padding: 50px;
background-color: #fff;
border-radius: 1em;

a:link, a:visited
color: #38488f;
text-decoration: none;

@media (max-width: 700px)
body
background-color: #fff;

div
width: auto;
margin: 0 auto;
border-radius: 0;
padding: 1em;


</style>
</head>

<body>
<div>
<h1>Example Domain</h1>
<p>This domain is established to be used for illustrative examples in documents. You may use this
domain in examples without prior coordination or asking for permission.</p>
<p><a href="http://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>









share|improve this question
























  • Is your vpn connected to internet ?

    – user801247
    Mar 21 at 22:04











  • Ofcourse. As I said, same thing with PHP and cURL works fine.

    – edwvee
    Mar 22 at 13:06















3















I have to make http requests through VPN. There is php code using cURL making what I need, nothing additional:



curl_setopt($cu, CURLOPT_INTERFACE, "tun0");


This interface from ifconfig:



 tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
inet 10.13.13.2 netmask 255.255.255.255 destination 10.13.13.1
inet6 fe80::80ee:132:d102:a52d prefixlen 64 scopeid 0x20<link>
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 100 (UNSPEC)


My go code (as I understand, I should bind to ip of tun0):



package main

import (
"io/ioutil"
"log"
"net"
"net/http"
"time"
)

func main()
httpTransport := &http.Transport
ief, err := net.InterfaceByName("tun0")
if err != nil
log.Fatal(err)

addrs, err := ief.Addrs()
if err != nil
log.Fatal(err)

tcpAddr := &net.TCPAddrIP: addrs[0].(*net.IPNet).IP
println(tcpAddr.String())
httpTransport.Dial = (&net.Dialer
Timeout: 20 * time.Second,
LocalAddr: tcpAddr,
).Dial

c := &http.Client
Transport: httpTransport,
Timeout: 30 * time.Second,


req, err := http.NewRequest(
http.MethodGet,
"http://example.com/",
nil,
)
if err != nil
log.Fatal(err)


resp, err := c.Do(req)
if err != nil
log.Fatal(err)

bytes, err := ioutil.ReadAll(resp.Body)
if err != nil
log.Fatal(err)

println(string(bytes))



So what I get :



10.13.13.2:0
2019/03/21 15:29:42 Get http://example.com/: dial tcp 10.13.13.2:0->93.184.216.34:80: i/o timeout
exit status 1


Php code with cUrl gets this page fast. I tried many times with Go code, so timeouts can do nothing. Any ideas how to replace that one PHP string in Go?



UPDATE



PHP code getting same page via tun0 and it's output:



<?php
$cu = curl_init();
curl_setopt($cu, CURLOPT_URL, "http://example.com");
curl_setopt($cu, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($cu, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($cu, CURLOPT_TIMEOUT, 30);
curl_setopt($cu, CURLOPT_INTERFACE, "tun0");
$result = curl_exec($cu);;
curl_close($cu);
echo $result . PHP_EOL;


Output:



<!doctype html>
<html>
<head>
<title>Example Domain</title>

<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;


div
width: 600px;
margin: 5em auto;
padding: 50px;
background-color: #fff;
border-radius: 1em;

a:link, a:visited
color: #38488f;
text-decoration: none;

@media (max-width: 700px)
body
background-color: #fff;

div
width: auto;
margin: 0 auto;
border-radius: 0;
padding: 1em;


</style>
</head>

<body>
<div>
<h1>Example Domain</h1>
<p>This domain is established to be used for illustrative examples in documents. You may use this
domain in examples without prior coordination or asking for permission.</p>
<p><a href="http://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>









share|improve this question
























  • Is your vpn connected to internet ?

    – user801247
    Mar 21 at 22:04











  • Ofcourse. As I said, same thing with PHP and cURL works fine.

    – edwvee
    Mar 22 at 13:06













3












3








3








I have to make http requests through VPN. There is php code using cURL making what I need, nothing additional:



curl_setopt($cu, CURLOPT_INTERFACE, "tun0");


This interface from ifconfig:



 tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
inet 10.13.13.2 netmask 255.255.255.255 destination 10.13.13.1
inet6 fe80::80ee:132:d102:a52d prefixlen 64 scopeid 0x20<link>
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 100 (UNSPEC)


My go code (as I understand, I should bind to ip of tun0):



package main

import (
"io/ioutil"
"log"
"net"
"net/http"
"time"
)

func main()
httpTransport := &http.Transport
ief, err := net.InterfaceByName("tun0")
if err != nil
log.Fatal(err)

addrs, err := ief.Addrs()
if err != nil
log.Fatal(err)

tcpAddr := &net.TCPAddrIP: addrs[0].(*net.IPNet).IP
println(tcpAddr.String())
httpTransport.Dial = (&net.Dialer
Timeout: 20 * time.Second,
LocalAddr: tcpAddr,
).Dial

c := &http.Client
Transport: httpTransport,
Timeout: 30 * time.Second,


req, err := http.NewRequest(
http.MethodGet,
"http://example.com/",
nil,
)
if err != nil
log.Fatal(err)


resp, err := c.Do(req)
if err != nil
log.Fatal(err)

bytes, err := ioutil.ReadAll(resp.Body)
if err != nil
log.Fatal(err)

println(string(bytes))



So what I get :



10.13.13.2:0
2019/03/21 15:29:42 Get http://example.com/: dial tcp 10.13.13.2:0->93.184.216.34:80: i/o timeout
exit status 1


Php code with cUrl gets this page fast. I tried many times with Go code, so timeouts can do nothing. Any ideas how to replace that one PHP string in Go?



UPDATE



PHP code getting same page via tun0 and it's output:



<?php
$cu = curl_init();
curl_setopt($cu, CURLOPT_URL, "http://example.com");
curl_setopt($cu, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($cu, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($cu, CURLOPT_TIMEOUT, 30);
curl_setopt($cu, CURLOPT_INTERFACE, "tun0");
$result = curl_exec($cu);;
curl_close($cu);
echo $result . PHP_EOL;


Output:



<!doctype html>
<html>
<head>
<title>Example Domain</title>

<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;


div
width: 600px;
margin: 5em auto;
padding: 50px;
background-color: #fff;
border-radius: 1em;

a:link, a:visited
color: #38488f;
text-decoration: none;

@media (max-width: 700px)
body
background-color: #fff;

div
width: auto;
margin: 0 auto;
border-radius: 0;
padding: 1em;


</style>
</head>

<body>
<div>
<h1>Example Domain</h1>
<p>This domain is established to be used for illustrative examples in documents. You may use this
domain in examples without prior coordination or asking for permission.</p>
<p><a href="http://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>









share|improve this question
















I have to make http requests through VPN. There is php code using cURL making what I need, nothing additional:



curl_setopt($cu, CURLOPT_INTERFACE, "tun0");


This interface from ifconfig:



 tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
inet 10.13.13.2 netmask 255.255.255.255 destination 10.13.13.1
inet6 fe80::80ee:132:d102:a52d prefixlen 64 scopeid 0x20<link>
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 100 (UNSPEC)


My go code (as I understand, I should bind to ip of tun0):



package main

import (
"io/ioutil"
"log"
"net"
"net/http"
"time"
)

func main()
httpTransport := &http.Transport
ief, err := net.InterfaceByName("tun0")
if err != nil
log.Fatal(err)

addrs, err := ief.Addrs()
if err != nil
log.Fatal(err)

tcpAddr := &net.TCPAddrIP: addrs[0].(*net.IPNet).IP
println(tcpAddr.String())
httpTransport.Dial = (&net.Dialer
Timeout: 20 * time.Second,
LocalAddr: tcpAddr,
).Dial

c := &http.Client
Transport: httpTransport,
Timeout: 30 * time.Second,


req, err := http.NewRequest(
http.MethodGet,
"http://example.com/",
nil,
)
if err != nil
log.Fatal(err)


resp, err := c.Do(req)
if err != nil
log.Fatal(err)

bytes, err := ioutil.ReadAll(resp.Body)
if err != nil
log.Fatal(err)

println(string(bytes))



So what I get :



10.13.13.2:0
2019/03/21 15:29:42 Get http://example.com/: dial tcp 10.13.13.2:0->93.184.216.34:80: i/o timeout
exit status 1


Php code with cUrl gets this page fast. I tried many times with Go code, so timeouts can do nothing. Any ideas how to replace that one PHP string in Go?



UPDATE



PHP code getting same page via tun0 and it's output:



<?php
$cu = curl_init();
curl_setopt($cu, CURLOPT_URL, "http://example.com");
curl_setopt($cu, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($cu, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($cu, CURLOPT_TIMEOUT, 30);
curl_setopt($cu, CURLOPT_INTERFACE, "tun0");
$result = curl_exec($cu);;
curl_close($cu);
echo $result . PHP_EOL;


Output:



<!doctype html>
<html>
<head>
<title>Example Domain</title>

<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;


div
width: 600px;
margin: 5em auto;
padding: 50px;
background-color: #fff;
border-radius: 1em;

a:link, a:visited
color: #38488f;
text-decoration: none;

@media (max-width: 700px)
body
background-color: #fff;

div
width: auto;
margin: 0 auto;
border-radius: 0;
padding: 1em;


</style>
</head>

<body>
<div>
<h1>Example Domain</h1>
<p>This domain is established to be used for illustrative examples in documents. You may use this
domain in examples without prior coordination or asking for permission.</p>
<p><a href="http://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>






http go vpn network-interface






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 22 at 20:50







edwvee

















asked Mar 21 at 15:51









edwveeedwvee

162




162












  • Is your vpn connected to internet ?

    – user801247
    Mar 21 at 22:04











  • Ofcourse. As I said, same thing with PHP and cURL works fine.

    – edwvee
    Mar 22 at 13:06

















  • Is your vpn connected to internet ?

    – user801247
    Mar 21 at 22:04











  • Ofcourse. As I said, same thing with PHP and cURL works fine.

    – edwvee
    Mar 22 at 13:06
















Is your vpn connected to internet ?

– user801247
Mar 21 at 22:04





Is your vpn connected to internet ?

– user801247
Mar 21 at 22:04













Ofcourse. As I said, same thing with PHP and cURL works fine.

– edwvee
Mar 22 at 13:06





Ofcourse. As I said, same thing with PHP and cURL works fine.

– edwvee
Mar 22 at 13:06












1 Answer
1






active

oldest

votes


















0














I have a working example:



package main

import (
"fmt"
"io/ioutil"
"net"
"net/http"
)

func main()
ifname := "tun0"
iface, err := net.InterfaceByName(ifname)
if err != nil
panic(fmt.Sprintf("could not get interface: %s", err))


addrs, err := iface.Addrs()
if err != nil
panic(fmt.Sprintf("could not get addresses from interface: %s", err))


fmt.Printf("%+vn", addrs)

c := &http.Client
Transport: &http.Transport
Dial: (&net.Dialer
LocalAddr: &net.TCPAddr
IP: addrs[0].(*net.IPNet).IP,
//IP: net.ParseIP("192.168.0.2"),
//IP: net.ParseIP("127.0.0.1"),
,
).Dial,
,


r, err := c.Get("http://localhost/ip")
if err != nil
panic(fmt.Sprintf("couldn't get http:%s", err))

b, err := ioutil.ReadAll(r.Body)
if err != nil
panic(fmt.Sprintf("could not read body:%s", err))

fmt.Printf("%s", b)



You can see in the LocalAddrcommented different addresses for my tests in my environment.



I used a local running httpbin and I can see this:



$ go run main.go
[myipv6 myipv4]
"origin":"192.168.0.2"


Here, the 2nd line of output is the response from the server.
If I change a bit the code to force 127.0.0.1 (as commented), I get this:



$ go run main.go
[myipv6 myipv4]
"origin":"127.0.0.1"


Which means, the server does indeed see a different source address.



I think, your code works but as you see in the output you have an I/O timeout.
The cause of this might be because your VPN connection is not allowed to connect to your destination. The program seems to do the right connection you asked it, the message dial tcp 10.13.13.2:0->93.184.216.34:80 which is correct according you your ifconfig output.



Also, if I especially connect to a closed port I get this:



panic: couldn't get http:Get http://localhost:81/ip: dial tcp 192.168.0.2:0->127.0.0.1:81: connect: connection refused


Which shows that your addresses are correct.






share|improve this answer

























  • You've just replaced thing about preparing request and client.Do with client.Get. So, it doesn't work either - same result. I added php code getting example.com via tun0 and it's out. It's what I expect from Go code I'm trying to write.

    – edwvee
    Mar 22 at 20:46












  • Yes , the code is basically the same as yours and I expected the same result. You should probably sniff the traffic with tcpdump to see what happens. I kind of doubt it's a bug in golang.

    – user801247
    Mar 22 at 20:47












  • Sniffing the traffic will allow you to see what going on, what are the differences between golang and php + curl.

    – user801247
    Mar 22 at 20:49











  • Or you can try to connect elsewhere, starting with, if possible, on the vpn endpoint itself, see if the error message changes.

    – user801247
    Mar 22 at 20:54











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55284356%2fgolang-http-client-through-vpn-openvpn-set-network-interface%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














I have a working example:



package main

import (
"fmt"
"io/ioutil"
"net"
"net/http"
)

func main()
ifname := "tun0"
iface, err := net.InterfaceByName(ifname)
if err != nil
panic(fmt.Sprintf("could not get interface: %s", err))


addrs, err := iface.Addrs()
if err != nil
panic(fmt.Sprintf("could not get addresses from interface: %s", err))


fmt.Printf("%+vn", addrs)

c := &http.Client
Transport: &http.Transport
Dial: (&net.Dialer
LocalAddr: &net.TCPAddr
IP: addrs[0].(*net.IPNet).IP,
//IP: net.ParseIP("192.168.0.2"),
//IP: net.ParseIP("127.0.0.1"),
,
).Dial,
,


r, err := c.Get("http://localhost/ip")
if err != nil
panic(fmt.Sprintf("couldn't get http:%s", err))

b, err := ioutil.ReadAll(r.Body)
if err != nil
panic(fmt.Sprintf("could not read body:%s", err))

fmt.Printf("%s", b)



You can see in the LocalAddrcommented different addresses for my tests in my environment.



I used a local running httpbin and I can see this:



$ go run main.go
[myipv6 myipv4]
"origin":"192.168.0.2"


Here, the 2nd line of output is the response from the server.
If I change a bit the code to force 127.0.0.1 (as commented), I get this:



$ go run main.go
[myipv6 myipv4]
"origin":"127.0.0.1"


Which means, the server does indeed see a different source address.



I think, your code works but as you see in the output you have an I/O timeout.
The cause of this might be because your VPN connection is not allowed to connect to your destination. The program seems to do the right connection you asked it, the message dial tcp 10.13.13.2:0->93.184.216.34:80 which is correct according you your ifconfig output.



Also, if I especially connect to a closed port I get this:



panic: couldn't get http:Get http://localhost:81/ip: dial tcp 192.168.0.2:0->127.0.0.1:81: connect: connection refused


Which shows that your addresses are correct.






share|improve this answer

























  • You've just replaced thing about preparing request and client.Do with client.Get. So, it doesn't work either - same result. I added php code getting example.com via tun0 and it's out. It's what I expect from Go code I'm trying to write.

    – edwvee
    Mar 22 at 20:46












  • Yes , the code is basically the same as yours and I expected the same result. You should probably sniff the traffic with tcpdump to see what happens. I kind of doubt it's a bug in golang.

    – user801247
    Mar 22 at 20:47












  • Sniffing the traffic will allow you to see what going on, what are the differences between golang and php + curl.

    – user801247
    Mar 22 at 20:49











  • Or you can try to connect elsewhere, starting with, if possible, on the vpn endpoint itself, see if the error message changes.

    – user801247
    Mar 22 at 20:54
















0














I have a working example:



package main

import (
"fmt"
"io/ioutil"
"net"
"net/http"
)

func main()
ifname := "tun0"
iface, err := net.InterfaceByName(ifname)
if err != nil
panic(fmt.Sprintf("could not get interface: %s", err))


addrs, err := iface.Addrs()
if err != nil
panic(fmt.Sprintf("could not get addresses from interface: %s", err))


fmt.Printf("%+vn", addrs)

c := &http.Client
Transport: &http.Transport
Dial: (&net.Dialer
LocalAddr: &net.TCPAddr
IP: addrs[0].(*net.IPNet).IP,
//IP: net.ParseIP("192.168.0.2"),
//IP: net.ParseIP("127.0.0.1"),
,
).Dial,
,


r, err := c.Get("http://localhost/ip")
if err != nil
panic(fmt.Sprintf("couldn't get http:%s", err))

b, err := ioutil.ReadAll(r.Body)
if err != nil
panic(fmt.Sprintf("could not read body:%s", err))

fmt.Printf("%s", b)



You can see in the LocalAddrcommented different addresses for my tests in my environment.



I used a local running httpbin and I can see this:



$ go run main.go
[myipv6 myipv4]
"origin":"192.168.0.2"


Here, the 2nd line of output is the response from the server.
If I change a bit the code to force 127.0.0.1 (as commented), I get this:



$ go run main.go
[myipv6 myipv4]
"origin":"127.0.0.1"


Which means, the server does indeed see a different source address.



I think, your code works but as you see in the output you have an I/O timeout.
The cause of this might be because your VPN connection is not allowed to connect to your destination. The program seems to do the right connection you asked it, the message dial tcp 10.13.13.2:0->93.184.216.34:80 which is correct according you your ifconfig output.



Also, if I especially connect to a closed port I get this:



panic: couldn't get http:Get http://localhost:81/ip: dial tcp 192.168.0.2:0->127.0.0.1:81: connect: connection refused


Which shows that your addresses are correct.






share|improve this answer

























  • You've just replaced thing about preparing request and client.Do with client.Get. So, it doesn't work either - same result. I added php code getting example.com via tun0 and it's out. It's what I expect from Go code I'm trying to write.

    – edwvee
    Mar 22 at 20:46












  • Yes , the code is basically the same as yours and I expected the same result. You should probably sniff the traffic with tcpdump to see what happens. I kind of doubt it's a bug in golang.

    – user801247
    Mar 22 at 20:47












  • Sniffing the traffic will allow you to see what going on, what are the differences between golang and php + curl.

    – user801247
    Mar 22 at 20:49











  • Or you can try to connect elsewhere, starting with, if possible, on the vpn endpoint itself, see if the error message changes.

    – user801247
    Mar 22 at 20:54














0












0








0







I have a working example:



package main

import (
"fmt"
"io/ioutil"
"net"
"net/http"
)

func main()
ifname := "tun0"
iface, err := net.InterfaceByName(ifname)
if err != nil
panic(fmt.Sprintf("could not get interface: %s", err))


addrs, err := iface.Addrs()
if err != nil
panic(fmt.Sprintf("could not get addresses from interface: %s", err))


fmt.Printf("%+vn", addrs)

c := &http.Client
Transport: &http.Transport
Dial: (&net.Dialer
LocalAddr: &net.TCPAddr
IP: addrs[0].(*net.IPNet).IP,
//IP: net.ParseIP("192.168.0.2"),
//IP: net.ParseIP("127.0.0.1"),
,
).Dial,
,


r, err := c.Get("http://localhost/ip")
if err != nil
panic(fmt.Sprintf("couldn't get http:%s", err))

b, err := ioutil.ReadAll(r.Body)
if err != nil
panic(fmt.Sprintf("could not read body:%s", err))

fmt.Printf("%s", b)



You can see in the LocalAddrcommented different addresses for my tests in my environment.



I used a local running httpbin and I can see this:



$ go run main.go
[myipv6 myipv4]
"origin":"192.168.0.2"


Here, the 2nd line of output is the response from the server.
If I change a bit the code to force 127.0.0.1 (as commented), I get this:



$ go run main.go
[myipv6 myipv4]
"origin":"127.0.0.1"


Which means, the server does indeed see a different source address.



I think, your code works but as you see in the output you have an I/O timeout.
The cause of this might be because your VPN connection is not allowed to connect to your destination. The program seems to do the right connection you asked it, the message dial tcp 10.13.13.2:0->93.184.216.34:80 which is correct according you your ifconfig output.



Also, if I especially connect to a closed port I get this:



panic: couldn't get http:Get http://localhost:81/ip: dial tcp 192.168.0.2:0->127.0.0.1:81: connect: connection refused


Which shows that your addresses are correct.






share|improve this answer















I have a working example:



package main

import (
"fmt"
"io/ioutil"
"net"
"net/http"
)

func main()
ifname := "tun0"
iface, err := net.InterfaceByName(ifname)
if err != nil
panic(fmt.Sprintf("could not get interface: %s", err))


addrs, err := iface.Addrs()
if err != nil
panic(fmt.Sprintf("could not get addresses from interface: %s", err))


fmt.Printf("%+vn", addrs)

c := &http.Client
Transport: &http.Transport
Dial: (&net.Dialer
LocalAddr: &net.TCPAddr
IP: addrs[0].(*net.IPNet).IP,
//IP: net.ParseIP("192.168.0.2"),
//IP: net.ParseIP("127.0.0.1"),
,
).Dial,
,


r, err := c.Get("http://localhost/ip")
if err != nil
panic(fmt.Sprintf("couldn't get http:%s", err))

b, err := ioutil.ReadAll(r.Body)
if err != nil
panic(fmt.Sprintf("could not read body:%s", err))

fmt.Printf("%s", b)



You can see in the LocalAddrcommented different addresses for my tests in my environment.



I used a local running httpbin and I can see this:



$ go run main.go
[myipv6 myipv4]
"origin":"192.168.0.2"


Here, the 2nd line of output is the response from the server.
If I change a bit the code to force 127.0.0.1 (as commented), I get this:



$ go run main.go
[myipv6 myipv4]
"origin":"127.0.0.1"


Which means, the server does indeed see a different source address.



I think, your code works but as you see in the output you have an I/O timeout.
The cause of this might be because your VPN connection is not allowed to connect to your destination. The program seems to do the right connection you asked it, the message dial tcp 10.13.13.2:0->93.184.216.34:80 which is correct according you your ifconfig output.



Also, if I especially connect to a closed port I get this:



panic: couldn't get http:Get http://localhost:81/ip: dial tcp 192.168.0.2:0->127.0.0.1:81: connect: connection refused


Which shows that your addresses are correct.







share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 22 at 0:30

























answered Mar 22 at 0:22









user801247user801247

1,06279




1,06279












  • You've just replaced thing about preparing request and client.Do with client.Get. So, it doesn't work either - same result. I added php code getting example.com via tun0 and it's out. It's what I expect from Go code I'm trying to write.

    – edwvee
    Mar 22 at 20:46












  • Yes , the code is basically the same as yours and I expected the same result. You should probably sniff the traffic with tcpdump to see what happens. I kind of doubt it's a bug in golang.

    – user801247
    Mar 22 at 20:47












  • Sniffing the traffic will allow you to see what going on, what are the differences between golang and php + curl.

    – user801247
    Mar 22 at 20:49











  • Or you can try to connect elsewhere, starting with, if possible, on the vpn endpoint itself, see if the error message changes.

    – user801247
    Mar 22 at 20:54


















  • You've just replaced thing about preparing request and client.Do with client.Get. So, it doesn't work either - same result. I added php code getting example.com via tun0 and it's out. It's what I expect from Go code I'm trying to write.

    – edwvee
    Mar 22 at 20:46












  • Yes , the code is basically the same as yours and I expected the same result. You should probably sniff the traffic with tcpdump to see what happens. I kind of doubt it's a bug in golang.

    – user801247
    Mar 22 at 20:47












  • Sniffing the traffic will allow you to see what going on, what are the differences between golang and php + curl.

    – user801247
    Mar 22 at 20:49











  • Or you can try to connect elsewhere, starting with, if possible, on the vpn endpoint itself, see if the error message changes.

    – user801247
    Mar 22 at 20:54

















You've just replaced thing about preparing request and client.Do with client.Get. So, it doesn't work either - same result. I added php code getting example.com via tun0 and it's out. It's what I expect from Go code I'm trying to write.

– edwvee
Mar 22 at 20:46






You've just replaced thing about preparing request and client.Do with client.Get. So, it doesn't work either - same result. I added php code getting example.com via tun0 and it's out. It's what I expect from Go code I'm trying to write.

– edwvee
Mar 22 at 20:46














Yes , the code is basically the same as yours and I expected the same result. You should probably sniff the traffic with tcpdump to see what happens. I kind of doubt it's a bug in golang.

– user801247
Mar 22 at 20:47






Yes , the code is basically the same as yours and I expected the same result. You should probably sniff the traffic with tcpdump to see what happens. I kind of doubt it's a bug in golang.

– user801247
Mar 22 at 20:47














Sniffing the traffic will allow you to see what going on, what are the differences between golang and php + curl.

– user801247
Mar 22 at 20:49





Sniffing the traffic will allow you to see what going on, what are the differences between golang and php + curl.

– user801247
Mar 22 at 20:49













Or you can try to connect elsewhere, starting with, if possible, on the vpn endpoint itself, see if the error message changes.

– user801247
Mar 22 at 20:54






Or you can try to connect elsewhere, starting with, if possible, on the vpn endpoint itself, see if the error message changes.

– user801247
Mar 22 at 20:54




















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55284356%2fgolang-http-client-through-vpn-openvpn-set-network-interface%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

용인 삼성생명 블루밍스 목차 통계 역대 감독 선수단 응원단 경기장 같이 보기 외부 링크 둘러보기 메뉴samsungblueminx.comeh선수 명단용인 삼성생명 블루밍스용인 삼성생명 블루밍스ehsamsungblueminx.comeheheheh

155 수학 과학 기타 둘러보기 메뉴eh추가해eh문서를 완성해