Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
8031dc8
add whitelist, docker-compose
mfittko Oct 14, 2021
6d85d80
add preview
mfittko Oct 14, 2021
ea89c49
trigger workflow
mfittko Oct 14, 2021
b40d48f
trigger workflow
mfittko Oct 14, 2021
eaeb17a
master
mfittko Oct 14, 2021
128576f
on master yeah
mfittko Oct 14, 2021
2e92ff0
use previews.sofatutor.de
mfittko Oct 14, 2021
a3a6b96
use remote IP
mfittko Oct 14, 2021
fb6b476
update IP
mfittko Oct 14, 2021
a1ef09a
apply whitelist
mfittko Oct 14, 2021
3a2477c
Revert "apply whitelist"
mfittko Oct 15, 2021
d2cc54d
Update README.md
mfittko Mar 15, 2022
55adc3f
Update backend.conf.example
mfittko Mar 15, 2022
06af284
Update backend.conf.example
mfittko May 25, 2022
253eeb1
Merge branch 'master' into master
mfittko Feb 14, 2023
5d88fa3
add dev container and related config
mfittko Feb 14, 2023
db3d126
add required changes values from upstream
mfittko Feb 14, 2023
5668e97
Merge remote-tracking branch 'origin/master'
mfittko Feb 14, 2023
b44476d
update preview action
mfittko Feb 14, 2023
4647bad
use preview action again
mfittko Feb 14, 2023
a909bba
Revert "use preview action again"
mfittko Feb 14, 2023
acba55f
change dns
mfittko Feb 14, 2023
275c4e7
parameterize DOMAIN and IP
mfittko Feb 17, 2023
b418550
use sofatutor version again
mfittko Feb 17, 2023
1c67b5e
add gitignore
mfittko Feb 17, 2023
c93e0b2
pass in IP and DOMAIN
mfittko Feb 17, 2023
ca34edf
pass in DOMAIN directly
mfittko Feb 17, 2023
3bf75ed
use owner name
mfittko Feb 17, 2023
8f4ed15
pin ubuntu version
mfittko Feb 17, 2023
e924c2c
update from branch
mfittko Feb 17, 2023
29609b9
fix www cname
mfittko Feb 17, 2023
a170c6f
always restart
mfittko Feb 17, 2023
88bdfc5
add cleanup action
mfittko Feb 17, 2023
28442d0
use env var for DNS domain
mfittko Feb 17, 2023
614571f
add config for previews
mfittko Feb 17, 2023
3632c4b
use PULLPREVIEW_ENV_VARS
mfittko Feb 17, 2023
3b9ca3a
fix yml
mfittko Feb 17, 2023
5ddd26d
default to env
mfittko Feb 17, 2023
b4bc974
fix
mfittko Feb 17, 2023
f26eda9
revert
mfittko Feb 17, 2023
1366b09
try protection rule
mfittko Feb 17, 2023
9f8587d
use env var again
mfittko Feb 17, 2023
5d90fbf
parameterize sofatutor dns
mfittko Feb 17, 2023
e8c43cf
Merge remote-tracking branch 'origin/master' into sofatutor
mfittko Feb 17, 2023
c5e23bb
try default
mfittko Feb 17, 2023
d2dc6cd
use top level env
mfittko Feb 17, 2023
a95141c
set explicitly
mfittko Feb 17, 2023
9679f6c
enable debugging
mfittko Feb 17, 2023
2d942fc
parameterize nameserver subdomain
mfittko Feb 17, 2023
732e8e7
pass in ID instead
mfittko Feb 17, 2023
ad0def2
re-order args
mfittko Feb 17, 2023
fb9dac0
add dnstools
mfittko Feb 17, 2023
3e344d8
Merge remote-tracking branch 'origin/master'
mfittko Feb 17, 2023
f819deb
implement whitelist check
mfittko Feb 17, 2023
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
35 changes: 35 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Use Ubuntu 22.04 as the base image
FROM ubuntu:22.04

# Set environment variables
ENV DEBIAN_FRONTEND=noninteractive

# Update the package index and install common dependencies
RUN apt-get update && apt-get install -y \
build-essential \
curl \
git \
vim \
python3 \
python3-dev \
python3-pip \
zsh \
awscli \
software-properties-common \
dnsutils

# Install starship prompt
RUN sh -c "$(curl -fsSL https://starship.rs/install.sh)" -- --force \
&& echo 'eval "$(starship init zsh)"' >> /root/.zshrc \
&& mkdir -p /root/.config

COPY starship.toml /root/.config/

# Install docker
RUN curl -fsSL https://get.docker.com | sh

# Add environment variable for the prompt
ENV SHELL /usr/bin/zsh

# Set the default command to start a ZSH shell
CMD ["zsh"]
21 changes: 21 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "PowerDNS Python Backend Dev Container",
"dockerFile": "Dockerfile",
"extensions": [
"ms-python.python",
"amazonwebservices.aws-toolkit-vscode",
"ms-python.pylance-release",
"ms-python.vscode-pylance",
"gmemstr.cloudformation",
"ms-python.python-testing",
"ms-python.linting-flake8",
"ms-vsliveshare.vsliveshare",
],
"mounts": [
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"
],
"postCreateCommand": "apt-get update && apt-get install -y git && ( curl -fsSL https://get.docker.com | sh )",
"remoteEnv": {
"GIT_SSL_NO_VERIFY": "1"
}
}
4 changes: 4 additions & 0 deletions .devcontainer/starship.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
format = "🐳 $all"

[container]
disabled = true
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.git
.github
4 changes: 2 additions & 2 deletions .github/workflows/image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ on:

env:
REGISTRY: ghcr.io
IMAGE_NAME: resmo/nip-io
IMAGE_NAME: ${{ github.event.repository.owner.name }}/nip-io

jobs:
build-and-push-image:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
permissions:
contents: read
packages: write
Expand Down
43 changes: 43 additions & 0 deletions .github/workflows/preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: preview
on:
push:
branches:
- master
- sofatutor
pull_request:
types: [labeled, unlabeled, synchronize, closed, reopened]

env:
DNS: 'p.sofatutor-sandbox.de'
ID: '1'

jobs:
deploy:
runs-on: ubuntu-22.04
if: github.event_name == 'push' || github.event.label.name == 'preview' || contains(github.event.pull_request.labels.*.name, 'preview')
timeout-minutes: 10

steps:
- name: Optionally override DNS
run: |
SOFATUTOR_DNS="${{ vars.SOFATUTOR_DNS }}"
if [[ $GITHUB_REF == 'refs/heads/sofatutor' && -n "$SOFATUTOR_DNS" ]]; then
echo "DNS=$SOFATUTOR_DNS" >> "$GITHUB_ENV"
fi
- uses: actions/checkout@v2
- uses: sofatutor/pullpreview@sofatutor
with:
admins: mfittko
always_on: master,sofatutor
app_path: .
instance_type: nano_2_0
dns: ${{env.DNS}}
ports: 53/tcp,53/udp
registries: docker://index.docker.io/v1
compose_files: docker-compose.yml
env:
AWS_REGION: eu-central-1
PULLPREVIEW_ENV_VARS: IP="$(ec2-metadata | grep public-ipv4 | cut -d ' ' -f2)",DOMAIN=${{ env.DNS }},ID=${{ env.ID }}
PULLPREVIEW_LAUNCH_COMMAND: docker-compose up -d --build --force-recreate
AWS_ACCESS_KEY_ID: "${{ secrets.AWS_ACCESS_KEY_ID }}"
AWS_SECRET_ACCESS_KEY: "${{ secrets.AWS_SECRET_ACCESS_KEY }}"
18 changes: 18 additions & 0 deletions .github/workflows/preview_cleanup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Preview Cleanup
on:
pull_request:
types: [unlabeled, closed]

jobs:
destroy:
if: github.event.label.name == 'preview' || contains(github.event.pull_request.labels.*.name, 'preview')
name: Destroy
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: sofatutor/pullpreview@sofatutor
continue-on-error: true
env:
AWS_ACCESS_KEY_ID: "${{ secrets.AWS_ACCESS_KEY_ID }}"
AWS_SECRET_ACCESS_KEY: "${{ secrets.AWS_SECRET_ACCESS_KEY }}"
AWS_REGION: "eu-central-1"
14 changes: 12 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
FROM bitnami/minideb:latest

RUN install_packages python pdns-server pdns-backend-pipe
ADD src/backend.conf.example /usr/local/bin/backend.conf
RUN install_packages python pdns-server pdns-backend-pipe curl jq gettext

ARG ID=${ID:-1}
ARG IP=${IP:-127.0.0.1}
ARG DOMAIN=${DOMAIN:-example.com}

ADD src/backend.conf.example /var/
ADD src/nip.py /usr/local/bin/nip
ADD docker/pdns.conf /etc/pdns/pdns.conf
ADD src/add_ec2_ip_ranges.sh /usr/local/bin/

EXPOSE 53/udp 53/tcp

COPY src/entrypoint.sh /usr/local/bin/entrypoint
RUN chmod +x /usr/local/bin/entrypoint
ENTRYPOINT ["entrypoint"]
CMD ["pdns_server", "--master", "--daemon=no", "--local-address=0.0.0.0", "--config-dir=/etc/pdns/"]
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Fork of nip.io

This is a fork of http://nip.io with some neat changes.
This is a fork of http://nip.io with some neat changes...

## About

Expand Down
15 changes: 15 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: '3.6'

services:
nipio:
container_name: nipio
build:
context: .
restart: always
environment:
ID: "${ID:-1}"
IP: "${IP:-127.0.0.1}"
DOMAIN: "${DOMAIN:-example.com}"
ports:
- "53:53/udp"
- "53:53/tcp"
10 changes: 10 additions & 0 deletions src/add_ec2_ip_ranges.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash

ip_ranges=($(curl -sk https://ip-ranges.amazonaws.com/ip-ranges.json | jq -c '.prefixes[] | select(.region=="eu-central-1" and .ip_prefix and .service == "EC2") | .ip_prefix'))
whitelist=$(for i in "${!ip_ranges[@]}"; do echo "ec2_eu_central_1_$i = ${ip_ranges[$i]}"; done | sed 's/"//g')
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use $AWS_REGION env variable. make sure it's available here.


if [ -f /usr/local/bin/backend.conf ]; then
echo "$whitelist" >> /usr/local/bin/backend.conf
else
echo "$whitelist"
fi
24 changes: 14 additions & 10 deletions src/backend.conf.example
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
[main]
# main domain
domain=example.com
domain=$DOMAIN

# default ttl
ttl=432000

# default IP address for non-wildcard entries
ipaddress=127.0.0.1

ipaddress=$IP

# SOA
[soa]
# serial number
id=1
id=$ID
# Hostmaster email address
hostmaster=hostmaster@example.com
hostmaster=hostmaster@$DOMAIN
# Name server
ns=ns1.example.com
ns=ns$ID.$DOMAIN
refresh=10800
retry=3600
expire=604800
minimum=3600

# nameservers
[nameservers]
ns1.example.com=127.0.0.1
ns2.example.com=127.0.0.1
ns$ID.$DOMAIN=$IP

[additional_cnames]
_acme-challenge=xyz.auth.example.com.
www=business.example.com
_acme-challenge=xyz.auth.$DOMAIN.
www=www.$DOMAIN.

[whitelist]
loopback = 127.0.0.0/8
private_net_10 = 10.0.0.0/8
private_net_172_16 = 172.16.0.0/12
private_net_192_168 = 192.168.0.0/16
4 changes: 4 additions & 0 deletions src/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
envsubst < /var/backend.conf.example > /usr/local/bin/backend.conf # replace config placeholders with env vars
add_ec2_ip_ranges.sh # add ec2 ip addresses to whitelist section
"$1" "${@:2}"
30 changes: 29 additions & 1 deletion src/nip.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
import re
import os
import ConfigParser
import struct

DEBUG = 0
DEBUG = 1


def log(msg):
Expand Down Expand Up @@ -84,6 +85,7 @@ def configure(self):
self.domain = config.get('main', 'domain')
self.ip_address = config.get('main', 'ipaddress')
self.ttl = config.get('main', 'ttl')
self.whitelist = config.items('whitelist')

for entry in config.items('nameservers'):
if not entry[0].endswith(self.domain):
Expand Down Expand Up @@ -174,6 +176,12 @@ def handle_subdomains(self, qname):
self.handle_self(qname)
return

if not self.check_ip_in_whitelist(ipaddress):
if DEBUG:
log('ip not allowed: %s' % ipaddress)
self.handle_self(qname)
return

write('DATA', qname, 'IN', 'A', self.ttl, self.id, '%s.%s.%s.%s' % (ipaddress[0], ipaddress[1], ipaddress[2], ipaddress[3]))
self.write_name_servers(qname)
write('END')
Expand Down Expand Up @@ -204,6 +212,26 @@ def handle_unknown(self, qtype, qname):
write('LOG', 'Unknown type: %s, domain: %s' % (qtype, qname))
write('END')

def check_ip_address(self, ip_address):
ip = ipaddress.IPv4Address('.'.join(str(x) for x in ip_address))
for network_mask in self.whitelist:
if ip in ipaddress.ip_network(network_mask):
return True
return False

def ip_in_network(self, ip, network):
ip_int = [int(x) for x in ip]
ip_bin = struct.unpack('!I', struct.pack('!4B', *ip_int))[0]
network_address, subnet_mask = network.split('/')
network_address_bin = struct.unpack('!I', struct.pack('!4B', *map(int, network_address.split('.'))))[0]
subnet_mask_bin = (0xffffffff << (32 - int(subnet_mask))) & 0xffffffff
return (ip_bin & subnet_mask_bin) == (network_address_bin & subnet_mask_bin)

def check_ip_in_whitelist(self, ip):
for net in self.whitelist:
if self.ip_in_network(ip, net[1]):
return True
return False

if __name__ == '__main__':
backend = DynamicBackend()
Expand Down