Skip to content

Instantly share code, notes, and snippets.

@habibiefaried
Created September 23, 2024 07:58
Show Gist options
  • Save habibiefaried/292734eddaae5bfaa1a4dc734a605d04 to your computer and use it in GitHub Desktop.
Save habibiefaried/292734eddaae5bfaa1a4dc734a605d04 to your computer and use it in GitHub Desktop.
golang vpn tcp server
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
}
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