Bläddra i källkod

WIP. improving algo/mitmproxy packer stuff

cobbzilla/introduce_packer
Jonathan Cobb 4 år sedan
förälder
incheckning
870f5658dc
34 ändrade filer med 2114 tillägg och 163 borttagningar
  1. +1
    -1
      bubble-server/src/main/java/bubble/ApiConstants.java
  2. +5
    -8
      bubble-server/src/main/java/bubble/resources/cloud/ComputePackerResource.java
  3. +0
    -4
      bubble-server/src/main/resources/ansible/install_local.sh.hbs
  4. +1
    -5
      bubble-server/src/main/resources/ansible/roles/algo/files/bubble_role.json
  5. +2
    -41
      bubble-server/src/main/resources/ansible/roles/algo/tasks/main.yml
  6. +1
    -5
      bubble-server/src/main/resources/ansible/roles/mitmproxy/files/bubble_role.json
  7. +0
    -57
      bubble-server/src/main/resources/ansible/roles/mitmproxy/tasks/main.yml
  8. +24
    -0
      bubble-server/src/main/resources/packer/roles/algo/defaults/main.yml
  9. +4
    -0
      bubble-server/src/main/resources/packer/roles/algo/files/50-dnscrypt-proxy-unattended-upgrades
  10. +29
    -0
      bubble-server/src/main/resources/packer/roles/algo/files/apparmor.profile.dnscrypt-proxy
  11. +2
    -28
      bubble-server/src/main/resources/packer/roles/algo/tasks/algo_firewall.yml
  12. +249
    -0
      bubble-server/src/main/resources/packer/roles/algo/tasks/algo_packer.yml
  13. +7
    -6
      bubble-server/src/main/resources/packer/roles/algo/tasks/main.yml
  14. +7
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/10-algo-lo100.network.j2
  15. +2
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/100-CustomLimitations.conf.j2
  16. +4
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/10periodic.j2
  17. +96
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/50unattended-upgrades.j2
  18. +45
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/adblock.sh.j2
  19. +365
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/charon.conf.j2
  20. +23
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/client_ipsec.conf.j2
  21. +1
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/client_ipsec.secrets.j2
  22. +568
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/dnscrypt-proxy.toml.j2
  23. +44
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/ip-blacklist.txt.j2
  24. +35
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/ipsec.conf.j2
  25. +1
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/ipsec.secrets.j2
  26. +197
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/mobileconfig.j2
  27. +139
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/openssl.cnf.j2
  28. +111
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/rules.v4.j2
  29. +119
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/rules.v6.j2
  30. +28
    -0
      bubble-server/src/main/resources/packer/roles/algo/templates/strongswan.conf.j2
  31. +1
    -2
      bubble-server/src/main/resources/packer/roles/firewall/tasks/main.yml
  32. +0
    -0
      bubble-server/src/main/resources/packer/roles/firewall/tasks/rules.yml
  33. +2
    -5
      bubble-server/src/main/resources/packer/roles/mitmproxy/tasks/main.yml
  34. +1
    -1
      bubble-server/src/main/resources/packer/roles/mitmproxy/tasks/route.yml

+ 1
- 1
bubble-server/src/main/java/bubble/ApiConstants.java Visa fil

@@ -45,7 +45,7 @@ public class ApiConstants {
public static final String DEFAULT_LOCALE = "en_US";

public static final String[] ROLES_SAGE = {"common", "nginx", "bubble", "finalizer"};
public static final String[] ROLES_NODE = {"common", "nginx", "algo", "mitmproxy", "bubble", "finalizer"};
public static final String[] ROLES_NODE = {"common", "nginx", "bubble", "algo", "mitmproxy", "finalizer"};

public static final String ANSIBLE_DIR = "ansible";
public static final List<String> BUBBLE_SCRIPTS = splitAndTrim(stream2string(ANSIBLE_DIR + "/bubble_scripts.txt"), "\n")


+ 5
- 8
bubble-server/src/main/java/bubble/resources/cloud/ComputePackerResource.java Visa fil

@@ -10,10 +10,7 @@ import org.glassfish.grizzly.http.server.Request;
import org.glassfish.jersey.server.ContainerRequest;
import org.springframework.beans.factory.annotation.Autowired;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Produces;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;

@@ -42,11 +39,11 @@ public class ComputePackerResource {
return ok(driver.getPackerImages());
}

@PUT
@PUT @Path("/{type}")
public Response writeImages(@Context Request req,
@Context ContainerRequest ctx) {
packer.writePackerImages(cloud, AnsibleInstallType.sage, null);
packer.writePackerImages(cloud, AnsibleInstallType.node, null);
@Context ContainerRequest ctx,
@PathParam("type") AnsibleInstallType installType) {
packer.writePackerImages(cloud, installType, null);
return ok();
}


+ 0
- 4
bubble-server/src/main/resources/ansible/install_local.sh.hbs Visa fil

@@ -43,10 +43,6 @@ if [[ -f "${ADMIN_PUB_KEY}" ]] ; then
cat "${ADMIN_PUB_KEY}" >> "${AUTH_KEYS}"
fi

sudo apt-get update -y && apt-get upgrade -y || die "Error in apt update / upgrade"
sudo apt-get -y install python3 python3-pip virtualenv || die "Error apt installing python3 or python3-pip"
sudo pip3 install setuptools psycopg2-binary || die "Error pip3 installing setuptools or psycopg2-binary"

SSH_OPTIONS="--ssh-extra-args '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o PreferredAuthentications=publickey -i ${ID_FILE}'"

cd "${ANSIBLE_DIR}" && \


+ 1
- 5
bubble-server/src/main/resources/ansible/roles/algo/files/bubble_role.json Visa fil

@@ -1,12 +1,8 @@
{
"name": "algo-0.0.1",
"priority": 400,
"template": true,
"install": "node",
"config": [
{"name": "server_name", "value": "[[node.fqdn]]"},
{"name": "endpoint", "value": "[[node.ip4]]"},
{"name": "ssl_port", "value": "[[node.sslPort]]"}
],
"tgzB64": ""
]
}

+ 2
- 41
bubble-server/src/main/resources/ansible/roles/algo/tasks/main.yml Visa fil

@@ -1,32 +1,6 @@
#
# Copyright (c) 2020 Bubble, Inc. All rights reserved. For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/
#
- name: Unzip algo master.zip
unarchive:
src: master.zip
dest: /root/ansible/roles/algo

- name: Write algo config.cfg.hbs
copy:
src: config.cfg.hbs
dest: /root/ansible/roles/algo/algo/config.cfg.hbs

- name: Install algo_refresh_users script and monitor
copy:
src: "{{ item }}"
dest: "/usr/local/bin/{{ item }}"
owner: root
group: root
mode: 0500
with_items:
- "algo_refresh_users.sh"
- "algo_refresh_users_monitor.sh"

- name: Install algo_refresh_users_monitor supervisor conf file
copy:
src: supervisor_algo_refresh_users_monitor.conf
dest: /etc/supervisor/conf.d/algo_refresh_users_monitor.conf

- name: Write install_algo.sh template
template:
src: install_algo.sh.j2
@@ -35,30 +9,17 @@
group: root
mode: 0500

- name: Install wg_monitor_connections script
copy:
src: wg_monitor_connections.sh
dest: "/usr/local/sbin/wg_monitor_connections.sh"
owner: root
group: root
mode: 0500

- name: Install wg_monitor_connections supervisor conf file
copy:
src: supervisor_wg_monitor_connections.conf
dest: /etc/supervisor/conf.d/wg_monitor_connections.conf

# Don't setup algo when in restore mode, bubble_restore_monitor.sh will set it up after the CA key has been restored
- name: Run algo playbook to install algo
shell: /root/ansible/roles/algo/algo/install_algo.sh
when: restore_key is not defined

# Don't start monitors when in restore mode, bubble_restore_monitor.sh will start it after algo is installed
- name: Run algo playbook to install algo
- name: Restart algo monitors
shell: bash -c "supervisorctl reload && sleep 5s && supervisorctl restart algo_refresh_users_monitor && supervisorctl restart wg_monitor_connections"
when: restore_key is not defined

- name: Run algo playbook to install algo
- name: Stop algo monitors (in restore mode)
shell: bash -c "supervisorctl reload && sleep 5s && supervisorctl stop algo_refresh_users_monitor && supervisorctl stop wg_monitor_connections"
when: restore_key is defined



+ 1
- 5
bubble-server/src/main/resources/ansible/roles/mitmproxy/files/bubble_role.json Visa fil

@@ -1,8 +1,5 @@
{
"name": "mitmproxy-0.0.1",
"priority": 600,
"template": true,
"install": "node",
"config": [
{"name": "admin_port", "value": "[[node.adminPort]]"},
{"name": "bubble_network", "value": "[[node.network]]"},
@@ -10,6 +7,5 @@
{"name": "server_name", "value": "[[node.fqdn]]"},
{"name": "server_alias", "value": "[[network.networkDomain]]"},
{"name": "ssl_port", "value": "[[node.sslPort]]"}
],
"tgzB64": ""
]
}

+ 0
- 57
bubble-server/src/main/resources/ansible/roles/mitmproxy/tasks/main.yml Visa fil

@@ -31,43 +31,9 @@
mode: 0755
state: directory

- name: Unzip mitmproxy.zip
unarchive:
src: mitmproxy.zip
dest: /home/mitmproxy/mitmproxy

- name: Copy mitmdump files
copy:
src: "{{ item }}"
dest: "/home/mitmproxy/mitmproxy/{{ item }}"
owner: mitmproxy
group: mitmproxy
mode: 0500
with_items:
- bubble_api.py
- dns_spoofing.py
- bubble_passthru.py
- bubble_modify.py
- run_mitmdump.sh

- name: Install cert helper scripts
copy:
src: "{{ item }}"
dest: "/usr/local/bin/{{ item }}"
owner: root
group: root
mode: 0500
with_items:
- install_cert.sh
- set_cert_name.sh
- reuse_bubble_mitm_certs.sh

- name: Set the cert name
shell: set_cert_name.sh /home/mitmproxy/mitmproxy {{ server_alias }}

- name: Set ownership of mitmproxy files
shell: chown -R mitmproxy /home/mitmproxy/mitmproxy

- name: Reuse bubble mitm certs if available
shell: reuse_bubble_mitm_certs.sh

@@ -79,14 +45,6 @@
group: mitmproxy
mode: 0500

- name: Fix missing symlink for libstdc++
file:
src: /usr/lib/x86_64-linux-gnu/libstdc++.so.6
dest: /usr/lib/x86_64-linux-gnu/libstdc++.so
owner: root
group: root
state: link

- name: Restart dnscrypt-proxy
shell: service dnscrypt-proxy restart

@@ -96,20 +54,5 @@
enabled: yes
state: restarted

- import_tasks: route.yml

- name: Install mitmdump_monitor
copy:
src: "mitmdump_monitor.sh"
dest: "/usr/local/sbin/mitmdump_monitor.sh"
owner: root
group: root
mode: 0500

- name: Install mitmdump_monitor supervisor conf file
copy:
src: supervisor_mitmdump_monitor.conf
dest: /etc/supervisor/conf.d/mitmdump_monitor.conf

- name: Ensure mitmdump_monitor is started
shell: supervisorctl restart mitmdump_monitor

+ 24
- 0
bubble-server/src/main/resources/packer/roles/algo/defaults/main.yml Visa fil

@@ -0,0 +1,24 @@
---
algo_dns_adblocking: false
apparmor_enabled: true
dns_encryption: true
ipv6_support: false
dnscrypt_servers:
ipv4:
- cloudflare
ipv6:
- cloudflare-ipv6

unattended_reboot:
enabled: false
time: 06:00

local_service_ip: 172.16.0.1
local_service_ipv6: fd00::1

ipsec_enabled: true

wireguard_enabled: true
wireguard_port: 51820
wireguard_port_avoid: 53
wireguard_port_actual: 51820

+ 4
- 0
bubble-server/src/main/resources/packer/roles/algo/files/50-dnscrypt-proxy-unattended-upgrades Visa fil

@@ -0,0 +1,4 @@
// Automatically upgrade packages from these (origin:archive) pairs
Unattended-Upgrade::Allowed-Origins {
"LP-PPA-shevchuk-dnscrypt-proxy:${distro_codename}";
};

+ 29
- 0
bubble-server/src/main/resources/packer/roles/algo/files/apparmor.profile.dnscrypt-proxy Visa fil

@@ -0,0 +1,29 @@
#include <tunables/global>

/usr/{s,}bin/dnscrypt-proxy flags=(attach_disconnected) {
#include <abstractions/base>
#include <abstractions/nameservice>
#include <abstractions/openssl>

capability chown,
capability dac_override,
capability net_bind_service,
capability setgid,
capability setuid,
capability sys_resource,

/etc/dnscrypt-proxy/** r,
/usr/bin/dnscrypt-proxy mr,
/tmp/public-resolvers.md* rw,

/tmp/*.tmp w,
owner /tmp/*.tmp r,

/run/systemd/notify rw,
/lib/x86_64-linux-gnu/ld-*.so mr,
@{PROC}/sys/kernel/hostname r,
@{PROC}/sys/net/core/somaxconn r,
/etc/ld.so.cache r,
/usr/local/lib/{@{multiarch}/,}libldns.so* mr,
/usr/local/lib/{@{multiarch}/,}libsodium.so* mr,
}

+ 2
- 28
bubble-server/src/main/resources/packer/roles/algo/tasks/algo_firewall.yml Visa fil

@@ -2,37 +2,11 @@
# Copyright (c) 2020 Bubble, Inc. All rights reserved. For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/
#
# Insert additional firewall rules to allow required services to function
- name: Allow HTTP
iptables:
chain: INPUT
action: insert
rule_num: 5
protocol: tcp
destination_port: 80
ctstate: NEW
syn: match
jump: ACCEPT
comment: Accept new HTTP connections
become: yes

- name: Allow HTTPS
iptables:
chain: INPUT
action: insert
rule_num: 6
protocol: tcp
destination_port: 443
ctstate: NEW
syn: match
jump: ACCEPT
comment: Accept new HTTPS connections
become: yes

- name: Allow admin HTTPS on port 1443
iptables:
chain: INPUT
action: insert
rule_num: 7
rule_num: 6
protocol: tcp
destination_port: 1443
ctstate: NEW
@@ -45,7 +19,7 @@
iptables:
chain: INPUT
action: insert
rule_num: 8
rule_num: 7
protocol: tcp
destination_port: 1080
ctstate: NEW


+ 249
- 0
bubble-server/src/main/resources/packer/roles/algo/tasks/algo_packer.yml Visa fil

@@ -0,0 +1,249 @@
# From algo/roles/common/tasks/unattended-upgrades.yml
- name: Install unattended-upgrades
apt:
name: [ 'git', 'apparmor-utils', 'uuid-runtime', 'coreutils', 'cgroup-tools', 'openssl', 'gnupg2', 'linux-headers-generic' ]
state: present
update_cache: yes

- name: Configure unattended-upgrades
template:
src: 50unattended-upgrades.j2
dest: /etc/apt/apt.conf.d/50unattended-upgrades
owner: root
group: root
mode: 0644

- name: Periodic upgrades configured
template:
src: 10periodic.j2
dest: /etc/apt/apt.conf.d/10periodic
owner: root
group: root
mode: 0644

# From algo/roles/common/tasks/ubuntu.yml
- name: Disable MOTD on login and SSHD
replace: dest="{{ item.file }}" regexp="{{ item.regexp }}" replace="{{ item.line }}"
with_items:
- { regexp: '^session.*optional.*pam_motd.so.*', line: '# MOTD DISABLED', file: '/etc/pam.d/login' }
- { regexp: '^session.*optional.*pam_motd.so.*', line: '# MOTD DISABLED', file: '/etc/pam.d/sshd' }

- name: Loopback for services configured
template:
src: 10-algo-lo100.network.j2
dest: /etc/systemd/network/10-algo-lo100.network
# notify:
# - restart systemd-networkd

- name: Install algo packages
apt:
name: [ 'git', 'apparmor-utils', 'uuid-runtime', 'coreutils', 'cgroup-tools', 'openssl', 'gnupg2', 'linux-headers-generic' ]
state: present
update_cache: yes

# From algo/roles/common/tasks/iptables.yml
- name: Iptables configured
template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: root
group: root
mode: 0640
with_items:
- { src: rules.v4.j2, dest: /etc/iptables/rules.v4 }
# notify:
# - restart iptables

- name: Iptables configured
template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: root
group: root
mode: 0640
when: ipv6_support
with_items:
- { src: rules.v6.j2, dest: /etc/iptables/rules.v6 }
# notify:
# - restart iptables

# From algo/roles/dns/tasks/dns_adblocking.yml
- name: Adblock script created
template:
src: adblock.sh.j2
dest: /usr/local/sbin/adblock.sh
owner: root
group: "{{ root_group|default('root') }}"
mode: 0755

- name: Adblock script added to cron
cron:
name: Adblock hosts update
minute: "{{ range(0, 60) | random }}"
hour: "{{ range(0, 24) | random }}"
job: /usr/local/sbin/adblock.sh
user: root

- name: Update adblock hosts
command: /usr/local/sbin/adblock.sh
changed_when: false

# From algo/roles/dns/tasks/ubuntu.yml
- name: Add the repository
apt_repository:
state: present
codename: "{{ ansible_distribution_release }}"
repo: ppa:shevchuk/dnscrypt-proxy
register: result
until: result is succeeded
retries: 10
delay: 3

- name: Install dnscrypt-proxy
apt:
name: dnscrypt-proxy
state: present
update_cache: true

- name: Install Bubble-enhanced dnscrypt-proxy
get_url:
url: https://github.com/getbubblenow/bubble-dist/raw/master/dnscrypt-proxy/dnscrypt-proxy
dest: /usr/bin/dnscrypt-proxy
checksum: sha256:c0c8db69e0ab1ce6b493c65cb848f1b6cca077a6091eaa8207d76d672e12fc18
owner: root
group: root
mode: 0500

- block:
- name: Ubuntu | Configure AppArmor policy for dnscrypt-proxy
copy:
src: apparmor.profile.dnscrypt-proxy
dest: /etc/apparmor.d/usr.bin.dnscrypt-proxy
owner: root
group: root
mode: 0600
# notify: restart dnscrypt-proxy

- name: Ubuntu | Enforce the dnscrypt-proxy AppArmor policy
command: aa-enforce usr.bin.dnscrypt-proxy
changed_when: false
tags: apparmor
when: apparmor_enabled|default(false)|bool

- name: Ubuntu | Ensure that the dnscrypt-proxy service directory exist
file:
path: /etc/systemd/system/dnscrypt-proxy.service.d/
state: directory
mode: 0755
owner: root
group: root

- name: Ubuntu | Add custom requirements to successfully start the unit
copy:
dest: /etc/systemd/system/dnscrypt-proxy.service.d/99-algo.conf
content: |
[Unit]
After=systemd-resolved.service
Requires=systemd-resolved.service

[Service]
AmbientCapabilities=CAP_NET_BIND_SERVICE
# notify:
# - restart dnscrypt-proxy

# From algo/roles/wireguard/tasks/main.yml
- name: Ensure the required directories exist
file:
dest: "{{ item }}"
state: directory
recurse: true
with_items:
- "{{ wireguard_pki_path }}/preshared"
- "{{ wireguard_pki_path }}/private"
- "{{ wireguard_pki_path }}/public"
- "{{ wireguard_config_path }}"
delegate_to: localhost
become: false

- name: WireGuard repository configured
apt_repository:
repo: ppa:wireguard/wireguard
state: present
register: result
until: result is succeeded
retries: 10
delay: 3

- name: WireGuard installed
apt:
name: wireguard
state: present
update_cache: true

# From algo/roles/strongswan/tasks/ubuntu.yml
- name: Set OS specific facts
set_fact:
strongswan_additional_plugins: []

- name: Ubuntu | Install strongSwan
apt:
name: strongswan
state: present
update_cache: yes
install_recommends: yes

- block:
# https://bugs.launchpad.net/ubuntu/+source/strongswan/+bug/1826238
- name: Ubuntu | Charon profile for apparmor configured
copy:
dest: /etc/apparmor.d/local/usr.lib.ipsec.charon
content: ' capability setpcap,'
owner: root
group: root
mode: 0644
# notify: restart strongswan

- name: Ubuntu | Enforcing ipsec with apparmor
command: aa-enforce "{{ item }}"
changed_when: false
with_items:
- /usr/lib/ipsec/charon
- /usr/lib/ipsec/lookip
- /usr/lib/ipsec/stroke
tags: apparmor
when: apparmor_enabled|default(false)|bool

- name: Ubuntu | Enable services
service: name={{ item }} enabled=yes
with_items:
- apparmor
- strongswan
- netfilter-persistent

- name: Ubuntu | Ensure that the strongswan service directory exists
file:
path: /etc/systemd/system/strongswan.service.d/
state: directory
mode: 0755
owner: root
group: root

- name: Ubuntu | Setup the cgroup limitations for the ipsec daemon
template:
src: 100-CustomLimitations.conf.j2
dest: /etc/systemd/system/strongswan.service.d/100-CustomLimitations.conf
# notify:
# - daemon-reload
# - restart strongswan

# From algo/roles/strongswan/tasks/main.yml
- name: Ensure that the strongswan user exists
user:
name: strongswan
group: nogroup
shell: "{{ strongswan_shell }}"
home: "{{ strongswan_home }}"
state: present

- name: Install strongSwan
package: name=strongswan state=present

+ 7
- 6
bubble-server/src/main/resources/packer/roles/algo/tasks/main.yml Visa fil

@@ -3,7 +3,7 @@
#
- name: Create algo staging directory
file:
path: /root/ansible-staging/roles/algo/algo
path: /root/ansible/roles/algo/algo
owner: root
group: root
mode: 0770
@@ -12,19 +12,19 @@
- name: Download algo dist file
get_url:
url: https://github.com/getbubblenow/bubble-dist/raw/master/algo/master.zip
dest: /root/ansible-staging/algo.zip
checksum: sha256:3d5f297d309af9b956525a2cbb40e0dca216fb735cc35befc3d5a5bdd54163a5
dest: /tmp/algo.zip
checksum: sha256:62070ada76f19ef81e0fb0563af43d76a8dbd77e528866421a445bc4364960cc

- name: Unzip algo master.zip
unarchive:
remote_src: yes
src: /root/ansible-staging/algo.zip
dest: /root/ansible-staging/roles/algo
src: /tmp/algo.zip
dest: /root/ansible/roles/algo

- name: Write algo config.cfg.hbs
copy:
src: config.cfg.hbs
dest: /root/ansible-staging/roles/algo/algo/config.cfg.hbs
dest: /root/ansible/roles/algo/algo/config.cfg.hbs

- name: Install algo_refresh_users script and monitor
copy:
@@ -55,4 +55,5 @@
src: supervisor_wg_monitor_connections.conf
dest: /etc/supervisor/conf.d/wg_monitor_connections.conf

- include: algo_packer.yml
- include: algo_firewall.yml

+ 7
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/10-algo-lo100.network.j2 Visa fil

@@ -0,0 +1,7 @@
[Match]
Name=lo

[Network]
Description=lo:100
Address={{ local_service_ip }}/32
Address={{ local_service_ipv6 }}/128

+ 2
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/100-CustomLimitations.conf.j2 Visa fil

@@ -0,0 +1,2 @@
[Service]
MemoryLimit=16777216

+ 4
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/10periodic.j2 Visa fil

@@ -0,0 +1,4 @@
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";

+ 96
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/50unattended-upgrades.j2 Visa fil

@@ -0,0 +1,96 @@
// Automatically upgrade packages from these (origin:archive) pairs
//
// Note that in Ubuntu security updates may pull in new dependencies
// from non-security sources (e.g. chromium). By allowing the release
// pocket these get automatically pulled in.
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
// Extended Security Maintenance; doesn't necessarily exist for
// every release and this system may not have it installed, but if
// available, the policy for updates is such that unattended-upgrades
// should also install from here by default.
"${distro_id}ESM:${distro_codename}";
"${distro_id}:${distro_codename}-updates";
// "${distro_id}:${distro_codename}-proposed";
// "${distro_id}:${distro_codename}-backports";
};

// List of packages to not update (regexp are supported)
Unattended-Upgrade::Package-Blacklist {
// "vim";
// "libc6";
// "libc6-dev";
// "libc6-i686";
};

// This option will controls whether the development release of Ubuntu will be
// upgraded automatically.
Unattended-Upgrade::DevRelease "false";

// This option allows you to control if on a unclean dpkg exit
// unattended-upgrades will automatically run
// dpkg --force-confold --configure -a
// The default is true, to ensure updates keep getting installed
Unattended-Upgrade::AutoFixInterruptedDpkg "true";

// Split the upgrade into the smallest possible chunks so that
// they can be interrupted with SIGTERM. This makes the upgrade
// a bit slower but it has the benefit that shutdown while a upgrade
// is running is possible (with a small delay)
Unattended-Upgrade::MinimalSteps "true";

// Install all unattended-upgrades when the machine is shutting down
// instead of doing it in the background while the machine is running
// This will (obviously) make shutdown slower
//Unattended-Upgrade::InstallOnShutdown "true";

// Send email to this address for problems or packages upgrades
// If empty or unset then no email is sent, make sure that you
// have a working mail setup on your system. A package that provides
// 'mailx' must be installed. E.g. "user@example.com"
//Unattended-Upgrade::Mail "root";

// Set this value to "true" to get emails only on errors. Default
// is to always send a mail if Unattended-Upgrade::Mail is set
//Unattended-Upgrade::MailOnlyOnError "true";

// Remove unused automatically installed kernel-related packages
// (kernel images, kernel headers and kernel version locked tools).
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";

// Do automatic removal of new unused dependencies after the upgrade
// (equivalent to apt-get autoremove)
Unattended-Upgrade::Remove-Unused-Dependencies "true";

// Automatically reboot *WITHOUT CONFIRMATION*
// if the file /var/run/reboot-required is found after the upgrade
Unattended-Upgrade::Automatic-Reboot "{{ unattended_reboot.enabled|lower }}";

// If automatic reboot is enabled and needed, reboot at the specific
// time instead of immediately
// Default: "now"
Unattended-Upgrade::Automatic-Reboot-Time "{{ unattended_reboot.time }}";

// Use apt bandwidth limit feature, this example limits the download
// speed to 70kb/sec
//Acquire::http::Dl-Limit "70";

// Enable logging to syslog. Default is False
Unattended-Upgrade::SyslogEnable "true";

// Specify syslog facility. Default is daemon
// Unattended-Upgrade::SyslogFacility "daemon";

// Download and install upgrades only on AC power
// (i.e. skip or gracefully stop updates on battery)
// Unattended-Upgrade::OnlyOnACPower "true";

// Download and install upgrades only on non-metered connection
// (i.e. skip or gracefully stop updates on a metered connection)
// Unattended-Upgrade::Skip-Updates-On-Metered-Connections "true";

// Keep the custom conffile when upgrading
Dpkg::Options {
"--force-confdef";
"--force-confold";
};

+ 45
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/adblock.sh.j2 Visa fil

@@ -0,0 +1,45 @@
#!/bin/sh
# Block ads, malware, etc..

TEMP="$(mktemp)"
TEMP_SORTED="$(mktemp)"
WHITELIST="/etc/dnscrypt-proxy/white.list"
BLACKLIST="/etc/dnscrypt-proxy/black.list"
BLOCKHOSTS="{{ config_prefix|default('/') }}etc/dnscrypt-proxy/blacklist.txt"
BLOCKLIST_URLS="{% for url in adblock_lists %}{{ url }} {% endfor %}"

#Delete the old block.hosts to make room for the updates
rm -f $BLOCKHOSTS

echo 'Downloading hosts lists...'
#Download and process the files needed to make the lists (enable/add more, if you want)
for url in $BLOCKLIST_URLS; do
wget --timeout=2 --tries=3 -qO- "$url" | grep -Ev "(localhost)" | grep -Ew "(0.0.0.0|127.0.0.1)" | awk '{sub(/\r$/,"");print $2}' >> "$TEMP"
done

#Add black list, if non-empty
if [ -s "$BLACKLIST" ]
then
echo 'Adding blacklist...'
cat $BLACKLIST >> "$TEMP"
fi

#Sort the download/black lists
awk '/^[^#]/ { print $1 }' "$TEMP" | sort -u > "$TEMP_SORTED"

#Filter (if applicable)
if [ -s "$WHITELIST" ]
then
#Filter the blacklist, suppressing whitelist matches
# This is relatively slow =-(
echo 'Filtering white list...'
grep -v -E "^[[:space:]]*$" $WHITELIST | awk '/^[^#]/ {sub(/\r$/,"");print $1}' | grep -vf - "$TEMP_SORTED" > $BLOCKHOSTS
else
cat "$TEMP_SORTED" > $BLOCKHOSTS
fi

echo 'Restarting dns service...'
#Restart the dns service
systemctl restart dnscrypt-proxy.service

exit 0

+ 365
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/charon.conf.j2 Visa fil

@@ -0,0 +1,365 @@
# Options for the charon IKE daemon.
charon {

# Accept unencrypted ID and HASH payloads in IKEv1 Main Mode.
# accept_unencrypted_mainmode_messages = no

# Maximum number of half-open IKE_SAs for a single peer IP.
# block_threshold = 5

# Whether Certificate Revocation Lists (CRLs) fetched via HTTP or LDAP
# should be saved under a unique file name derived from the public key of
# the Certification Authority (CA) to /etc/ipsec.d/crls (stroke) or
# /etc/swanctl/x509crl (vici), respectively.
# cache_crls = no

# Whether relations in validated certificate chains should be cached in
# memory.
# cert_cache = yes

# Send Cisco Unity vendor ID payload (IKEv1 only).
# cisco_unity = no

# Close the IKE_SA if setup of the CHILD_SA along with IKE_AUTH failed.
close_ike_on_child_failure = yes

# Number of half-open IKE_SAs that activate the cookie mechanism.
# cookie_threshold = 10

# Delete CHILD_SAs right after they got successfully rekeyed (IKEv1 only).
# delete_rekeyed = no

# Delay in seconds until inbound IPsec SAs are deleted after rekeyings
# (IKEv2 only).
# delete_rekeyed_delay = 5

# Use ANSI X9.42 DH exponent size or optimum size matched to cryptographic
# strength.
# dh_exponent_ansi_x9_42 = yes

# Use RTLD_NOW with dlopen when loading plugins and IMV/IMCs to reveal
# missing symbols immediately.
# dlopen_use_rtld_now = no

# DNS server assigned to peer via configuration payload (CP).
# dns1 =

# DNS server assigned to peer via configuration payload (CP).
# dns2 =

# Enable Denial of Service protection using cookies and aggressiveness
# checks.
# dos_protection = yes

# Compliance with the errata for RFC 4753.
# ecp_x_coordinate_only = yes

# Free objects during authentication (might conflict with plugins).
# flush_auth_cfg = no

# Whether to follow IKEv2 redirects (RFC 5685).
# follow_redirects = yes

# Maximum size (complete IP datagram size in bytes) of a sent IKE fragment
# when using proprietary IKEv1 or standardized IKEv2 fragmentation, defaults
# to 1280 (use 0 for address family specific default values, which uses a
# lower value for IPv4). If specified this limit is used for both IPv4 and
# IPv6.
# fragment_size = 1280

# Name of the group the daemon changes to after startup.
# group =

# Timeout in seconds for connecting IKE_SAs (also see IKE_SA_INIT DROPPING).
half_open_timeout = 5

# Enable hash and URL support.
# hash_and_url = no

# Allow IKEv1 Aggressive Mode with pre-shared keys as responder.
# i_dont_care_about_security_and_use_aggressive_mode_psk = no

# Whether to ignore the traffic selectors from the kernel's acquire events
# for IKEv2 connections (they are not used for IKEv1).
# ignore_acquire_ts = no

# A space-separated list of routing tables to be excluded from route
# lookups.
# ignore_routing_tables =

# Maximum number of IKE_SAs that can be established at the same time before
# new connection attempts are blocked.
# ikesa_limit = 0

# Number of exclusively locked segments in the hash table.
# ikesa_table_segments = 1

# Size of the IKE_SA hash table.
# ikesa_table_size = 1

# Whether to close IKE_SA if the only CHILD_SA closed due to inactivity.
inactivity_close_ike = yes

# Limit new connections based on the current number of half open IKE_SAs,
# see IKE_SA_INIT DROPPING in strongswan.conf(5).
# init_limit_half_open = 0

# Limit new connections based on the number of queued jobs.
# init_limit_job_load = 0

# Causes charon daemon to ignore IKE initiation requests.
# initiator_only = no

# Install routes into a separate routing table for established IPsec
# tunnels.
# install_routes = yes

# Install virtual IP addresses.
# install_virtual_ip = yes

# The name of the interface on which virtual IP addresses should be
# installed.
# install_virtual_ip_on =

# Check daemon, libstrongswan and plugin integrity at startup.
# integrity_test = no

# A comma-separated list of network interfaces that should be ignored, if
# interfaces_use is specified this option has no effect.
# interfaces_ignore =

# A comma-separated list of network interfaces that should be used by
# charon. All other interfaces are ignored.
# interfaces_use =

# NAT keep alive interval.
keep_alive = 25s

# Plugins to load in the IKE daemon charon.
# load =

# Determine plugins to load via each plugin's load option.
# load_modular = no

# Initiate IKEv2 reauthentication with a make-before-break scheme.
# make_before_break = no

# Maximum number of IKEv1 phase 2 exchanges per IKE_SA to keep state about
# and track concurrently.
# max_ikev1_exchanges = 3

# Maximum packet size accepted by charon.
# max_packet = 10000

# Enable multiple authentication exchanges (RFC 4739).
# multiple_authentication = yes

# WINS servers assigned to peer via configuration payload (CP).
# nbns1 =

# WINS servers assigned to peer via configuration payload (CP).
# nbns2 =

# UDP port used locally. If set to 0 a random port will be allocated.
# port = 500

# UDP port used locally in case of NAT-T. If set to 0 a random port will be
# allocated. Has to be different from charon.port, otherwise a random port
# will be allocated.
# port_nat_t = 4500

# Whether to prefer updating SAs to the path with the best route.
# prefer_best_path = no

# Prefer locally configured proposals for IKE/IPsec over supplied ones as
# responder (disabling this can avoid keying retries due to
# INVALID_KE_PAYLOAD notifies).
# prefer_configured_proposals = yes

# By default public IPv6 addresses are preferred over temporary ones (RFC
# 4941), to make connections more stable. Enable this option to reverse
# this.
# prefer_temporary_addrs = no

# Process RTM_NEWROUTE and RTM_DELROUTE events.
# process_route = yes

# Delay in ms for receiving packets, to simulate larger RTT.
# receive_delay = 0

# Delay request messages.
# receive_delay_request = yes

# Delay response messages.
# receive_delay_response = yes

# Specific IKEv2 message type to delay, 0 for any.
# receive_delay_type = 0

# Size of the AH/ESP replay window, in packets.
# replay_window = 32

# Base to use for calculating exponential back off, see IKEv2 RETRANSMISSION
# in strongswan.conf(5).
# retransmit_base = 1.8

# Maximum jitter in percent to apply randomly to calculated retransmission
# timeout (0 to disable).
# retransmit_jitter = 0

# Upper limit in seconds for calculated retransmission timeout (0 to
# disable).
# retransmit_limit = 0

# Timeout in seconds before sending first retransmit.
# retransmit_timeout = 4.0

# Number of times to retransmit a packet before giving up.
# retransmit_tries = 5

# Interval in seconds to use when retrying to initiate an IKE_SA (e.g. if
# DNS resolution failed), 0 to disable retries.
# retry_initiate_interval = 0

# Initiate CHILD_SA within existing IKE_SAs (always enabled for IKEv1).
reuse_ikesa = yes

# Numerical routing table to install routes to.
# routing_table =

# Priority of the routing table.
# routing_table_prio =

# Whether to use RSA with PSS padding instead of PKCS#1 padding by default.
# rsa_pss = no

# Delay in ms for sending packets, to simulate larger RTT.
# send_delay = 0

# Delay request messages.
# send_delay_request = yes

# Delay response messages.
# send_delay_response = yes

# Specific IKEv2 message type to delay, 0 for any.
# send_delay_type = 0

# Send strongSwan vendor ID payload
# send_vendor_id = no

# Whether to enable Signature Authentication as per RFC 7427.
# signature_authentication = yes

# Whether to enable constraints against IKEv2 signature schemes.
# signature_authentication_constraints = yes

# The upper limit for SPIs requested from the kernel for IPsec SAs.
# spi_max = 0xcfffffff

# The lower limit for SPIs requested from the kernel for IPsec SAs.
# spi_min = 0xc0000000

# Number of worker threads in charon.
# threads = 16

# Name of the user the daemon changes to after startup.
# user =

crypto_test {

# Benchmark crypto algorithms and order them by efficiency.
# bench = no

# Buffer size used for crypto benchmark.
# bench_size = 1024

# Number of iterations to test each algorithm.
# bench_time = 50

# Test crypto algorithms during registration (requires test vectors
# provided by the test-vectors plugin).
# on_add = no

# Test crypto algorithms on each crypto primitive instantiation.
# on_create = no

# Strictly require at least one test vector to enable an algorithm.
# required = no

# Whether to test RNG with TRUE quality; requires a lot of entropy.
# rng_true = no

}

host_resolver {

# Maximum number of concurrent resolver threads (they are terminated if
# unused).
# max_threads = 3

# Minimum number of resolver threads to keep around.
# min_threads = 0

}

leak_detective {

# Includes source file names and line numbers in leak detective output.
# detailed = yes

# Threshold in bytes for leaks to be reported (0 to report all).
# usage_threshold = 10240

# Threshold in number of allocations for leaks to be reported (0 to
# report all).
# usage_threshold_count = 0

}

processor {

# Section to configure the number of reserved threads per priority class
# see JOB PRIORITY MANAGEMENT in strongswan.conf(5).
priority_threads {

}

}

# Section containing a list of scripts (name = path) that are executed when
# the daemon is started.
start-scripts {

}

# Section containing a list of scripts (name = path) that are executed when
# the daemon is terminated.
stop-scripts {

}

tls {

# List of TLS encryption ciphers.
# cipher =

# List of TLS key exchange methods.
# key_exchange =

# List of TLS MAC algorithms.
# mac =

# List of TLS cipher suites.
# suites =

}

x509 {

# Discard certificates with unsupported or unknown critical extensions.
# enforce_critical = yes

}

}

+ 23
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/client_ipsec.conf.j2 Visa fil

@@ -0,0 +1,23 @@
conn algovpn-{{ IP_subject_alt_name }}
fragmentation=yes
rekey=no
dpdaction=clear
keyexchange=ikev2
compress=no
dpddelay=35s

ike={{ ciphers.defaults.ike }}
esp={{ ciphers.defaults.esp }}

right={{ IP_subject_alt_name }}
rightid={{ IP_subject_alt_name }}
rightsubnet={{ rightsubnet | default('0.0.0.0/0') }}
rightauth=pubkey

leftsourceip=%config
leftauth=pubkey
leftcert={{ item }}.crt
leftfirewall=yes
left=%defaultroute

auto=add

+ 1
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/client_ipsec.secrets.j2 Visa fil

@@ -0,0 +1 @@
{{ IP_subject_alt_name }} : ECDSA {{ item }}.key

+ 568
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/dnscrypt-proxy.toml.j2 Visa fil

@@ -0,0 +1,568 @@

##############################################
# #
# dnscrypt-proxy configuration #
# #
##############################################

## This is an example configuration file.
## You should adjust it to your needs, and save it as "dnscrypt-proxy.toml"
##
## Online documentation is available here: https://dnscrypt.info/doc



##################################
# Global settings #
##################################

## List of servers to use
##
## Servers from the "public-resolvers" source (see down below) can
## be viewed here: https://dnscrypt.info/public-servers
##
## If this line is commented, all registered servers matching the require_* filters
## will be used.
##
## The proxy will automatically pick the fastest, working servers from the list.
## Remove the leading # first to enable this; lines starting with # are ignored.

{# Allow either list to be empty. Output nothing if both are empty. #}
{% set servers = [] %}
{% if dnscrypt_servers.ipv4 %}{% set servers = dnscrypt_servers.ipv4 %}{% endif %}
{% if ipv6_support and dnscrypt_servers.ipv6 %}{% set servers = servers + dnscrypt_servers.ipv6 %}{% endif %}
{% if servers %}server_names = ['{{ servers | join("', '") }}']{% endif %}


## List of local addresses and ports to listen to. Can be IPv4 and/or IPv6.
## Note: When using systemd socket activation, choose an empty set (i.e. [] ).

listen_addresses = [
'{{ local_service_ip }}:53'{% if ipv6_support %},
'[{{ local_service_ipv6 }}]:53'{% endif %}
]


## Maximum number of simultaneous client connections to accept

max_clients = 250


## Switch to a different system user after listening sockets have been created.
## Note (1): this feature is currently unsupported on Windows.
## Note (2): this feature is not compatible with systemd socket activation.
## Note (3): when using -pidfile, the PID file directory must be writable by the new user

# user_name = 'nobody'


## Require servers (from static + remote sources) to satisfy specific properties

# Use servers reachable over IPv4
ipv4_servers = true

# Use servers reachable over IPv6 -- Do not enable if you don't have IPv6 connectivity
ipv6_servers = {{ ipv6_support | bool | lower }}

# Use servers implementing the DNSCrypt protocol
dnscrypt_servers = true

# Use servers implementing the DNS-over-HTTPS protocol
doh_servers = true


## Require servers defined by remote sources to satisfy specific properties

# Server must support DNS security extensions (DNSSEC)
require_dnssec = true

# Server must not log user queries (declarative)
require_nolog = true

# Server must not enforce its own blacklist (for parental control, ads blocking...)
require_nofilter = true

# Server names to avoid even if they match all criteria
disabled_server_names = []


## Always use TCP to connect to upstream servers.
## This can be useful if you need to route everything through Tor.
## Otherwise, leave this to `false`, as it doesn't improve security
## (dnscrypt-proxy will always encrypt everything even using UDP), and can
## only increase latency.

force_tcp = false


## SOCKS proxy
## Uncomment the following line to route all TCP connections to a local Tor node
## Tor doesn't support UDP, so set `force_tcp` to `true` as well.

# proxy = "socks5://127.0.0.1:9050"


## HTTP/HTTPS proxy
## Only for DoH servers

# http_proxy = "http://127.0.0.1:8888"


## How long a DNS query will wait for a response, in milliseconds

timeout = 2500


## Keepalive for HTTP (HTTPS, HTTP/2) queries, in seconds

keepalive = 30


## Use the REFUSED return code for blocked responses
## Setting this to `false` means that some responses will be lies.
## Unfortunately, `false` appears to be required for Android 8+

refused_code_in_responses = false


## Load-balancing strategy: 'p2' (default), 'ph', 'first' or 'random'

lb_strategy = 'p2'

## Set to `true` to constantly try to estimate the latency of all the resolvers
## and adjust the load-balancing parameters accordingly, or to `false` to disable.

# lb_estimator = true


## Log level (0-6, default: 2 - 0 is very verbose, 6 only contains fatal errors)

log_level = 2


## log file for the application

# log_file = 'dnscrypt-proxy.log'


## Use the system logger (syslog on Unix, Event Log on Windows)

use_syslog = true


## Delay, in minutes, after which certificates are reloaded

cert_refresh_delay = 240


## DNSCrypt: Create a new, unique key for every single DNS query
## This may improve privacy but can also have a significant impact on CPU usage
## Only enable if you don't have a lot of network load

dnscrypt_ephemeral_keys = true


## DoH: Disable TLS session tickets - increases privacy but also latency

tls_disable_session_tickets = true


## DoH: Use a specific cipher suite instead of the server preference
## 49199 = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
## 49195 = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
## 52392 = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
## 52393 = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
## 4865 = TLS_AES_128_GCM_SHA256
## 4867 = TLS_CHACHA20_POLY1305_SHA256
##
## On non-Intel CPUs such as MIPS routers and ARM systems (Android, Raspberry Pi...),
## the following suite improves performance.
## This may also help on Intel CPUs running 32-bit operating systems.
##
## Keep tls_cipher_suite empty if you have issues fetching sources or
## connecting to some DoH servers. Google and Cloudflare are fine with it.

# tls_cipher_suite = [52392, 49199]


## Fallback resolver
## This is a normal, non-encrypted DNS resolver, that will be only used
## for one-shot queries when retrieving the initial resolvers list, and
## only if the system DNS configuration doesn't work.
## No user application queries will ever be leaked through this resolver,
## and it will not be used after IP addresses of resolvers URLs have been found.
## It will never be used if lists have already been cached, and if stamps
## don't include host names without IP addresses.
## It will not be used if the configured system DNS works.
## A resolver supporting DNSSEC is recommended. This may become mandatory.
##
## People in China may need to use 114.114.114.114:53 here.
## Other popular options include 8.8.8.8 and 1.1.1.1.

fallback_resolver = '{% if ansible_distribution == "FreeBSD" %}{{ ansible_dns.nameservers.0 }}:53{% else %}127.0.0.53:53{% endif %}'


## Never let dnscrypt-proxy try to use the system DNS settings;
## unconditionally use the fallback resolver.

ignore_system_dns = true


## Maximum time (in seconds) to wait for network connectivity before
## initializing the proxy.
## Useful if the proxy is automatically started at boot, and network
## connectivity is not guaranteed to be immediately available.
## Use 0 to not test for connectivity at all (not recommended),
## and -1 to wait as much as possible.

netprobe_timeout = 60

## Address and port to try initializing a connection to, just to check
## if the network is up. It can be any address and any port, even if
## there is nothing answering these on the other side. Just don't use
## a local address, as the goal is to check for Internet connectivity.
## On Windows, a datagram with a single, nul byte will be sent, only
## when the system starts.
## On other operating systems, the connection will be initialized
## but nothing will be sent at all.

netprobe_address = "1.1.1.1:53"


## Offline mode - Do not use any remote encrypted servers.
## The proxy will remain fully functional to respond to queries that
## plugins can handle directly (forwarding, cloaking, ...)

# offline_mode = false


## Automatic log files rotation

# Maximum log files size in MB
log_files_max_size = 10

# How long to keep backup files, in days
log_files_max_age = 7

# Maximum log files backups to keep (or 0 to keep all backups)
log_files_max_backups = 1



#########################
# Filters #
#########################

## Immediately respond to IPv6-related queries with an empty response
## This makes things faster when there is no IPv6 connectivity, but can
## also cause reliability issues with some stub resolvers.
## Do not enable if you added a validating resolver such as dnsmasq in front
## of the proxy.

block_ipv6 = false



##################################################################################
# Route queries for specific domains to a dedicated set of servers #
##################################################################################

## Example map entries (one entry per line):
## example.com 9.9.9.9
## example.net 9.9.9.9,8.8.8.8,1.1.1.1

# forwarding_rules = 'forwarding-rules.txt'



###############################
# Cloaking rules #
###############################

## Cloaking returns a predefined address for a specific name.
## In addition to acting as a HOSTS file, it can also return the IP address
## of a different name. It will also do CNAME flattening.
##
## Example map entries (one entry per line)
## example.com 10.1.1.1
## www.google.com forcesafesearch.google.com

# cloaking_rules = 'cloaking-rules.txt'



###########################
# DNS cache #
###########################

## Enable a DNS cache to reduce latency and outgoing traffic

cache = true


## Cache size

cache_size = 512


## Minimum TTL for cached entries

cache_min_ttl = 600


## Maximum TTL for cached entries

cache_max_ttl = 86400


## Minimum TTL for negatively cached entries

cache_neg_min_ttl = 60


## Maximum TTL for negatively cached entries

cache_neg_max_ttl = 600


###############################
# Bubble resolver cache #
###############################

## Cache name->IP resolutions in redis. This allows cert-pinned sites and apps to function properly.
## When mitmproxy is performing SSL interception, it will check the name of the IP in redis
## If the name is on the "TLS Passthu" whitelist, then SSL interception will not be performed

[reverse_resolve_cache]

## Redis configuration for cache

prefix = 'bubble_dns_'


###############################
# Query logging #
###############################

## Log client queries to a file

[query_log]

## Path to the query log file (absolute, or relative to the same directory as the executable file)

# file = 'query.log'


## Query log format (currently supported: tsv and ltsv)

format = 'tsv'


## Do not log these query types, to reduce verbosity. Keep empty to log everything.

# ignored_qtypes = ['DNSKEY', 'NS']



############################################
# Suspicious queries logging #
############################################

## Log queries for nonexistent zones
## These queries can reveal the presence of malware, broken/obsolete applications,
## and devices signaling their presence to 3rd parties.

[nx_log]

## Path to the query log file (absolute, or relative to the same directory as the executable file)

# file = 'nx.log'


## Query log format (currently supported: tsv and ltsv)

format = 'tsv'



######################################################
# Pattern-based blocking (blacklists) #
######################################################

## Blacklists are made of one pattern per line. Example of valid patterns:
##
## example.com
## =example.com
## *sex*
## ads.*
## ads*.example.*
## ads*.example[0-9]*.com
##
## Example blacklist files can be found at https://download.dnscrypt.info/blacklists/
## A script to build blacklists from public feeds can be found in the
## `utils/generate-domains-blacklists` directory of the dnscrypt-proxy source code.

[blacklist]

## Path to the file of blocking rules (absolute, or relative to the same directory as the executable file)

{{ "blacklist_file = 'blacklist.txt'" if algo_dns_adblocking else "" }}


## Optional path to a file logging blocked queries

# log_file = 'blocked.log'


## Optional log format: tsv or ltsv (default: tsv)

# log_format = 'tsv'



###########################################################
# Pattern-based IP blocking (IP blacklists) #
###########################################################

## IP blacklists are made of one pattern per line. Example of valid patterns:
##
## 127.*
## fe80:abcd:*
## 192.168.1.4

[ip_blacklist]

## Path to the file of blocking rules (absolute, or relative to the same directory as the executable file)

blacklist_file = 'ip-blacklist.txt'


## Optional path to a file logging blocked queries

# log_file = 'ip-blocked.log'


## Optional log format: tsv or ltsv (default: tsv)

# log_format = 'tsv'



######################################################
# Pattern-based whitelisting (blacklists bypass) #
######################################################

## Whitelists support the same patterns as blacklists
## If a name matches a whitelist entry, the corresponding session
## will bypass names and IP filters.
##
## Time-based rules are also supported to make some websites only accessible at specific times of the day.

[whitelist]

## Path to the file of whitelisting rules (absolute, or relative to the same directory as the executable file)

# whitelist_file = 'whitelist.txt'


## Optional path to a file logging whitelisted queries

# log_file = 'whitelisted.log'


## Optional log format: tsv or ltsv (default: tsv)

# log_format = 'tsv'



##########################################
# Time access restrictions #
##########################################

## One or more weekly schedules can be defined here.
## Patterns in the name-based blocklist can optionally be followed with @schedule_name
## to apply the pattern 'schedule_name' only when it matches a time range of that schedule.
##
## For example, the following rule in a blacklist file:
## *.youtube.* @time-to-sleep
## would block access to YouTube only during the days, and period of the days
## define by the 'time-to-sleep' schedule.
##
## {after='21:00', before= '7:00'} matches 0:00-7:00 and 21:00-0:00
## {after= '9:00', before='18:00'} matches 9:00-18:00

[schedules]

# [schedules.'time-to-sleep']
# mon = [{after='21:00', before='7:00'}]
# tue = [{after='21:00', before='7:00'}]
# wed = [{after='21:00', before='7:00'}]
# thu = [{after='21:00', before='7:00'}]
# fri = [{after='23:00', before='7:00'}]
# sat = [{after='23:00', before='7:00'}]
# sun = [{after='21:00', before='7:00'}]

# [schedules.'work']
# mon = [{after='9:00', before='18:00'}]
# tue = [{after='9:00', before='18:00'}]
# wed = [{after='9:00', before='18:00'}]
# thu = [{after='9:00', before='18:00'}]
# fri = [{after='9:00', before='17:00'}]



#########################
# Servers #
#########################

## Remote lists of available servers
## Multiple sources can be used simultaneously, but every source
## requires a dedicated cache file.
##
## Refer to the documentation for URLs of public sources.
##
## A prefix can be prepended to server names in order to
## avoid collisions if different sources share the same for
## different servers. In that case, names listed in `server_names`
## must include the prefixes.
##
## If the `urls` property is missing, cache files and valid signatures
## must be already present; This doesn't prevent these cache files from
## expiring after `refresh_delay` hours.

[sources]

## An example of a remote source from https://github.com/DNSCrypt/dnscrypt-resolvers

[sources.'public-resolvers']
urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v2/public-resolvers.md', 'https://download.dnscrypt.info/resolvers-list/v2/public-resolvers.md']
cache_file = '/tmp/public-resolvers.md'
minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
prefix = ''

## Quad9 over DNSCrypt - https://quad9.net/

# [sources.quad9-resolvers]
# urls = ["https://www.quad9.net/quad9-resolvers.md"]
# minisign_key = "RWQBphd2+f6eiAqBsvDZEBXBGHQBJfeG6G+wJPPKxCZMoEQYpmoysKUN"
# cache_file = "quad9-resolvers.md"
# prefix = "quad9-"

## Another example source, with resolvers censoring some websites not appropriate for children
## This is a subset of the `public-resolvers` list, so enabling both is useless

# [sources.'parental-control']
# urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v2/parental-control.md', 'https://download.dnscrypt.info/resolvers-list/v2/parental-control.md']
# cache_file = 'parental-control.md'
# minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'



## Optional, local, static list of additional servers
## Mostly useful for testing your own servers.

[static]

# [static.'myserver']
# stamp = 'sdns:AQcAAAAAAAAAAAAQMi5kbnNjcnlwdC1jZXJ0Lg'

+ 44
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/ip-blacklist.txt.j2 Visa fil

@@ -0,0 +1,44 @@
0.0.0.0
10.*
127.*
169.254.*
172.16.*
172.17.*
172.18.*
172.19.*
172.20.*
172.21.*
172.22.*
172.23.*
172.24.*
172.25.*
172.26.*
172.27.*
172.28.*
172.29.*
172.30.*
172.31.*
192.168.*
::ffff:0.0.0.0
::ffff:10.*
::ffff:127.*
::ffff:169.254.*
::ffff:172.16.*
::ffff:172.17.*
::ffff:172.18.*
::ffff:172.19.*
::ffff:172.20.*
::ffff:172.21.*
::ffff:172.22.*
::ffff:172.23.*
::ffff:172.24.*
::ffff:172.25.*
::ffff:172.26.*
::ffff:172.27.*
::ffff:172.28.*
::ffff:172.29.*
::ffff:172.30.*
::ffff:172.31.*
::ffff:192.168.*
fd00::*
fe80::*

+ 35
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/ipsec.conf.j2 Visa fil

@@ -0,0 +1,35 @@
config setup
uniqueids=never # allow multiple connections per user
charondebug="ike {{ strongswan_log_level }}, knl {{ strongswan_log_level }}, cfg {{ strongswan_log_level }}, net {{ strongswan_log_level }}, esp {{ strongswan_log_level }}, dmn {{ strongswan_log_level }}, mgr {{ strongswan_log_level }}"

conn %default
fragmentation=yes
rekey=no
dpdaction=clear
keyexchange=ikev2
compress=yes
dpddelay=35s
lifetime=3h
ikelifetime=12h

ike={{ ciphers.defaults.ike }}
esp={{ ciphers.defaults.esp }}

left=%any
leftauth=pubkey
leftid={{ IP_subject_alt_name }}
leftcert={{ IP_subject_alt_name }}.crt
leftsendcert=always
leftsubnet=0.0.0.0/0,::/0

right=%any
rightauth=pubkey
rightsourceip={{ strongswan_network }},{{ strongswan_network_ipv6 }}
{% if algo_dns_adblocking or dns_encryption %}
rightdns={{ local_service_ip }}{{ ',' + local_service_ipv6 if ipv6_support else '' }}
{% else %}
rightdns={% for host in dns_servers.ipv4 %}{{ host }}{% if not loop.last %},{% endif %}{% endfor %}{% if ipv6_support %},{% for host in dns_servers.ipv6 %}{{ host }}{% if not loop.last %},{% endif %}{% endfor %}{% endif %}
{% endif %}

conn ikev2-pubkey
auto=add

+ 1
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/ipsec.secrets.j2 Visa fil

@@ -0,0 +1 @@
: ECDSA {{ IP_subject_alt_name }}.key

+ 197
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/mobileconfig.j2 Visa fil

@@ -0,0 +1,197 @@
#jinja2:lstrip_blocks: True
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>IKEv2</key>
<dict>
<key>OnDemandEnabled</key>
<integer>{{ 1 if algo_ondemand_wifi or algo_ondemand_cellular else 0 }}</integer>
<key>OnDemandRules</key>
<array>
{% if algo_ondemand_wifi or algo_ondemand_cellular %}
{% if algo_ondemand_wifi_exclude|b64decode != '_null' %}
{% set WIFI_EXCLUDE_LIST = (algo_ondemand_wifi_exclude|b64decode|string).split(',') %}
<dict>
<key>Action</key>
<string>Disconnect</string>
<key>InterfaceTypeMatch</key>
<string>WiFi</string>
<key>SSIDMatch</key>
<array>
{% for network_name in WIFI_EXCLUDE_LIST %}
<string>{{ network_name|e }}</string>
{% endfor %}
</array>
</dict>
{% endif %}
<dict>
<key>Action</key>
{% if algo_ondemand_wifi %}
<string>Connect</string>
{% else %}
<string>Disconnect</string>
{% endif %}
<key>InterfaceTypeMatch</key>
<string>WiFi</string>
<key>URLStringProbe</key>
<string>http://captive.apple.com/hotspot-detect.html</string>
</dict>
<dict>
<key>Action</key>
{% if algo_ondemand_cellular %}
<string>Connect</string>
{% else %}
<string>Disconnect</string>
{% endif %}
<key>InterfaceTypeMatch</key>
<string>Cellular</string>
<key>URLStringProbe</key>
<string>http://captive.apple.com/hotspot-detect.html</string>
</dict>
{% endif %}
<dict>
<key>Action</key>
<string>{{ 'Disconnect' if algo_ondemand_wifi or algo_ondemand_cellular else 'Connect' }}</string>
</dict>
</array>
<key>AuthenticationMethod</key>
<string>Certificate</string>
<key>ChildSecurityAssociationParameters</key>
<dict>
<key>DiffieHellmanGroup</key>
<integer>20</integer>
<key>EncryptionAlgorithm</key>
<string>AES-256-GCM</string>
<key>IntegrityAlgorithm</key>
<string>SHA2-512</string>
<key>LifeTimeInMinutes</key>
<integer>1440</integer>
</dict>
<key>DeadPeerDetectionRate</key>
<string>Medium</string>
<key>DisableMOBIKE</key>
<integer>0</integer>
<key>DisableRedirect</key>
<integer>1</integer>
<key>EnableCertificateRevocationCheck</key>
<integer>0</integer>
<key>EnablePFS</key>
<true/>
<key>IKESecurityAssociationParameters</key>
<dict>
<key>DiffieHellmanGroup</key>
<integer>20</integer>
<key>EncryptionAlgorithm</key>
<string>AES-256-GCM</string>
<key>IntegrityAlgorithm</key>
<string>SHA2-512</string>
<key>LifeTimeInMinutes</key>
<integer>1440</integer>
</dict>
<key>LocalIdentifier</key>
<string>{{ item.0 }}</string>
<key>PayloadCertificateUUID</key>
<string>{{ pkcs12_PayloadCertificateUUID }}</string>
<key>CertificateType</key>
<string>ECDSA384</string>
<key>ServerCertificateIssuerCommonName</key>
<string>{{ IP_subject_alt_name }}</string>
<key>RemoteAddress</key>
<string>{{ IP_subject_alt_name }}</string>
<key>RemoteIdentifier</key>
<string>{{ IP_subject_alt_name }}</string>
<key>UseConfigurationAttributeInternalIPSubnet</key>
<integer>0</integer>
</dict>
<key>IPv4</key>
<dict>
<key>OverridePrimary</key>
<integer>1</integer>
</dict>
<key>PayloadDescription</key>
<string>Configures VPN settings</string>
<key>PayloadDisplayName</key>
<string>{{ algo_server_name }}</string>
<key>PayloadIdentifier</key>
<string>com.apple.vpn.managed.{{ VPN_PayloadIdentifier }}</string>
<key>PayloadType</key>
<string>com.apple.vpn.managed</string>
<key>PayloadUUID</key>
<string>{{ VPN_PayloadIdentifier }}</string>
<key>PayloadVersion</key>
<real>1</real>
<key>Proxies</key>
<dict>
<key>HTTPEnable</key>
<integer>0</integer>
<key>HTTPSEnable</key>
<integer>0</integer>
</dict>
<key>UserDefinedName</key>
<string>AlgoVPN {{ algo_server_name }} IKEv2</string>
<key>VPNType</key>
<string>IKEv2</string>
</dict>
<dict>
<key>Password</key>
<string>{{ p12_export_password }}</string>
<key>PayloadCertificateFileName</key>
<string>{{ item.0 }}.p12</string>
<key>PayloadContent</key>
<data>
{{ item.1.stdout }}
</data>
<key>PayloadDescription</key>
<string>Adds a PKCS#12-formatted certificate</string>
<key>PayloadDisplayName</key>
<string>{{ algo_server_name }}</string>
<key>PayloadIdentifier</key>
<string>com.apple.security.pkcs12.{{ pkcs12_PayloadCertificateUUID }}</string>
<key>PayloadType</key>
<string>com.apple.security.pkcs12</string>
<key>PayloadUUID</key>
<string>{{ pkcs12_PayloadCertificateUUID }}</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
<dict>
<key>PayloadCertificateFileName</key>
<string>ca.crt</string>
<key>PayloadContent</key>
<data>
{{ PayloadContentCA }}
</data>
<key>PayloadDescription</key>
<string>Adds a CA root certificate</string>
<key>PayloadDisplayName</key>
<string>{{ algo_server_name }}</string>
<key>PayloadIdentifier</key>
<string>com.apple.security.root.{{ CA_PayloadIdentifier }}</string>
<key>PayloadType</key>
<string>com.apple.security.root</string>
<key>PayloadUUID</key>
<string>{{ CA_PayloadIdentifier }}</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</array>
<key>PayloadDisplayName</key>
<string>AlgoVPN {{ algo_server_name }} IKEv2</string>
<key>PayloadIdentifier</key>
<string>donut.local.{{ 500000 | random | to_uuid | upper }}</string>
<key>PayloadOrganization</key>
<string>AlgoVPN</string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>{{ 400000 | random | to_uuid | upper }}</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

+ 139
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/openssl.cnf.j2 Visa fil

@@ -0,0 +1,139 @@
# For use with Easy-RSA 3.0 and OpenSSL 1.0.*

RANDFILE = .rnd

####################################################################
[ ca ]
default_ca = CA_default # The default ca section

####################################################################
[ CA_default ]

dir = . # Where everything is kept
certs = $dir # Where the issued certs are kept
crl_dir = $dir # Where the issued crl are kept
database = $dir/index.txt # database index file.
new_certs_dir = $dir/certs # default place for new certs.

certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem # The private key
RANDFILE = $dir/private/.rand # private random number file

x509_extensions = basic_exts # The extentions to add to the cert

# This allows a V2 CRL. Ancient browsers don't like it, but anything Easy-RSA
# is designed for will. In return, we get the Issuer attached to CRLs.
crl_extensions = crl_ext

default_days = 3650 # how long to certify for
default_crl_days= 3650 # how long before next CRL
default_md = sha256 # use public key default MD
preserve = no # keep passed DN ordering

# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_anything

# For the 'anything' policy, which defines allowed DN fields
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
name = optional
emailAddress = optional

####################################################################
# Easy-RSA request handling
# We key off $DN_MODE to determine how to format the DN
[ req ]
default_bits = 2048
default_keyfile = privkey.pem
default_md = sha256
distinguished_name = cn_only
x509_extensions = easyrsa_ca # The extentions to add to the self signed cert

# A placeholder to handle the $EXTRA_EXTS feature:
#%EXTRA_EXTS% # Do NOT remove or change this line as $EXTRA_EXTS support requires it

####################################################################
# Easy-RSA DN (Subject) handling

# Easy-RSA DN for cn_only support:
[ cn_only ]
commonName = Common Name (eg: your user, host, or server name)
commonName_max = 64
commonName_default = {{ IP_subject_alt_name }}

# Easy-RSA DN for org support:
[ org ]
countryName = Country Name (2 letter code)
countryName_default = US
countryName_min = 2
countryName_max = 2

stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = California

localityName = Locality Name (eg, city)
localityName_default = San Francisco

0.organizationName = Organization Name (eg, company)
0.organizationName_default = Copyleft Certificate Co

organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = My Organizational Unit

commonName = Common Name (eg: your user, host, or server name)
commonName_max = 64
commonName_default = {{ IP_subject_alt_name }}

emailAddress = Email Address
emailAddress_default = me@example.net
emailAddress_max = 64

####################################################################
# Easy-RSA cert extension handling

# This section is effectively unused as the main script sets extensions
# dynamically. This core section is left to support the odd usecase where
# a user calls openssl directly.
[ basic_exts ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always

extendedKeyUsage = serverAuth,clientAuth,1.3.6.1.5.5.7.3.17
keyUsage = digitalSignature, keyEncipherment

# The Easy-RSA CA extensions
[ easyrsa_ca ]

# PKIX recommendations:

subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always

# This could be marked critical, but it's nice to support reading by any
# broken clients who attempt to do so.
basicConstraints = CA:true

# Limit key usage to CA tasks. If you really want to use the generated pair as
# a self-signed cert, comment this out.
keyUsage = cRLSign, keyCertSign

# nsCertType omitted by default. Let's try to let the deprecated stuff die.
# nsCertType = sslCA

# CRL extensions.
[ crl_ext ]

# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.

# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always,issuer:always

+ 111
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/rules.v4.j2 Visa fil

@@ -0,0 +1,111 @@
{% set subnets = ([strongswan_network] if ipsec_enabled else []) + ([wireguard_network_ipv4] if wireguard_enabled else []) %}
{% set ports = (['500', '4500'] if ipsec_enabled else []) + ([wireguard_port] if wireguard_enabled else []) + ([wireguard_port_actual] if wireguard_enabled and wireguard_port|int == wireguard_port_avoid|int else []) %}

#### The mangle table
# This table allows us to modify packet headers
# Packets enter this table first
#
*mangle

:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

{% if reduce_mtu|int > 0 and ipsec_enabled %}
-A FORWARD -s {{ strongswan_network }} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss {{ 1360 - reduce_mtu|int }}
{% endif %}

COMMIT


#### The nat table
# This table enables Network Address Translation
# (This is technically a type of packet mangling)
#
*nat

:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

{% if wireguard_enabled and wireguard_port|int == wireguard_port_avoid|int %}
# Handle the special case of allowing access to WireGuard over an already used
# port like 53
-A PREROUTING --in-interface {{ ansible_default_ipv4['interface'] }} -p udp --dport {{ wireguard_port_avoid }} -j REDIRECT --to-port {{ wireguard_port_actual }}
{% endif %}
# Allow traffic from the VPN network to the outside world, and replies
-A POSTROUTING -s {{ subnets|join(',') }} -m policy --pol none --dir out -j MASQUERADE


COMMIT


#### The filter table
# The default ipfilter table
#
*filter

# By default, drop packets that are destined for this server
:INPUT DROP [0:0]
# By default, drop packets that request to be forwarded by this server
:FORWARD DROP [0:0]
# By default, accept any packets originating from this server
:OUTPUT ACCEPT [0:0]

# Accept packets destined for localhost
-A INPUT -i lo -j ACCEPT
# Accept any packet from an open TCP connection
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# Accept packets using the encapsulation protocol
-A INPUT -p esp -j ACCEPT
-A INPUT -p ah -j ACCEPT
# rate limit ICMP traffic per source
-A INPUT -p icmp --icmp-type echo-request -m hashlimit --hashlimit-upto 5/s --hashlimit-mode srcip --hashlimit-srcmask 32 --hashlimit-name icmp-echo-drop -j ACCEPT
# Accept IPSEC/WireGuard traffic to ports {{ subnets|join(',') }}
-A INPUT -p udp -m multiport --dports {{ ports|join(',') }} -j ACCEPT
# Allow new traffic to port 22 (SSH)
-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT

{% if ipsec_enabled %}
# Allow any traffic from the IPsec VPN
-A INPUT -p ipencap -m policy --dir in --pol ipsec --proto esp -j ACCEPT
{% endif %}

# TODO:
# The IP of the resolver should be bound to a DUMMY interface.
# DUMMY interfaces are the proper way to install IPs without assigning them any
# particular virtual (tun,tap,...) or physical (ethernet) interface.

# Accept DNS traffic to the local DNS resolver
-A INPUT -d {{ local_service_ip }} -p udp --dport 53 -j ACCEPT

# Drop traffic between VPN clients
-A FORWARD -s {{ subnets|join(',') }} -d {{ subnets|join(',') }} -j {{ "DROP" if BetweenClients_DROP else "ACCEPT" }}
# Drop traffic to VPN clients from SSH tunnels
-A OUTPUT -d {{ subnets|join(',') }} -m owner --gid-owner 15000 -j {{ "DROP" if BetweenClients_DROP else "ACCEPT" }}

# Drop traffic to the link-local network
-A FORWARD -s {{ subnets|join(',') }} -d 169.254.0.0/16 -j DROP
# Drop traffic to the link-local network from SSH tunnels
-A OUTPUT -d 169.254.0.0/16 -m owner --gid-owner 15000 -j DROP

# Forward any packet that's part of an established connection
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# Drop SMB/CIFS traffic that requests to be forwarded
-A FORWARD -p tcp --dport 445 -j {{ "DROP" if block_smb else "ACCEPT" }}
# Drop NETBIOS trafic that requests to be forwarded
-A FORWARD -p udp -m multiport --ports 137,138 -j {{ "DROP" if block_netbios else "ACCEPT" }}
-A FORWARD -p tcp -m multiport --ports 137,139 -j {{ "DROP" if block_netbios else "ACCEPT" }}

{% if ipsec_enabled %}
# Forward any IPSEC traffic from the VPN network
-A FORWARD -m conntrack --ctstate NEW -s {{ strongswan_network }} -m policy --pol ipsec --dir in -j ACCEPT
{% endif %}

{% if wireguard_enabled %}
# Forward any traffic from the WireGuard VPN network
-A FORWARD -m conntrack --ctstate NEW -s {{ wireguard_network_ipv4 }} -m policy --pol none --dir in -j ACCEPT
{% endif %}

COMMIT

+ 119
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/rules.v6.j2 Visa fil

@@ -0,0 +1,119 @@
{% set subnets = ([strongswan_network_ipv6] if ipsec_enabled else []) + ([wireguard_network_ipv6] if wireguard_enabled else []) %}
{% set ports = (['500', '4500'] if ipsec_enabled else []) + ([wireguard_port] if wireguard_enabled else []) + ([wireguard_port_actual] if wireguard_enabled and wireguard_port|int == wireguard_port_avoid|int else []) %}

#### The mangle table
# This table allows us to modify packet headers
# Packets enter this table first
#
*mangle

:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

{% if reduce_mtu|int > 0 and ipsec_enabled %}
-A FORWARD -s {{ strongswan_network_ipv6 }} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss {{ 1340 - reduce_mtu|int }}
{% endif %}

COMMIT

#### The nat table
# This table enables Network Address Translation
# (This is technically a type of packet mangling)
#
*nat

:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

{% if wireguard_enabled and wireguard_port|int == wireguard_port_avoid|int %}
# Handle the special case of allowing access to WireGuard over an already used
# port like 53
-A PREROUTING --in-interface {{ ansible_default_ipv6['interface'] }} -p udp --dport {{ wireguard_port_avoid }} -j REDIRECT --to-port {{ wireguard_port_actual }}
{% endif %}
# Allow traffic from the VPN network to the outside world, and replies
-A POSTROUTING -s {{ subnets|join(',') }} -m policy --pol none --dir out -j MASQUERADE

COMMIT

#### The filter table
# The default ipfilter table
#
*filter

# By default, drop packets that are destined for this server
:INPUT DROP [0:0]
# By default, drop packets that request to be forwarded by this server
:FORWARD DROP [0:0]
# By default, accept any packets originating from this server
:OUTPUT ACCEPT [0:0]

# Create the ICMPV6-CHECK chain and its log chain
# These chains are used later to prevent a type of bug that would
# allow malicious traffic to reach over the server into the private network
# An instance of such a bug on Cisco software is described here:
# https://www.insinuator.net/2016/05/cve-2016-1409-ipv6-ndp-dos-vulnerability-in-cisco-software/
# other software implementations might be at least as broken as the one in CISCO gear.
:ICMPV6-CHECK - [0:0]
:ICMPV6-CHECK-LOG - [0:0]

# Accept packets destined for localhost
-A INPUT -i lo -j ACCEPT
# Accept any packet from an open TCP connection
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# Accept packets using the encapsulation protocol
-A INPUT -p esp -j ACCEPT
-A INPUT -m ah -j ACCEPT
# rate limit ICMP traffic per source
-A INPUT -p icmpv6 --icmpv6-type echo-request -m hashlimit --hashlimit-upto 5/s --hashlimit-mode srcip --hashlimit-srcmask 32 --hashlimit-name icmp-echo-drop -j ACCEPT
# Accept IPSEC/WireGuard traffic to ports {{ subnets|join(',') }}
-A INPUT -p udp -m multiport --dports {{ ports|join(',') }} -j ACCEPT
# Allow new traffic to port 22 (SSH)
-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT

# Accept properly formatted Neighbor Discovery Protocol packets
-A INPUT -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT
-A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j ACCEPT
-A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j ACCEPT
-A INPUT -p icmpv6 --icmpv6-type redirect -m hl --hl-eq 255 -j ACCEPT

# DHCP in AWS
-A INPUT -m conntrack --ctstate NEW -m udp -p udp --dport 546 -d fe80::/64 -j ACCEPT

# TODO:
# The IP of the resolver should be bound to a DUMMY interface.
# DUMMY interfaces are the proper way to install IPs without assigning them any
# particular virtual (tun,tap,...) or physical (ethernet) interface.

# Accept DNS traffic to the local DNS resolver
-A INPUT -d {{ local_service_ipv6 }}/128 -p udp --dport 53 -j ACCEPT

# Drop traffic between VPN clients
-A FORWARD -s {{ subnets|join(',') }} -d {{ subnets|join(',') }} -j {{ "DROP" if BetweenClients_DROP else "ACCEPT" }}
# Drop traffic to VPN clients from SSH tunnels
-A OUTPUT -d {{ subnets|join(',') }} -m owner --gid-owner 15000 -j {{ "DROP" if BetweenClients_DROP else "ACCEPT" }}

-A FORWARD -j ICMPV6-CHECK
-A FORWARD -p tcp --dport 445 -j {{ "DROP" if block_smb else "ACCEPT" }}
-A FORWARD -p udp -m multiport --ports 137,138 -j {{ "DROP" if block_netbios else "ACCEPT" }}
-A FORWARD -p tcp -m multiport --ports 137,139 -j {{ "DROP" if block_netbios else "ACCEPT" }}

-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
{% if ipsec_enabled %}
-A FORWARD -m conntrack --ctstate NEW -s {{ strongswan_network_ipv6 }} -m policy --pol ipsec --dir in -j ACCEPT
{% endif %}
{% if wireguard_enabled %}
-A FORWARD -m conntrack --ctstate NEW -s {{ wireguard_network_ipv6 }} -m policy --pol none --dir in -j ACCEPT
{% endif %}

# Use the ICMPV6-CHECK chain, described above
-A ICMPV6-CHECK -p icmpv6 -m hl ! --hl-eq 255 --icmpv6-type router-solicitation -j ICMPV6-CHECK-LOG
-A ICMPV6-CHECK -p icmpv6 -m hl ! --hl-eq 255 --icmpv6-type router-advertisement -j ICMPV6-CHECK-LOG
-A ICMPV6-CHECK -p icmpv6 -m hl ! --hl-eq 255 --icmpv6-type neighbor-solicitation -j ICMPV6-CHECK-LOG
-A ICMPV6-CHECK -p icmpv6 -m hl ! --hl-eq 255 --icmpv6-type neighbor-advertisement -j ICMPV6-CHECK-LOG
-A ICMPV6-CHECK-LOG -j LOG --log-prefix "ICMPV6-CHECK-LOG DROP "
-A ICMPV6-CHECK-LOG -j DROP

COMMIT

+ 28
- 0
bubble-server/src/main/resources/packer/roles/algo/templates/strongswan.conf.j2 Visa fil

@@ -0,0 +1,28 @@
# strongswan.conf - strongSwan configuration file
#
# Refer to the strongswan.conf(5) manpage for details
#
# Configuration changes should be made in the included files

charon {
load_modular = yes
plugins {
include strongswan.d/charon/*.conf
}
user = strongswan
group = nogroup
{% if ansible_distribution == 'FreeBSD' %}
filelog {
charon {
path = /var/log/charon.log
time_format = %b %e %T
ike_name = yes
append = no
default = 1
flush_line = yes
}
}
{% endif %}
}

include strongswan.d/*.conf

+ 1
- 2
bubble-server/src/main/resources/packer/roles/firewall/tasks/main.yml Visa fil

@@ -99,8 +99,7 @@
dest: /etc/supervisor/conf.d/bubble_peer_manager.conf
when: fw_enable_admin

- include: sage.yml
when: install_type == 'sage'
- include: rules.yml

- name: Creates /etc/iptables directory
file:


bubble-server/src/main/resources/packer/roles/firewall/tasks/sage.yml → bubble-server/src/main/resources/packer/roles/firewall/tasks/rules.yml Visa fil


+ 2
- 5
bubble-server/src/main/resources/packer/roles/mitmproxy/tasks/main.yml Visa fil

@@ -34,13 +34,13 @@
- name: Download mitmproxy dist file
get_url:
url: https://github.com/getbubblenow/bubble-dist/raw/master/mitmproxy/mitmproxy.zip
dest: /root/ansible-staging/mitmproxy.zip
dest: /tmp/mitmproxy.zip
checksum: sha256:c578ca9da75777a30f7af065583e5e29e65336a2dc346d6453dfa9c002a8bcc2

- name: Unzip mitmproxy.zip
unarchive:
remote_src: yes
src: /root/ansible-staging/mitmproxy.zip
src: /tmp/mitmproxy.zip
dest: /home/mitmproxy/mitmproxy

- name: Copy mitmdump files
@@ -72,9 +72,6 @@
- name: Set ownership of mitmproxy files
shell: chown -R mitmproxy /home/mitmproxy/mitmproxy

- name: Reuse bubble mitm certs if available
shell: reuse_bubble_mitm_certs.sh

- name: Fix missing symlink for libstdc++
file:
src: /usr/lib/x86_64-linux-gnu/libstdc++.so.6


+ 1
- 1
bubble-server/src/main/resources/packer/roles/mitmproxy/tasks/route.yml Visa fil

@@ -18,7 +18,7 @@
iptables:
chain: INPUT
action: insert
rule_num: 9
rule_num: 7
protocol: tcp
destination_port: 8888
ctstate: NEW


Laddar…
Avbryt
Spara