|
| 1 | +# Pi-hole Architecture Documentation |
| 2 | + |
| 3 | +This document provides a comprehensive overview of the Pi-hole architecture inspired by the C4 model approach, which offers multiple levels of abstraction to understand the system from different perspectives. |
| 4 | + |
| 5 | +## Table of Contents |
| 6 | + |
| 7 | +- [Level 1: System Context](#level-1-system-context) |
| 8 | +- [Level 2: Container Diagram](#level-2-container-diagram) |
| 9 | +- [Level 3: Component Diagram](#level-3-component-diagram) |
| 10 | +- [Additional Diagrams](#additional-diagrams) |
| 11 | + - [DNS Query Flow](#dns-query-flow) |
| 12 | + - [Blocklist Update Process](#blocklist-update-process) |
| 13 | + |
| 14 | +## Level 1: System Context |
| 15 | + |
| 16 | +The System Context diagram shows Pi-hole in its environment, depicting how it interacts with external systems and users. |
| 17 | + |
| 18 | +```mermaid |
| 19 | +graph TB |
| 20 | + classDef primary fill:#4CAF50,stroke:#388E3C,color:white |
| 21 | + classDef secondary fill:#2196F3,stroke:#1976D2,color:white |
| 22 | + classDef external fill:#78909C,stroke:#546E7A,color:white |
| 23 | + classDef user fill:#FF5722,stroke:#E64A19,color:white |
| 24 | +
|
| 25 | + %% External Users |
| 26 | + User([Network User]):::user |
| 27 | + Admin([Pi-hole Administrator]):::user |
| 28 | +
|
| 29 | + %% Main System |
| 30 | + PiHole[Pi-hole System]:::primary |
| 31 | +
|
| 32 | + %% External Systems |
| 33 | + ClientDevices([Client Devices]):::external |
| 34 | + Router([Network Router]):::external |
| 35 | + UpstreamDNS([Upstream DNS Servers]):::external |
| 36 | + AdLists([Ad List Providers]):::external |
| 37 | + Internet([Internet]):::external |
| 38 | +
|
| 39 | + %% Connections |
| 40 | + User -- "Uses devices that\nconnect through Pi-hole" --> ClientDevices |
| 41 | + ClientDevices -- "Send DNS queries" --> Router |
| 42 | + Router -- "Forwards DNS queries" --> PiHole |
| 43 | + PiHole -- "Forwards allowed\nDNS queries" --> UpstreamDNS |
| 44 | + UpstreamDNS -- "Resolves domains" --> Internet |
| 45 | + PiHole -- "Downloads\nad lists" --> AdLists |
| 46 | + Admin -- "Configures and\nmonitors" --> PiHole |
| 47 | +``` |
| 48 | + |
| 49 | +The System Context diagram shows: |
| 50 | +- **Network Users**: People using devices on the network protected by Pi-hole |
| 51 | +- **Pi-hole Administrator**: Person who configures and maintains the Pi-hole system |
| 52 | +- **Client Devices**: Computers, phones, smart TVs, and other devices on the network |
| 53 | +- **Network Router**: Directs network traffic and is configured to use Pi-hole as the DNS server |
| 54 | +- **Upstream DNS Servers**: External DNS servers that Pi-hole forwards allowed queries to |
| 55 | +- **Ad List Providers**: Sources of domain blocklists that Pi-hole downloads |
| 56 | +- **Internet**: The broader internet that devices access through Pi-hole's filtering |
| 57 | + |
| 58 | +## Level 2: Container Diagram |
| 59 | + |
| 60 | +The Container diagram zooms in on the Pi-hole system, showing its major subsystems and how they interact. |
| 61 | + |
| 62 | +```mermaid |
| 63 | +flowchart TB |
| 64 | + classDef primary fill:#4CAF50,stroke:#388E3C,color:white |
| 65 | + classDef secondary fill:#2196F3,stroke:#1976D2,color:white |
| 66 | + classDef tertiary fill:#FF9800,stroke:#F57C00,color:white |
| 67 | + classDef quaternary fill:#9C27B0,stroke:#7B1FA2,color:white |
| 68 | + classDef external fill:#78909C,stroke:#546E7A,color:white |
| 69 | + classDef database fill:#795548,stroke:#5D4037,color:white |
| 70 | + classDef user fill:#FF5722,stroke:#E64A19,color:white |
| 71 | +
|
| 72 | + %% External Users and Systems |
| 73 | + User([Network User]):::user |
| 74 | + Admin([Pi-hole Administrator]):::user |
| 75 | + Router([Network Router]):::external |
| 76 | + UpstreamDNS([Upstream DNS Servers]):::external |
| 77 | + AdLists([Ad List Providers]):::external |
| 78 | +
|
| 79 | + %% Pi-hole Containers |
| 80 | + subgraph PiHole[Pi-hole System] |
| 81 | + FTL[FTL DNS Service]:::primary |
| 82 | + WebAdmin[Web Admin Interface]:::quaternary |
| 83 | + CLI[Command Line Interface]:::secondary |
| 84 | + Gravity[Gravity Updater]:::tertiary |
| 85 | +
|
| 86 | + %% Databases |
| 87 | + GravityDB[(Gravity Database)]:::database |
| 88 | + FTLDB[(FTL Database)]:::database |
| 89 | +
|
| 90 | + %% Configuration |
| 91 | + Config[(Configuration Files)]:::database |
| 92 | + end |
| 93 | +
|
| 94 | + %% External Connections |
| 95 | + Router -- "DNS Queries\n(Port 53)" --> FTL |
| 96 | + FTL -- "Allowed Queries" --> UpstreamDNS |
| 97 | + Gravity -- "Download\nBlocklists" --> AdLists |
| 98 | + Admin -- "Web Access\n(HTTP/HTTPS)" --> WebAdmin |
| 99 | + Admin -- "Shell Commands" --> CLI |
| 100 | + User -. "DNS Requests\nvia Network" .-> Router |
| 101 | +
|
| 102 | + %% Internal Connections |
| 103 | + FTL -- "Stores Query\nStatistics" --> FTLDB |
| 104 | + FTL -- "Checks if Domain\nis Blocked" --> GravityDB |
| 105 | + FTL -- "Reads" --> Config |
| 106 | + Gravity -- "Updates" --> GravityDB |
| 107 | + CLI -- "Manages" --> FTL |
| 108 | + CLI -- "Runs" --> Gravity |
| 109 | + CLI -- "Updates" --> Config |
| 110 | + WebAdmin -- "API Calls" --> FTL |
| 111 | + WebAdmin -- "Reads/Writes" --> Config |
| 112 | + WebAdmin -- "Reads" --> FTLDB |
| 113 | + WebAdmin -- "Manages" --> GravityDB |
| 114 | +``` |
| 115 | + |
| 116 | +The Container diagram shows: |
| 117 | +- **FTL DNS Service**: The core DNS service that processes queries and blocks ads |
| 118 | +- **Web Admin Interface**: The web-based dashboard for managing Pi-hole |
| 119 | +- **Command Line Interface**: The terminal-based interface for administration |
| 120 | +- **Gravity Updater**: The component that downloads and processes blocklists |
| 121 | +- **Databases**: The Gravity DB (for blocklists) and FTL DB (for statistics) |
| 122 | +- **Configuration Files**: Settings that control Pi-hole's behavior |
| 123 | + |
| 124 | +## Level 3: Component Diagram |
| 125 | + |
| 126 | +The Component diagram focuses on the internal structure of the FTL DNS Service, which is the core of Pi-hole's functionality. |
| 127 | + |
| 128 | +```mermaid |
| 129 | +flowchart TB |
| 130 | + classDef primary fill:#4CAF50,stroke:#388E3C,color:white |
| 131 | + classDef secondary fill:#2196F3,stroke:#1976D2,color:white |
| 132 | + classDef tertiary fill:#FF9800,stroke:#F57C00,color:white |
| 133 | + classDef database fill:#795548,stroke:#5D4037,color:white |
| 134 | + classDef external fill:#78909C,stroke:#546E7A,color:white |
| 135 | +
|
| 136 | + %% External Systems |
| 137 | + Router([Network Router]):::external |
| 138 | + UpstreamDNS([Upstream DNS Servers]):::external |
| 139 | + WebAdmin([Web Admin Interface]):::external |
| 140 | + CLI([Command Line Interface]):::external |
| 141 | +
|
| 142 | + %% FTL Components |
| 143 | + subgraph FTL[FTL DNS Service] |
| 144 | + DNSResolver[DNS Resolver]:::primary |
| 145 | + QueryAnalyzer[Query Analyzer]:::primary |
| 146 | + BlockingEngine[Blocking Engine]:::primary |
| 147 | + CacheManager[Cache Manager]:::secondary |
| 148 | + APIServer[API Server]:::secondary |
| 149 | + TelnetServer[Telnet Server]:::secondary |
| 150 | + StatisticsCollector[Statistics Collector]:::tertiary |
| 151 | + end |
| 152 | +
|
| 153 | + %% Databases |
| 154 | + GravityDB[(Gravity Database)]:::database |
| 155 | + FTLDB[(FTL Database)]:::database |
| 156 | + DNSCache[(DNS Cache)]:::database |
| 157 | +
|
| 158 | + %% External Connections |
| 159 | + Router -- "DNS Queries" --> DNSResolver |
| 160 | + DNSResolver -- "Allowed Queries" --> UpstreamDNS |
| 161 | + WebAdmin -- "HTTP Requests" --> APIServer |
| 162 | + CLI -- "Commands" --> APIServer |
| 163 | + CLI -- "Direct Queries" --> TelnetServer |
| 164 | +
|
| 165 | + %% Internal Connections |
| 166 | + DNSResolver --> QueryAnalyzer |
| 167 | + QueryAnalyzer --> BlockingEngine |
| 168 | + BlockingEngine -- "Checks Domain" --> GravityDB |
| 169 | + BlockingEngine -- "Blocked/Allowed\nDecision" --> DNSResolver |
| 170 | + DNSResolver -- "Cache Results" --> CacheManager |
| 171 | + CacheManager -- "Store/Retrieve" --> DNSCache |
| 172 | + QueryAnalyzer --> StatisticsCollector |
| 173 | + StatisticsCollector -- "Store Stats" --> FTLDB |
| 174 | + APIServer -- "Get Data" --> StatisticsCollector |
| 175 | + TelnetServer -- "Get Data" --> StatisticsCollector |
| 176 | +``` |
| 177 | + |
| 178 | +The Component diagram shows: |
| 179 | +- **DNS Resolver**: Handles incoming DNS queries and returns responses |
| 180 | +- **Query Analyzer**: Processes queries to determine if they should be blocked |
| 181 | +- **Blocking Engine**: Implements the blocking logic based on blocklists |
| 182 | +- **Cache Manager**: Manages the DNS cache for improved performance |
| 183 | +- **API Server**: Provides an HTTP API for the Web Admin Interface |
| 184 | +- **Telnet Server**: Provides a telnet interface for direct queries |
| 185 | +- **Statistics Collector**: Gathers and stores statistics about DNS queries |
| 186 | + |
| 187 | + |
| 188 | +## Additional Diagrams |
| 189 | + |
| 190 | +### DNS Query Flow |
| 191 | + |
| 192 | +This diagram illustrates the detailed flow of a DNS query through the Pi-hole system. |
| 193 | + |
| 194 | +```mermaid |
| 195 | +sequenceDiagram |
| 196 | + participant Client as Client Device |
| 197 | + participant Router as Network Router |
| 198 | + participant FTL as FTL DNS Service |
| 199 | + participant Cache as DNS Cache |
| 200 | + participant Gravity as Gravity DB |
| 201 | + participant Upstream as Upstream DNS |
| 202 | +
|
| 203 | + Client->>Router: DNS Query for domain |
| 204 | + Router->>FTL: Forward DNS Query |
| 205 | +
|
| 206 | + FTL->>Cache: Check if domain is cached |
| 207 | +
|
| 208 | + alt Domain is cached |
| 209 | + Cache-->>FTL: Return cached result |
| 210 | + else Domain not cached |
| 211 | + FTL->>Gravity: Check if domain is blocked |
| 212 | +
|
| 213 | + alt Domain is blocked |
| 214 | + Gravity-->>FTL: Domain is blocked |
| 215 | + FTL->>FTL: Generate blocking response |
| 216 | + else Domain is not blocked |
| 217 | + Gravity-->>FTL: Domain is not blocked |
| 218 | + FTL->>Upstream: Forward query to upstream DNS |
| 219 | + Upstream-->>FTL: Return DNS result |
| 220 | + FTL->>Cache: Store result in cache |
| 221 | + end |
| 222 | + end |
| 223 | +
|
| 224 | + FTL->>Router: Return DNS response |
| 225 | + Router->>Client: Forward DNS response |
| 226 | +``` |
| 227 | + |
| 228 | +This sequence diagram shows: |
| 229 | +1. A client device sends a DNS query to the router |
| 230 | +2. The router forwards the query to Pi-hole's FTL service |
| 231 | +3. FTL checks if the domain is in its cache |
| 232 | +4. If not cached, FTL checks if the domain is blocked |
| 233 | +5. If blocked, FTL generates a blocking response |
| 234 | +6. If not blocked, FTL forwards the query to upstream DNS |
| 235 | +7. The response is cached and returned to the client |
| 236 | + |
| 237 | +### Blocklist Update Process |
| 238 | + |
| 239 | +This diagram shows how Pi-hole updates its blocklists. |
| 240 | + |
| 241 | +```mermaid |
| 242 | +flowchart TD |
| 243 | + classDef primary fill:#4CAF50,stroke:#388E3C,color:white |
| 244 | + classDef secondary fill:#2196F3,stroke:#1976D2,color:white |
| 245 | + classDef tertiary fill:#FF9800,stroke:#F57C00,color:white |
| 246 | + classDef database fill:#795548,stroke:#5D4037,color:white |
| 247 | +
|
| 248 | + Start([Start Update]) --> CheckConnection{Check Internet\nConnection} |
| 249 | + CheckConnection -- Available --> FetchLists[Fetch Blocklists\nfrom Sources] |
| 250 | + CheckConnection -- Unavailable --> Error[Log Error] |
| 251 | + Error --> End([End]) |
| 252 | +
|
| 253 | + FetchLists --> ProcessLists[Process and\nParse Lists] |
| 254 | + ProcessLists --> RemoveDuplicates[Remove Duplicate\nEntries] |
| 255 | + RemoveDuplicates --> ApplyWhitelist[Apply Whitelist\nExceptions] |
| 256 | + ApplyWhitelist --> ApplyRegex[Apply Regex\nFilters] |
| 257 | +
|
| 258 | + ApplyRegex --> CreateTemp[Create Temporary\nDatabase] |
| 259 | + CreateTemp --> PopulateTemp[Populate with\nProcessed Domains] |
| 260 | + PopulateTemp --> ValidateTemp{Validate\nDatabase} |
| 261 | +
|
| 262 | + ValidateTemp -- Valid --> BackupOld[Backup Old\nDatabase] |
| 263 | + ValidateTemp -- Invalid --> RestoreBackup[Restore from\nBackup] |
| 264 | + RestoreBackup --> End |
| 265 | +
|
| 266 | + BackupOld --> SwapDB[Swap in New\nDatabase] |
| 267 | + SwapDB --> UpdateTimestamp[Update Last\nUpdated Timestamp] |
| 268 | + UpdateTimestamp --> RestartDNS{Restart DNS\nRequired?} |
| 269 | +
|
| 270 | + RestartDNS -- Yes --> RestartFTL[Restart FTL\nService] |
| 271 | + RestartDNS -- No --> FlushCache[Flush DNS\nCache] |
| 272 | + RestartFTL --> End |
| 273 | + FlushCache --> End |
| 274 | +
|
| 275 | + style Start fill:#4CAF50,stroke:#388E3C,color:white |
| 276 | + style End fill:#F44336,stroke:#D32F2F,color:white |
| 277 | +``` |
| 278 | + |
| 279 | +This flowchart shows: |
| 280 | +1. The process starts with checking internet connectivity |
| 281 | +2. Blocklists are fetched from various sources |
| 282 | +3. Lists are processed, deduplicated, and filtered |
| 283 | +4. A temporary database is created and populated |
| 284 | +5. After validation, the old database is backed up |
| 285 | +6. The new database is swapped in |
| 286 | +7. The DNS cache is flushed or the FTL service is restarted |
0 commit comments