Add files

This commit is contained in:
Hoang Nguyen 2021-11-27 09:30:00 +07:00
parent 4ec4789ea0
commit c9d83f63b5
No known key found for this signature in database
GPG Key ID: 813CF484F4993419
48 changed files with 2383 additions and 2 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "satellite/satellite"]
path = satellite/satellite
url = https://git.sr.ht/~gsthnz/satellite

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) <year> <copyright holders>
Copyright (c) 2021 FollieHiyuki
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@ -1,3 +1,7 @@
# docker-templates
Docker templates for personal usage
Docker templates for personal usage.
## License
MIT

3
gitea/.config/db.env Normal file
View File

@ -0,0 +1,3 @@
POSTGRES_USER=gitea
POSTGRES_PASSWORD=changeme
POSTGRES_DB=gitea

13
gitea/.config/gitea.env Normal file
View File

@ -0,0 +1,13 @@
USER_UID=1001
USER_GID=1001
GITEA__database__DB_TYPE=postgres
GITEA__database__HOST=db:5432
GITEA__database__NAME=gitea
GITEA__database__USER=gitea
GITEA__database__PASSWD=changeme
GITEA__service__DISABLE_REGISTRATION=true
GITEA__service__explore__DISABLE_USERS_PAGE=true
GITEA__server__LANDING_PAGE=explore
GITEA__ui__THEMES=gitea,arc-green,nord-nav
GITEA__ui__DEFAULT_THEME=nord-nav
GITEA__ui__SHOW_USER_EMAIL=false

15
gitea/README.md Normal file
View File

@ -0,0 +1,15 @@
# gitea + 🐳
This is a template for deploying a Gitea instance with some custom settings.
## Notes
- The template is meant for personal usage, in case I forget the settings.
- Should be set up with user `git` on the host system
- Some useful official guides I do want to take note:
- [SSH passthrough](https://docs.gitea.io/en-us/install-with-docker/#ssh-container-passthrough)
- [Additions to Gitea pages](https://docs.gitea.io/en-us/customizing-gitea/#other-additions-to-the-page)
- [Serve static resources directly](https://docs.gitea.io/en-us/reverse-proxies/#two-nodes-and-two-domains)
- [Signed commits](https://docs.gitea.io/en-us/signing/)
- [Additional renderers](https://docs.gitea.io/en-us/external-renderers/)
- [No robots](https://docs.gitea.io/en-us/search-engines-indexation/)

View File

@ -0,0 +1,87 @@
@import "/assets/css/theme-arc-green.css";
@font-face {
font-family: 'Iosevka Aile';
font-display: swap;
font-weight: 400;
font-stretch: normal;
font-style: normal;
src: url('https://folliehiyuki.com/woff2/iosevka-aile-regular.woff2') format('woff2'), url('https://folliehiyuki.com/ttf/iosevka-aile-regular.ttf') format('truetype');
}
@font-face {
font-family: 'Iosevka Aile';
font-display: swap;
font-weight: 400;
font-stretch: normal;
font-style: italic;
src: url('https://folliehiyuki.com/woff2/iosevka-aile-italic.woff2') format('woff2'), url('https://folliehiyuki.com/ttf/iosevka-aile-italic.ttf') format('truetype');
}
@font-face {
font-family: 'Iosevka Aile';
font-display: swap;
font-weight: 700;
font-stretch: normal;
font-style: normal;
src: url('https://folliehiyuki.com/woff2/iosevka-aile-bold.woff2') format('woff2'), url('https://folliehiyuki.com/ttf/iosevka-aile-bold.ttf') format('truetype');
}
@font-face {
font-family: 'Iosevka Aile';
font-display: swap;
font-weight: 700;
font-stretch: normal;
font-style: italic;
src: url('https://folliehiyuki.com/woff2/iosevka-aile-bolditalic.woff2') format('woff2'), url('https://folliehiyuki.com/ttf/iosevka-aile-bolditalic.ttf') format('truetype');
}
@font-face {
font-family: 'Iosevka';
font-display: swap;
font-weight: 400;
font-stretch: normal;
font-style: normal;
src: url('https://folliehiyuki.com/woff2/iosevka-regular.woff2') format('woff2'), url('https://folliehiyuki.com/ttf/iosevka-regular.ttf') format('truetype');
}
@font-face {
font-family: 'Iosevka';
font-display: swap;
font-weight: 400;
font-stretch: normal;
font-style: italic;
src: url('https://folliehiyuki.com/woff2/iosevka-italic.woff2') format('woff2'), url('https://folliehiyuki.com/ttf/iosevka-italic.ttf') format('truetype');
}
@font-face {
font-family: 'Iosevka';
font-display: swap;
font-weight: 700;
font-stretch: normal;
font-style: normal;
src: url('https://folliehiyuki.com/woff2/iosevka-bold.woff2') format('woff2'), url('https://folliehiyuki.com/ttf/iosevka-bold.ttf') format('truetype');
}
@font-face {
font-family: 'Iosevka';
font-display: swap;
font-weight: 700;
font-stretch: normal;
font-style: italic;
src: url('https://folliehiyuki.com/woff2/iosevka-bolditalic.woff2') format('woff2'), url('https://folliehiyuki.com/ttf/iosevka-bolditalic.ttf') format('truetype');
}
:root {
--fonts-proportional: 'Iosevka Aile' !important;
--fonts-monospace: 'Iosevka' !important;
}
.ui.bar {
background-image: linear-gradient(-90deg, #5e81ac, #b48ead) !important;
}
#navbar > .item,
#navbar > .right.menu > .item {
color: white;
}

34
gitea/docker-compose.yml Normal file
View File

@ -0,0 +1,34 @@
version: "3"
networks:
gitea:
external: false
services:
server:
image: gitea/gitea:latest
container_name: gitea
env_file:
- .config/gitea.env
restart: unless-stopped
networks:
- gitea
volumes:
- ./data:/data
- /etc/localtime:/etc/localtime:ro
- /home/git/.ssh:/data/git/.ssh
ports:
- "3000:3000"
- "127.0.0.1:2222:22"
depends_on:
- db
db:
image: postgres:13-alpine
restart: unless-stopped
env_file:
- .config/db.env
networks:
- gitea
volumes:
- ./postgres:/var/lib/postgresql/data

7
nginx_certbot/Dockerfile Normal file
View File

@ -0,0 +1,7 @@
FROM alpine:latest
RUN apk add --no-cache nginx nginx-mod-stream certbot-nginx
EXPOSE 80 443 6443 70
COPY ./entrypoint.sh /entrypoint.sh
RUN chmod a+x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

16
nginx_certbot/README.md Normal file
View File

@ -0,0 +1,16 @@
# Nginx + Certbot + 🐳
## Introduction
This is a Docker template for nginx + certbot deployment, with stream support. I also include configurations for forwarding on ports 70 and 6443, and also for my personal website, as examples.
`http.d` directory contains configurations for normal http/https traffics. The other one, `stream.d` is for stream configurations.
## How to use
- Clone this repository
- Change the content to your need, also mount necessary additional volumes
- Do `docker-compose up -d`
- Generate LetsEncrypt certificate by `docker-compose exec nginx sh -c 'certbot --nginx certonly -d yourdomain.tld'`
- Restart the container
- Profit

View File

@ -0,0 +1,24 @@
version: "3"
volumes:
letsencrypt:
driver: local
services:
nginx:
build: .
restart: unless-stopped
container_name: nginx
ports:
- "80:80"
- "443:443"
- "70:70"
- "6443:6443"
volumes:
- /srv/www:/srv/www:ro # I have static site, so read-only is ok
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./http.d:/etc/nginx/http.d
- ./stream.d:/etc/nginx/stream.d
- /var/log/nginx:/var/log/nginx
- /tmp/proxy-media-cache:/tmp/proxy-media-cache
- letsencrypt:/etc/letsencrypt

View File

@ -0,0 +1,9 @@
#!/bin/ash
set -e
echo "-- Adding crontab ..."
echo "0 0,12 * * * root python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew -q" | crontab -
echo "-- Starting nginx ..."
nginx -c /etc/nginx/nginx.conf

View File

@ -0,0 +1,54 @@
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.folliehiyuki.com;
charset utf-8;
location / {
root /srv/www;
index index.html;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/lib/nginx/html;
}
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
add_header Content-Security-Policy "default-src 'self'; script 'none'; img-src 'self'; style-src 'self'; font-src 'self'; frame-src 'none'; object-src 'none'";
ssl_certificate /etc/letsencrypt/live/www.folliehiyuki.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.folliehiyuki.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
listen 80;
listen [::]:80;
server_name www.folliehiyuki.com;
if ($host = www.folliehiyuki.com) {
return 301 https://$host$request_uri;
}
return 404;
}
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name folliehiyuki.com;
ssl_certificate /etc/letsencrypt/live/folliehiyuki.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/folliehiyuki.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
if ($host = folliehiyuki.com) {
return 301 https://www.$host$request_uri;
}
return 404;
}

View File

@ -0,0 +1,44 @@
proxy_cache_path /tmp/proxy-media-cache levels=1:2 keys_zone=cache1:16m max_size=1g inactive=720m use_temp_path=off;
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
client_max_body_size 20m;
location / {
proxy_pass http://192.168.1.105:3000;
proxy_set_header Host $host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# Caching
proxy_cache cache1;
proxy_cache_lock on;
proxy_cache_use_stale updating;
add_header X-Cache $upstream_cache_status;
}
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
listen 80;
listen [::]:80;
server_name example.com;
root /var/lib/nginx/html;
location /.well-known/acme-challenge/ { allow all; }
location /.well-known/pki-validation/ { allow all; }
location / { return 301 https://$server_name$request_uri; }
}

127
nginx_certbot/nginx.conf Normal file
View File

@ -0,0 +1,127 @@
# /etc/nginx/nginx.conf
user nginx;
daemon off; # Better with the use of docker
# Set number of worker processes automatically based on number of CPU cores
worker_processes auto;
worker_rlimit_nofile 100000;
worker_cpu_affinity auto;
# Enables the use of JIT for regular expressions to speed-up their processing.
pcre_jit on;
# Configures default error logger.
error_log /var/log/nginx/error.log warn;
# Includes files with directives to load dynamic modules.
include /etc/nginx/modules/*.conf;
# Include files with config snippets into the root context.
include /etc/nginx/conf.d/*.conf;
events {
# The maximum number of simultaneous connections that can be opened by
# a worker process.
multi_accept on;
worker_connections 1024;
use epoll;
}
http {
# Includes mapping of file name extensions to MIME types of responses
# and defines the default type.
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Name servers used to resolve names of upstream servers into addresses.
# It's also needed when using tcpsocket and udpsocket in Lua modules.
#resolver 1.1.1.1 1.0.0.1 2606:4700:4700::1111 2606:4700:4700::1001;
# Don't tell nginx version to the clients. Default is 'on'.
server_tokens off;
# Security headers. See https://github.com/ironpeakservices/iron-alpine/
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
# Limit requests
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=5r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
# Timeout
reset_timedout_connection on;
client_body_timeout 10;
client_header_timeout 3m;
send_timeout 2;
keepalive_timeout 30;
keepalive_requests 100000;
# Specifies the maximum accepted body size of a client request, as
# indicated by the request header Content-Length. If the stated content
# length is greater than this size, then the client receives the HTTP
# error code 413. Set to 0 to disable. Default is '1m'.
client_max_body_size 1m;
client_body_buffer_size 128k;
client_header_buffer_size 3m;
large_client_header_buffers 4 256k;
# Sendfile copies data between one FD and other from within the kernel,
# which is more efficient than read() + write(). Default is off.
sendfile on;
sendfile_max_chunk 512k;
# Causes nginx to attempt to send its HTTP response head in one packet,
# instead of using partial frames. Default is 'off'.
tcp_nopush on;
tcp_nodelay on;
# Enables the specified protocols. Default is TLSv1 TLSv1.1 TLSv1.2.
# TIP: If you're not obligated to support ancient clients, remove TLSv1.1.
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
# Specifies that our cipher suits should be preferred over client ciphers.
# Default is 'off'.
ssl_prefer_server_ciphers on;
# Enables a shared SSL cache with size that can hold around 8000 sessions.
# Default is 'none'.
ssl_session_cache shared:SSL:2m;
# Specifies a time during which a client may reuse the session parameters.
# Default is '5m'.
ssl_session_timeout 1h;
# Disable TLS session tickets (they are insecure). Default is 'on'.
ssl_session_tickets off;
# Enable gzipping of responses.
gzip on;
gzip_types text/plain;
# Set the Vary HTTP header as defined in the RFC 2616. Default is 'off'.
gzip_vary on;
# Helper variable for proxying websockets.
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Specifies the main/download log format.
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_x_forwarded_for" "$gzip_ratio"';
# Sets the path, format, and configuration for a buffered log write.
access_log /var/log/nginx/access.log main;
# Includes virtual hosts configs.
include /etc/nginx/http.d/*.conf;
}
# Stream module.
include /etc/nginx/stream.conf;

View File

@ -0,0 +1,4 @@
server {
listen 70;
proxy_pass 192.168.1.101:70;
}

View File

@ -0,0 +1,10 @@
upstream backend_servers {
server 192.168.1.102:6443;
server 192.168.1.103:6443;
server 192.168.1.104:6443;
}
server {
listen 6443;
proxy_pass backend_servers;
}

4
pi-hole/Dockerfile Normal file
View File

@ -0,0 +1,4 @@
FROM alpine:latest
RUN apk --no-cache add dhcp-helper
EXPOSE 67 67/udp
ENTRYPOINT ["dhcp-helper", "-n"]

77
pi-hole/README.md Normal file
View File

@ -0,0 +1,77 @@
# Pi-hole + 🐳
## Introduction
This repository holds docker template for [Pi-hole](https://docs.pi-hole.net/) with [Unbound](https://unbound.net) + [Stubby](https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Daemon+-+Stubby) on top, running in my home network as both DNS server and DHCP server (using bridge network). [Wireguard](https://www.wireguard.com) is included for convenience.
The DHCP part is yanked from [@DerFetzer](https://discourse.pi-hole.net/t/dhcp-with-docker-compose-and-bridge-networking/17038), with some improvements. The Unbound and Wireguard parts are based on [Wirehole](https://github.com/IAmStoxe/wirehole). You can also check out [this gist](https://gist.github.com/Jiab77/1cdc2896f22791c4db492e87bbf609ff) and the [official Unbound guide](https://docs.pi-hole.net/guides/dns/unbound).
## Deployment
You should change the variables in `docker-compose.yml` file. If you want to change the default IP addresses of the internal network, remember to also replace the forward address in `unbound.conf`, and add the new IP range to "access-control" and "private-address" accordingly.
- Clone this repository
- Review the content
- `docker-compose up -d`
- Route DNS traffic from your router to the Pi-hole server
- Turn on Pi-hole's DHCP server and turn off DHCP function in your router
- Add more gravity lists. [firebog.net](https://firebog.net) has some good ones
- Profit
## Notes
- To check whether recursive DNS is working, you can inspect with `ngrep` or `tcpdump`:
```bash
# Check Unbound
ngrep -d br-pihole port 53 and host 10.2.0.200
# Check Stubby
ngrep -d br-pihole port 8053 and host 10.2.0.150
# tcpdump -vv -x -X -s 1500 -i br-pihole 'port 8053'
# Check FTLDNS
ngrep -d lo port 53
```
- To check DNSSEC validation, use `drill`:
```bash
# You should see 'Error: Bogus DNSSEC signature' with exit code 5
drill -DT sigfail.verteiltesysteme.net
# This command should run successfully
drill -DT sigok.verteiltesysteme.net
```
- To display the peer's QR code again, do `docker exec -it wireguard /app/show-peer [peer_name]`.
- Stubby isn't packaged for Alpine, so I use Voidlinux-musl for now.
- You can omit the hostname variables for **pi-hole** and **unbound** in `docker-compose.yml`. The pi-hole's one is for the displayed hostname (top right corner) in the web UI. The other one just makes queries logs easier to read.
- You can also run Docker Pi-hole as your DHCP server using host network or Macvlan network. Check the [official documentation](https://docs.pi-hole.net/docker/dhcp/).
- `DNSMASQ_LISTENING: all` is needed, because Pi-hole will listen on both the host network (for DNS requests), and the subnet `br-pihole`. This brings some security risks, so make sure to only run this inside your home network, and do not forward port 53 from your router to the Pi-hole server.
- dhcphelper needs `network_mode: host` because it has to be seen by clients on your local network. Though it only needs port 67.
- If you don't like `dhcphelper`, here is the diff for using ISC DHCP relay instead:
**Dockerfile:**
```Dockerfile
FROM debian:stable-slim
RUN apt update
RUN apt install -y isc-dhcp-relay
EXPOSE 67 67/udp
ENTRYPOINT ["dhcrelay", "-d"]
```
**docker-compose.yml:**
```diff
dhcprelay:
build: .
restart: unless-stopped
network_mode: "host"
- command: ["-i", "eth0", "-b", "br-pihole", "-s", "10.2.0.100"]
+ command: ["-id", "eth0", "-iu", "br-pihole", "10.2.0.100"]
cap_add:
- NET_ADMIN
```
## License
MIT

112
pi-hole/docker-compose.yml Normal file
View File

@ -0,0 +1,112 @@
version: "3"
networks:
private_network:
driver: bridge
driver_opts:
com.docker.network.bridge.name: br-pihole
ipam:
config:
- subnet: 10.2.0.0/24
services:
dhcprelay:
build: .
restart: unless-stopped
container_name: dhcprelay
network_mode: "host"
command: ["-i", "eth0", "-b", "br-pihole", "-s", "10.2.0.100"]
cap_add:
- NET_ADMIN
stubby:
build: ./stubby
restart: unless-stopped
container_name: stubby
volumes:
- ./stubby/stubby.yml:/etc/stubby/stubby.yml:ro
networks:
private_network:
ipv4_address: 10.2.0.150
unbound:
build: ./unbound
restart: unless-stopped
container_name: unbound
hostname: unbound
volumes:
- ./unbound/unbound.conf:/etc/unbound/unbound.conf:ro
networks:
private_network:
ipv4_address: 10.2.0.200
depends_on:
- stubby
pihole:
image: pihole/pihole:latest
restart: unless-stopped
container_name: pihole
hostname: pi-hole
ports:
- 53:53/tcp
- 53:53/udp
- 80:80/tcp
dns:
- 127.0.0.1
- 10.2.0.200 # Point to Unbound
environment:
TZ: "America/Chicago"
WEBPASSWORD: "changeme"
PIHOLE_DNS_: "10.2.0.200;10.2.0.200"
ServerIP: "192.168.1.101"
VIRTUAL_HOST: "pi.hole"
DNSMASQ_LISTENING: "all"
volumes:
- ./etc-pihole/:/etc/pihole/
- ./etc-dnsmasq.d/:/etc/dnsmasq.d/
cap_add:
- NET_ADMIN
networks:
private_network:
ipv4_address: 10.2.0.100
depends_on:
- dhcprelay
- stubby
- unbound
wireguard:
image: linuxserver/wireguard:latest
restart: unless-stopped
container_name: wireguard
environment:
- PUID=1000
- PGID=1000
- TZ=America/Chicago
- SERVERURL=wireguard.example.com
- SERVERPORT=51820
- PEERS=2
- PEERDNS=10.2.0.100 # Point to Pi-hole
- INTERNAL_SUBNET=10.6.0.0
# - ALLOWEDIPS=0.0.0.0/0
volumes:
- ./wireguard/config:/config
- ./wireguard/etc-wireguard:/etc/wireguard
- /lib/modules:/lib/modules
ports:
- 51820:51820/udp
dns:
- 10.2.0.100 # Point to Pi-hole
- 10.2.0.200 # Point to Unbound
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
cap_add:
- NET_ADMIN
- SYS_MODULE
networks:
private_network:
ipv4_address: 10.2.0.3
depends_on:
- dhcprelay
- stubby
- unbound
- pihole

View File

@ -0,0 +1 @@
dhcp-option=option:dns-server,192.168.1.101

View File

@ -0,0 +1 @@
BLOCKINGMODE=NXDOMAIN

View File

@ -0,0 +1,6 @@
FROM voidlinux/voidlinux-musl:latest
RUN xbps-install -Sy stubby
EXPOSE 8053/udp
USER _stubby:_stubby
CMD ["/usr/bin/stubby", "-C", "/etc/stubby/stubby.yml"]

555
pi-hole/stubby/stubby.yml Normal file
View File

@ -0,0 +1,555 @@
################################################################################
######################## STUBBY YAML CONFIG FILE ###############################
################################################################################
# For more information see:
# https://dnsprivacy.org/wiki/display/DP/Configuring+Stubby
# https://raw.githubusercontent.com/getdnsapi/stubby/develop/stubby.yml.example
#
# This format does not fully support all yaml features - the restrictions are:
# - the outer-most data structure must be a yaml mapping
# - mapping keys must be yaml scalars
# - plain scalars will be converted to json unchanged
# - non-plain scalars (quoted, double-quoted, wrapped) will be interpreted
# as json strings, i.e. double quoted.
# - yaml tags are not supported
# - IPv6 addresses ending in :: are not yet supported (use ::0)
#
# Also beware that yaml is sensitive to the indentation at the start of each
# line so if you encounter errors when parsing the config file then please check
# that. We will add better checking but a useful online tool to check yaml
# format is here (it also converts yaml to json)
# https://yaml-online-parser.appspot.com/
#
# Note that we plan to introduce a more compact format for defining upstreams
# in future: https://github.com/getdnsapi/stubby/issues/79
########################## BASIC & PRIVACY SETTINGS ############################
# Specifies whether to run as a recursive or stub resolver
# For stubby this MUST be set to GETDNS_RESOLUTION_STUB
resolution_type: GETDNS_RESOLUTION_STUB
# Ordered list composed of one or more transport protocols:
# GETDNS_TRANSPORT_UDP, GETDNS_TRANSPORT_TCP or GETDNS_TRANSPORT_TLS
# If only one transport value is specified it will be the only transport used.
# Should it not be available basic resolution will fail.
# Fallback transport options are specified by including multiple values in the
# list. Strict mode (see below) should use only GETDNS_TRANSPORT_TLS.
dns_transport_list:
- GETDNS_TRANSPORT_TLS
# Selects Strict or Opportunistic Usage profile as described in
# https://datatracker.ietf.org/doc/draft-ietf-dprive-dtls-and-tls-profiles/
# ONLY for the case when TLS is the one and only transport specified above.
# Strict mode requires that authentication information for the upstreams is
# specified below. Opportunistic may fallback to clear text DNS if UDP or TCP
# is included in the transport list above.
# For Strict use GETDNS_AUTHENTICATION_REQUIRED
# For Opportunistic use GETDNS_AUTHENTICATION_NONE
tls_authentication: GETDNS_AUTHENTICATION_REQUIRED
# EDNS0 option to pad the size of the DNS query to the given blocksize
# 128 is currently recommended by
# https://tools.ietf.org/html/draft-ietf-dprive-padding-policy-03
tls_query_padding_blocksize: 128
# EDNS0 option for ECS client privacy as described in Section 7.1.2 of
# https://tools.ietf.org/html/rfc7871
edns_client_subnet_private : 1
############################# CONNECTION SETTINGS ##############################
# Set to 1 to instruct stubby to distribute queries across all available name
# servers - this will use multiple simultaneous connections which can give
# better performance in most (but not all) cases.
# Set to 0 to treat the upstreams below as an ordered list and use a single
# upstream until it becomes unavailable, then use the next one.
round_robin_upstreams: 1
# EDNS0 option for keepalive idle timeout in milliseconds as specified in
# https://tools.ietf.org/html/rfc7828
# This keeps idle TLS connections open to avoid the overhead of opening a new
# connection for every query. Note that if a given server doesn't implement
# EDNS0 keepalive and uses an idle timeout shorter than this stubby will backoff
# from using that server because the server is always closing the connection.
# This can degrade performance for certain configurations so reducing the
# idle_timeout to below that of that lowest server value is recommended.
idle_timeout: 10000
# Control the maximum number of connection failures that will be permitted
# before Stubby backs-off from using an individual upstream (default 2)
# tls_connection_retries: 5
# Control the maximum time in seconds Stubby will back-off from using an
# individual upstream after failures under normal circumstances (default 3600)
# tls_backoff_time: 300
# Specify the location for CA certificates used for verification purposes are
# located - this overrides the OS specific default location.
# tls_ca_path: "/etc/ssl/certs/"
# Limit the total number of outstanding queries permitted
# limit_outstanding_queries: 100
# Specify the timeout in milliseconds on getting a response to an individual
# request (default 5000)
# timeout: 1000
# Set the acceptable ciphers for DNS over TLS. With OpenSSL 1.1.1 this list is
# for TLS1.2 and older only. Ciphers for TLS1.3 should be set with the
# tls_ciphersuites option. This option can also be given per upstream.
# tls_cipher_list: "EECDH+AESGCM:EECDH+CHACHA20"
# Set the acceptable cipher for DNS over TLS1.3. OpenSSL >= 1.1.1 is required
# for this option. This option can also be given per upstream.
# tls_ciphersuites: "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
# Set the minimum acceptable TLS version. Works with OpenSSL >= 1.1.1 only.
# This option can also be given per upstream.
# tls_min_version: GETDNS_TLS1_2
# Set the maximum acceptable TLS version. Works with OpenSSL >= 1.1.1 only.
# This option can also be given per upstream.
# tls_max_version: GETDNS_TLS1_3
################################ LISTEN ADDRESS ################################
# Set the listen addresses for the stubby DAEMON. This specifies localhost IPv4
# and IPv6. It will listen on port 53 by default. Use <IP_address>@<port> to
# specify a different port
listen_addresses:
- 0.0.0.0@8053
- 0:0:0:0:0:0:0:0@8053
############################### DNSSEC SETTINGS ################################
# Require DNSSEC validation. This will withhold answers with BOGUS DNSSEC
# status and answers that could not be validated (i.e. with DNSSEC status
# INDETERMINATE). Beware that if no DNSSEC trust-anchor is provided, or if
# stubby is not able to fetch and validate the DNSSEC trust-anchor itself,
# (using Zero configuration DNSSEC) stubby will not return answers at all.
# If DNSSEC validation is required, a trust-anchor is also required.
dnssec: GETDNS_EXTENSION_TRUE
# Stubby tries to fetch and validate the DNSSEC root trust anchor on the fly
# when needed (Zero configuration DNSSEC), but only if it can store then
# somewhere. The default location to store these files is the ".getdns"
# subdirectory in the user's home directory on Unixes, and the %appdata%\getdns
# directory on Windows. If there is no home directory, or
# the required subdirectory could not be created (or is not present), Stubby
# will fall back to the current working directory to try to store the
# trust-anchor files.
#
# When stubby runs as a special system-level user without a home directory
# however (such as in setups using systemd), it is recommended that an explicit
# location for storing the trust-anchor files is provided that is writable (and
# readable) by that special system user.
# appdata_dir: "/var/cache/stubby"
# When Zero configuration DNSSEC failed, because of network unavailability or
# failure to write to the appdata directory, stubby will backoff trying to
# refetch the DNSSEC trust-anchor for a specified amount of time expressed
# in milliseconds (which defaults to two and a half seconds).
# trust_anchors_backoff_time: 2500
# Specify the location of the installed trust anchor files to override the
# default location (see above)
# dnssec_trust_anchors:
# - "/etc/unbound/getdns-root.key"
# https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Test+Servers
# If you don't have IPv6 then comment then out those upstreams.
# In Opportunistic mode they only require an IP address in address_data.
# The information for an upstream can include the following:
# - address_data: IPv4 or IPv6 address of the upstream
# port: Port for UDP/TCP (default is 53)
# tls_auth_name: Authentication domain name checked against the server
# certificate
# tls_pubkey_pinset: An SPKI pinset verified against the keys in the server
# certificate
# - digest: Only "sha256" is currently supported
# value: Base64 encoded value of the sha256 fingerprint of the public
# key
# tls_port: Port for TLS (default is 853)
# To always use the DHCP resolvers provided by the local network in Opportunistic
# mode then
# 1) In the dns_transport_list after TLS add UDP then TCP
# 2) Change to tls_authentication: GETDNS_AUTHENTICATION_NONE
# 3) Remove all the upstream_recursive_servers listed below
upstream_recursive_servers:
############################ DEFAULT UPSTREAMS ################################
####### IPv4 addresses ######
### Test servers ###
# The Surfnet/Sinodun servers
# - address_data: 145.100.185.15
# tls_auth_name: "dnsovertls.sinodun.com"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: 62lKu9HsDVbyiPenApnc4sfmSYTHOVfFgL3pyB+cBL4=
# - address_data: 145.100.185.16
# tls_auth_name: "dnsovertls1.sinodun.com"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: cE2ecALeE5B+urJhDrJlVFmf38cJLAvqekONvjvpqUA=
# The getdnsapi.net server
# - address_data: 185.49.141.37
# tls_auth_name: "getdnsapi.net"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q=
####### IPv6 addresses ######
### Test servers ###
# The Surfnet/Sinodun servers
# - address_data: 2001:610:1:40ba:145:100:185:15
# tls_auth_name: "dnsovertls.sinodun.com"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: 62lKu9HsDVbyiPenApnc4sfmSYTHOVfFgL3pyB+cBL4=
# - address_data: 2001:610:1:40ba:145:100:185:16
# tls_auth_name: "dnsovertls1.sinodun.com"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: cE2ecALeE5B+urJhDrJlVFmf38cJLAvqekONvjvpqUA=
# The getdnsapi.net server
# - address_data: 2a04:b900:0:100::38
# tls_auth_name: "getdnsapi.net"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q=
############################ OPTIONAL UPSTREAMS ###############################
####### IPv4 addresses ######
### Anycast services ###
## Quad 9 'secure' service - Filters, does DNSSEC, doesn't send ECS
- address_data: 9.9.9.9
tls_auth_name: "dns.quad9.net"
- address_data: 149.112.112.112
tls_auth_name: "dns.quad9.net"
## Quad 9 'insecure' service - No filtering, no DNSSEC, doesn't send ECS
# - address_data: 9.9.9.10
# tls_auth_name: "dns10.quad9.net"
# - address_data: 149.112.112.10
# tls_auth_name: "dns10.quad9.net"
## Cloudflare 1.1.1.1 and 1.0.0.1
## (NOTE: recommend reducing idle_timeout to 9000 if using Coudflare)
# - address_data: 1.1.1.1
# tls_auth_name: "cloudflare-dns.com"
# - address_data: 1.0.0.1
# tls_auth_name: "cloudflare-dns.com"
## The Uncensored DNS servers
# - address_data: 91.239.100.100
# tls_auth_name: "anycast.censurfridns.dk"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: 2JjZgBZkfjSjs117vX+AnyKeYzJNM38zwsaxHwStWsg=
# comment: "deic-ore.anycast.censurfridns.dk RSA"
# - digest: "sha256"
# value: UXs8xWXai9ZXBAjDKYDiYl/jbIYtyV/bY2w3F1FFTDs=
# comment: "deic-ore.anycast.censurfridns.dk ECDSA"
# - digest: "sha256"
# value: oDxJrI/lG1Jhl1J7LvapMlYwlHMphZUODvCDBm0nof8=
# comment: "deic-lgb.anycast.censurfridns.dk RSA"
# - digest: "sha256"
# value: iYkCUwXdH7sT8qh26zt+r5dbTySL43wgJtLCTHaSH9M=
# comment: "deic-lgb.anycast.censurfridns.dk ECDSA"
# - digest: "sha256"
# value: Clii3HzZr48onFoog7I0ma5QmMPSpOBpCykXqgA0Wn0=
# comment: "kracon.anycast.censurfridns.dk RSA"
# - digest: "sha256"
# value: 6eW98h0+xxuaGQkgNalEU5e/hbgKyUoydpPMY6xcKyY=
# comment: "kracon.anycast.censurfridns.dk ECDSA"
# - digest: "sha256"
# value: sp2Low3+oTsQljNzs3gkYgLRYo7o91t3XGka+pwX//4=
# comment: "rgnet-iad.anycast.censurfridns.dk RSA"
# - digest: "sha256"
# value: /NPc7sIUzKLAQbsvRRhK6Ul3jip6Gi49bxutfrzpsQM=
# comment: "rgnet-iad.anycast.censurfridns.dk ECDSA"
# - address_data: 2001:67c:28a4::0
# tls_auth_name: "anycast.censurfridns.dk"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: 2JjZgBZkfjSjs117vX+AnyKeYzJNM38zwsaxHwStWsg=
# comment: "deic-ore.anycast.censurfridns.dk RSA"
# - digest: "sha256"
# value: UXs8xWXai9ZXBAjDKYDiYl/jbIYtyV/bY2w3F1FFTDs=
# comment: "deic-ore.anycast.censurfridns.dk ECDSA"
# - digest: "sha256"
# value: oDxJrI/lG1Jhl1J7LvapMlYwlHMphZUODvCDBm0nof8=
# comment: "deic-lgb.anycast.censurfridns.dk RSA"
# - digest: "sha256"
# value: iYkCUwXdH7sT8qh26zt+r5dbTySL43wgJtLCTHaSH9M=
# comment: "deic-lgb.anycast.censurfridns.dk ECDSA"
# - digest: "sha256"
# value: Clii3HzZr48onFoog7I0ma5QmMPSpOBpCykXqgA0Wn0=
# comment: "kracon.anycast.censurfridns.dk RSA"
# - digest: "sha256"
# value: 6eW98h0+xxuaGQkgNalEU5e/hbgKyUoydpPMY6xcKyY=
# comment: "kracon.anycast.censurfridns.dk ECDSA"
# - digest: "sha256"
# value: sp2Low3+oTsQljNzs3gkYgLRYo7o91t3XGka+pwX//4=
# comment: "rgnet-iad.anycast.censurfridns.dk RSA"
# - digest: "sha256"
# value: /NPc7sIUzKLAQbsvRRhK6Ul3jip6Gi49bxutfrzpsQM=
# comment: "rgnet-iad.anycast.censurfridns.dk ECDSA"
# - address_data: 89.233.43.71
# tls_auth_name: "unicast.censurfridns.dk"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: wikE3jYAA6jQmXYTr/rbHeEPmC78dQwZbQp6WdrseEs=
# comment: "unicast.censurfridns.dk RSA"
# - digest: "sha256"
# value: INSZEZpDoWKiavosV2/xVT8O83vk/RRwS+LTiL+IpHs=
# comment: "unicast.censurfridns.dk ECDSA"
# - address_data: 2a01:3a0:53:53::0
# tls_auth_name: "unicast.censurfridns.dk"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: wikE3jYAA6jQmXYTr/rbHeEPmC78dQwZbQp6WdrseEs=
# comment: "unicast.censurfridns.dk RSA"
# - digest: "sha256"
# value: INSZEZpDoWKiavosV2/xVT8O83vk/RRwS+LTiL+IpHs=
# comment: "unicast.censurfridns.dk ECDSA"
#
## Fondation RESTENA (NREN for Luxembourg)
# - address_data: 158.64.1.29
# tls_auth_name: "kaitain.restena.lu"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: 7ftvIkA+UeN/ktVkovd/7rPZ6mbkhVI7/8HnFJIiLa4=
## Google
# - address_data: 8.8.8.8
# tls_auth_name: "dns.google"
# - address_data: 8.8.4.4
# tls_auth_name: "dns.google"
## Adguard Default servers
# - address_data: 176.103.130.130
# tls_auth_name: "dns.adguard.com"
# - address_data: 176.103.130.131
# tls_auth_name: "dns.adguard.com"
## Adguard Family Protection servers
# - address_data: 176.103.130.132
# tls_auth_name: "dns-family.adguard.com"
# - address_data: 176.103.130.134
# tls_auth_name: "dns-family.adguard.com"
## Comcast public Beta
# - address_data: 96.113.151.145
# tls_auth_name: "dot.xfinity.com"
### Test servers ###
## A Surfnet/Sinodun server supporting TLS 1.2 and 1.3
# - address_data: 145.100.185.18
# tls_auth_name: "dnsovertls3.sinodun.com"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: 5SpFz7JEPzF71hditH1v2dBhSErPUMcLPJx1uk2svT8=
## A Surfnet/Sinodun server using Knot resolver. Warning - has issue when used
## for DNSSEC
# - address_data: 145.100.185.17
# tls_auth_name: "dnsovertls2.sinodun.com"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: NAXBESvpjZMnPWQcrxa2KFIkHV/pDEIjRkA3hLWogSg=
## dns.cmrg.net server using Knot resolver. Warning - has issue when used for
## DNSSEC.
# - address_data: 199.58.81.218
# tls_auth_name: "dns.cmrg.net"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: 3IOHSS48KOc/zlkKGtI46a9TY9PPKDVGhE3W2ZS4JZo=
# - digest: "sha256"
# value: 5zFN3smRPuHIlM/8L+hANt99LW26T97RFHqHv90awjo=
## Lorraine Data Network (self-signed cert).
# - address_data: 80.67.188.188
# tls_pubkey_pinset:
# - digest: "sha256"
# value: WaG0kHUS5N/ny0labz85HZg+v+f0b/UQ73IZjFep0nM=
## dns.neutopia.org
# - address_data: 89.234.186.112
# tls_auth_name: "dns.neutopia.org"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: wTeXHM8aczvhRSi0cv2qOXkXInoDU+2C+M8MpRyT3OI=
## NIC Chile (self-signed cert)
# - address_data: 200.1.123.46
# tls_pubkey_pinset:
# - digest: "sha256"
# value: sG6kj+XJToXwt1M6+9BeCz1SOj/1/mdZn56OZvCyZZc=
## Foundation for Applied Privacy
# - address_data: 146.255.56.98
# tls_auth_name: "dot1.applied-privacy.net"
####### IPv6 addresses #######
### Anycast services ###
## Quad 9 'secure' service - Filters, does DNSSEC, doesn't send ECS
- address_data: 2620:fe::fe
tls_auth_name: "dns.quad9.net"
- address_data: 2620:fe::9
tls_auth_name: "dns.quad9.net"
## Quad 9 'insecure' service - No filtering, does DNSSEC, may send ECS (it is
## unclear if it honours the edns_client_subnet_private request from stubby)
# - address_data: 2620:fe::10
# tls_auth_name: "dns10.quad9.net"
# - address_data: 2620:fe::fe:10
# tls_auth_name: "dns10.quad9.net"
## Cloudflare servers
## (NOTE: recommend reducing idle_timeout to 9000 if using Coudflare)
# - address_data: 2606:4700:4700::1111
# tls_auth_name: "cloudflare-dns.com"
# - address_data: 2606:4700:4700::1001
# tls_auth_name: "cloudflare-dns.com"
## Google
# - address_data: 2001:4860:4860::8888
# tls_auth_name: "dns.google"
# - address_data: 2001:4860:4860::8844
# tls_auth_name: "dns.google"
## Adguard Default servers
# - address_data: 2a00:5a60::ad1:0ff
# tls_auth_name: "dns.adguard.com"
# - address_data: 2a00:5a60::ad2:0ff
# tls_auth_name: "dns.adguard.com"
## Adguard Family Protection servers
# - address_data: 2a00:5a60::bad1:0ff
# tls_auth_name: "dns-family.adguard.com"
# - address_data: 2a00:5a60::bad2:0ff
# tls_auth_name: "dns-family.adguard.com"
## Comcast public Beta
# - address_data: 2001:558:fe21:6b:96:113:151:145
# tls_auth_name: "dot.xfinity.com"
### Test servers ###
## The Uncensored DNS server
# - address_data: 2a01:3a0:53:53::0
# tls_auth_name: "unicast.censurfridns.dk"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: wikE3jYAA6jQmXYTr/rbHeEPmC78dQwZbQp6WdrseEs=
## Fondation RESTENA (NREN for Luxembourg)
# - address_data: 2001:a18:1::29
# tls_auth_name: "kaitain.restena.lu"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: 7ftvIkA+UeN/ktVkovd/7rPZ6mbkhVI7/8HnFJIiLa4=
## A Surfnet/Sinodun server supporting TLS 1.2 and 1.3
# - address_data: 2001:610:1:40ba:145:100:185:18
# tls_auth_name: "dnsovertls3.sinodun.com"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: 5SpFz7JEPzF71hditH1v2dBhSErPUMcLPJx1uk2svT8=
## A Surfnet/Sinodun server using Knot resolver. Warning - has issue when used
## for DNSSEC
# - address_data: 2001:610:1:40ba:145:100:185:17
# tls_auth_name: "dnsovertls2.sinodun.com"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: NAXBESvpjZMnPWQcrxa2KFIkHV/pDEIjRkA3hLWogSg=
## dns.cmrg.net server using Knot resolver. Warning - has issue when used for
## DNSSEC.
# - address_data: 2001:470:1c:76d::53
# tls_auth_name: "dns.cmrg.net"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: 3IOHSS48KOc/zlkKGtI46a9TY9PPKDVGhE3W2ZS4JZo=
# - digest: "sha256"
# value: 5zFN3smRPuHIlM/8L+hANt99LW26T97RFHqHv90awjo=
## Go6Lab
# - address_data: 2001:67c:27e4::35
# tls_auth_name: "privacydns.go6lab.si"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: g5lqtwHia/plKqWU/Fe2Woh4+7MO3d0JYqYJpj/iYAw=
## Lorraine Data Network (self-signed cert).
# - address_data: 2001:913::8
# tls_pubkey_pinset:
# - digest: "sha256"
# value: WaG0kHUS5N/ny0labz85HZg+v+f0b/UQ73IZjFep0nM=
## dns.neutopia.org
# - address_data: 2a00:5884:8209::2
# tls_auth_name: "dns.neutopia.org"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: wTeXHM8aczvhRSi0cv2qOXkXInoDU+2C+M8MpRyT3OI=
## NIC Chile (self-signed cert)
# - address_data: 2001:1398:1:0:200:1:123:46
# tls_pubkey_pinset:
# - digest: "sha256"
# value: sG6kj+XJToXwt1M6+9BeCz1SOj/1/mdZn56OZvCyZZc=
## Foundation for Applied Privacy
# - address_data: 2a02:1b8:10:234::2
# tls_auth_name: "dot1.applied-privacy.net"
####### Servers that listen on port 443 (IPv4 and IPv6) #######
### Test servers ###
## Surfnet/Sinodun servers
# - address_data: 145.100.185.15
# tls_port: 443
# tls_auth_name: "dnsovertls.sinodun.com"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: 62lKu9HsDVbyiPenApnc4sfmSYTHOVfFgL3pyB+cBL4=
# - address_data: 145.100.185.16
# tls_port: 443
# tls_auth_name: "dnsovertls1.sinodun.com"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: cE2ecALeE5B+urJhDrJlVFmf38cJLAvqekONvjvpqUA=
## dns.cmrg.net server using Knot resolver
# - address_data: 199.58.81.218
# tls_port: 443
# tls_auth_name: "dns.cmrg.net"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: 3IOHSS48KOc/zlkKGtI46a9TY9PPKDVGhE3W2ZS4JZo=
# - digest: "sha256"
# value: 5zFN3smRPuHIlM/8L+hANt99LW26T97RFHqHv90awjo=
## Lorraine Data Network (self-signed cert)
# - address_data: 80.67.188.188
# tls_port: 443
# tls_pubkey_pinset:
# - digest: "sha256"
# value: WaG0kHUS5N/ny0labz85HZg+v+f0b/UQ73IZjFep0nM=
## dns.neutopia.org
# - address_data: 89.234.186.112
# tls_port: 443
# tls_auth_name: "dns.neutopia.org"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: wTeXHM8aczvhRSi0cv2qOXkXInoDU+2C+M8MpRyT3OI=
## The Surfnet/Sinodun servers
# - address_data: 2001:610:1:40ba:145:100:185:15
# tls_port: 443
# tls_auth_name: "dnsovertls.sinodun.com"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: 62lKu9HsDVbyiPenApnc4sfmSYTHOVfFgL3pyB+cBL4=
# - address_data: 2001:610:1:40ba:145:100:185:16
# tls_port: 443
# tls_auth_name: "dnsovertls1.sinodun.com"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: cE2ecALeE5B+urJhDrJlVFmf38cJLAvqekONvjvpqUA=
## dns.cmrg.net server using Knot resolver
# - address_data: 2001:470:1c:76d::53
# tls_port: 443
# tls_auth_name: "dns.cmrg.net"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: 3IOHSS48KOc/zlkKGtI46a9TY9PPKDVGhE3W2ZS4JZo=
# - digest: "sha256"
# value: 5zFN3smRPuHIlM/8L+hANt99LW26T97RFHqHv90awjo=
## Lorraine Data Network (self-signed cert)
# - address_data: 2001:913::8
# tls_port: 443
# tls_pubkey_pinset:
# - digest: "sha256"
# value: WaG0kHUS5N/ny0labz85HZg+v+f0b/UQ73IZjFep0nM=
## dns.neutopia.org
# - address_data: 2a00:5884:8209::2
# tls_port: 443
# tls_auth_name: "dns.neutopia.org"
# tls_pubkey_pinset:
# - digest: "sha256"
# value: wTeXHM8aczvhRSi0cv2qOXkXInoDU+2C+M8MpRyT3OI=
## Foundation for Applied Privacy
# - address_data: 146.255.56.98
# tls_port: 443
# tls_auth_name: "dot1.applied-privacy.net"
# - address_data: 2a02:1b8:10:234::2
# tls_port: 443
# tls_auth_name: "dot1.applied-privacy.net"

View File

@ -0,0 +1,8 @@
FROM alpine:latest
RUN apk --no-cache add unbound
EXPOSE 53/tcp
EXPOSE 53/udp
COPY ./unbound.sh /
RUN chmod a+x /unbound.sh
CMD ["/unbound.sh"]

View File

@ -0,0 +1,318 @@
server:
###########################################################################
# LOGGING
###########################################################################
# Only log errors
verbosity: 0
# Do not print log lines to inform about local zone actions
log-local-actions: no
# Do not print one line per query to the log
log-queries: no
# Do not print one line per reply to the log
log-replies: no
# Do not print log lines that say why queries return SERVFAIL to clients
log-servfail: no
# Further limit logging
logfile: /dev/null
###########################################################################
# BASIC SETTINGS
###########################################################################
# the time to live (TTL) value cap for RRsets and messages in the
# cache. Items are not cached for longer. In seconds.
cache-max-ttl: 86400
# the time to live (TTL) value lower bound, in seconds. Default 0.
# If more than an hour could easily give trouble due to stale data.
cache-min-ttl: 300
# Set the working directory for the program.
directory: "/etc/unbound"
# RFC 6891. Number of bytes size to advertise as the EDNS reassembly buffer
# size. This is the value put into datagrams over UDP towards peers.
# The actual buffer size is determined by msg-buffer-size (both for TCP and
# UDP). Do not set higher than that value.
# Default is 1232 which is the DNS Flag Day 2020 recommendation.
# Setting to 512 bypasses even the most stringent path MTU problems, but
# is seen as extreme, since the amount of TCP fallback generated is
# excessive (probably also for this resolver, consider tuning the outgoing
# tcp number).
edns-buffer-size: 1472
# Listen to for queries from clients and answer from this network interface
# and port.
interface: 0.0.0.0
port: 53
# Set to yes if you have IPv6
do-ip4: yes
do-udp: yes
do-tcp: yes
do-ip6: no
prefer-ip6: no
# Rotates RRSet order in response (the pseudo-random number is taken from
# the query ID, for speed and thread safety).
rrset-roundrobin: yes
# Drop user privileges after binding the port.
username: "unbound"
# Use this only when you downloaded the list of primary root servers!
# If you use the default dns-root-data package, unbound will find it automatically
#root-hints: "/var/lib/unbound/root.hints"
###########################################################################
# PRIVACY SETTINGS
###########################################################################
# RFC 8198. Use the DNSSEC NSEC chain to synthesize NXDO-MAIN and other
# denials, using information from previous NXDO-MAINs answers. In other
# words, use cached NSEC records to generate negative answers within a
# range and positive answers from wildcards. This increases performance,
# decreases latency and resource utilization on both authoritative and
# recursive servers, and increases privacy. Also, it may help increase
# resilience to certain DoS attacks in some circumstances.
aggressive-nsec: yes
# Extra delay for timeouted UDP ports before they are closed, in msec.
# This prevents very delayed answer packets from the upstream (recursive)
# servers from bouncing against closed ports and setting off all sort of
# close-port counters, with eg. 1500 msec. When timeouts happen you need
# extra sockets, it checks the ID and remote IP of packets, and unwanted
# packets are added to the unwanted packet counter.
delay-close: 10000
# Prevent the unbound server from forking into the background as a daemon
do-daemonize: no
# Add localhost to the do-not-query-address list.
do-not-query-localhost: no
# Number of bytes size of the aggressive negative cache.
neg-cache-size: 4M
# Send minimum amount of information to upstream servers to enhance
# privacy (best privacy).
qname-minimisation: yes
# Do not fall-back to sending full QNAME to potentially broken nameservers.
# A lot of domains will not be resolvable when this option in enabled.
# Only use if you know what you are doing.
# qname-minimisation-strict: yes
###########################################################################
# SECURITY SETTINGS
###########################################################################
# Only give access to recursion clients from LAN IPs
access-control: 127.0.0.1/32 allow
access-control: 192.168.0.0/16 allow
access-control: 172.16.0.0/12 allow
access-control: 10.0.0.0/8 allow
# access-control: fc00::/7 allow
# access-control: ::1/128 allow
# File with trust anchor for one zone, which is tracked with RFC5011
# probes.
auto-trust-anchor-file: "var/root.key"
# Enable chroot (i.e, change apparent root directory for the current
# running process and its children)
chroot: "/etc/unbound"
# Deny queries of type ANY with an empty response.
deny-any: yes
# Harden against algorithm downgrade when multiple algorithms are
# advertised in the DS record.
harden-algo-downgrade: yes
# RFC 8020. returns nxdomain to queries for a name below another name that
# is already known to be nxdomain.
harden-below-nxdomain: yes
# Require DNSSEC data for trust-anchored zones, if such data is absent, the
# zone becomes bogus. If turned off you run the risk of a downgrade attack
# that disables security for a zone.
harden-dnssec-stripped: yes
# Only trust glue if it is within the servers authority.
harden-glue: yes
# Ignore very large queries.
harden-large-queries: yes
# Perform additional queries for infrastructure data to harden the referral
# path. Validates the replies if trust anchors are configured and the zones
# are signed. This enforces DNSSEC validation on nameserver NS sets and the
# nameserver addresses that are encountered on the referral path to the
# answer. Experimental option.
harden-referral-path: no
# Ignore very small EDNS buffer sizes from queries.
harden-short-bufsize: yes
# Refuse id.server and hostname.bind queries
hide-identity: yes
# Refuse version.server and version.bind queries
hide-version: yes
# Report this identity rather than the hostname of the server.
identity: "DNS"
# These private network addresses are not allowed to be returned for public
# internet names. Any occurrence of such addresses are removed from DNS
# answers. Additionally, the DNSSEC validator may mark the answers bogus.
# This protects against DNS Rebinding
private-address: 10.0.0.0/8
private-address: 172.16.0.0/12
private-address: 192.168.0.0/16
private-address: 169.254.0.0/16
# private-address: fd00::/8
# private-address: fe80::/10
# private-address: ::ffff:0:0/96
# Enable ratelimiting of queries (per second) sent to nameserver for
# performing recursion. More queries are turned away with an error
# (servfail). This stops recursive floods (e.g., random query names), but
# not spoofed reflection floods. Cached responses are not rate limited by
# this setting. Experimental option.
ratelimit: 1000
# Use this certificate bundle for authenticating connections made to
# outside peers (e.g., auth-zone urls, DNS over TLS connections).
tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
# Set the total number of unwanted replies to eep track of in every thread.
# When it reaches the threshold, a defensive action of clearing the rrset
# and message caches is taken, hopefully flushing away any poison.
# Unbound suggests a value of 10 million.
unwanted-reply-threshold: 10000
# Use 0x20-encoded random bits in the query to foil spoof attempts. This
# perturbs the lowercase and uppercase of query names sent to authority
# servers and checks if the reply still has the correct casing.
# This feature is an experimental implementation of draft dns-0x20.
# Experimental option.
use-caps-for-id: yes
# Help protect users that rely on this validator for authentication from
# potentially bad data in the additional section. Instruct the validator to
# remove data from the additional section of secure messages that are not
# signed properly. Messages that are insecure, bogus, indeterminate or
# unchecked are not affected.
val-clean-additional: yes
###########################################################################
# PERFORMANCE SETTINGS
###########################################################################
# https://nlnetlabs.nl/documentation/unbound/howto-optimise/
# https://nlnetlabs.nl/news/2019/Feb/05/unbound-1.9.0-released/
# Number of slabs in the infrastructure cache. Slabs reduce lock contention
# by threads. Must be set to a power of 2.
# infra-cache-slabs: 4
# Number of incoming TCP buffers to allocate per thread. Default
# is 10. If set to 0, or if do-tcp is "no", no TCP queries from
# clients are accepted. For larger installations increasing this
# value is a good idea.
# incoming-num-tcp: 10
# Number of slabs in the key cache. Slabs reduce lock contention by
# threads. Must be set to a power of 2. Setting (close) to the number
# of cpus is a reasonable guess.
# key-cache-slabs: 4
# Number of bytes size of the message cache.
# Unbound recommendation is to Use roughly twice as much rrset cache memory
# as you use msg cache memory.
msg-cache-size: 260991658
# Number of slabs in the message cache. Slabs reduce lock contention by
# threads. Must be set to a power of 2. Setting (close) to the number of
# cpus is a reasonable guess.
# msg-cache-slabs: 4
# The number of queries that every thread will service simultaneously. If
# more queries arrive that need servicing, and no queries can be jostled
# out (see jostle-timeout), then the queries are dropped.
# This is best set at half the number of the outgoing-range.
# This Unbound instance was compiled with libevent so it can efficiently
# use more than 1024 file descriptors.
num-queries-per-thread: 4096
# The number of threads to create to serve clients.
# This is set dynamically at run time to effectively use available CPUs
# resources
# num-threads: 3
# Number of ports to open. This number of file descriptors can be opened
# per thread.
# This Unbound instance was compiled with libevent so it can efficiently
# use more than 1024 file descriptors.
outgoing-range: 8192
# Number of bytes size of the RRset cache.
# Use roughly twice as much rrset cache memory as msg cache memory
rrset-cache-size: 260991658
# Number of slabs in the RRset cache. Slabs reduce lock contention by
# threads. Must be set to a power of 2.
# rrset-cache-slabs: 4
# Do no insert authority/additional sections into response messages when
# those sections are not required. This reduces response size
# significantly, and may avoid TCP fallback for some responses. This may
# cause a slight speedup.
minimal-responses: yes
# Fetch the DNSKEYs earlier in the validation process, when a DS record
# is encountered. This lowers the latency of requests at the expense of
# little more CPU usage.
prefetch: yes
# Fetch the DNSKEYs earlier in the validation process, when a DS record is
# encountered. This lowers the latency of requests at the expense of little
# more CPU usage.
prefetch-key: yes
# Have unbound attempt to serve old responses from cache with a TTL of 0 in
# the response without waiting for the actual resolution to finish. The
# actual resolution answer ends up in the cache later on.
serve-expired: yes
# Open dedicated listening sockets for incoming queries for each thread and
# try to set the SO_REUSEPORT socket option on each socket. May distribute
# incoming queries to threads more evenly.
so-reuseport: yes
# Ensure kernel buffer is large enough to not lose messages in traffic spikes
so-rcvbuf: 1m
###########################################################################
# LOCAL ZONE
###########################################################################
# Include file for local-data and local-data-ptr
# include: /etc/unbound/forward-records.conf
###########################################################################
# FORWARD ZONE
###########################################################################
forward-zone:
name: "."
# Forward to Stubby
forward-addr: 10.2.0.150@8053
# Unbound can hanle DNS over TLS on its own
# forward-tls-upstream: yes
# forward-addr: 9.9.9.9@853#dns.quad9.net
# forward-addr: 149.112.112.112@853#dns.quad9.net
remote-control:
control-enable: no

View File

@ -0,0 +1,12 @@
#!/bin/ash
set -e
mkdir -p /etc/unbound/dev && \
cp -a /dev/random /dev/urandom /dev/null /etc/unbound/dev/
mkdir -p -m 700 /etc/unbound/var && \
/usr/sbin/unbound-anchor -a /etc/unbound/var/root.key && \
chown -R unbound:unbound /etc/unbound/var
exec /usr/sbin/unbound -d -c /etc/unbound/unbound.conf

48
pleroma/Dockerfile Normal file
View File

@ -0,0 +1,48 @@
FROM alpine:latest
ARG PLEROMA_VER=develop
ENV UID=1000 \
GID=1000 \
LC_ALL=C.UTF-8 \
LANG=C.UTF-8 \
MIX_ENV=prod
RUN apk add --no-cache git build-base cmake file-dev \
elixir erlang erlang-dev \
exiftool imagemagick ffmpeg postgresql-client
ARG DATA=/var/lib/pleroma
RUN addgroup -g ${GID} pleroma \
&& adduser -S -s /bin/false -D -G pleroma -h /pleroma -u ${UID} pleroma \
&& mkdir -p ${DATA}/uploads \
&& mkdir -p ${DATA}/static \
&& chown -R pleroma:pleroma ${DATA}
COPY ./entrypoint.sh /entrypoint.sh
RUN chmod a+x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
USER pleroma
WORKDIR /pleroma
RUN git clone --progress https://git.pleroma.social/pleroma/pleroma.git /pleroma
# Use a random variable to force rebuild
ARG __CACHE_TAG
ENV __CACHE_TAG $__CACHE_TAG
RUN git fetch --all \
&& git checkout ${PLEROMA_VER} \
&& if git show-ref --quiet "refs/heads/$PLEROMA_VERSION"; then \
git pull --rebase --autostash \
fi
RUN cp /pleroma/config/dev.exs /pleroma/config/prod.secret.exs \
&& mix local.hex --force \
&& mix local.rebar --force \
&& mix deps.get \
&& mix compile \
&& rm /pleroma/config/prod.secret.exs
EXPOSE 4000 70

29
pleroma/README.md Normal file
View File

@ -0,0 +1,29 @@
# Pleroma + 🐳
Docker template and configuration for Pleroma powering [kokkoro.moe](https://kokkoro.moe). This is a shorter version compared to [@sn0w's one](https://memleak.eu/sn0w/pleroma-docker), which means you have to do all the maintenance (updating, running mix tasks) by hands and it doesn't have any safe checks.
## Notes
- Deploy: run `build.sh` and `docker-compose up --remove-orphan -d`
- Update: `docker-compose pull` (update postgres image) and rebuild
- Exec into the container: `docker-compose exec web sh -c 'cd /pleroma && /bin/ash'`
## Postgres upgrades
Postgres upgrades are a slow process in docker (even more than usual) because we can't utilize `pg_upgrade` in any sensible way.<br/>
If you ever wish to upgrade postgres to a new major release for some reason, here's a list of things you'll need to do.
- Inform your users about the impending downtime
- Seriously this can take anywhere from a couple hours to a week depending on your instance
- Make sure you have enough free disk space or some network drive to dump to, we can't do in-place upgrades
- Stop pleroma (`docker-compose stop server`)
- Dump the current database into an SQL file (`docker-compose exec db pg_dumpall -U pleroma > /my/sql/location/pleroma.sql`)
- Remove the old containers (`docker-compose down`)
- Modify the postgres version in `docker-compose.yml` to your desired release
- Delete `data/db` or move it into some different place (might be handy if you want to abort/revert the migration)
- Start the new postgres container (`docker-compose up -d db`)
- Start the import (`docker-compose exec -T db psql -U pleroma < /my/sql/location/pleroma.sql`)
- Wait for a possibly ridculously long time
- Boot pleroma again (`docker-compose up -d`)
- Wait for service to stabilize while federation catches up
- Done!

26
pleroma/build.sh Normal file
View File

@ -0,0 +1,26 @@
#!/bin/sh
cacheTag=""
echo "Generating a random tag..."
if command -v git >/dev/null; then
resolveHash=$(git ls-remote https://git.pleroma.social/pleroma/pleroma.git | grep "/develop" | awk '{ print $1 }')
if [ -n "$resolveHash" ]; then
cacheTag="$resolveHash"
fi
fi
if [ -z "$cacheTag" ] && command -v date; then
cacheTag="$(date '+%s')"
fi
if [ -z "$cacheTag" ]; then
echo "Can't get a random variable. Stopped."
exit 1
fi
echo "Building Pleroma..."
docker-compose build \
--build-arg __CACHE_TAG="$cacheTag" \
web

67
pleroma/config.exs Normal file
View File

@ -0,0 +1,67 @@
# You can always run `MIX_ENV=prod mix pleroma.instance gen` to have a base config
use Mix.Config
config :pleroma, Pleroma.Web.Endpoint,
url: [host: System.get_env("DOMAIN", "localhost"), scheme: "https", port: 443],
http: [ip: {0, 0, 0, 0}, port: 4000],
secret_key_base: "<use 'openssl rand -base64 48' to generate a key>",
signing_salt: ""
config :pleroma, :gopher,
enabled: true,
ip: {0, 0, 0, 0},
port: 70
config :pleroma, :media_proxy,
enabled: true,
proxy_opts: [
redirect_on_failure: true
]
#base_url: "https://cache.kokkoro.moe"
config :pleroma, :frontend_configurations,
pleroma_fe: %{
showInstanceSpecificPanel: true,
theme: "nord-one",
background: "/images/kokorow.png",
logo: "/static/logo.png"
}
config :pleroma, :instance,
name: System.get_env("INSTANCE_NAME", "Pleroma"),
email: System.get_env("ADMIN_EMAIL"),
notify_email: System.get_env("NOTIFY_EMAIL"),
limit: 5000,
registrations_open: false,
invites_enabled: true,
account_approval_required: false,
federating: true,
healthcheck: true
config :pleroma, Pleroma.Repo,
adapter: Ecto.Adapters.Postgres,
username: System.get_env("DB_USER", "pleroma"),
password: System.fetch_env!("DB_PASS"),
database: System.get_env("DB_NAME", "pleroma"),
hostname: System.get_env("DB_HOST", "db"),
pool_size: 10
config :web_push_encryption, :vapid_details,
subject: "mailto:#{System.get_env("NOTIFY_EMAIL")}",
public_key: "",
private_key: ""
config :pleroma, :database, rum_enabled: false
config :pleroma, :instance, static_dir: "/var/lib/pleroma/static"
config :pleroma, Pleroma.Uploaders.Local, uploads: "/var/lib/pleroma/uploads"
config :pleroma, :http_security,
enabled: true,
sts: true,
referrer_policy: "same-origin"
config :joken, default_signer: ""
config :pleroma, configurable_from_database: false
config :pleroma, Pleroma.Upload, filters: [Pleroma.Upload.Filter.Exiftool, Pleroma.Upload.Filter.AnonymizeFilename]

View File

@ -0,0 +1,37 @@
version: "3"
services:
web:
build: .
container_name: pleroma_web
restart: unless-stopped
ports:
- "4000:4000"
- "70:70"
volumes:
- ./uploads:/var/lib/pleroma/uploads
- ./static:/var/lib/pleroma/static
- ./config.exs:/pleroma/config/prod.secret.exs:ro
- ./config.exs:/pleroma/config/dev.secret.exs:ro
environment:
DOMAIN: 'kokkoro.moe'
INSTANCE_NAME: 'kokkoro.moe'
ADMIN_EMAIL: ''
NOTIFY_EMAIL: ''
DB_NAME: pleroma
DB_USER: pleroma
DB_PASS: changeme
depends_on:
- db
db:
image: postgres:13-alpine
container_name: pleroma_db
restart: unless-stopped
environment:
POSTGRES_DB: pleroma
POSTGRES_USER: pleroma
POSTGRES_PASSWORD: changeme
volumes:
- ./db:/var/lib/postgresql/data
- ./initdb.sql:/docker-entrypoint-initdb.d/pleroma.sql

14
pleroma/entrypoint.sh Normal file
View File

@ -0,0 +1,14 @@
#!/bin/ash
set -e
echo "-- Waiting for database..."
while ! pg_isready -U ${DB_USER:-pleroma} -d postgres://${DB_HOST:-db}:5432/${DB_NAME:-pleroma} -t 1; do
sleep 1s
done
echo "-- Running migrations..."
mix ecto.migrate
echo "-- Starting..."
exec mix phx.server

3
pleroma/initdb.sql Normal file
View File

@ -0,0 +1,3 @@
CREATE EXTENSION IF NOT EXISTS citext;
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

BIN
pleroma/static/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 458 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

@ -0,0 +1,9 @@
<div style="margin-left: 12px; margin-right: 12px">
<img src='/images/kokkoro_sprite.png' style="height: 120px; float: right; margin-bottom: 12px"/>
<p>Welcome to Pleroma!</p>
<p>Frontends:</p>
<ul>
<li style="margin-bottom: 12px"><a href="/main/all">PleromaFE</a></li>
<li><a href="/web">MastoFE</a></li>
</ul>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

View File

@ -0,0 +1,12 @@
{
"pleroma-dark": "/static/themes/pleroma-dark.json",
"pleroma-light": "/static/themes/pleroma-light.json",
"redmond-xx": "/static/themes/redmond-xx.json",
"redmond-xx-se": "/static/themes/redmond-xx-se.json",
"redmond-xxi": "/static/themes/redmond-xxi.json",
"breezy-dark": "/static/themes/breezy-dark.json",
"breezy-light": "/static/themes/breezy-light.json",
"mammal": "/static/themes/mammal.json",
"paper": "/static/themes/paper.json",
"nord-one": "/static/themes/nord-one.json"
}

View File

@ -0,0 +1,9 @@
<img src="/images/kokkoro_swimsuit.png" style="float: right; height: 220px; margin-bottom: 12px"/>
<h2>Terms of Service</h2>
<p>This is a personal Fedi instance for myself only, so technically there is no need for a ToS. But I will try to "restrict" myself in posting things related to Anime/Manga and technology.</p>
<h2>Credits</h2>
<ul>
<li><a href="https://fedi.absturztau.be/">fedi.absturztau.be</a> for the emoji sets</li>
</ul>

View File

@ -0,0 +1,542 @@
{
"_pleroma_theme_version": 2,
"name": "Nord One",
"theme": {
"themeEngineVersion": 3,
"shadows": {
"panel": [
{
"color": "#000000",
"x": "0",
"y": "0",
"blur": "3",
"spread": 0,
"alpha": "0.5"
},
{
"color": "#000000",
"x": "0",
"y": "4",
"blur": "6",
"spread": "3",
"inset": false,
"alpha": "0.3"
}
],
"topBar": [
{
"color": "#000000",
"x": 0,
"y": "1",
"blur": 4,
"spread": 0,
"alpha": "0.4"
},
{
"color": "#000000",
"x": 0,
"y": "2",
"blur": "7",
"spread": 0,
"inset": false,
"alpha": "0.3"
}
],
"popup": [
{
"x": 2,
"y": 2,
"blur": 3,
"spread": 0,
"color": "#000000",
"alpha": 0.5
}
],
"avatar": [
{
"x": 0,
"y": 1,
"blur": 8,
"spread": 0,
"color": "#000000",
"alpha": 0.7
}
],
"avatarStatus": [],
"panelHeader": [
{
"color": "#ffffff",
"x": "0",
"y": "1",
"blur": "0",
"spread": 0,
"inset": true,
"alpha": "0.2"
}
],
"button": [
{
"color": "#FFFFFF",
"x": 0,
"y": 1,
"blur": 0,
"spread": 0,
"alpha": 0.2,
"inset": true
},
{
"color": "#000000",
"x": 0,
"y": -1,
"blur": 0,
"spread": 0,
"alpha": 0.2,
"inset": true
}
],
"buttonHover": [
{
"color": "#b9b9ba",
"x": 0,
"y": 0,
"blur": "1",
"spread": "2",
"alpha": "0.4",
"inset": true
},
{
"color": "#FFFFFF",
"x": 0,
"y": 1,
"blur": 0,
"spread": 0,
"alpha": 0.2,
"inset": true
},
{
"color": "#000000",
"x": 0,
"y": -1,
"blur": 0,
"spread": 0,
"alpha": 0.2,
"inset": true
}
],
"buttonPressed": [
{
"color": "#000000",
"x": 0,
"y": 0,
"blur": 4,
"spread": 0,
"alpha": 1,
"inset": true
},
{
"color": "#000000",
"x": 0,
"y": 1,
"blur": 0,
"spread": 0,
"alpha": 0.2,
"inset": true
},
{
"color": "#FFFFFF",
"x": 0,
"y": -1,
"blur": 0,
"spread": 0,
"alpha": 0.2,
"inset": true
},
{
"color": "#000000",
"x": 0,
"y": 0,
"blur": "2",
"spread": 0,
"inset": false,
"alpha": 1
}
],
"input": [
{
"x": 0,
"y": 1,
"blur": 0,
"spread": 0,
"color": "#000000",
"alpha": 0.2,
"inset": true
},
{
"x": 0,
"y": -1,
"blur": 0,
"spread": 0,
"color": "#FFFFFF",
"alpha": 0.2,
"inset": true
},
{
"x": 0,
"y": 0,
"blur": 2,
"inset": true,
"spread": 0,
"color": "#000000",
"alpha": 1
}
]
},
"colors": {
"underlay": "#181a1f",
"bg": "#2e3440",
"fg": "#3b4252",
"cRed": "#fd7776",
"cOrange": "#d19a66",
"cGreen": "#98c379",
"cBlue": "#61afef",
"accent": "#56b6c2",
"link": "#e5c07b",
"text": "#d8dee9",
"chatBg": "#2e3440",
"chatMessageIncomingBg": "#2e3440",
"chatMessageOutgoingB": "#39404f",
"chatMessageOutgoingBorder": "#3d4555",
"chatMessageOutgoingLink": "#e5c07b",
"chatMessageOutgoingText": "#d8dee9",
"border": "#424a5b",
"chatMessageIncomingBorder": "#464e61",
"chatMessageIncomingLink": "#e5c07b",
"chatMessageIncomingText": "#d8dee9",
"badgeNotification": "#61afef",
"badgeNotificationText": "#282c34",
"alertNeutral": "#434c5e",
"alertNeutralText": "#ffffff",
"alertPopupNeutral": "#434c5e",
"alertPopupNeutralText": "#ffffff",
"alertWarning": "#d19a66",
"alertWarningText": "#ffffff",
"alertPopupWarning": "#d19a66",
"alertPopupWarningText": "#000000",
"alertError": "#e06c75",
"alertErrorText": "#ffffff",
"alertPopupError": "#e06c75",
"alertPopupErrorText": "#000000",
"panel": "#2e3440",
"panelText": "#d8dee9",
"alertNeutralPanelText": "#d8dee9",
"alertWarningPanelText": "#ffffff",
"alertErrorPanelText": "#d8dee9",
"fgText": "#eceff4",
"topBar": "#2e3440",
"topBarText": "#b9c3d8",
"input": "#3b4252",
"inputTopbarText": "#b9c3d8",
"inputPanelText": "#d8dee9",
"inputText": "#d8dee9",
"btn": "#3b4252",
"btnText": "#eceff4",
"btnTopBarText": "#eceff4",
"btnDisabled": "#323845",
"btnDisabledTopBarText": "#606671",
"btnPanelText": "#eceff4",
"btnDisabledPanelText": "#606671",
"btnDisabledText": "#606671",
"btnToggled": "#8fbcbb",
"btnToggledTopBarText": "#0c0e14",
"btnToggledPanelText": "#0c0e14",
"btnToggledText": "#0c0e14",
"btnPressed": "#3b4252",
"btnPressedTopBarText": "#eceff4",
"btnPressedTopBar": "#3b4252",
"btnPressedPanelText": "#eceff4",
"btnPressedPanel": "#3b4252",
"btnPressedText": "#eceff4",
"tabActiveText": "#d8dee9",
"tabText": "#eceff4",
"tab": "#3b4252",
"fgLink": "#ecbe7b",
"topBarLink": "#b9c3d8",
"panelLink": "#ecbe7b",
"panelFaint": "#eceff4",
"icon": "#838995",
"poll": "#3e6874",
"pollText": "#d8dee9",
"postGreentext": "#98c379",
"postLink": "#e5c07b",
"lightText": "#ffffff",
"popover": "#2e3440",
"selectedMenuPopover": "#39404f",
"highlight": "#39404f",
"highlightText": "#d8dee9",
"selectedMenu": "#39404f",
"selectedMenuText": "#d8dee9",
"selectedMenuPopoverIcon": "#898f9c",
"highlightLink": "#e5c07b",
"selectedMenuLink": "#e5c07b",
"selectedMenuPopoverLink": "#e5c07b",
"selectedMenuPopoverText": "#d8dee9",
"faintLink": "#e5c07b",
"highlightFaintLink": "#e5c07b",
"selectedMenuFaintLink": "#e5c07b",
"selectedMenuPopoverFaintLink": "#e5c07b",
"faint": "#d8dee9",
"highlightFaintText": "#d8dee9",
"selectedMenuFaintText": "#d8dee9",
"selectedMenuPopoverFaintText": "#d8dee9",
"highlightLightText": "#ffffff",
"selectedMenuLightText": "#ffffff",
"selectedMenuPopoverLightText": "#ffffff",
"selectedMenuIcon": "#898f9c",
"selectedPost": "#39404f",
"selectedPostText": "#d8dee9",
"selectedPostIcon": "#898f9c",
"selectedPostLink": "#e5c07b",
"selectedPostFaintLink": "#e5c07b",
"highlightPostLink": "#e5c07b",
"selectedPostPostLink": "#e5c07b",
"selectedPostLightText": "#ffffff",
"selectedPostFaintText": "#d8dee9",
"popoverText": "#d8dee9",
"popoverIcon": "#838995",
"popoverLink": "#e5c07b",
"postFaintLink": "#e5c07b",
"popoverPostFaintLink": "#e5c07b",
"popoverFaintLink": "#e5c07b",
"popoverFaintText": "#d8dee9",
"popoverPostLink": "#e5c07b",
"popoverLightText": "#ffffff",
"highlightIcon": "#898f9c",
"highlightPostFaintLink": "#e5c07b",
"profileTint": "#2e3440",
"profileBg": "#181d25",
"wallpaper": "#2a303b"
},
"opacity": {
"underlay": 0.6,
"bg": 0.9,
"border": 1,
"alert": 0.5,
"alertPopup": 0.95,
"panel": 0.1,
"input": 0.5,
"btn": 1,
"faint": 0.5,
"popover": 1,
"profileTint": 0.5
},
"radii": {
"btn": "4",
"input": "3",
"checkbox": 2,
"panel": "6",
"avatar": "5",
"avatarAlt": 50,
"tooltip": 2,
"attachment": "2",
"chatMessage": "6"
},
"fonts": {
"interface": {
"family": "sans-serif"
},
"input": {
"family": "inherit"
},
"post": {
"family": "inherit"
},
"postCode": {
"family": "monospace"
}
}
},
"source": {
"themeEngineVersion": 3,
"fonts": {},
"shadows": {
"buttonHover": [
{
"x": 0,
"y": 0,
"blur": "1",
"spread": "2",
"color": "#b9b9ba",
"alpha": "0.4",
"inset": true
},
{
"x": 0,
"y": 1,
"blur": 0,
"spread": 0,
"color": "#FFFFFF",
"alpha": 0.2,
"inset": true
},
{
"x": 0,
"y": -1,
"blur": 0,
"spread": 0,
"color": "#000000",
"alpha": 0.2,
"inset": true
}
],
"buttonPressed": [
{
"x": 0,
"y": 0,
"blur": 4,
"spread": 0,
"color": "#000000",
"alpha": 1,
"inset": true
},
{
"x": 0,
"y": 1,
"blur": 0,
"spread": 0,
"color": "#000000",
"alpha": 0.2,
"inset": true
},
{
"x": 0,
"y": -1,
"blur": 0,
"spread": 0,
"color": "#FFFFFF",
"alpha": 0.2,
"inset": true
},
{
"x": 0,
"y": 0,
"blur": "2",
"spread": 0,
"inset": false,
"color": "#000000",
"alpha": 1
}
],
"panelHeader": [
{
"x": "0",
"y": "1",
"blur": "0",
"spread": 0,
"inset": true,
"color": "#ffffff",
"alpha": "0.2"
}
],
"panel": [
{
"x": "0",
"y": "0",
"blur": "3",
"spread": 0,
"color": "#000000",
"alpha": "0.5"
},
{
"x": "0",
"y": "4",
"blur": "6",
"spread": "3",
"inset": false,
"color": "#000000",
"alpha": "0.3"
}
],
"button": [
{
"x": 0,
"y": 1,
"blur": 0,
"spread": 0,
"color": "#FFFFFF",
"alpha": 0.2,
"inset": true
},
{
"x": 0,
"y": -1,
"blur": 0,
"spread": 0,
"color": "#000000",
"alpha": 0.2,
"inset": true
}
],
"topBar": [
{
"x": 0,
"y": "1",
"blur": 4,
"spread": 0,
"color": "#000000",
"alpha": "0.4"
},
{
"x": 0,
"y": "2",
"blur": "7",
"spread": 0,
"inset": false,
"color": "#000000",
"alpha": "0.3"
}
]
},
"opacity": {
"bg": "0.9",
"underlay": "0.6",
"panel": "0.1"
},
"colors": {
"bg": "#2e3440",
"fg": "#3b4252",
"text": "#d8dee9",
"underlay": "#181a1f",
"link": "#e5c07b",
"accent": "#56b6c2",
"cBlue": "#61afef",
"cRed": "#fd7776",
"cGreen": "#98c379",
"cOrange": "#d19a66",
"postLink": "#e5c07b",
"postGreentext": "#98c379",
"border": "--fg,3",
"fgText": "#eceff4",
"fgLink": "#ecbe7b",
"panel": "#2e3440",
"topBar": "#2e3440",
"topBarText": "--text,-9.75",
"topBarLink": "--topBarText",
"btnToggled": "#8fbcbb",
"alertError": "#e06c75",
"alertErrorText": "#ffffff",
"alertWarning": "#d19a66",
"alertWarningText": "#ffffff",
"alertNeutral": "#434c5e",
"alertNeutralText": "#ffffff",
"badgeNotification": "#61afef",
"badgeNotificationText": "#282c34"
},
"radii": {
"btn": "4",
"input": "3",
"panel": "6",
"avatar": "5",
"attachment": "2"
}
}
}

18
satellite/README.md Normal file
View File

@ -0,0 +1,18 @@
# Satellite + 🐳
## Introduction
This repository holds docker template for [Satellite](https://sr.ht/~gsthnz/satellite) (an easy to use Gemini server). Satellite already provides `Dockerfile`, so I only create `docker-compose.yml` for easier build + deployment.
## Deployment
You should change the domain name in `config.toml`, as well as Docker's volume paths, opened port (default is 1965).
The `Dockerfile` uses UID=1000, so assure your normal user has the same UID.
- Clone this repository
- Change directory into it and do `git submodule update --init`
- `cp config.toml satellite/config/ && chmod 700 satellite/config`
- `docker-compose up -d`
- Wait for Satellite to build
- Profit

6
satellite/config.toml Normal file
View File

@ -0,0 +1,6 @@
[tls]
directory = "/config"
[[domain]]
name = "folliehiyuki.com"
root = "/data"

View File

@ -0,0 +1,12 @@
version: "3"
services:
gemini:
build: ./satellite
container_name: satellite
restart: unless-stopped
ports:
- "1965:1965"
volumes:
- ./satellite/config:/config
- /srv/gemini:/data

1
satellite/satellite Submodule

@ -0,0 +1 @@
Subproject commit 2e806d27c15089d524ae7b284846bbe9dff6d158