Example #1
0
        // This works, but we use base to avoid shell

        /*
         *      public override long Ping(IpAddress host, int timeoutSec)
         *      {
         *              if ((host == null) || (host.Valid == false))
         *                      return -1;
         *
         *              // <2.17.3, require root
         *              //return NativeMethods.PingIP(host.ToString(), timeoutSec * 1000);
         *
         *              {
         *                      float iMS = -1;
         *
         *                      string pingPath = LocateExecutable("ping");
         *                      if (pingPath != "")
         *                      {
         *                              SystemShell s = new SystemShell();
         *                              s.Path = pingPath;
         *                              s.Arguments.Add("-c 1");
         *                              s.Arguments.Add("-w " + timeoutSec.ToString());
         *                              s.Arguments.Add("-q");
         *                              s.Arguments.Add("-n");
         *                              s.Arguments.Add(host.Address);
         *                              s.NoDebugLog = true;
         *
         *                              if (s.Run())
         *                              {
         *                                      string result = s.Output;
         *                                      string sMS = UtilsString.ExtractBetween(result.ToLowerInvariant(), "min/avg/max/mdev = ", "/");
         *                                      if (float.TryParse(sMS, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out iMS) == false)
         *                                              iMS = -1;
         *                              }
         *                      }
         *
         *                      return (long)iMS;
         *              }
         *      }
         */

        public override bool RouteAdd(Json jRoute)
        {
            IpAddress ip = jRoute["address"].Value as string;

            if (ip.Valid == false)
            {
                return(false);
            }
            IpAddress gateway = jRoute["gateway"].Value as string;

            if (gateway.Valid == false)
            {
                return(false);
            }

            try
            {
                ElevatedProcess.Command c = new ElevatedProcess.Command();
                c.Parameters["command"] = "route";
                if (ip.IsV4)
                {
                    c.Parameters["layer"] = "ipv4";
                }
                else if (ip.IsV6)
                {
                    c.Parameters["layer"] = "ipv6";
                }
                c.Parameters["action"]  = "add";
                c.Parameters["cidr"]    = ip.ToCIDR();
                c.Parameters["gateway"] = gateway.ToCIDR();
                if (jRoute.HasKey("interface"))
                {
                    c.Parameters["interface"] = jRoute["interface"].Value as string;
                }
                else
                {
                    c.Parameters["interface"] = "";
                }
                if (jRoute.HasKey("metric"))
                {
                    c.Parameters["metric"] = jRoute["metric"].Value as string;
                }
                else
                {
                    c.Parameters["metric"] = "";
                }
                Engine.Instance.Elevated.DoCommandSync(c);
                return(base.RouteAdd(jRoute));
            }
            catch (Exception e)
            {
                Engine.Instance.Logs.LogWarning(LanguageManager.GetText("RouteAddFailed", ip.ToCIDR(), gateway.ToCIDR(), e.Message));

                return(false);
            }
        }
Example #2
0
        public override bool RouteRemove(Json jRoute)
        {
            IpAddress ip = jRoute["address"].Value as string;

            if (ip.Valid == false)
            {
                return(false);
            }
            IpAddress gateway = jRoute["gateway"].Value as string;

            if (gateway.Valid == false)
            {
                return(false);
            }

            ElevatedProcess.Command c = new ElevatedProcess.Command();
            c.Parameters["command"] = "route";
            if (ip.IsV4)
            {
                c.Parameters["layer"] = "ipv4";
            }
            else if (ip.IsV6)
            {
                c.Parameters["layer"] = "ipv6";
            }
            c.Parameters["action"]  = "delete";
            c.Parameters["cidr"]    = ip.ToCIDR();
            c.Parameters["gateway"] = gateway.Address;

            string result = Engine.Instance.Elevated.DoCommandSync(c);

            if (result == "")
            {
                return(base.RouteRemove(jRoute));
            }
            else
            {
                Engine.Instance.Logs.LogWarning(LanguageManager.GetText("RouteDelFailed", ip.ToCIDR(), gateway.ToCIDR(), result));

                return(false);
            }
        }
        public override void Activation()
        {
            base.Activation();

            m_supportIPv4 = true; // IPv4 assumed, if not available, will throw a fatal exception.
            m_supportIPv6 = Conversions.ToBool(Engine.Instance.Manifest["network_info"]["support_ipv6"].Value);

            if (m_supportIPv6 == false)
            {
                Engine.Instance.Logs.Log(LogType.Verbose, LanguageManager.GetText("NetworkLockLinuxIPv6NotAvailable"));
            }

            try
            {
                IpAddresses ipsWhiteListIncoming = GetIpsWhiteListIncoming();
                IpAddresses ipsWhiteListOutgoing = GetIpsWhiteListOutgoing(true);

                // Build rules
                var rulesIPv4 = new System.Text.StringBuilder();
                var rulesIPv6 = new System.Text.StringBuilder();

                {
                    string defaultPolicyInput   = "DROP";
                    string defaultPolicyForward = "DROP";
                    string defaultPolicyOutput  = "DROP";
                    if (Engine.Instance.Storage.Get("netlock.incoming") == "allow")
                    {
                        defaultPolicyInput = "ACCEPT";
                    }
                    if (Engine.Instance.Storage.Get("netlock.outgoing") == "allow")
                    {
                        defaultPolicyOutput = "ACCEPT";
                    }

                    // IPv4
                    if (m_supportIPv4)
                    {
                        rulesIPv4.AppendLine("*mangle");
                        rulesIPv4.AppendLine(":PREROUTING ACCEPT [0:0]");
                        rulesIPv4.AppendLine(":INPUT ACCEPT [0:0]");
                        rulesIPv4.AppendLine(":FORWARD ACCEPT [0:0]");
                        rulesIPv4.AppendLine(":OUTPUT ACCEPT [0:0]");
                        rulesIPv4.AppendLine(":POSTROUTING ACCEPT [0:0]");
                        rulesIPv4.AppendLine("COMMIT");
                        rulesIPv4.AppendLine("*nat");
                        rulesIPv4.AppendLine(":PREROUTING ACCEPT [0:0]");
                        rulesIPv4.AppendLine(":INPUT ACCEPT [0:0]");
                        rulesIPv4.AppendLine(":OUTPUT ACCEPT [0:0]");
                        rulesIPv4.AppendLine(":POSTROUTING ACCEPT [0:0]");
                        rulesIPv4.AppendLine("COMMIT");
                        rulesIPv4.AppendLine("*filter");
                        rulesIPv4.AppendLine(":INPUT " + defaultPolicyInput + " [0:0]");
                        rulesIPv4.AppendLine(":FORWARD " + defaultPolicyForward + " [0:0]");
                        rulesIPv4.AppendLine(":OUTPUT " + defaultPolicyOutput + " [0:0]");

                        // Local
                        rulesIPv4.AppendLine("-A INPUT -i lo -j ACCEPT");

                        if (Engine.Instance.Storage.GetBool("netlock.allow_dhcp") == true)
                        {
                            rulesIPv4.AppendLine("-A INPUT -s 255.255.255.255/32 -j ACCEPT");
                        }

                        if (Engine.Instance.Storage.GetBool("netlock.allow_private"))
                        {
                            // Private networks
                            rulesIPv4.AppendLine("-A INPUT -s 192.168.0.0/16 -d 192.168.0.0/16 -j ACCEPT");
                            rulesIPv4.AppendLine("-A INPUT -s 10.0.0.0/8 -d 10.0.0.0/8 -j ACCEPT");
                            rulesIPv4.AppendLine("-A INPUT -s 172.16.0.0/12 -d 172.16.0.0/12 -j ACCEPT");
                        }

                        if (Engine.Instance.Storage.GetBool("netlock.allow_ping"))
                        {
                            // icmp-type: echo-request
                            rulesIPv4.AppendLine("-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT");
                        }

                        // Allow established sessions to receive traffic
                        rulesIPv4.AppendLine("-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT");

                        // Allow TUN
                        rulesIPv4.AppendLine("-A INPUT -i tun+ -j ACCEPT");

                        // Whitelist incoming
                        foreach (IpAddress ip in ipsWhiteListIncoming.IPs)
                        {
                            if (ip.IsV4)
                            {
                                //body.AppendLine("-A INPUT -s " + ip.ToCIDR() + " -m state --state NEW,ESTABLISHED -j ACCEPT");
                                rulesIPv4.AppendLine("-A INPUT -s " + ip.ToCIDR() + " -j ACCEPT");
                            }
                        }

                        // Redundand, equal to default policy
                        rulesIPv4.AppendLine("-A INPUT -j " + defaultPolicyInput);

                        // Allow TUN
                        rulesIPv4.AppendLine("-A FORWARD -i tun+ -j ACCEPT");

                        // Redundand, equal to default policy
                        rulesIPv4.AppendLine("-A FORWARD -j " + defaultPolicyForward);

                        // Local
                        rulesIPv4.AppendLine("-A OUTPUT -o lo -j ACCEPT");

                        if (Engine.Instance.Storage.GetBool("netlock.allow_dhcp") == true)
                        {
                            // Make sure you can communicate with any DHCP server
                            rulesIPv4.AppendLine("-A OUTPUT -d 255.255.255.255/32 -j ACCEPT");
                        }

                        if (Engine.Instance.Storage.GetBool("netlock.allow_private"))
                        {
                            // Private networks
                            rulesIPv4.AppendLine("-A OUTPUT -s 192.168.0.0/16 -d 192.168.0.0/16 -j ACCEPT");
                            rulesIPv4.AppendLine("-A OUTPUT -s 10.0.0.0/8 -d 10.0.0.0/8 -j ACCEPT");
                            rulesIPv4.AppendLine("-A OUTPUT -s 172.16.0.0/12 -d 172.16.0.0/12 -j ACCEPT");

                            // Multicast
                            rulesIPv4.AppendLine("-A OUTPUT -s 192.168.0.0/16 -d 224.0.0.0/24 -j ACCEPT");
                            rulesIPv4.AppendLine("-A OUTPUT -s 10.0.0.0/8 -d 224.0.0.0/24 -j ACCEPT");
                            rulesIPv4.AppendLine("-A OUTPUT -s 172.16.0.0/12 -d 224.0.0.0/24 -j ACCEPT");

                            // Simple Service Discovery Protocol address
                            rulesIPv4.AppendLine("-A OUTPUT -s 192.168.0.0/16 -d 239.255.255.250/32 -j ACCEPT");
                            rulesIPv4.AppendLine("-A OUTPUT -s 10.0.0.0/8 -d 239.255.255.250/32 -j ACCEPT");
                            rulesIPv4.AppendLine("-A OUTPUT -s 172.16.0.0/12 -d 239.255.255.250/32 -j ACCEPT");

                            // Service Location Protocol version 2 address
                            rulesIPv4.AppendLine("-A OUTPUT -s 192.168.0.0/16 -d 239.255.255.253/32 -j ACCEPT");
                            rulesIPv4.AppendLine("-A OUTPUT -s 10.0.0.0/8 -d 239.255.255.253/32 -j ACCEPT");
                            rulesIPv4.AppendLine("-A OUTPUT -s 172.16.0.0/12 -d 239.255.255.253/32 -j ACCEPT");
                        }

                        if (Engine.Instance.Storage.GetBool("netlock.allow_ping"))
                        {
                            // icmp-type: echo-reply
                            rulesIPv4.AppendLine("-A OUTPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT");
                        }

                        // Allow TUN
                        rulesIPv4.AppendLine("-A OUTPUT -o tun+ -j ACCEPT");

                        // If incoming=allow, allow packet response to out
                        // We avoid a general rules, because in block/block mode don't drop already exists keepalive
                        if (defaultPolicyInput == "ACCEPT")
                        {
                            rulesIPv4.AppendLine("-A OUTPUT -m state --state ESTABLISHED -j ACCEPT");
                        }

                        // Whitelist incoming
                        foreach (IpAddress ip in ipsWhiteListIncoming.IPs)
                        {
                            if (ip.IsV4)
                            {
                                rulesIPv4.AppendLine("-A OUTPUT -d " + ip.ToCIDR() + " -m state --state ESTABLISHED -j ACCEPT");
                            }
                        }

                        // Whitelist outgoing
                        foreach (IpAddress ip in ipsWhiteListOutgoing.IPs)
                        {
                            if (ip.IsV4)
                            {
                                rulesIPv4.AppendLine("-A OUTPUT -d " + ip.ToCIDR() + " -j ACCEPT");
                            }
                        }

                        // Redundand, equal to default policy
                        rulesIPv4.AppendLine("-A OUTPUT -j " + defaultPolicyOutput);

                        // Commit
                        rulesIPv4.AppendLine("COMMIT");
                    }

                    // IPv6
                    if (m_supportIPv6)
                    {
                        rulesIPv6.AppendLine("*mangle");
                        rulesIPv6.AppendLine(":PREROUTING ACCEPT [0:0]");
                        rulesIPv6.AppendLine(":INPUT ACCEPT [0:0]");
                        rulesIPv6.AppendLine(":FORWARD ACCEPT [0:0]");
                        rulesIPv6.AppendLine(":OUTPUT ACCEPT [0:0]");
                        rulesIPv6.AppendLine(":POSTROUTING ACCEPT [0:0]");
                        rulesIPv6.AppendLine("COMMIT");
                        rulesIPv6.AppendLine("*nat");
                        rulesIPv6.AppendLine(":PREROUTING ACCEPT [0:0]");
                        rulesIPv6.AppendLine(":INPUT ACCEPT [0:0]");
                        rulesIPv6.AppendLine(":OUTPUT ACCEPT [0:0]");
                        rulesIPv6.AppendLine(":POSTROUTING ACCEPT [0:0]");
                        rulesIPv6.AppendLine("COMMIT");
                        rulesIPv6.AppendLine("*filter");
                        rulesIPv6.AppendLine(":INPUT " + defaultPolicyInput + " [0:0]");
                        rulesIPv6.AppendLine(":FORWARD " + defaultPolicyForward + " [0:0]");
                        rulesIPv6.AppendLine(":OUTPUT " + defaultPolicyOutput + " [0:0]");

                        // Local
                        rulesIPv6.AppendLine("-A INPUT -i lo -j ACCEPT");

                        // Reject traffic to localhost that does not originate from lo0.
                        rulesIPv6.AppendLine("-A INPUT -s ::1/128 ! -i lo -j REJECT --reject-with icmp6-port-unreachable");

                        // Disable processing of any RH0 packet which could allow a ping-pong of packets
                        rulesIPv6.AppendLine("-A INPUT -m rt --rt-type 0 -j DROP");

                        // icmpv6-type:router-advertisement - Rules which are required for your IPv6 address to be properly allocated
                        rulesIPv6.AppendLine("-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 134 -m hl --hl-eq 255 -j ACCEPT");

                        // icmpv6-type:neighbor-solicitation - Rules which are required for your IPv6 address to be properly allocated
                        rulesIPv6.AppendLine("-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 135 -m hl --hl-eq 255 -j ACCEPT");

                        // icmpv6-type:neighbor-advertisement - Rules which are required for your IPv6 address to be properly allocated
                        rulesIPv6.AppendLine("-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 136 -m hl --hl-eq 255 -j ACCEPT");

                        // icmpv6-type:redirect - Rules which are required for your IPv6 address to be properly allocated
                        rulesIPv6.AppendLine("-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 137 -m hl --hl-eq 255 -j ACCEPT");

                        if (Engine.Instance.Storage.GetBool("netlock.allow_private"))
                        {
                            // Allow Link-Local addresses
                            rulesIPv6.AppendLine("-A INPUT -s fe80::/10 -j ACCEPT");

                            // Allow multicast
                            rulesIPv6.AppendLine("-A INPUT -d ff00::/8 -j ACCEPT");
                        }

                        if (Engine.Instance.Storage.GetBool("netlock.allow_ping"))
                        {
                            rulesIPv6.AppendLine("-A INPUT -p ipv6-icmp -j ACCEPT");
                        }

                        // Allow established sessions to receive traffic
                        rulesIPv6.AppendLine("-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT");

                        // Allow TUN
                        rulesIPv6.AppendLine("-A INPUT -i tun+ -j ACCEPT");

                        // Whitelist incoming
                        foreach (IpAddress ip in ipsWhiteListIncoming.IPs)
                        {
                            if (ip.IsV6)
                            {
                                rulesIPv6.AppendLine("-A INPUT -s " + ip.ToCIDR() + " -j ACCEPT");
                            }
                        }

                        // Redundand, equal to default policy
                        rulesIPv6.AppendLine("-A INPUT -j " + defaultPolicyInput);

                        // Disable processing of any RH0 packet which could allow a ping-pong of packets
                        rulesIPv6.AppendLine("-A FORWARD -m rt --rt-type 0 -j DROP");

                        // Allow TUN
                        rulesIPv6.AppendLine("-A FORWARD -i tun+ -j ACCEPT");

                        // Redundand, equal to default policy
                        rulesIPv6.AppendLine("-A FORWARD -j " + defaultPolicyForward);

                        // Local
                        rulesIPv6.AppendLine("-A OUTPUT -o lo -j ACCEPT");

                        // Disable processing of any RH0 packet which could allow a ping-pong of packets
                        rulesIPv6.AppendLine("-A OUTPUT -m rt --rt-type 0 -j DROP");

                        if (Engine.Instance.Storage.GetBool("netlock.allow_private"))
                        {
                            // Allow Link-Local addresses
                            rulesIPv6.AppendLine("-A OUTPUT -s fe80::/10 -j ACCEPT");

                            // Allow multicast
                            rulesIPv6.AppendLine("-A OUTPUT -d ff00::/8 -j ACCEPT");
                        }

                        if (Engine.Instance.Storage.GetBool("netlock.allow_ping"))
                        {
                            rulesIPv6.AppendLine("-A OUTPUT -p ipv6-icmp -j ACCEPT");
                        }

                        // Allow TUN
                        rulesIPv6.AppendLine("-A OUTPUT -o tun+ -j ACCEPT");

                        // If incoming=allow, allow packet response to out
                        // We avoid a general rules, because in block/block mode don't drop already exists keepalive
                        if (defaultPolicyInput == "ACCEPT")
                        {
                            rulesIPv6.AppendLine("-A OUTPUT -m state --state ESTABLISHED -j ACCEPT");
                        }

                        // Whitelist incoming
                        foreach (IpAddress ip in ipsWhiteListIncoming.IPs)
                        {
                            if (ip.IsV6)
                            {
                                rulesIPv6.AppendLine("-A OUTPUT -o " + ip.ToCIDR() + " -m state --state ESTABLISHED -j ACCEPT");
                            }
                        }

                        // Whitelist outgoing
                        foreach (IpAddress ip in ipsWhiteListOutgoing.IPs)
                        {
                            if (ip.IsV6)
                            {
                                rulesIPv6.AppendLine("-A OUTPUT -d " + ip.ToCIDR() + " -j ACCEPT");
                            }
                        }

                        // Redundand, equal to default policy
                        rulesIPv6.AppendLine("-A OUTPUT -j " + defaultPolicyOutput);

                        // Commit
                        rulesIPv6.AppendLine("COMMIT");
                    }
                }

                Elevated.Command c = new ElevatedProcess.Command();
                c.Parameters["command"] = "netlock-iptables-activate";
                if (m_supportIPv4)
                {
                    c.Parameters["rules-ipv4"] = rulesIPv4.ToString();
                }
                if (m_supportIPv6)
                {
                    c.Parameters["rules-ipv6"] = rulesIPv6.ToString();
                }
                string result = Engine.Instance.Elevated.DoCommandSync(c);
                if (result != "")
                {
                    throw new Exception("Unexpected result: " + result);
                }

                m_ipsWhiteListIncoming = ipsWhiteListIncoming;
                m_ipsWhiteListOutgoing = ipsWhiteListOutgoing;

                OnUpdateIps();
            }
            catch (Exception ex)
            {
                Deactivation();
                throw new Exception(ex.Message);
            }
        }