From 29d0bf1ebed114d3d1fe76c07e899065e0b5c571 Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Tue, 3 Nov 2020 18:35:15 +0300 Subject: [PATCH 01/15] Assign server TUN one of local network addresses for testing --- internal/vpn/server.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/vpn/server.go b/internal/vpn/server.go index 01f7633a50..52aa3ecb33 100644 --- a/internal/vpn/server.go +++ b/internal/vpn/server.go @@ -258,6 +258,11 @@ func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, err error) cTUNIP := net.IPv4(subnetOctets[0], subnetOctets[1], subnetOctets[2], subnetOctets[3]+4) cTUNGateway := net.IPv4(subnetOctets[0], subnetOctets[1], subnetOctets[2], subnetOctets[3]+3) + sTUNIP = net.IPv4(192, 168, 1, 18) + sTUNGateway = net.IPv4(192, 168, 1, 17) + cTUNIP = net.IPv4(192, 168, 1, 16) + cTUNGateway = net.IPv4(192, 168, 1, 15) + sHello.TUNIP = cTUNIP sHello.TUNGateway = cTUNGateway From 2439cdaa9b8977be7eb316692d467749e54e2a6e Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Tue, 3 Nov 2020 19:13:57 +0300 Subject: [PATCH 02/15] Revert, exclude some private IPs from generation --- internal/vpn/ip_generator.go | 3 ++- internal/vpn/server.go | 5 ----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/internal/vpn/ip_generator.go b/internal/vpn/ip_generator.go index 6ec61b7e38..10795c22b3 100644 --- a/internal/vpn/ip_generator.go +++ b/internal/vpn/ip_generator.go @@ -17,7 +17,8 @@ type IPGenerator struct { func NewIPGenerator() *IPGenerator { return &IPGenerator{ ranges: []*subnetIPIncrementer{ - newSubnetIPIncrementer([4]uint8{192, 168, 0, 0}, [4]uint8{192, 168, 255, 255}, 8), + // exclude some most commonly used addresses in local networks + newSubnetIPIncrementer([4]uint8{192, 168, 2, 0}, [4]uint8{192, 168, 255, 255}, 8), newSubnetIPIncrementer([4]uint8{172, 16, 0, 0}, [4]uint8{172, 31, 255, 255}, 8), newSubnetIPIncrementer([4]uint8{10, 0, 0, 0}, [4]uint8{10, 255, 255, 255}, 8), }, diff --git a/internal/vpn/server.go b/internal/vpn/server.go index 52aa3ecb33..01f7633a50 100644 --- a/internal/vpn/server.go +++ b/internal/vpn/server.go @@ -258,11 +258,6 @@ func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, err error) cTUNIP := net.IPv4(subnetOctets[0], subnetOctets[1], subnetOctets[2], subnetOctets[3]+4) cTUNGateway := net.IPv4(subnetOctets[0], subnetOctets[1], subnetOctets[2], subnetOctets[3]+3) - sTUNIP = net.IPv4(192, 168, 1, 18) - sTUNGateway = net.IPv4(192, 168, 1, 17) - cTUNIP = net.IPv4(192, 168, 1, 16) - cTUNGateway = net.IPv4(192, 168, 1, 15) - sHello.TUNIP = cTUNIP sHello.TUNGateway = cTUNGateway From d6827d23b810203ac97645ede96aa3e4b273d17f Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Thu, 5 Nov 2020 16:58:26 +0300 Subject: [PATCH 03/15] Block all traffic from client TUN to local network during client/server HS --- internal/vpn/os_server.go | 13 ++++++++++++ internal/vpn/os_server_linux.go | 25 +++++++++++++++++++++++ internal/vpn/server.go | 36 ++++++++++++++++++++++++--------- 3 files changed, 65 insertions(+), 9 deletions(-) diff --git a/internal/vpn/os_server.go b/internal/vpn/os_server.go index 0449a28b6a..ec17deeb50 100644 --- a/internal/vpn/os_server.go +++ b/internal/vpn/os_server.go @@ -4,12 +4,25 @@ package vpn import ( "errors" + "net" ) var ( errServerMethodsNotSupported = errors.New("server related methods are not supported for this OS") ) +// AllowIPToLocalNetwork allows all the packets coming from `source` +// to private IP ranges. +func AllowIPToLocalNetwork(source net.IP) error { + return errServerMethodsNotSupported +} + +// BlockIPToLocalNetwork blocks all the packets coming from `source` +// to private IP ranges. +func BlockIPToLocalNetwork(source net.IP) error { + return errServerMethodsNotSupported +} + // DefaultNetworkInterface fetches default network interface name. func DefaultNetworkInterface() (string, error) { return "", errServerMethodsNotSupported diff --git a/internal/vpn/os_server_linux.go b/internal/vpn/os_server_linux.go index 7444fae670..b79afad4c4 100644 --- a/internal/vpn/os_server_linux.go +++ b/internal/vpn/os_server_linux.go @@ -5,6 +5,7 @@ package vpn import ( "bytes" "fmt" + "net" "os/exec" ) @@ -16,8 +17,32 @@ const ( setIPv6ForwardingCMDFmt = "sysctl -w net.ipv6.conf.all.forwarding=%s" enableIPMasqueradingCMDFmt = "iptables -t nat -A POSTROUTING -o %s -j MASQUERADE" disableIPMasqueradingCMDFmt = "iptables -t nat -D POSTROUTING -o %s -j MASQUERADE" + blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP" + allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP" ) +// AllowIPToLocalNetwork allows all the packets coming from `source` +// to private IP ranges. +func AllowIPToLocalNetwork(source net.IP) error { + cmd := fmt.Sprintf(allowIPToLocalNetCMDFmt, source) + if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec + return fmt.Errorf("error running command %s: %w", cmd, err) + } + + return nil +} + +// BlockIPToLocalNetwork blocks all the packets coming from `source` +// to private IP ranges. +func BlockIPToLocalNetwork(source net.IP) error { + cmd := fmt.Sprintf(blockIPToLocalNetCMDFmt, source) + if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec + return fmt.Errorf("error running command %s: %w", cmd, err) + } + + return nil +} + // DefaultNetworkInterface fetches default network interface name. func DefaultNetworkInterface() (string, error) { outputBytes, err := exec.Command("sh", "-c", defaultNetworkInterfaceCMD).Output() diff --git a/internal/vpn/server.go b/internal/vpn/server.go index 01f7633a50..9eaf8552b1 100644 --- a/internal/vpn/server.go +++ b/internal/vpn/server.go @@ -144,11 +144,12 @@ func (s *Server) closeConn(conn net.Conn) { func (s *Server) serveConn(conn net.Conn) { defer s.closeConn(conn) - tunIP, tunGateway, err := s.shakeHands(conn) + tunIP, tunGateway, allowTraffToLocalNet, err := s.shakeHands(conn) if err != nil { s.log.WithError(err).Errorf("Error negotiating with client %s", conn.RemoteAddr()) return } + defer allowTraffToLocalNet() tun, err := newTUNDevice() if err != nil { @@ -193,10 +194,10 @@ func (s *Server) serveConn(conn net.Conn) { } } -func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, err error) { +func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, allowTrafficToLocalNet func(), err error) { var cHello ClientHello if err := ReadJSON(conn, &cHello); err != nil { - return nil, nil, fmt.Errorf("error reading client hello: %w", err) + return nil, nil, nil, fmt.Errorf("error reading client hello: %w", err) } s.log.Debugf("Got client hello: %v", cHello) @@ -209,7 +210,7 @@ func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, err error) s.log.WithError(err).Errorln("Error sending server hello") } - return nil, nil, errors.New("got wrong passcode from client") + return nil, nil, nil, errors.New("got wrong passcode from client") } for _, ip := range cHello.UnavailablePrivateIPs { @@ -220,7 +221,7 @@ func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, err error) s.log.WithError(err).Errorln("Error sending server hello") } - return nil, nil, fmt.Errorf("error reserving IP %s: %w", ip.String(), err) + return nil, nil, nil, fmt.Errorf("error reserving IP %s: %w", ip.String(), err) } } @@ -231,7 +232,7 @@ func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, err error) s.log.WithError(err).Errorln("Error sending server hello") } - return nil, nil, fmt.Errorf("error getting free subnet IP: %w", err) + return nil, nil, nil, fmt.Errorf("error getting free subnet IP: %w", err) } subnetOctets, err := fetchIPv4Octets(subnet) @@ -241,7 +242,7 @@ func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, err error) s.log.WithError(err).Errorln("Error sending server hello") } - return nil, nil, fmt.Errorf("error breaking IP into octets: %w", err) + return nil, nil, nil, fmt.Errorf("error breaking IP into octets: %w", err) } // basically IP address comprised of `subnetOctets` items is the IP address of the subnet, @@ -258,12 +259,29 @@ func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, err error) cTUNIP := net.IPv4(subnetOctets[0], subnetOctets[1], subnetOctets[2], subnetOctets[3]+4) cTUNGateway := net.IPv4(subnetOctets[0], subnetOctets[1], subnetOctets[2], subnetOctets[3]+3) + if err := BlockIPToLocalNetwork(cTUNIP); err != nil { + sHello.Status = HandshakeStatusInternalError + if err := WriteJSON(conn, &sHello); err != nil { + s.log.WithError(err).Errorln("Error sending server hello") + } + + return nil, nil, nil, + fmt.Errorf("error securing local network for IP %s: %w", cTUNIP, err) + } + + allowTrafficToLocalNet = func() { + if err := AllowIPToLocalNetwork(cTUNIP); err != nil { + s.log.WithError(err).Errorln("Error allowing traffic to local network") + } + } + sHello.TUNIP = cTUNIP sHello.TUNGateway = cTUNGateway if err := WriteJSON(conn, &sHello); err != nil { - return nil, nil, fmt.Errorf("error finishing hadnshake: error sending server hello: %w", err) + allowTrafficToLocalNet() + return nil, nil, nil, fmt.Errorf("error finishing hadnshake: error sending server hello: %w", err) } - return sTUNIP, sTUNGateway, nil + return sTUNIP, sTUNGateway, allowTrafficToLocalNet, nil } From d284badd54cfac9e5e4c2c2750d42f6b12f8d0c3 Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Fri, 6 Nov 2020 18:08:23 +0300 Subject: [PATCH 04/15] Prevent client->server, server->client SSH, make network security optional --- cmd/apps/vpn-server/vpn-server.go | 2 + internal/vpn/os_server.go | 14 ++++- internal/vpn/os_server_linux.go | 22 ++++++++ internal/vpn/server.go | 85 +++++++++++++++++-------------- internal/vpn/server_config.go | 1 + 5 files changed, 85 insertions(+), 39 deletions(-) diff --git a/cmd/apps/vpn-server/vpn-server.go b/cmd/apps/vpn-server/vpn-server.go index b934addee2..db19315563 100644 --- a/cmd/apps/vpn-server/vpn-server.go +++ b/cmd/apps/vpn-server/vpn-server.go @@ -30,6 +30,7 @@ var ( localPKStr = flag.String("pk", "", "Local PubKey") localSKStr = flag.String("sk", "", "Local SecKey") passcode = flag.String("passcode", "", "Passcode to authenticate connecting users") + secure = flag.Bool("secure", true, "Forbid connections from clients to server local network") ) func main() { @@ -73,6 +74,7 @@ func main() { srvCfg := vpn.ServerConfig{ Passcode: *passcode, + Secure: *secure, } srv, err := vpn.NewServer(srvCfg, log) if err != nil { diff --git a/internal/vpn/os_server.go b/internal/vpn/os_server.go index ec17deeb50..01214c52fd 100644 --- a/internal/vpn/os_server.go +++ b/internal/vpn/os_server.go @@ -11,15 +11,25 @@ var ( errServerMethodsNotSupported = errors.New("server related methods are not supported for this OS") ) +// AllowSSH allows all SSH traffic (via default 22 port) between `src` and `dst`. +func AllowSSH(_, _ net.IP) error { + return errServerMethodsNotSupported +} + +// BlockSSH blocks all SSH traffic (via default 22 port) between `src` and `dst`. +func BlockSSH(_, _ net.IP) error { + return errServerMethodsNotSupported +} + // AllowIPToLocalNetwork allows all the packets coming from `source` // to private IP ranges. -func AllowIPToLocalNetwork(source net.IP) error { +func AllowIPToLocalNetwork(_ net.IP) error { return errServerMethodsNotSupported } // BlockIPToLocalNetwork blocks all the packets coming from `source` // to private IP ranges. -func BlockIPToLocalNetwork(source net.IP) error { +func BlockIPToLocalNetwork(_ net.IP) error { return errServerMethodsNotSupported } diff --git a/internal/vpn/os_server_linux.go b/internal/vpn/os_server_linux.go index b79afad4c4..672910efab 100644 --- a/internal/vpn/os_server_linux.go +++ b/internal/vpn/os_server_linux.go @@ -19,8 +19,30 @@ const ( disableIPMasqueradingCMDFmt = "iptables -t nat -D POSTROUTING -o %s -j MASQUERADE" blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP" allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP" + blockSSHCMDFmt = "iptables -I FORWARD -p tcp --dport 22 -d %s,%s -s %s,%s -j DROP" + allowSSHCMDFmt = "iptables -D FORWARD -p tcp --dport 22 -d %s,%s -s %s,%s -j DROP" ) +// AllowSSH allows all SSH traffic (via default 22 port) between `src` and `dst`. +func AllowSSH(src, dst net.IP) error { + cmd := fmt.Sprintf(allowSSHCMDFmt, dst, src, dst, src) + if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec + return fmt.Errorf("error running command %s: %w", cmd, err) + } + + return nil +} + +// BlockSSH blocks all SSH traffic (via default 22 port) between `src` and `dst`. +func BlockSSH(src, dst net.IP) error { + cmd := fmt.Sprintf(blockSSHCMDFmt, dst, src, dst, src) + if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec + return fmt.Errorf("error running command %s: %w", cmd, err) + } + + return nil +} + // AllowIPToLocalNetwork allows all the packets coming from `source` // to private IP ranges. func AllowIPToLocalNetwork(source net.IP) error { diff --git a/internal/vpn/server.go b/internal/vpn/server.go index 9eaf8552b1..76dd9d2d24 100644 --- a/internal/vpn/server.go +++ b/internal/vpn/server.go @@ -194,54 +194,39 @@ func (s *Server) serveConn(conn net.Conn) { } } -func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, allowTrafficToLocalNet func(), err error) { +func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, unsecureVPN func(), err error) { var cHello ClientHello if err := ReadJSON(conn, &cHello); err != nil { return nil, nil, nil, fmt.Errorf("error reading client hello: %w", err) } - s.log.Debugf("Got client hello: %v", cHello) + // default value + unsecureVPN = func() {} - var sHello ServerHello + s.log.Debugf("Got client hello: %v", cHello) if s.cfg.Passcode != "" && cHello.Passcode != s.cfg.Passcode { - sHello.Status = HandshakeStatusForbidden - if err := WriteJSON(conn, &sHello); err != nil { - s.log.WithError(err).Errorln("Error sending server hello") - } - + s.sendServerErrHello(conn, HandshakeStatusForbidden) return nil, nil, nil, errors.New("got wrong passcode from client") } for _, ip := range cHello.UnavailablePrivateIPs { if err := s.ipGen.Reserve(ip); err != nil { // this happens only on malformed IP - sHello.Status = HandshakeStatusBadRequest - if err := WriteJSON(conn, &sHello); err != nil { - s.log.WithError(err).Errorln("Error sending server hello") - } - + s.sendServerErrHello(conn, HandshakeStatusBadRequest) return nil, nil, nil, fmt.Errorf("error reserving IP %s: %w", ip.String(), err) } } subnet, err := s.ipGen.Next() if err != nil { - sHello.Status = HandshakeNoFreeIPs - if err := WriteJSON(conn, &sHello); err != nil { - s.log.WithError(err).Errorln("Error sending server hello") - } - + s.sendServerErrHello(conn, HandshakeNoFreeIPs) return nil, nil, nil, fmt.Errorf("error getting free subnet IP: %w", err) } subnetOctets, err := fetchIPv4Octets(subnet) if err != nil { - sHello.Status = HandshakeStatusInternalError - if err := WriteJSON(conn, &sHello); err != nil { - s.log.WithError(err).Errorln("Error sending server hello") - } - + s.sendServerErrHello(conn, HandshakeStatusInternalError) return nil, nil, nil, fmt.Errorf("error breaking IP into octets: %w", err) } @@ -259,29 +244,55 @@ func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, allowTraff cTUNIP := net.IPv4(subnetOctets[0], subnetOctets[1], subnetOctets[2], subnetOctets[3]+4) cTUNGateway := net.IPv4(subnetOctets[0], subnetOctets[1], subnetOctets[2], subnetOctets[3]+3) - if err := BlockIPToLocalNetwork(cTUNIP); err != nil { - sHello.Status = HandshakeStatusInternalError - if err := WriteJSON(conn, &sHello); err != nil { - s.log.WithError(err).Errorln("Error sending server hello") + if s.cfg.Secure { + if err := BlockIPToLocalNetwork(cTUNIP); err != nil { + s.sendServerErrHello(conn, HandshakeStatusInternalError) + return nil, nil, nil, + fmt.Errorf("error securing local network for IP %s: %w", cTUNIP, err) } - return nil, nil, nil, - fmt.Errorf("error securing local network for IP %s: %w", cTUNIP, err) - } + allowLocalNetTraff := func() { + if err := AllowIPToLocalNetwork(cTUNIP); err != nil { + s.log.WithError(err).Errorln("Error allowing traffic to local network") + } + } + + if err := BlockSSH(cTUNIP, sTUNIP); err != nil { + s.sendServerErrHello(conn, HandshakeStatusInternalError) + allowLocalNetTraff() + return nil, nil, nil, + fmt.Errorf("error securing local network for IP %s: %w", cTUNIP, err) + } - allowTrafficToLocalNet = func() { - if err := AllowIPToLocalNetwork(cTUNIP); err != nil { - s.log.WithError(err).Errorln("Error allowing traffic to local network") + unsecureVPN = func() { + allowLocalNetTraff() + + if err := AllowSSH(cTUNIP, sTUNIP); err != nil { + s.log.WithError(err).Errorln("Error allowing SSH through") + } } } - sHello.TUNIP = cTUNIP - sHello.TUNGateway = cTUNGateway + sHello := ServerHello{ + Status: HandshakeStatusOK, + TUNIP: cTUNIP, + TUNGateway: cTUNGateway, + } if err := WriteJSON(conn, &sHello); err != nil { - allowTrafficToLocalNet() + unsecureVPN() return nil, nil, nil, fmt.Errorf("error finishing hadnshake: error sending server hello: %w", err) } - return sTUNIP, sTUNGateway, allowTrafficToLocalNet, nil + return sTUNIP, sTUNGateway, unsecureVPN, nil +} + +func (s *Server) sendServerErrHello(conn net.Conn, status HandshakeStatus) { + sHello := ServerHello{ + Status: status, + } + + if err := WriteJSON(conn, &sHello); err != nil { + s.log.WithError(err).Errorln("Error sending server hello") + } } diff --git a/internal/vpn/server_config.go b/internal/vpn/server_config.go index e1e6a51776..b954765984 100644 --- a/internal/vpn/server_config.go +++ b/internal/vpn/server_config.go @@ -3,4 +3,5 @@ package vpn // ServerConfig is a configuration for VPN server. type ServerConfig struct { Passcode string + Secure bool } From 90e1c22d84fa9f51297868577db50af3d34cdc80 Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Fri, 6 Nov 2020 18:31:09 +0300 Subject: [PATCH 05/15] Allow packets valid through server TUN --- internal/vpn/os_server.go | 4 ++-- internal/vpn/os_server_linux.go | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/internal/vpn/os_server.go b/internal/vpn/os_server.go index 01214c52fd..43d7aeb34b 100644 --- a/internal/vpn/os_server.go +++ b/internal/vpn/os_server.go @@ -23,13 +23,13 @@ func BlockSSH(_, _ net.IP) error { // AllowIPToLocalNetwork allows all the packets coming from `source` // to private IP ranges. -func AllowIPToLocalNetwork(_ net.IP) error { +func AllowIPToLocalNetwork(_, _ net.IP) error { return errServerMethodsNotSupported } // BlockIPToLocalNetwork blocks all the packets coming from `source` // to private IP ranges. -func BlockIPToLocalNetwork(_ net.IP) error { +func BlockIPToLocalNetwork(_, _ net.IP) error { return errServerMethodsNotSupported } diff --git a/internal/vpn/os_server_linux.go b/internal/vpn/os_server_linux.go index 672910efab..ab857d9f89 100644 --- a/internal/vpn/os_server_linux.go +++ b/internal/vpn/os_server_linux.go @@ -17,8 +17,8 @@ const ( setIPv6ForwardingCMDFmt = "sysctl -w net.ipv6.conf.all.forwarding=%s" enableIPMasqueradingCMDFmt = "iptables -t nat -A POSTROUTING -o %s -j MASQUERADE" disableIPMasqueradingCMDFmt = "iptables -t nat -D POSTROUTING -o %s -j MASQUERADE" - blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP" - allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP" + blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -I FORWARD -d %s -s %s -j ACCEPT" + allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -I FORWARD -d %s -s %s -j ACCEPT" blockSSHCMDFmt = "iptables -I FORWARD -p tcp --dport 22 -d %s,%s -s %s,%s -j DROP" allowSSHCMDFmt = "iptables -D FORWARD -p tcp --dport 22 -d %s,%s -s %s,%s -j DROP" ) @@ -45,8 +45,8 @@ func BlockSSH(src, dst net.IP) error { // AllowIPToLocalNetwork allows all the packets coming from `source` // to private IP ranges. -func AllowIPToLocalNetwork(source net.IP) error { - cmd := fmt.Sprintf(allowIPToLocalNetCMDFmt, source) +func AllowIPToLocalNetwork(src, dst net.IP) error { + cmd := fmt.Sprintf(allowIPToLocalNetCMDFmt, src, dst, src) if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec return fmt.Errorf("error running command %s: %w", cmd, err) } @@ -56,8 +56,8 @@ func AllowIPToLocalNetwork(source net.IP) error { // BlockIPToLocalNetwork blocks all the packets coming from `source` // to private IP ranges. -func BlockIPToLocalNetwork(source net.IP) error { - cmd := fmt.Sprintf(blockIPToLocalNetCMDFmt, source) +func BlockIPToLocalNetwork(src, dst net.IP) error { + cmd := fmt.Sprintf(blockIPToLocalNetCMDFmt, src, dst, src) if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec return fmt.Errorf("error running command %s: %w", cmd, err) } From 211e93539c712516b0591f7c2ef5b0c3818cb3da Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Fri, 6 Nov 2020 18:33:01 +0300 Subject: [PATCH 06/15] Fix --- internal/vpn/server.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/vpn/server.go b/internal/vpn/server.go index 76dd9d2d24..0c94f913f2 100644 --- a/internal/vpn/server.go +++ b/internal/vpn/server.go @@ -245,14 +245,14 @@ func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, unsecureVP cTUNGateway := net.IPv4(subnetOctets[0], subnetOctets[1], subnetOctets[2], subnetOctets[3]+3) if s.cfg.Secure { - if err := BlockIPToLocalNetwork(cTUNIP); err != nil { + if err := BlockIPToLocalNetwork(cTUNIP, sTUNIP); err != nil { s.sendServerErrHello(conn, HandshakeStatusInternalError) return nil, nil, nil, fmt.Errorf("error securing local network for IP %s: %w", cTUNIP, err) } allowLocalNetTraff := func() { - if err := AllowIPToLocalNetwork(cTUNIP); err != nil { + if err := AllowIPToLocalNetwork(cTUNIP, sTUNIP); err != nil { s.log.WithError(err).Errorln("Error allowing traffic to local network") } } From 950d22952ea560ecdfd5513883abf4dcf0628446 Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Fri, 6 Nov 2020 18:38:31 +0300 Subject: [PATCH 07/15] Fix network securing cleanup command --- internal/vpn/os_server_linux.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/vpn/os_server_linux.go b/internal/vpn/os_server_linux.go index ab857d9f89..a104f1f1aa 100644 --- a/internal/vpn/os_server_linux.go +++ b/internal/vpn/os_server_linux.go @@ -18,7 +18,7 @@ const ( enableIPMasqueradingCMDFmt = "iptables -t nat -A POSTROUTING -o %s -j MASQUERADE" disableIPMasqueradingCMDFmt = "iptables -t nat -D POSTROUTING -o %s -j MASQUERADE" blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -I FORWARD -d %s -s %s -j ACCEPT" - allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -I FORWARD -d %s -s %s -j ACCEPT" + allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -D FORWARD -d %s -s %s -j ACCEPT" blockSSHCMDFmt = "iptables -I FORWARD -p tcp --dport 22 -d %s,%s -s %s,%s -j DROP" allowSSHCMDFmt = "iptables -D FORWARD -p tcp --dport 22 -d %s,%s -s %s,%s -j DROP" ) From 3c881994c98e992579bc91e011c8faf34c4d0f9a Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Mon, 9 Nov 2020 14:53:40 +0300 Subject: [PATCH 08/15] Properly block client->server SSH --- internal/vpn/os_server_linux.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/vpn/os_server_linux.go b/internal/vpn/os_server_linux.go index a104f1f1aa..34e2e216e7 100644 --- a/internal/vpn/os_server_linux.go +++ b/internal/vpn/os_server_linux.go @@ -19,8 +19,8 @@ const ( disableIPMasqueradingCMDFmt = "iptables -t nat -D POSTROUTING -o %s -j MASQUERADE" blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -I FORWARD -d %s -s %s -j ACCEPT" allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -D FORWARD -d %s -s %s -j ACCEPT" - blockSSHCMDFmt = "iptables -I FORWARD -p tcp --dport 22 -d %s,%s -s %s,%s -j DROP" - allowSSHCMDFmt = "iptables -D FORWARD -p tcp --dport 22 -d %s,%s -s %s,%s -j DROP" + blockSSHCMDFmt = "iptables -I FORWARD -p tcp --dport 22 -d %s,%s -s %s,%s -j DROP && iptables -I INPUT -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -p tcp --dport 22 -j DROP" + allowSSHCMDFmt = "iptables -D FORWARD -p tcp --dport 22 -d %s,%s -s %s,%s -j DROP && iptables -D INPUT -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -p tcp --dport 22 -j DROP" ) // AllowSSH allows all SSH traffic (via default 22 port) between `src` and `dst`. From c279b19d2cc7261d2740c93ec24b93c909b75109 Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Mon, 9 Nov 2020 15:02:29 +0300 Subject: [PATCH 09/15] Fix SSH block/allow commands formatting --- internal/vpn/os_server_linux.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/vpn/os_server_linux.go b/internal/vpn/os_server_linux.go index 34e2e216e7..a7708d2dea 100644 --- a/internal/vpn/os_server_linux.go +++ b/internal/vpn/os_server_linux.go @@ -25,7 +25,7 @@ const ( // AllowSSH allows all SSH traffic (via default 22 port) between `src` and `dst`. func AllowSSH(src, dst net.IP) error { - cmd := fmt.Sprintf(allowSSHCMDFmt, dst, src, dst, src) + cmd := fmt.Sprintf(allowSSHCMDFmt, dst, src, dst, src, src) if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec return fmt.Errorf("error running command %s: %w", cmd, err) } @@ -35,7 +35,7 @@ func AllowSSH(src, dst net.IP) error { // BlockSSH blocks all SSH traffic (via default 22 port) between `src` and `dst`. func BlockSSH(src, dst net.IP) error { - cmd := fmt.Sprintf(blockSSHCMDFmt, dst, src, dst, src) + cmd := fmt.Sprintf(blockSSHCMDFmt, dst, src, dst, src, src) if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec return fmt.Errorf("error running command %s: %w", cmd, err) } From 55af60d595f2778cba7262f898b4ba35052e237d Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Wed, 11 Nov 2020 17:07:45 +0300 Subject: [PATCH 10/15] Change log text --- internal/vpn/os.go | 65 +++++++++++++++++++++++++++++++++ internal/vpn/os_client.go | 52 -------------------------- internal/vpn/os_server.go | 4 +- internal/vpn/os_server_linux.go | 23 +++++++++--- internal/vpn/server.go | 31 ++++++++++------ 5 files changed, 104 insertions(+), 71 deletions(-) delete mode 100644 internal/vpn/os_client.go diff --git a/internal/vpn/os.go b/internal/vpn/os.go index 58a9caecfe..d703645925 100644 --- a/internal/vpn/os.go +++ b/internal/vpn/os.go @@ -7,6 +7,71 @@ import ( "os/exec" ) +// LocalNetworkInterfaceIPs gets IPs of all local interfaces. +func LocalNetworkInterfaceIPs() ([]net.IP, error) { + ips, _, err := localNetworkInterfaceIPs("") + return ips, err +} + +// NetworkInterfaceIPs gets IPs of network interface with name `name`. +func NetworkInterfaceIPs(name string) ([]net.IP, error) { + _, ifcIPs, err := localNetworkInterfaceIPs(name) + return ifcIPs, err +} + +// localNetworkInterfaceIPs gets IPs of all local interfaces. Separately returns list of IPs +// of interface `ifcName`. +func localNetworkInterfaceIPs(ifcName string) ([]net.IP, []net.IP, error) { + var ifcIPs []net.IP + + ifaces, err := net.Interfaces() + if err != nil { + return nil, nil, fmt.Errorf("error getting network interfaces: %w", err) + } + + var ips []net.IP + for _, iface := range ifaces { + if iface.Flags&net.FlagUp == 0 { + continue // interface down + } + if iface.Flags&net.FlagLoopback != 0 { + continue // loopback interface + } + + addrs, err := iface.Addrs() + if err != nil { + return nil, nil, fmt.Errorf("error getting addresses for interface %s: %w", iface.Name, err) + } + + for _, addr := range addrs { + var ip net.IP + switch v := addr.(type) { + case *net.IPNet: + ip = v.IP + case *net.IPAddr: + ip = v.IP + } + + if ip == nil || ip.IsLoopback() { + continue + } + + ip = ip.To4() + if ip == nil { + continue // not an ipv4 address + } + + ips = append(ips, ip) + + if ifcName != "" && iface.Name == ifcName { + ifcIPs = append(ifcIPs, ip) + } + } + } + + return ips, ifcIPs, nil +} + func parseCIDR(ipCIDR string) (ipStr, netmask string, err error) { ip, net, err := net.ParseCIDR(ipCIDR) if err != nil { diff --git a/internal/vpn/os_client.go b/internal/vpn/os_client.go deleted file mode 100644 index 4e1aab4f0e..0000000000 --- a/internal/vpn/os_client.go +++ /dev/null @@ -1,52 +0,0 @@ -package vpn - -import ( - "fmt" - "net" -) - -// LocalNetworkInterfaceIPs gets IPs of all local interfaces. -func LocalNetworkInterfaceIPs() ([]net.IP, error) { - ifaces, err := net.Interfaces() - if err != nil { - return nil, fmt.Errorf("error getting network interfaces: %w", err) - } - - var ips []net.IP - for _, iface := range ifaces { - if iface.Flags&net.FlagUp == 0 { - continue // interface down - } - if iface.Flags&net.FlagLoopback != 0 { - continue // loopback interface - } - - addrs, err := iface.Addrs() - if err != nil { - return nil, fmt.Errorf("error getting addresses for interface %s: %w", iface.Name, err) - } - - for _, addr := range addrs { - var ip net.IP - switch v := addr.(type) { - case *net.IPNet: - ip = v.IP - case *net.IPAddr: - ip = v.IP - } - - if ip == nil || ip.IsLoopback() { - continue - } - - ip = ip.To4() - if ip == nil { - continue // not an ipv4 address - } - - ips = append(ips, ip) - } - } - - return ips, nil -} diff --git a/internal/vpn/os_server.go b/internal/vpn/os_server.go index 43d7aeb34b..8daa14e442 100644 --- a/internal/vpn/os_server.go +++ b/internal/vpn/os_server.go @@ -12,12 +12,12 @@ var ( ) // AllowSSH allows all SSH traffic (via default 22 port) between `src` and `dst`. -func AllowSSH(_, _ net.IP) error { +func AllowSSH(_, _ net.IP, _ []net.IP) error { return errServerMethodsNotSupported } // BlockSSH blocks all SSH traffic (via default 22 port) between `src` and `dst`. -func BlockSSH(_, _ net.IP) error { +func BlockSSH(_, _ net.IP, _ []net.IP) error { return errServerMethodsNotSupported } diff --git a/internal/vpn/os_server_linux.go b/internal/vpn/os_server_linux.go index a7708d2dea..8abebe758c 100644 --- a/internal/vpn/os_server_linux.go +++ b/internal/vpn/os_server_linux.go @@ -7,6 +7,7 @@ import ( "fmt" "net" "os/exec" + "strings" ) const ( @@ -19,13 +20,18 @@ const ( disableIPMasqueradingCMDFmt = "iptables -t nat -D POSTROUTING -o %s -j MASQUERADE" blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -I FORWARD -d %s -s %s -j ACCEPT" allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -D FORWARD -d %s -s %s -j ACCEPT" - blockSSHCMDFmt = "iptables -I FORWARD -p tcp --dport 22 -d %s,%s -s %s,%s -j DROP && iptables -I INPUT -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -p tcp --dport 22 -j DROP" - allowSSHCMDFmt = "iptables -D FORWARD -p tcp --dport 22 -d %s,%s -s %s,%s -j DROP && iptables -D INPUT -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -p tcp --dport 22 -j DROP" + blockSSHCMDFmt = "iptables -I FORWARD -p tcp --dport 22 -d %s,%s -s %s,%s -j DROP && iptables -I INPUT -d %s -s %s -j DROP" + allowSSHCMDFmt = "iptables -D FORWARD -p tcp --dport 22 -d %s,%s -s %s,%s -j DROP && iptables -D INPUT -d %s -s %s -j DROP" ) // AllowSSH allows all SSH traffic (via default 22 port) between `src` and `dst`. -func AllowSSH(src, dst net.IP) error { - cmd := fmt.Sprintf(allowSSHCMDFmt, dst, src, dst, src, src) +func AllowSSH(src, dst net.IP, defaultNetIfcIPs []net.IP) error { + defaultNetIfcIPsStr := make([]string, 0, len(defaultNetIfcIPs)) + for _, ip := range defaultNetIfcIPs { + defaultNetIfcIPsStr = append(defaultNetIfcIPsStr, ip.String()) + } + + cmd := fmt.Sprintf(allowSSHCMDFmt, dst, src, dst, src, strings.Join(defaultNetIfcIPsStr, ","), src) if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec return fmt.Errorf("error running command %s: %w", cmd, err) } @@ -34,8 +40,13 @@ func AllowSSH(src, dst net.IP) error { } // BlockSSH blocks all SSH traffic (via default 22 port) between `src` and `dst`. -func BlockSSH(src, dst net.IP) error { - cmd := fmt.Sprintf(blockSSHCMDFmt, dst, src, dst, src, src) +func BlockSSH(src, dst net.IP, defaultNetIfcIPs []net.IP) error { + defaultNetIfcIPsStr := make([]string, 0, len(defaultNetIfcIPs)) + for _, ip := range defaultNetIfcIPs { + defaultNetIfcIPsStr = append(defaultNetIfcIPsStr, ip.String()) + } + + cmd := fmt.Sprintf(blockSSHCMDFmt, dst, src, dst, src, strings.Join(defaultNetIfcIPsStr, ","), src) if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec return fmt.Errorf("error running command %s: %w", cmd, err) } diff --git a/internal/vpn/server.go b/internal/vpn/server.go index 0c94f913f2..633451f785 100644 --- a/internal/vpn/server.go +++ b/internal/vpn/server.go @@ -12,15 +12,16 @@ import ( // Server is a VPN server. type Server struct { - cfg ServerConfig - lisMx sync.Mutex - lis net.Listener - log logrus.FieldLogger - serveOnce sync.Once - ipGen *IPGenerator - defaultNetworkInterface string - ipv4ForwardingVal string - ipv6ForwardingVal string + cfg ServerConfig + lisMx sync.Mutex + lis net.Listener + log logrus.FieldLogger + serveOnce sync.Once + ipGen *IPGenerator + defaultNetworkInterface string + defaultNetworkInterfaceIPs []net.IP + ipv4ForwardingVal string + ipv6ForwardingVal string } // NewServer creates VPN server instance. @@ -38,6 +39,13 @@ func NewServer(cfg ServerConfig, l logrus.FieldLogger) (*Server, error) { l.Infof("Got default network interface: %s", defaultNetworkIfc) + defaultNetworkIfcIPs, err := NetworkInterfaceIPs(defaultNetworkIfc) + if err != nil { + return nil, fmt.Errorf("error getting IPs of interface %s: %w", defaultNetworkIfc, err) + } + + l.Infof("Got IPs of interface %s: %v", defaultNetworkIfc, defaultNetworkIfcIPs) + ipv4ForwardingVal, err := GetIPv4ForwardingValue() if err != nil { return nil, fmt.Errorf("error getting IPv4 forwarding value: %w", err) @@ -51,6 +59,7 @@ func NewServer(cfg ServerConfig, l logrus.FieldLogger) (*Server, error) { l.Infof("IPv4: %s, IPv6: %s", ipv4ForwardingVal, ipv6ForwardingVal) s.defaultNetworkInterface = defaultNetworkIfc + s.defaultNetworkInterfaceIPs = defaultNetworkIfcIPs s.ipv4ForwardingVal = ipv4ForwardingVal s.ipv6ForwardingVal = ipv6ForwardingVal @@ -257,7 +266,7 @@ func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, unsecureVP } } - if err := BlockSSH(cTUNIP, sTUNIP); err != nil { + if err := BlockSSH(cTUNIP, sTUNIP, s.defaultNetworkInterfaceIPs); err != nil { s.sendServerErrHello(conn, HandshakeStatusInternalError) allowLocalNetTraff() return nil, nil, nil, @@ -267,7 +276,7 @@ func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, unsecureVP unsecureVPN = func() { allowLocalNetTraff() - if err := AllowSSH(cTUNIP, sTUNIP); err != nil { + if err := AllowSSH(cTUNIP, sTUNIP, s.defaultNetworkInterfaceIPs); err != nil { s.log.WithError(err).Errorln("Error allowing SSH through") } } From b7483ea42d581e0659a97dea53858660b31a6024 Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Wed, 11 Nov 2020 18:35:15 +0300 Subject: [PATCH 11/15] Change iptables cmds --- internal/vpn/os_server_linux.go | 12 ++++++------ internal/vpn/server.go | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/internal/vpn/os_server_linux.go b/internal/vpn/os_server_linux.go index 8abebe758c..c15025f551 100644 --- a/internal/vpn/os_server_linux.go +++ b/internal/vpn/os_server_linux.go @@ -18,10 +18,10 @@ const ( setIPv6ForwardingCMDFmt = "sysctl -w net.ipv6.conf.all.forwarding=%s" enableIPMasqueradingCMDFmt = "iptables -t nat -A POSTROUTING -o %s -j MASQUERADE" disableIPMasqueradingCMDFmt = "iptables -t nat -D POSTROUTING -o %s -j MASQUERADE" - blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -I FORWARD -d %s -s %s -j ACCEPT" - allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -D FORWARD -d %s -s %s -j ACCEPT" - blockSSHCMDFmt = "iptables -I FORWARD -p tcp --dport 22 -d %s,%s -s %s,%s -j DROP && iptables -I INPUT -d %s -s %s -j DROP" - allowSSHCMDFmt = "iptables -D FORWARD -p tcp --dport 22 -d %s,%s -s %s,%s -j DROP && iptables -D INPUT -d %s -s %s -j DROP" + blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -I INPUT -d %s -s %s -j DROP && iptables -I FORWARD -d %s -s %s -j ACCEPT" + allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -D INPUT -d %s -s %s -j DROP && iptables -D FORWARD -d %s -s %s -j ACCEPT" + blockSSHCMDFmt = "iptables -I FORWARD -d %s,%s -s %s,%s -j DROP && iptables -I INPUT -d %s -s %s -j DROP" + allowSSHCMDFmt = "iptables -D FORWARD -d %s,%s -s %s,%s -j DROP && iptables -D INPUT -d %s -s %s -j DROP" ) // AllowSSH allows all SSH traffic (via default 22 port) between `src` and `dst`. @@ -57,7 +57,7 @@ func BlockSSH(src, dst net.IP, defaultNetIfcIPs []net.IP) error { // AllowIPToLocalNetwork allows all the packets coming from `source` // to private IP ranges. func AllowIPToLocalNetwork(src, dst net.IP) error { - cmd := fmt.Sprintf(allowIPToLocalNetCMDFmt, src, dst, src) + cmd := fmt.Sprintf(allowIPToLocalNetCMDFmt, src, dst, src, dst, src) if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec return fmt.Errorf("error running command %s: %w", cmd, err) } @@ -68,7 +68,7 @@ func AllowIPToLocalNetwork(src, dst net.IP) error { // BlockIPToLocalNetwork blocks all the packets coming from `source` // to private IP ranges. func BlockIPToLocalNetwork(src, dst net.IP) error { - cmd := fmt.Sprintf(blockIPToLocalNetCMDFmt, src, dst, src) + cmd := fmt.Sprintf(blockIPToLocalNetCMDFmt, src, dst, src, dst, src) if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec return fmt.Errorf("error running command %s: %w", cmd, err) } diff --git a/internal/vpn/server.go b/internal/vpn/server.go index 633451f785..6d3809ba69 100644 --- a/internal/vpn/server.go +++ b/internal/vpn/server.go @@ -266,19 +266,19 @@ func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, unsecureVP } } - if err := BlockSSH(cTUNIP, sTUNIP, s.defaultNetworkInterfaceIPs); err != nil { + /*if err := BlockSSH(cTUNIP, sTUNIP, s.defaultNetworkInterfaceIPs); err != nil { s.sendServerErrHello(conn, HandshakeStatusInternalError) allowLocalNetTraff() return nil, nil, nil, fmt.Errorf("error securing local network for IP %s: %w", cTUNIP, err) - } + }*/ unsecureVPN = func() { allowLocalNetTraff() - if err := AllowSSH(cTUNIP, sTUNIP, s.defaultNetworkInterfaceIPs); err != nil { + /*if err := AllowSSH(cTUNIP, sTUNIP, s.defaultNetworkInterfaceIPs); err != nil { s.log.WithError(err).Errorln("Error allowing SSH through") - } + }*/ } } From 84da3d728e03e4e225bf5d4fd0d9143e1481bb50 Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Wed, 11 Nov 2020 18:43:10 +0300 Subject: [PATCH 12/15] Change iptables cmds --- internal/vpn/os_server_linux.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/internal/vpn/os_server_linux.go b/internal/vpn/os_server_linux.go index c15025f551..9033cb1feb 100644 --- a/internal/vpn/os_server_linux.go +++ b/internal/vpn/os_server_linux.go @@ -18,10 +18,12 @@ const ( setIPv6ForwardingCMDFmt = "sysctl -w net.ipv6.conf.all.forwarding=%s" enableIPMasqueradingCMDFmt = "iptables -t nat -A POSTROUTING -o %s -j MASQUERADE" disableIPMasqueradingCMDFmt = "iptables -t nat -D POSTROUTING -o %s -j MASQUERADE" - blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -I INPUT -d %s -s %s -j DROP && iptables -I FORWARD -d %s -s %s -j ACCEPT" - allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -D INPUT -d %s -s %s -j DROP && iptables -D FORWARD -d %s -s %s -j ACCEPT" - blockSSHCMDFmt = "iptables -I FORWARD -d %s,%s -s %s,%s -j DROP && iptables -I INPUT -d %s -s %s -j DROP" - allowSSHCMDFmt = "iptables -D FORWARD -d %s,%s -s %s,%s -j DROP && iptables -D INPUT -d %s -s %s -j DROP" + //blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -I INPUT -d %s -s %s -j DROP && iptables -I FORWARD -d %s -s %s -j ACCEPT" + //allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -D INPUT -d %s -s %s -j DROP && iptables -D FORWARD -d %s -s %s -j ACCEPT" + blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP" + allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP" + blockSSHCMDFmt = "iptables -I FORWARD -d %s,%s -s %s,%s -j DROP && iptables -I INPUT -d %s -s %s -j DROP" + allowSSHCMDFmt = "iptables -D FORWARD -d %s,%s -s %s,%s -j DROP && iptables -D INPUT -d %s -s %s -j DROP" ) // AllowSSH allows all SSH traffic (via default 22 port) between `src` and `dst`. @@ -57,7 +59,8 @@ func BlockSSH(src, dst net.IP, defaultNetIfcIPs []net.IP) error { // AllowIPToLocalNetwork allows all the packets coming from `source` // to private IP ranges. func AllowIPToLocalNetwork(src, dst net.IP) error { - cmd := fmt.Sprintf(allowIPToLocalNetCMDFmt, src, dst, src, dst, src) + //cmd := fmt.Sprintf(allowIPToLocalNetCMDFmt, src, dst, src, dst, src) + cmd := fmt.Sprintf(allowIPToLocalNetCMDFmt, src) if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec return fmt.Errorf("error running command %s: %w", cmd, err) } @@ -68,7 +71,8 @@ func AllowIPToLocalNetwork(src, dst net.IP) error { // BlockIPToLocalNetwork blocks all the packets coming from `source` // to private IP ranges. func BlockIPToLocalNetwork(src, dst net.IP) error { - cmd := fmt.Sprintf(blockIPToLocalNetCMDFmt, src, dst, src, dst, src) + //cmd := fmt.Sprintf(blockIPToLocalNetCMDFmt, src, dst, src, dst, src) + cmd := fmt.Sprintf(blockIPToLocalNetCMDFmt, src) if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec return fmt.Errorf("error running command %s: %w", cmd, err) } From 7c6867b49d908c2a1373240a146c2453e0d0486e Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Wed, 11 Nov 2020 18:56:38 +0300 Subject: [PATCH 13/15] Change iptables commands --- internal/vpn/os_server_linux.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/vpn/os_server_linux.go b/internal/vpn/os_server_linux.go index 9033cb1feb..69128bc3cb 100644 --- a/internal/vpn/os_server_linux.go +++ b/internal/vpn/os_server_linux.go @@ -20,8 +20,8 @@ const ( disableIPMasqueradingCMDFmt = "iptables -t nat -D POSTROUTING -o %s -j MASQUERADE" //blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -I INPUT -d %s -s %s -j DROP && iptables -I FORWARD -d %s -s %s -j ACCEPT" //allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -D INPUT -d %s -s %s -j DROP && iptables -D FORWARD -d %s -s %s -j ACCEPT" - blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP" - allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP" + blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -I INPUT -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP" + allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -D INPUT -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP" blockSSHCMDFmt = "iptables -I FORWARD -d %s,%s -s %s,%s -j DROP && iptables -I INPUT -d %s -s %s -j DROP" allowSSHCMDFmt = "iptables -D FORWARD -d %s,%s -s %s,%s -j DROP && iptables -D INPUT -d %s -s %s -j DROP" ) From 8c1f69f21250d7c3061091d0e2fea665dd8415c7 Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Wed, 11 Nov 2020 19:04:59 +0300 Subject: [PATCH 14/15] Fix iptables command --- internal/vpn/os_server_linux.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/vpn/os_server_linux.go b/internal/vpn/os_server_linux.go index 69128bc3cb..c36101bbc2 100644 --- a/internal/vpn/os_server_linux.go +++ b/internal/vpn/os_server_linux.go @@ -60,7 +60,7 @@ func BlockSSH(src, dst net.IP, defaultNetIfcIPs []net.IP) error { // to private IP ranges. func AllowIPToLocalNetwork(src, dst net.IP) error { //cmd := fmt.Sprintf(allowIPToLocalNetCMDFmt, src, dst, src, dst, src) - cmd := fmt.Sprintf(allowIPToLocalNetCMDFmt, src) + cmd := fmt.Sprintf(allowIPToLocalNetCMDFmt, src, src) if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec return fmt.Errorf("error running command %s: %w", cmd, err) } @@ -72,7 +72,7 @@ func AllowIPToLocalNetwork(src, dst net.IP) error { // to private IP ranges. func BlockIPToLocalNetwork(src, dst net.IP) error { //cmd := fmt.Sprintf(blockIPToLocalNetCMDFmt, src, dst, src, dst, src) - cmd := fmt.Sprintf(blockIPToLocalNetCMDFmt, src) + cmd := fmt.Sprintf(blockIPToLocalNetCMDFmt, src, src) if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec return fmt.Errorf("error running command %s: %w", cmd, err) } From 0f90506e19efd889774d43bb76cb33defcbf876b Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Wed, 11 Nov 2020 20:30:30 +0300 Subject: [PATCH 15/15] Remove unused functions --- internal/vpn/os_server_linux.go | 41 ++------------------------------- internal/vpn/server.go | 21 +++-------------- 2 files changed, 5 insertions(+), 57 deletions(-) diff --git a/internal/vpn/os_server_linux.go b/internal/vpn/os_server_linux.go index c36101bbc2..0731873575 100644 --- a/internal/vpn/os_server_linux.go +++ b/internal/vpn/os_server_linux.go @@ -7,7 +7,6 @@ import ( "fmt" "net" "os/exec" - "strings" ) const ( @@ -18,48 +17,13 @@ const ( setIPv6ForwardingCMDFmt = "sysctl -w net.ipv6.conf.all.forwarding=%s" enableIPMasqueradingCMDFmt = "iptables -t nat -A POSTROUTING -o %s -j MASQUERADE" disableIPMasqueradingCMDFmt = "iptables -t nat -D POSTROUTING -o %s -j MASQUERADE" - //blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -I INPUT -d %s -s %s -j DROP && iptables -I FORWARD -d %s -s %s -j ACCEPT" - //allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -D INPUT -d %s -s %s -j DROP && iptables -D FORWARD -d %s -s %s -j ACCEPT" - blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -I INPUT -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP" - allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -D INPUT -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP" - blockSSHCMDFmt = "iptables -I FORWARD -d %s,%s -s %s,%s -j DROP && iptables -I INPUT -d %s -s %s -j DROP" - allowSSHCMDFmt = "iptables -D FORWARD -d %s,%s -s %s,%s -j DROP && iptables -D INPUT -d %s -s %s -j DROP" + blockIPToLocalNetCMDFmt = "iptables -I FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -I INPUT -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP" + allowIPToLocalNetCMDFmt = "iptables -D FORWARD -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP && iptables -D INPUT -d 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 -s %s -j DROP" ) -// AllowSSH allows all SSH traffic (via default 22 port) between `src` and `dst`. -func AllowSSH(src, dst net.IP, defaultNetIfcIPs []net.IP) error { - defaultNetIfcIPsStr := make([]string, 0, len(defaultNetIfcIPs)) - for _, ip := range defaultNetIfcIPs { - defaultNetIfcIPsStr = append(defaultNetIfcIPsStr, ip.String()) - } - - cmd := fmt.Sprintf(allowSSHCMDFmt, dst, src, dst, src, strings.Join(defaultNetIfcIPsStr, ","), src) - if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec - return fmt.Errorf("error running command %s: %w", cmd, err) - } - - return nil -} - -// BlockSSH blocks all SSH traffic (via default 22 port) between `src` and `dst`. -func BlockSSH(src, dst net.IP, defaultNetIfcIPs []net.IP) error { - defaultNetIfcIPsStr := make([]string, 0, len(defaultNetIfcIPs)) - for _, ip := range defaultNetIfcIPs { - defaultNetIfcIPsStr = append(defaultNetIfcIPsStr, ip.String()) - } - - cmd := fmt.Sprintf(blockSSHCMDFmt, dst, src, dst, src, strings.Join(defaultNetIfcIPsStr, ","), src) - if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec - return fmt.Errorf("error running command %s: %w", cmd, err) - } - - return nil -} - // AllowIPToLocalNetwork allows all the packets coming from `source` // to private IP ranges. func AllowIPToLocalNetwork(src, dst net.IP) error { - //cmd := fmt.Sprintf(allowIPToLocalNetCMDFmt, src, dst, src, dst, src) cmd := fmt.Sprintf(allowIPToLocalNetCMDFmt, src, src) if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec return fmt.Errorf("error running command %s: %w", cmd, err) @@ -71,7 +35,6 @@ func AllowIPToLocalNetwork(src, dst net.IP) error { // BlockIPToLocalNetwork blocks all the packets coming from `source` // to private IP ranges. func BlockIPToLocalNetwork(src, dst net.IP) error { - //cmd := fmt.Sprintf(blockIPToLocalNetCMDFmt, src, dst, src, dst, src) cmd := fmt.Sprintf(blockIPToLocalNetCMDFmt, src, src) if err := exec.Command("sh", "-c", cmd).Run(); err != nil { //nolint:gosec return fmt.Errorf("error running command %s: %w", cmd, err) diff --git a/internal/vpn/server.go b/internal/vpn/server.go index 6d3809ba69..3038b242ea 100644 --- a/internal/vpn/server.go +++ b/internal/vpn/server.go @@ -153,12 +153,12 @@ func (s *Server) closeConn(conn net.Conn) { func (s *Server) serveConn(conn net.Conn) { defer s.closeConn(conn) - tunIP, tunGateway, allowTraffToLocalNet, err := s.shakeHands(conn) + tunIP, tunGateway, allowTrafficToLocalNet, err := s.shakeHands(conn) if err != nil { s.log.WithError(err).Errorf("Error negotiating with client %s", conn.RemoteAddr()) return } - defer allowTraffToLocalNet() + defer allowTrafficToLocalNet() tun, err := newTUNDevice() if err != nil { @@ -260,26 +260,11 @@ func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, unsecureVP fmt.Errorf("error securing local network for IP %s: %w", cTUNIP, err) } - allowLocalNetTraff := func() { + unsecureVPN = func() { if err := AllowIPToLocalNetwork(cTUNIP, sTUNIP); err != nil { s.log.WithError(err).Errorln("Error allowing traffic to local network") } } - - /*if err := BlockSSH(cTUNIP, sTUNIP, s.defaultNetworkInterfaceIPs); err != nil { - s.sendServerErrHello(conn, HandshakeStatusInternalError) - allowLocalNetTraff() - return nil, nil, nil, - fmt.Errorf("error securing local network for IP %s: %w", cTUNIP, err) - }*/ - - unsecureVPN = func() { - allowLocalNetTraff() - - /*if err := AllowSSH(cTUNIP, sTUNIP, s.defaultNetworkInterfaceIPs); err != nil { - s.log.WithError(err).Errorln("Error allowing SSH through") - }*/ - } } sHello := ServerHello{