Exemple #1
0
        const int MAINTENANCE_TIMER_INTERVAL = 15 * 60 * 1000; //15 mins

        #endregion

        #region constructor

        private HealthService(IDnsServer dnsServer)
        {
            _dnsServer = dnsServer;

            _maintenanceTimer = new Timer(delegate(object state)
            {
                try
                {
                    foreach (KeyValuePair <string, HealthMonitor> healthMonitor in _healthMonitors)
                    {
                        if (healthMonitor.Value.IsExpired())
                        {
                            if (_healthMonitors.TryRemove(healthMonitor.Key, out HealthMonitor removedMonitor))
                            {
                                removedMonitor.Dispose();
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    _dnsServer.WriteLog(ex);
                }
                finally
                {
                    if (!_disposed)
                    {
                        _maintenanceTimer.Change(MAINTENANCE_TIMER_INTERVAL, Timeout.Infinite);
                    }
                }
            }, null, Timeout.Infinite, Timeout.Infinite);

            _maintenanceTimer.Change(MAINTENANCE_TIMER_INTERVAL, Timeout.Infinite);
        }
Exemple #2
0
        public static MaxMind Create(IDnsServer dnsServer)
        {
            if (_maxMind is null)
            {
                _maxMind = new MaxMind(dnsServer);
            }

            return(_maxMind);
        }
Exemple #3
0
        public static HealthService Create(IDnsServer dnsServer)
        {
            if (_healthService is null)
            {
                _healthService = new HealthService(dnsServer);
            }

            return(_healthService);
        }
Exemple #4
0
        public Task InitializeAsync(IDnsServer dnsServer, string config)
        {
            dynamic jsonConfig = JsonConvert.DeserializeObject(config);

            _enableBlocking = jsonConfig.enableBlocking.Value;

            if (jsonConfig.allowedNetworks is null)
            {
                _allowedNetworks = Array.Empty <NetworkAddress>();
            }
            else
            {
                List <NetworkAddress> allowedNetworks = new List <NetworkAddress>();

                foreach (dynamic allowedNetwork in jsonConfig.allowedNetworks)
                {
                    allowedNetworks.Add(NetworkAddress.Parse(allowedNetwork.Value));
                }

                _allowedNetworks = allowedNetworks;
            }

            if (jsonConfig.blockedNetworks is null)
            {
                _blockedNetworks = Array.Empty <NetworkAddress>();
            }
            else
            {
                List <NetworkAddress> blockedNetworks = new List <NetworkAddress>();

                foreach (dynamic blockedNetwork in jsonConfig.blockedNetworks)
                {
                    blockedNetworks.Add(NetworkAddress.Parse(blockedNetwork.Value));
                }

                _blockedNetworks = blockedNetworks;
            }

            if (jsonConfig.blockedQuestions is null)
            {
                _blockedQuestions = Array.Empty <BlockedQuestion>();
            }
            else
            {
                List <BlockedQuestion> blockedQuestions = new List <BlockedQuestion>();

                foreach (dynamic blockedQuestion in jsonConfig.blockedQuestions)
                {
                    blockedQuestions.Add(new BlockedQuestion(blockedQuestion));
                }

                _blockedQuestions = blockedQuestions;
            }

            return(Task.CompletedTask);
        }
Exemple #5
0
        const int MAINTENANCE_TIMER_INTERVAL = 15 * 60 * 1000; //15 mins

        #endregion

        #region constructor

        private HealthMonitoringService(IDnsServer dnsServer)
        {
            _dnsServer = dnsServer;

            _maintenanceTimer = new Timer(delegate(object state)
            {
                try
                {
                    foreach (KeyValuePair <IPAddress, AddressMonitoring> monitoring in _addressMonitoring)
                    {
                        if (monitoring.Value.IsExpired())
                        {
                            if (_addressMonitoring.TryRemove(monitoring.Key, out AddressMonitoring removedMonitoring))
                            {
                                removedMonitoring.Dispose();
                            }
                        }
                    }

                    foreach (KeyValuePair <string, DomainMonitoring> monitoring in _domainMonitoringA)
                    {
                        if (monitoring.Value.IsExpired())
                        {
                            if (_domainMonitoringA.TryRemove(monitoring.Key, out DomainMonitoring removedMonitoring))
                            {
                                removedMonitoring.Dispose();
                            }
                        }
                    }

                    foreach (KeyValuePair <string, DomainMonitoring> monitoring in _domainMonitoringAAAA)
                    {
                        if (monitoring.Value.IsExpired())
                        {
                            if (_domainMonitoringAAAA.TryRemove(monitoring.Key, out DomainMonitoring removedMonitoring))
                            {
                                removedMonitoring.Dispose();
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    _dnsServer.WriteLog(ex);
                }
                finally
                {
                    if (!_disposed)
                    {
                        _maintenanceTimer.Change(MAINTENANCE_TIMER_INTERVAL, Timeout.Infinite);
                    }
                }
            }, null, Timeout.Infinite, Timeout.Infinite);

            _maintenanceTimer.Change(MAINTENANCE_TIMER_INTERVAL, Timeout.Infinite);
        }
Exemple #6
0
        public Task InitializeAsync(IDnsServer dnsServer, string config)
        {
            if (_healthService is null)
            {
                _healthService = HealthService.Create(dnsServer);
            }

            _healthService.Initialize(JsonConvert.DeserializeObject(config));

            return(Task.CompletedTask);
        }
Exemple #7
0
        public Task InitializeAsync(IDnsServer dnsServer, string config)
        {
            if (_healthMonitor is null)
            {
                _healthMonitor = HealthMonitoringService.Create(dnsServer);
            }

            //let Address class initialize config

            return(Task.CompletedTask);
        }
Exemple #8
0
        public Task InitializeAsync(IDnsServer dnsServer, string config)
        {
            _soaRecord = new DnsSOARecord(dnsServer.ServerDomain, "hostadmin." + dnsServer.ServerDomain, 1, 14400, 3600, 604800, 60);

            dynamic jsonConfig = JsonConvert.DeserializeObject(config);

            _enableBlocking         = jsonConfig.enableBlocking.Value;
            _allowTxtBlockingReport = jsonConfig.allowTxtBlockingReport.Value;

            _blockListZone = ReadJsonDomainArray(jsonConfig.blocked);

            return(Task.CompletedTask);
        }
Exemple #9
0
        private MaxMind(IDnsServer dnsServer)
        {
            string mmFile = Path.Combine(dnsServer.ApplicationFolder, "GeoIP2-Country.mmdb");

            if (!File.Exists(mmFile))
            {
                mmFile = Path.Combine(dnsServer.ApplicationFolder, "GeoLite2-Country.mmdb");
            }

            if (!File.Exists(mmFile))
            {
                throw new FileNotFoundException("MaxMind Country file is missing!");
            }

            _mmCountryReader = new DatabaseReader(mmFile);
        }
Exemple #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WhitelistManager"/> class.
        /// </summary>
        /// <param name="dateTimeProvider">The provider for datetime.</param>
        /// <param name="loggerFactory">The factory to create the logger.</param>
        /// <param name="peerAddressManager">The manager implementation for peer addresses.</param>
        /// <param name="dnsServer">The DNS server.</param>
        /// <param name="connectionSettings">The connection settings.</param>
        public WhitelistManager(IDateTimeProvider dateTimeProvider, ILoggerFactory loggerFactory, IPeerAddressManager peerAddressManager, IDnsServer dnsServer, ConnectionManagerSettings connectionSettings, DnsSettings dnsSettings)
        {
            Guard.NotNull(dateTimeProvider, nameof(dateTimeProvider));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(peerAddressManager, nameof(peerAddressManager));
            Guard.NotNull(dnsServer, nameof(dnsServer));
            Guard.NotNull(dnsSettings, nameof(dnsSettings));
            Guard.NotNull(connectionSettings, nameof(connectionSettings));

            this.dateTimeProvider   = dateTimeProvider;
            this.logger             = loggerFactory.CreateLogger(this.GetType().FullName);
            this.peerAddressManager = peerAddressManager;
            this.dnsServer          = dnsServer;
            this.dnsSettings        = dnsSettings;
            this.externalEndpoint   = connectionSettings.ExternalEndpoint;
        }
Exemple #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DnsFeature"/> class.
        /// </summary>
        /// <param name="dnsServer">The DNS server.</param>
        /// <param name="whitelistManager">The whitelist manager.</param>
        /// <param name="loggerFactory">The factory to create the logger.</param>
        /// <param name="nodeLifetime">The node lifetime object used for graceful shutdown.</param>
        /// <param name="nodeSettings">The node settings object containing node configuration.</param>
        /// <param name="dataFolders">The data folders of the system.</param>
        /// <param name="asyncLoopFactory">The asynchronous loop factory.</param>
        public DnsFeature(IDnsServer dnsServer, IWhitelistManager whitelistManager, ILoggerFactory loggerFactory, INodeLifetime nodeLifetime, NodeSettings nodeSettings, DataFolder dataFolders, IAsyncLoopFactory asyncLoopFactory)
        {
            Guard.NotNull(dnsServer, nameof(dnsServer));
            Guard.NotNull(whitelistManager, nameof(whitelistManager));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(nodeLifetime, nameof(nodeLifetime));
            Guard.NotNull(nodeSettings, nameof(nodeSettings));
            Guard.NotNull(dataFolders, nameof(dataFolders));
            Guard.NotNull(asyncLoopFactory, nameof(asyncLoopFactory));

            this.dnsServer        = dnsServer;
            this.whitelistManager = whitelistManager;
            this.logger           = loggerFactory.CreateLogger(this.GetType().FullName);
            this.asyncLoopFactory = asyncLoopFactory;
            this.nodeLifetime     = nodeLifetime;
            this.nodeSettings     = nodeSettings;
            this.dataFolders      = dataFolders;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="WhitelistManager"/> class.
        /// </summary>
        /// <param name="dateTimeProvider">The provider for datetime.</param>
        /// <param name="loggerFactory">The factory to create the logger.</param>
        /// <param name="peerAddressManager">The manager implementation for peer addresses.</param>
        /// <param name="dnsServer">The DNS server.</param>
        /// <param name="connectionSettings">The connection settings.</param>
        /// <param name="dnsSettings">The DNS settings.</param>
        /// <param name="peerBanning">Peer banning component.</param>
        public WhitelistManager(IDateTimeProvider dateTimeProvider, ILoggerFactory loggerFactory, IPeerAddressManager peerAddressManager, IDnsServer dnsServer, ConnectionManagerSettings connectionSettings, DnsSettings dnsSettings, IPeerBanning peerBanning)
        {
            Guard.NotNull(dateTimeProvider, nameof(dateTimeProvider));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(peerAddressManager, nameof(peerAddressManager));
            Guard.NotNull(dnsServer, nameof(dnsServer));
            Guard.NotNull(dnsSettings, nameof(dnsSettings));
            Guard.NotNull(connectionSettings, nameof(connectionSettings));
            Guard.NotNull(peerBanning, nameof(peerBanning));

            this.dateTimeProvider   = dateTimeProvider;
            this.logger             = loggerFactory.CreateLogger("Impleum.Bitcoin.Fullnode");
            this.peerAddressManager = peerAddressManager;
            this.dnsServer          = dnsServer;
            this.dnsSettings        = dnsSettings;
            this.externalEndpoint   = connectionSettings.ExternalEndpoint;
            this.peerBanning        = peerBanning;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="WhitelistManager"/> class.
        /// </summary>
        /// <param name="dateTimeProvider">The provider for datetime.</param>
        /// <param name="loggerFactory">The factory to create the logger.</param>
        /// <param name="peerAddressManager">The manager implementation for peer addresses.</param>
        /// <param name="dnsServer">The DNS server.</param>
        /// <param name="nodeSettings">The node settings.</param>
        public WhitelistManager(IDateTimeProvider dateTimeProvider, ILoggerFactory loggerFactory, IPeerAddressManager peerAddressManager, IDnsServer dnsServer, NodeSettings nodeSettings)
        {
            Guard.NotNull(dateTimeProvider, nameof(dateTimeProvider));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(peerAddressManager, nameof(peerAddressManager));
            Guard.NotNull(dnsServer, nameof(dnsServer));
            Guard.NotNull(nodeSettings, nameof(nodeSettings));
            Guard.NotNull(nodeSettings.DnsHostName, nameof(nodeSettings.DnsHostName));
            Guard.NotNull(nodeSettings.ConnectionManager, nameof(nodeSettings.ConnectionManager));

            this.dateTimeProvider   = dateTimeProvider;
            this.logger             = loggerFactory.CreateLogger(this.GetType().FullName);
            this.peerAddressManager = peerAddressManager;
            this.dnsServer          = dnsServer;
            this.dnsPeerBlacklistThresholdInSeconds = nodeSettings.DnsPeerBlacklistThresholdInSeconds;
            this.dnsHostName      = nodeSettings.DnsHostName;
            this.externalEndpoint = nodeSettings.ConnectionManager.ExternalEndpoint;
            this.fullNodeMode     = nodeSettings.DnsFullNode;
        }
Exemple #14
0
        public Task InitializeAsync(IDnsServer dnsServer, string config)
        {
            if (_mmCountryReader == null)
            {
                string mmFile = Path.Combine(dnsServer.ApplicationFolder, "GeoIP2-Country.mmdb");

                if (!File.Exists(mmFile))
                {
                    mmFile = Path.Combine(dnsServer.ApplicationFolder, "GeoLite2-Country.mmdb");
                }

                if (!File.Exists(mmFile))
                {
                    throw new FileNotFoundException("MaxMind Country file is missing!");
                }

                _mmCountryReader = new DatabaseReader(mmFile);
            }

            return(Task.CompletedTask);
        }
Exemple #15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DnsFeature"/> class.
        /// </summary>
        /// <param name="dnsServer">The DNS server.</param>
        /// <param name="whitelistManager">The whitelist manager.</param>
        /// <param name="loggerFactory">The factory to create the logger.</param>
        /// <param name="nodeLifetime">The node lifetime object used for graceful shutdown.</param>
        /// <param name="nodeSettings">The node settings object containing node configuration.</param>
        /// <param name="dnsSettings">Defines the DNS settings for the node</param>
        /// <param name="dataFolders">The data folders of the system.</param>
        /// <param name="asyncLoopFactory">The asynchronous loop factory.</param>
        /// <param name="connectionManager">Manager of node's network connections.</param>
        /// <param name="unreliablePeerBehavior">Instance of the UnreliablePeerBehavior that will be added to the connectionManager Template.</param>
        public DnsFeature(IDnsServer dnsServer, IWhitelistManager whitelistManager, ILoggerFactory loggerFactory, INodeLifetime nodeLifetime, DnsSettings dnsSettings, NodeSettings nodeSettings, DataFolder dataFolders, IAsyncLoopFactory asyncLoopFactory, IConnectionManager connectionManager, UnreliablePeerBehavior unreliablePeerBehavior)
        {
            Guard.NotNull(dnsServer, nameof(dnsServer));
            Guard.NotNull(whitelistManager, nameof(whitelistManager));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(nodeLifetime, nameof(nodeLifetime));
            Guard.NotNull(nodeSettings, nameof(nodeSettings));
            Guard.NotNull(dataFolders, nameof(dataFolders));
            Guard.NotNull(asyncLoopFactory, nameof(asyncLoopFactory));
            Guard.NotNull(connectionManager, nameof(connectionManager));
            Guard.NotNull(unreliablePeerBehavior, nameof(unreliablePeerBehavior));

            this.dnsServer              = dnsServer;
            this.whitelistManager       = whitelistManager;
            this.logger                 = loggerFactory.CreateLogger("Impleum.Bitcoin.FullNode");
            this.asyncLoopFactory       = asyncLoopFactory;
            this.nodeLifetime           = nodeLifetime;
            this.nodeSettings           = nodeSettings;
            this.dnsSettings            = dnsSettings;
            this.dataFolders            = dataFolders;
            this.connectionManager      = connectionManager;
            this.unreliablePeerBehavior = unreliablePeerBehavior;
        }
Exemple #16
0
        public async Task InitializeAsync(IDnsServer dnsServer, string config)
        {
            dynamic jsonConfig = JsonConvert.DeserializeObject(config);

            _enableBlocking = jsonConfig.enableBlocking.Value;

            if (jsonConfig.dropMalformedRequests is null)
            {
                _dropMalformedRequests = false;
            }
            else
            {
                _dropMalformedRequests = jsonConfig.dropMalformedRequests.Value;
            }

            if (jsonConfig.allowedNetworks is null)
            {
                _allowedNetworks = Array.Empty <NetworkAddress>();
            }
            else
            {
                List <NetworkAddress> allowedNetworks = new List <NetworkAddress>();

                foreach (dynamic allowedNetwork in jsonConfig.allowedNetworks)
                {
                    allowedNetworks.Add(NetworkAddress.Parse(allowedNetwork.Value));
                }

                _allowedNetworks = allowedNetworks;
            }

            if (jsonConfig.blockedNetworks is null)
            {
                _blockedNetworks = Array.Empty <NetworkAddress>();
            }
            else
            {
                List <NetworkAddress> blockedNetworks = new List <NetworkAddress>();

                foreach (dynamic blockedNetwork in jsonConfig.blockedNetworks)
                {
                    blockedNetworks.Add(NetworkAddress.Parse(blockedNetwork.Value));
                }

                _blockedNetworks = blockedNetworks;
            }

            if (jsonConfig.blockedQuestions is null)
            {
                _blockedQuestions = Array.Empty <BlockedQuestion>();
            }
            else
            {
                List <BlockedQuestion> blockedQuestions = new List <BlockedQuestion>();

                foreach (dynamic blockedQuestion in jsonConfig.blockedQuestions)
                {
                    blockedQuestions.Add(new BlockedQuestion(blockedQuestion));
                }

                _blockedQuestions = blockedQuestions;
            }

            if (jsonConfig.dropMalformedRequests is null)
            {
                config = config.Replace("\"allowedNetworks\"", "\"dropMalformedRequests\": false,\r\n  \"allowedNetworks\"");

                await File.WriteAllTextAsync(Path.Combine(dnsServer.ApplicationFolder, "dnsApp.config"), config);
            }
        }
Exemple #17
0
 public DnsClientInternal(IDnsServer dnsServer)
 {
     _dnsServer = dnsServer;
 }
Exemple #18
0
        public DnsApplication(IDnsServer dnsServer, string appName)
        {
            _dnsServer = dnsServer;
            _appName   = appName;

            //load DLLs and handlers
            Dictionary <string, IDnsApplicationRequestHandler> dnsRequestHandlers = new Dictionary <string, IDnsApplicationRequestHandler>();
            Type dnsAppInterface = typeof(IDnsApplicationRequestHandler);

            Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();

            foreach (string dllFile in Directory.GetFiles(_dnsServer.ApplicationFolder, "*.dll", SearchOption.TopDirectoryOnly))
            {
                string dllFileName = Path.GetFileNameWithoutExtension(dllFile);

                bool isLoaded = false;

                foreach (Assembly loadedAssembly in loadedAssemblies)
                {
                    AssemblyName assemblyName = loadedAssembly.GetName();

                    if (assemblyName.CodeBase != null)
                    {
                        if (Path.GetFileNameWithoutExtension(assemblyName.CodeBase).Equals(dllFileName, StringComparison.OrdinalIgnoreCase))
                        {
                            isLoaded = true;
                            break;
                        }
                    }
                    else if ((assemblyName.Name != null) && assemblyName.Name.Equals(dllFileName, StringComparison.OrdinalIgnoreCase))
                    {
                        isLoaded = true;
                        break;
                    }
                }

                if (isLoaded)
                {
                    continue;
                }

                Assembly assembly;

                try
                {
                    string pdbFile = Path.Combine(_dnsServer.ApplicationFolder, Path.GetFileNameWithoutExtension(dllFile) + ".pdb");

                    if (File.Exists(pdbFile))
                    {
                        using (FileStream dllStream = new FileStream(dllFile, FileMode.Open, FileAccess.Read))
                        {
                            using (FileStream pdbStream = new FileStream(pdbFile, FileMode.Open, FileAccess.Read))
                            {
                                assembly = _appContext.LoadFromStream(dllStream, pdbStream);
                            }
                        }
                    }
                    else
                    {
                        using (FileStream dllStream = new FileStream(dllFile, FileMode.Open, FileAccess.Read))
                        {
                            assembly = _appContext.LoadFromStream(dllStream);
                        }
                    }
                }
                catch (Exception ex)
                {
                    _dnsServer.WriteLog(ex);
                    continue;
                }

                foreach (Type classType in assembly.ExportedTypes)
                {
                    foreach (Type interfaceType in classType.GetInterfaces())
                    {
                        if (interfaceType == dnsAppInterface)
                        {
                            IDnsApplicationRequestHandler handler = Activator.CreateInstance(classType) as IDnsApplicationRequestHandler;
                            dnsRequestHandlers.TryAdd(classType.FullName, handler);
                        }
                    }
                }
            }

            _dnsRequestHandlers = dnsRequestHandlers;
        }
Exemple #19
0
        public Task InitializeAsync(IDnsServer dnsServer, string config)
        {
            _dnsServer = dnsServer;

            dynamic jsonConfig = JsonConvert.DeserializeObject(config);

            _enableLogging = jsonConfig.enableLogging.Value;
            _maxLogDays    = Convert.ToInt32(jsonConfig.maxLogDays.Value);

            string sqliteDbPath     = jsonConfig.sqliteDbPath.Value;
            string connectionString = jsonConfig.connectionString.Value;

            if (!Path.IsPathRooted(sqliteDbPath))
            {
                sqliteDbPath = Path.Combine(_dnsServer.ApplicationFolder, sqliteDbPath);
            }

            _connectionString = connectionString.Replace("{sqliteDbPath}", sqliteDbPath);

            using (SqliteConnection connection = new SqliteConnection(_connectionString))
            {
                connection.Open();

                using (SqliteCommand command = connection.CreateCommand())
                {
                    command.CommandText = @"
CREATE TABLE IF NOT EXISTS dns_logs
(
    dlid INTEGER PRIMARY KEY,
    timestamp DATETIME NOT NULL,
    client_ip VARCHAR(39) NOT NULL,
    protocol TINYINT NOT NULL,
    response_type TINYINT NOT NULL,
    rcode TINYINT NOT NULL,
    qname VARCHAR(255),
    qtype SMALLINT,
    qclass SMALLINT,
    answer TEXT
);
";
                    command.ExecuteNonQuery();
                }

                using (SqliteCommand command = connection.CreateCommand())
                {
                    command.CommandText = "CREATE INDEX IF NOT EXISTS index_timestamp ON dns_logs (timestamp);";
                    command.ExecuteNonQuery();
                }

                using (SqliteCommand command = connection.CreateCommand())
                {
                    command.CommandText = "CREATE INDEX IF NOT EXISTS index_client_ip ON dns_logs (client_ip);";
                    command.ExecuteNonQuery();
                }

                using (SqliteCommand command = connection.CreateCommand())
                {
                    command.CommandText = "CREATE INDEX IF NOT EXISTS index_protocol ON dns_logs (protocol);";
                    command.ExecuteNonQuery();
                }

                using (SqliteCommand command = connection.CreateCommand())
                {
                    command.CommandText = "CREATE INDEX IF NOT EXISTS index_response_type ON dns_logs (response_type);";
                    command.ExecuteNonQuery();
                }

                using (SqliteCommand command = connection.CreateCommand())
                {
                    command.CommandText = "CREATE INDEX IF NOT EXISTS index_rcode ON dns_logs (rcode);";
                    command.ExecuteNonQuery();
                }

                using (SqliteCommand command = connection.CreateCommand())
                {
                    command.CommandText = "CREATE INDEX IF NOT EXISTS index_qname ON dns_logs (qname);";
                    command.ExecuteNonQuery();
                }

                using (SqliteCommand command = connection.CreateCommand())
                {
                    command.CommandText = "CREATE INDEX IF NOT EXISTS index_qtype ON dns_logs (qtype);";
                    command.ExecuteNonQuery();
                }

                using (SqliteCommand command = connection.CreateCommand())
                {
                    command.CommandText = "CREATE INDEX IF NOT EXISTS index_qclass ON dns_logs (qclass);";
                    command.ExecuteNonQuery();
                }

                using (SqliteCommand command = connection.CreateCommand())
                {
                    command.CommandText = "CREATE INDEX IF NOT EXISTS index_timestamp_client_ip ON dns_logs (timestamp, client_ip);";
                    command.ExecuteNonQuery();
                }

                using (SqliteCommand command = connection.CreateCommand())
                {
                    command.CommandText = "CREATE INDEX IF NOT EXISTS index_timestamp_qname ON dns_logs (timestamp, qname);";
                    command.ExecuteNonQuery();
                }

                using (SqliteCommand command = connection.CreateCommand())
                {
                    command.CommandText = "CREATE INDEX IF NOT EXISTS index_client_qname ON dns_logs (client_ip, qname);";
                    command.ExecuteNonQuery();
                }

                using (SqliteCommand command = connection.CreateCommand())
                {
                    command.CommandText = "CREATE INDEX IF NOT EXISTS index_query ON dns_logs (qname, qtype);";
                    command.ExecuteNonQuery();
                }

                using (SqliteCommand command = connection.CreateCommand())
                {
                    command.CommandText = "CREATE INDEX IF NOT EXISTS index_all ON dns_logs (timestamp, client_ip, protocol, response_type, rcode, qname, qtype, qclass);";
                    command.ExecuteNonQuery();
                }
            }

            if (_enableLogging)
            {
                _queueTimer = new Timer(delegate(object state)
                {
                    try
                    {
                        BulkInsertLogs();
                    }
                    catch (Exception ex)
                    {
                        _dnsServer.WriteLog(ex);
                    }
                    finally
                    {
                        if (_queueTimer is not null)
                        {
                            _queueTimer.Change(QUEUE_TIMER_INTERVAL, Timeout.Infinite);
                        }
                    }
                });

                _queueTimer.Change(QUEUE_TIMER_INTERVAL, Timeout.Infinite);
            }
            else
            {
                if (_queueTimer is not null)
                {
                    _queueTimer.Dispose();
                    _queueTimer = null;
                }
            }

            if (_maxLogDays < 1)
            {
                if (_cleanupTimer is not null)
                {
                    _cleanupTimer.Dispose();
                    _cleanupTimer = null;
                }
            }
            else
            {
                _cleanupTimer = new Timer(delegate(object state)
                {
                    try
                    {
                        using (SqliteConnection connection = new SqliteConnection(_connectionString))
                        {
                            connection.Open();

                            using (SqliteCommand command = connection.CreateCommand())
                            {
                                command.CommandText = "DELETE FROM dns_logs WHERE timestamp < @timestamp;";

                                command.Parameters.AddWithValue("@timestamp", DateTime.UtcNow.AddDays(_maxLogDays * -1));

                                command.ExecuteNonQuery();
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        _dnsServer.WriteLog(ex);
                    }
                    finally
                    {
                        if (_cleanupTimer is not null)
                        {
                            _cleanupTimer.Change(CLEAN_UP_TIMER_PERIODIC_INTERVAL, Timeout.Infinite);
                        }
                    }
                });

                _cleanupTimer.Change(CLEAN_UP_TIMER_INITIAL_INTERVAL, Timeout.Infinite);
            }

            return(Task.CompletedTask);
        }
Exemple #20
0
        public Task <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer)
        {
            DnsQuestionRecord question = request.Question[0];

            dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData);

            string healthCheck = jsonAppRecordData.healthCheck?.Value;

            IReadOnlyList <DnsResourceRecord> answers;

            if (question.Type == DnsResourceRecordType.TXT)
            {
                bool allowTxtStatus;

                if (jsonAppRecordData.allowTxtStatus == null)
                {
                    allowTxtStatus = false;
                }
                else
                {
                    allowTxtStatus = jsonAppRecordData.allowTxtStatus.Value;
                }

                if (!allowTxtStatus)
                {
                    return(Task.FromResult <DnsDatagram>(null));
                }

                List <DnsResourceRecord> txtAnswers = new List <DnsResourceRecord>();

                GetStatusAnswers(jsonAppRecordData.primary.Value, true, question, 30, healthCheck, txtAnswers);

                foreach (dynamic jsonDomain in jsonAppRecordData.secondary)
                {
                    GetStatusAnswers(jsonDomain.Value, false, question, 30, healthCheck, txtAnswers);
                }

                answers = txtAnswers;
            }
            else
            {
                answers = GetAnswers(jsonAppRecordData.primary.Value, question, zoneName, appRecordTtl, healthCheck);
                if (answers is null)
                {
                    foreach (dynamic jsonDomain in jsonAppRecordData.secondary)
                    {
                        answers = GetAnswers(jsonDomain.Value, question, zoneName, appRecordTtl, healthCheck);
                        if (answers is not null)
                        {
                            break;
                        }
                    }

                    if (answers is null)
                    {
                        return(Task.FromResult <DnsDatagram>(null));
                    }
                }
            }

            return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers)));
        }
Exemple #21
0
        public Task <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer)
        {
            dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData);
            dynamic jsonCname;

            if (NetUtilities.IsPrivateIP(remoteEP.Address))
            {
                jsonCname = jsonAppRecordData.@private;
            }
            else
            {
                jsonCname = jsonAppRecordData.@public;
            }

            if (jsonCname == null)
            {
                return(Task.FromResult <DnsDatagram>(null));
            }

            string cname = jsonCname.Value;

            if (string.IsNullOrEmpty(cname))
            {
                return(Task.FromResult <DnsDatagram>(null));
            }

            IReadOnlyList <DnsResourceRecord> answers;

            if (request.Question[0].Name.Equals(zoneName, StringComparison.OrdinalIgnoreCase)) //check for zone apex
            {
                answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.ANAME, DnsClass.IN, appRecordTtl, new DnsANAMERecord(cname)) }
            }
            ;                                                                                                                                                                             //use ANAME
            else
            {
                answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.CNAME, DnsClass.IN, appRecordTtl, new DnsCNAMERecord(cname)) }
            };

            return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers)));
        }
Exemple #22
0
 public Task InitializeAsync(IDnsServer dnsServer, string config)
 {
     //do nothing
     return(Task.CompletedTask);
 }
Exemple #23
0
        public Task <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer)
        {
            DnsResourceRecord answer;

            switch (request.Question[0].Type)
            {
            case DnsResourceRecordType.A:
                if (remoteEP.AddressFamily == AddressFamily.InterNetwork)
                {
                    answer = new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.A, DnsClass.IN, appRecordTtl, new DnsARecord(remoteEP.Address));
                }
                else
                {
                    return(Task.FromResult <DnsDatagram>(null));
                }

                break;

            case DnsResourceRecordType.AAAA:
                if (remoteEP.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    answer = new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.AAAA, DnsClass.IN, appRecordTtl, new DnsAAAARecord(remoteEP.Address));
                }
                else
                {
                    return(Task.FromResult <DnsDatagram>(null));
                }

                break;

            case DnsResourceRecordType.TXT:
                answer = new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.TXT, DnsClass.IN, appRecordTtl, new DnsTXTRecord(remoteEP.Address.ToString()));
                break;

            default:
                return(Task.FromResult <DnsDatagram>(null));
            }

            return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, new DnsResourceRecord[] { answer })));
        }
Exemple #24
0
        public Task <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer)
        {
            switch (request.Question[0].Type)
            {
            case DnsResourceRecordType.A:
            case DnsResourceRecordType.AAAA:
                Location location = null;

                if (_mmCityReader.TryCity(remoteEP.Address, out CityResponse response))
                {
                    location = response.Location;
                }

                dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData);
                dynamic jsonClosestServer = null;

                if ((location == null) || !location.HasCoordinates)
                {
                    jsonClosestServer = jsonAppRecordData[0];
                }
                else
                {
                    double lastDistance = double.MaxValue;

                    foreach (dynamic jsonServer in jsonAppRecordData)
                    {
                        double lat   = Convert.ToDouble(jsonServer.lat.Value);
                        double @long = Convert.ToDouble([email protected]);

                        double distance = GetDistance(lat, @long, location.Latitude.Value, location.Longitude.Value);

                        if (distance < lastDistance)
                        {
                            lastDistance      = distance;
                            jsonClosestServer = jsonServer;
                        }
                    }
                }

                if (jsonClosestServer == null)
                {
                    return(Task.FromResult <DnsDatagram>(null));
                }

                List <DnsResourceRecord> answers = new List <DnsResourceRecord>();

                foreach (dynamic jsonAddress in jsonClosestServer.addresses)
                {
                    IPAddress address = IPAddress.Parse(jsonAddress.Value);

                    switch (request.Question[0].Type)
                    {
                    case DnsResourceRecordType.A:
                        if (address.AddressFamily == AddressFamily.InterNetwork)
                        {
                            answers.Add(new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.A, DnsClass.IN, appRecordTtl, new DnsARecord(address)));
                        }

                        break;

                    case DnsResourceRecordType.AAAA:
                        if (address.AddressFamily == AddressFamily.InterNetworkV6)
                        {
                            answers.Add(new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.AAAA, DnsClass.IN, appRecordTtl, new DnsAAAARecord(address)));
                        }

                        break;
                    }
                }

                if (answers.Count == 0)
                {
                    return(Task.FromResult <DnsDatagram>(null));
                }

                return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers)));

            default:
                return(Task.FromResult <DnsDatagram>(null));
            }
        }
Exemple #25
0
        public async Task InitializeAsync(IDnsServer dnsServer, string config)
        {
            _dnsServer = dnsServer;

            dynamic jsonConfig = JsonConvert.DeserializeObject(config);

            {
                List <IPAddress> webServerLocalAddresses = new List <IPAddress>();

                foreach (dynamic jsonAddress in jsonConfig.webServerLocalAddresses)
                {
                    webServerLocalAddresses.Add(IPAddress.Parse(jsonAddress.Value));
                }

                _webServerLocalAddresses = webServerLocalAddresses;
            }

            if (jsonConfig.webServerUseSelfSignedTlsCertificate is null)
            {
                _webServerUseSelfSignedTlsCertificate = true;
            }
            else
            {
                _webServerUseSelfSignedTlsCertificate = jsonConfig.webServerUseSelfSignedTlsCertificate.Value;
            }

            _webServerTlsCertificateFilePath = jsonConfig.webServerTlsCertificateFilePath.Value;
            _webServerTlsCertificatePassword = jsonConfig.webServerTlsCertificatePassword.Value;

            _webServerRootPath = jsonConfig.webServerRootPath.Value;

            if (!Path.IsPathRooted(_webServerRootPath))
            {
                _webServerRootPath = Path.Combine(_dnsServer.ApplicationFolder, _webServerRootPath);
            }

            _serveBlockPageFromWebServerRoot = jsonConfig.serveBlockPageFromWebServerRoot.Value;

            string blockPageTitle   = jsonConfig.blockPageTitle.Value;
            string blockPageHeading = jsonConfig.blockPageHeading.Value;
            string blockPageMessage = jsonConfig.blockPageMessage.Value;

            string blockPageContent = @"<html>
<head>
  <title>" + (blockPageTitle is null ? "" : blockPageTitle) + @"</title>
</head>
<body>
" + (blockPageHeading is null ? "" : "  <h1>" + blockPageHeading + "</h1>") + @"
" + (blockPageMessage is null ? "" : "  <p>" + blockPageMessage + "</p>") + @"
</body>
</html>";

            _blockPageContent = Encoding.UTF8.GetBytes(blockPageContent);

            try
            {
                StopWebServer();

                string selfSignedCertificateFilePath = Path.Combine(_dnsServer.ApplicationFolder, "cert.pfx");

                if (_webServerUseSelfSignedTlsCertificate)
                {
                    if (!File.Exists(selfSignedCertificateFilePath))
                    {
                        RSA rsa = RSA.Create(2048);
                        CertificateRequest req  = new CertificateRequest("cn=" + _dnsServer.ServerDomain, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
                        X509Certificate2   cert = req.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(5));

                        await File.WriteAllBytesAsync(selfSignedCertificateFilePath, cert.Export(X509ContentType.Pkcs12, null as string));
                    }
                }
                else
                {
                    File.Delete(selfSignedCertificateFilePath);
                }

                if (string.IsNullOrEmpty(_webServerTlsCertificateFilePath))
                {
                    StopTlsCertificateUpdateTimer();

                    if (_webServerUseSelfSignedTlsCertificate)
                    {
                        LoadWebServiceTlsCertificate(selfSignedCertificateFilePath, null);
                    }
                    else
                    {
                        //disable HTTPS
                        _webServerTlsCertificate = null;
                    }
                }
                else
                {
                    LoadWebServiceTlsCertificate(_webServerTlsCertificateFilePath, _webServerTlsCertificatePassword);
                    StartTlsCertificateUpdateTimer();
                }

                StartWebServer();
            }
            catch (Exception ex)
            {
                _dnsServer.WriteLog(ex);
            }

            if (jsonConfig.webServerUseSelfSignedTlsCertificate is null)
            {
                config = config.Replace("\"webServerTlsCertificateFilePath\"", "\"webServerUseSelfSignedTlsCertificate\": true,\r\n  \"webServerTlsCertificateFilePath\"");

                await File.WriteAllTextAsync(Path.Combine(dnsServer.ApplicationFolder, "dnsApp.config"), config);
            }
        }
Exemple #26
0
        public Task <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer)
        {
            switch (request.Question[0].Type)
            {
            case DnsResourceRecordType.A:
            case DnsResourceRecordType.AAAA:
                dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData);
                dynamic jsonAddresses;

                if (NetUtilities.IsPrivateIP(remoteEP.Address))
                {
                    jsonAddresses = jsonAppRecordData.@private;
                }
                else
                {
                    jsonAddresses = jsonAppRecordData.@public;
                }

                if (jsonAddresses == null)
                {
                    return(Task.FromResult <DnsDatagram>(null));
                }

                List <DnsResourceRecord> answers = new List <DnsResourceRecord>();

                foreach (dynamic jsonAddress in jsonAddresses)
                {
                    IPAddress address = IPAddress.Parse(jsonAddress.Value);

                    switch (request.Question[0].Type)
                    {
                    case DnsResourceRecordType.A:
                        if (address.AddressFamily == AddressFamily.InterNetwork)
                        {
                            answers.Add(new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.A, DnsClass.IN, appRecordTtl, new DnsARecord(address)));
                        }

                        break;

                    case DnsResourceRecordType.AAAA:
                        if (address.AddressFamily == AddressFamily.InterNetworkV6)
                        {
                            answers.Add(new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.AAAA, DnsClass.IN, appRecordTtl, new DnsAAAARecord(address)));
                        }

                        break;
                    }
                }

                if (answers.Count == 0)
                {
                    return(Task.FromResult <DnsDatagram>(null));
                }

                return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers)));

            default:
                return(Task.FromResult <DnsDatagram>(null));
            }
        }
Exemple #27
0
        public HealthMonitor(IDnsServer dnsServer, IPAddress address, HealthCheck healthCheck, Uri healthCheckUrl)
        {
            _dnsServer   = dnsServer;
            _address     = address;
            _healthCheck = healthCheck;

            _healthCheckTimer = new Timer(async delegate(object state)
            {
                try
                {
                    if (_healthCheck is null)
                    {
                        _lastHealthCheckResponse = null;
                    }
                    else
                    {
                        HealthCheckResponse healthCheckResponse = await _healthCheck.IsHealthyAsync(_address, healthCheckUrl);

                        bool statusChanged = false;
                        bool maintenance   = false;

                        if (_lastHealthCheckResponse is null)
                        {
                            switch (healthCheckResponse.Status)
                            {
                            case HealthStatus.Failed:
                                statusChanged = true;
                                break;

                            case HealthStatus.Maintenance:
                                statusChanged = true;
                                maintenance   = true;
                                break;
                            }
                        }
                        else
                        {
                            if (_lastHealthCheckResponse.Status != healthCheckResponse.Status)
                            {
                                statusChanged = true;

                                if ((_lastHealthCheckResponse.Status == HealthStatus.Maintenance) || (healthCheckResponse.Status == HealthStatus.Maintenance))
                                {
                                    maintenance = true;
                                }
                            }
                        }

                        if (statusChanged)
                        {
                            switch (healthCheckResponse.Status)
                            {
                            case HealthStatus.Failed:
                                _dnsServer.WriteLog("ALERT! Address [" + _address.ToString() + "] status is FAILED based on '" + _healthCheck.Name + "' health check. The failure reason is: " + healthCheckResponse.FailureReason);
                                break;

                            default:
                                _dnsServer.WriteLog("ALERT! Address [" + _address.ToString() + "] status is " + healthCheckResponse.Status.ToString().ToUpper() + " based on '" + _healthCheck.Name + "' health check.");
                                break;
                            }

                            if (healthCheckResponse.Exception is not null)
                            {
                                _dnsServer.WriteLog(healthCheckResponse.Exception);
                            }

                            if (!maintenance)
                            {
                                //avoid sending email alerts when switching from or to maintenance
                                EmailAlert emailAlert = _healthCheck.EmailAlert;
                                if (emailAlert is not null)
                                {
                                    _ = emailAlert.SendAlertAsync(_address, _healthCheck.Name, healthCheckResponse);
                                }
                            }

                            WebHook webHook = _healthCheck.WebHook;
                            if (webHook is not null)
                            {
                                _ = webHook.CallAsync(_address, _healthCheck.Name, healthCheckResponse);
                            }
                        }

                        _lastHealthCheckResponse = healthCheckResponse;
                    }
                }
                catch (Exception ex)
                {
                    _dnsServer.WriteLog(ex);

                    if (_lastHealthCheckResponse is null)
                    {
                        EmailAlert emailAlert = _healthCheck.EmailAlert;
                        if (emailAlert is not null)
                        {
                            _ = emailAlert.SendAlertAsync(_address, _healthCheck.Name, ex);
                        }

                        WebHook webHook = _healthCheck.WebHook;
                        if (webHook is not null)
                        {
                            _ = webHook.CallAsync(_address, _healthCheck.Name, ex);
                        }

                        _lastHealthCheckResponse = new HealthCheckResponse(HealthStatus.Failed, ex.ToString(), ex);
                    }
                    else
                    {
                        _lastHealthCheckResponse = null;
                    }
                }
                finally
                {
                    if (!_disposed && (_healthCheck is not null))
                    {
                        _healthCheckTimer.Change(_healthCheck.Interval, Timeout.Infinite);
                    }
                }
            }, null, Timeout.Infinite, Timeout.Infinite);

            _healthCheckTimer.Change(HEALTH_CHECK_TIMER_INITIAL_INTERVAL, Timeout.Infinite);
        }
Exemple #28
0
        public Task <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer)
        {
            string continent;

            if (_mmCountryReader.TryCountry(remoteEP.Address, out CountryResponse response))
            {
                continent = response.Continent.Code;
            }
            else
            {
                continent = "default";
            }

            dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData);
            dynamic jsonCname         = jsonAppRecordData[continent];

            if (jsonCname != null)
            {
                string cname = jsonCname.Value;
                if (!string.IsNullOrEmpty(cname))
                {
                    IReadOnlyList <DnsResourceRecord> answers;

                    if (request.Question[0].Name.Equals(zoneName, StringComparison.OrdinalIgnoreCase)) //check for zone apex
                    {
                        answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.ANAME, DnsClass.IN, appRecordTtl, new DnsANAMERecord(cname)) }
                    }
                    ;                                                                                                                                                                             //use ANAME
                    else
                    {
                        answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.CNAME, DnsClass.IN, appRecordTtl, new DnsCNAMERecord(cname)) }
                    };

                    return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers)));
                }
            }

            return(Task.FromResult <DnsDatagram>(null));
        }
Exemple #29
0
        public Task InitializeAsync(IDnsServer dnsServer, string config)
        {
            _maxMind = MaxMind.Create(dnsServer);

            return(Task.CompletedTask);
        }
Exemple #30
0
 public Task InitializeAsync(IDnsServer dnsServer, string config)
 {
     //no config needed
     return(Task.CompletedTask);
 }