Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 30 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ You will need:
git clone https://github.com/enclave-networks/internet-gateway.git
```

1. Customise your DNS block page (`./template/blockpage/index.html`) as required

![Block Page Example](blockpage-example.png)

1. Install Enclave, Docker, and other dependencies

```bash
Expand Down Expand Up @@ -169,36 +173,49 @@ Done

If changes are accidentally made to any of these policies in the future, running the `configure-tenant.ps1` script again will attempt to automatically detect the drift and refresh the correct configuration into the tenant.

## Testing and installing root certificate
## Testing

Once your Internet Gateways are configured, you'll need to test them to ensure everything is working properly. This setup will have created three new Tags in your tenant:

- `[internet-gateway]` - Applied to the Internet Gateways themselves (automatically configured)
- `[internet-gateway-user]` - Apply this to end-user systems that should route traffic, DNS queries, or both through the Gateways
- `[internet-gateway-admin]` - Apply this to administrator systems for management access to the PiHole Admin interface

There are three new Tags in the tenant:
Enrol a system to the tenant and attach the `[internet-gateway-admin]` tag to that system for testing. With your admin-tagged system, you should now be able to access the PiHole administration interface:

- `[internet-gateway]` - Applied to the Internet Gateways themselves.
- `[internet-gateway-user]` - Should be applied to end-users.
- `[internet-gateway-admin]` - A special tag for Internet Gateway administrators only.
- **Load-balanced URL**: [http://dnsfilter.enclave](http://dnsfilter.enclave)

Enrol yourself to the tenant and attach the `[internet-gateway-admin]` tag to your system. You'll now be able to access [http://dnsfilter.enclave](http://dnsfilter.enclave) - the PiHole administration interface.
- **Direct access URLs** (for troubleshooting):
- Primary gateway: http://100.64.0.2:1080/
- Secondary gateway: http://100.64.0.3:1080/

## Installing Root Certificates

We recommend downloading and installing the Gateway's Root Certificate so your browser can trust the block page ([https://blocked.enclave/](https://blocked.enclave/)).
We recommend downloading and installing the Gateway's Root Certificate so your browser can trust the block page (served from [https://blocked.enclave/](https://blocked.enclave/)).

Download the Internet Gateway CA's public certificate in the appropriate format for yourself and end-users:

- http://dnsfilter.enclave/gateway.crt
- http://dnsfilter.enclave/gateway.p7b

On Windows, use the `certmgr` tool to install `gateway.crt` into the `Trusted Root Certification Authorities` store using the `LOCAL COMPUTER` scope and restart your browser. Navigate to [http://dnsfilter.enclave](http://dnsfilter.enclave) and check you don't receive any certificate warnings.
On Windows, use the `certmgr` tool to install `gateway.crt` into the `Trusted Root Certification Authorities` store using the `LOCAL COMPUTER` scope and restart your browser. Test by visiting [http://dnsfilter.enclave](http://dnsfilter.enclave) - you shouldn't receive any certificate warnings.

To test if your network traffic is successfully routing through the Internet Gateway, check your external IP address and then apply the `[internet-gateway-user]` tag to your system. Your Internet traffic should now be routing through the Internet Gateways and your external IP address should have changed to present as that of the primary Internet Gateway.

# Advanced

## Operational notes

- Failover between gateways is automatic. If one fails or goes offline, connected systems will automatically switch.
- You may need to disable `Use secure DNS` in Chrome (`chrome://settings/security`) to stop it sending DNS queries directly to Google nameservers.
- Notice the `300M` docker [memory limit](https://github.com/enclave-networks/internet-gateway/blob/main/template/docker-compose.primary.yml#L13) applied to the Enclave container and increase as required.
- Only make PiHole configuration changes on the _primary_ gateway as the PiHole configuration in [synced](https://github.com/enclave-networks/internet-gateway/blob/main/template/docker-compose.primary.yml#L124) _from_ the primary to the secondary every 30 minutes.
- Failover between gateways is automatic.
- If one gateway fails or goes offline, connected systems will immediately and automatically switch to the partner.
- When the primary gateway recovers, connected systems will automatically fail back to it.
- You may need to disable `Use secure DNS` in Chrome (`chrome://settings/security`) to stop Chrome sending DNS queries directly to Google nameservers and bypassing DNS.
- Only make PiHole configuration changes on the _primary_ gateway as the PiHole configuration in [synced](https://github.com/enclave-networks/internet-gateway/blob/main/template/docker-compose.primary.yml#L124) _from_ the primary to the secondary every minute.
- Any changes made to the secondary gateway will be destroyed during the next sync from the primary.
- Notice the `300M` docker [memory limit](https://github.com/enclave-networks/internet-gateway/blob/main/template/docker-compose.primary.yml#L13) applied to the Enclave container. Monitor and increase if necessary.
- To bring the stack down: `sudo docker compose down`
- To bring the stack up with latest images: `sudo docker compose up -d --pull always`
- To rename the stack, edit `COMPOSE_PROJECT_NAME=` variable in `.env`

## Inspection

Expand All @@ -212,7 +229,7 @@ sudo iptables -t nat -L POSTROUTING -v -n

### Uninstall

!!! Warning: Read these commands **BEFORE** you run them. If you don't understand exactly what they will do, contact us on our support channels for assistance.
!!! Warning: Read these commands **BEFORE** you run them. If you don't understand exactly what they will do, contact our support channels for assistance.

```bash
sudo docker stop $(sudo docker ps -q) && sudo docker rm $(sudo docker ps -aq)
Expand Down
Binary file added blockpage-example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 9 additions & 9 deletions configure-tenant.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,12 @@ $policiesModel = @(
@{
protocol = "Tcp"
ports = "444"
description = "PiHole"
description = "Load-balanced access to PiHole admin dashboard"
},
@{
protocol = "Tcp"
ports = "1080"
description = "Direct access to PiHole dashboard"
},
@{
protocol = "Icmp"
Expand Down Expand Up @@ -300,15 +305,10 @@ $policiesModel = @(
"internet-gateway"
)
acls = @(
@{
protocol = "Udp"
ports = "53"
description = "DNS"
},
@{
protocol = "Tcp"
ports = "9999"
description = "PiHole Gravity Database Sync"
ports = "1080"
description = "PiHole API Configuration Sync"
},
@{
protocol = "Icmp"
Expand Down Expand Up @@ -347,7 +347,7 @@ if ($HasEnrolledGateways -eq $true)
gateways = @()
gatewayTrafficDirection = "Exit"
gatewayAllowedIpRanges = @()
gatewayPriority = "Balanced"
gatewayPriority = "Ordered"
}

if ($HasPrimaryGateway -eq $true)
Expand Down
143 changes: 124 additions & 19 deletions template/blockpage/index.html
Original file line number Diff line number Diff line change
@@ -1,22 +1,127 @@
<!DOCTYPE html>
<html>
<head>
<title>Site Blocked</title>

<style>
.content {
margin-left: auto;
margin-right: auto;
text-align: center;
font-family: Arial, Helvetica, sans-serif;
margin-top: 400px;
height: 300px;
}
</style>
</head>
<body>
<div class="content">
<h1>This site has been blocked by your administrator.</h1>
<p>Contact your administrator to request an exception.</p>
<head>
<title>Access Blocked</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap');

body {
margin: 0;
padding: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
min-height: 640px;
}

a {
color: #30A9F6;
text-decoration: none;
}

a:hover {
color: #227eb8;
text-decoration-color: #64748b;
}

.content {
text-align: center;
max-width: 520px;
padding: 3rem 2.5rem;
background: white;
border-radius: 16px;
box-shadow: 0 8px 40px rgba(0,0,0,0.06), 0 1px 3px rgba(0,0,0,0.08);
}

h1 {
color: #1e293b;
font-size: 1.75rem;
font-weight: 600;
margin-top: 0rem;
margin-bottom: 0.75rem;
letter-spacing: -0.025em;
}

h2 {
color: #475569;
font-size: 1.125rem;
font-weight: 500;
margin-top: 0rem;
margin-bottom: 1.25rem;
letter-spacing: -0.015em;
}

p {
color: #64748b;
font-size: 1rem;
line-height: 1.6;
margin-bottom: 1rem;
}

.msp-info {
margin-top: 2.5rem;
padding-top: 2.5rem;
border-top: 1px solid #e2e8f0;
text-align: left;
}

.msp-info ul {
text-align: left;
color: #64748b;
line-height: 1.7;
padding-left: 1.25rem;
}

.msp-info li {
margin-bottom: 0.5rem;
}

.ticket-info {
background: #f8fafc;
padding: 1.25rem;
border-radius: 8px;
margin-top: 2.5rem;
margin-bottom: 0rem;
border: 1px solid #e2e8f0;
text-align: center;
}

.ticket-info strong {
color: #334155;
}

.ticket-info img {
max-width: 320px;
max-height: 40px;
padding: 0.5rem 0 1.5rem 0;
display: block;
margin: auto;
}

</style>
</head>
<body>
<div class="content">
<h1>This site isn't accessible right now.</h1>
<p>Content filtering is actively protecting our network, and this website has been identified as inappropriate, potentially unsafe, or malicious.</p>

<div class="msp-info">
<h2>Need to request access?</h2>
<ul>
<li>Raise a support ticket with the blocked website URL</li>
<li>Include your business justification for needing access</li>
<li>Tickets are typically reviewed within 24 hours</li>
</ul>
<p class="ticket-info">
<img src="https://placehold.co/320x70/transparent/333" alt="placeholder">
<!-- <img src="data:image/png;base64,YOUR_BASE64_STRING_HERE" alt="placeholder"> -->

<strong>To request access to this site, please raise a ticket at <br /><a href="https://example.com" target="_blank">https://example.com</a></strong>
</p>
</div>
</body>
</div>
</body>
</html>
68 changes: 30 additions & 38 deletions template/caddy/Caddyfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
}
}

# Redirect all plain HTTP to blocked page
http:// {
bind {$PIHOLE_PROXY_BIND_ADDR}
redir http://blocked.enclave
}

# Serve cert files over HTTP
http://dnsfilter.enclave {
bind {$PIHOLE_PROXY_BIND_ADDR}
route {
Expand All @@ -28,11 +30,38 @@ http://dnsfilter.enclave {
header * Content-Disposition "attachment"
file_server
}
redir * https://{host}/admin/
}
}

# Catch-all HTTPS handler for certs, blocked page, and redirects
https:// {
bind {$PIHOLE_PROXY_BIND_ADDR}
tls internal {
on_demand
}

redir * https://{host}
@dnsfilter host dnsfilter.enclave
handle @dnsfilter {
redir * https://{host}:444/admin
}

@blocked host blocked.enclave
handle @blocked {
header {
X-Frame-Options "DENY"
}
root * /blockpage
file_server
}

# Default fallback for all other HTTPS access
handle {
redir https://blocked.enclave
}
}

# Load-balanced access to pihole admin dashboard. Always targets the primary first as config is replicated.
https://dnsfilter.enclave:444 {
bind {$PIHOLE_PROXY_BIND_ADDR}
tls internal
Expand All @@ -47,40 +76,3 @@ https://dnsfilter.enclave:444 {
fail_duration 30s
}
}

# This is the 'end' of the chain; and points at the actual running pihole instance on the local host.
http://:9999 {
bind {$PIHOLE_PROXY_BIND_ADDR}

reverse_proxy http://localhost:1080
rewrite * /admin/{path}
}

https:// {

bind {$PIHOLE_PROXY_BIND_ADDR}

tls internal {
on_demand
}

@dnsfilter host dnsfilter.enclave

handle @dnsfilter {
redir * https://{host}:444
}

@blocked host blocked.enclave

handle @blocked {
header {
X-Frame-Options "DENY"
}
root * /blockpage
file_server
}

handle {
redir https://blocked.enclave
}
}
Loading