Created
September 23, 2024 07:58
-
-
Save habibiefaried/292734eddaae5bfaa1a4dc734a605d04 to your computer and use it in GitHub Desktop.
golang vpn tcp server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"io" | |
"log" | |
"net" | |
"github.com/songgao/water" | |
"github.com/vishvananda/netlink" | |
) | |
func main() { | |
// Setup the TUN interface | |
ifce, err := water.New(water.Config{ | |
DeviceType: water.TUN, | |
}) | |
if err != nil { | |
log.Fatalf("Unable to allocate TUN interface: %v", err) | |
} | |
log.Printf("Interface allocated: %s\n", ifce.Name()) | |
// Setup the TUN interface using netlink | |
err = setupInterface(ifce.Name(), "10.0.0.2/24") | |
if err != nil { | |
log.Fatalf("Failed to set up interface: %v", err) | |
} | |
// Connect to the VPN server | |
conn, err := net.Dial("tcp", "194.233.68.255:48989") // Replace with the actual server IP | |
if err != nil { | |
log.Fatalf("Failed to connect to server: %v", err) | |
} | |
log.Println("Connected to server") | |
// Handle bidirectional communication | |
go transfer(conn, ifce) | |
transfer(ifce, conn) | |
} | |
// transfer data between two interfaces (TUN or TCP) | |
func transfer(dst io.Writer, src io.Reader) { | |
buf := make([]byte, 1500) | |
for { | |
n, err := src.Read(buf) | |
if err != nil { | |
if err == io.EOF { | |
break | |
} | |
log.Println("Read error:", err) | |
return | |
} | |
_, err = dst.Write(buf[:n]) | |
if err != nil { | |
log.Println("Write error:", err) | |
return | |
} | |
} | |
} | |
// Setup the interface using the netlink package | |
func setupInterface(ifaceName string, ipCIDR string) error { | |
// Find the link for the TUN interface | |
link, err := netlink.LinkByName(ifaceName) | |
if err != nil { | |
return err | |
} | |
// Parse the IP address and CIDR | |
addr, err := netlink.ParseAddr(ipCIDR) | |
if err != nil { | |
return err | |
} | |
// Assign the IP address to the TUN interface | |
if err := netlink.AddrAdd(link, addr); err != nil { | |
return err | |
} | |
// Bring the TUN interface up | |
if err := netlink.LinkSetUp(link); err != nil { | |
return err | |
} | |
log.Printf("Interface %s set up with IP %s\n", ifaceName, ipCIDR) | |
return nil | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"io" | |
"log" | |
"net" | |
"github.com/songgao/water" | |
"github.com/vishvananda/netlink" | |
) | |
func main() { | |
// Setup the TUN interface | |
ifce, err := water.New(water.Config{ | |
DeviceType: water.TUN, | |
}) | |
if err != nil { | |
log.Fatalf("Unable to allocate TUN interface: %v", err) | |
} | |
log.Printf("Interface allocated: %s\n", ifce.Name()) | |
// Setup the TUN interface using netlink | |
err = setupInterface(ifce.Name(), "10.0.0.1/24") | |
if err != nil { | |
log.Fatalf("Failed to set up interface: %v", err) | |
} | |
// Listen for incoming client connections on port 48989 | |
listener, err := net.Listen("tcp", ":48989") | |
if err != nil { | |
log.Fatalf("Failed to listen on port 48989: %v", err) | |
} | |
log.Println("Listening on port 48989") | |
// Accept client connections in a loop | |
for { | |
conn, err := listener.Accept() | |
if err != nil { | |
log.Printf("Failed to accept client: %v", err) | |
continue | |
} | |
log.Println("Client connected") | |
// Handle each client connection in a new goroutine | |
go handleClient(conn, ifce) | |
} | |
} | |
// handleClient handles bidirectional communication between the server and the client | |
func handleClient(conn net.Conn, ifce *water.Interface) { | |
defer conn.Close() | |
// Transfer data between the TUN interface and the client | |
go transfer(conn, ifce) | |
transfer(ifce, conn) | |
} | |
// transfer data between two interfaces (TUN or TCP) | |
func transfer(dst io.Writer, src io.Reader) { | |
buf := make([]byte, 1500) | |
for { | |
n, err := src.Read(buf) | |
if err != nil { | |
if err == io.EOF { | |
log.Println("Connection closed") | |
break | |
} | |
log.Println("Read error:", err) | |
return | |
} | |
_, err = dst.Write(buf[:n]) | |
if err != nil { | |
log.Println("Write error:", err) | |
return | |
} | |
} | |
} | |
// Setup the interface using the netlink package | |
func setupInterface(ifaceName string, ipCIDR string) error { | |
// Find the link for the TUN interface | |
link, err := netlink.LinkByName(ifaceName) | |
if err != nil { | |
return err | |
} | |
// Parse the IP address and CIDR | |
addr, err := netlink.ParseAddr(ipCIDR) | |
if err != nil { | |
return err | |
} | |
// Assign the IP address to the TUN interface | |
if err := netlink.AddrAdd(link, addr); err != nil { | |
return err | |
} | |
// Bring the TUN interface up | |
if err := netlink.LinkSetUp(link); err != nil { | |
return err | |
} | |
log.Printf("Interface %s set up with IP %s\n", ifaceName, ipCIDR) | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment