initial commit
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
[defaults]
|
||||
inventory = inventory/
|
||||
roles_path = roles/
|
||||
host_key_checking = False
|
||||
forks = 8
|
||||
|
||||
[inventory]
|
||||
enable_plugins = community.proxmox.proxmox, host_list, yaml, ini
|
||||
cache = True
|
||||
@@ -0,0 +1,3 @@
|
||||
nft_managed_group: all
|
||||
dnsmasq_managed_group: all
|
||||
xray_managed_group: all
|
||||
@@ -0,0 +1,73 @@
|
||||
xray_ip_sets:
|
||||
refilter:
|
||||
urls:
|
||||
- https://raw.githubusercontent.com/1andrevich/Re-filter-lists/refs/heads/main/community_ips.lst
|
||||
- https://raw.githubusercontent.com/1andrevich/Re-filter-lists/refs/heads/main/discord_ips.lst
|
||||
- https://raw.githubusercontent.com/1andrevich/Re-filter-lists/refs/heads/main/ipsum.lst
|
||||
|
||||
cdn:
|
||||
urls:
|
||||
- https://raw.githubusercontent.com/123jjck/cdn-ip-ranges/refs/heads/main/all/all_plain_ipv4.txt
|
||||
|
||||
telegram:
|
||||
urls:
|
||||
- https://raw.githubusercontent.com/fernvenue/telegram-cidr-list/refs/heads/master/CIDRv4.txt
|
||||
|
||||
russian_whitelist:
|
||||
urls:
|
||||
- https://raw.githubusercontent.com/hxehex/russia-mobile-internet-whitelist/refs/heads/main/cidrwhitelist.txt
|
||||
- https://raw.githubusercontent.com/ebrasha/cidr-ip-ranges-by-country/refs/heads/master/CIDR/RU-ipv4-Hackers.Zone.txt
|
||||
|
||||
cloudflare:
|
||||
static:
|
||||
- 1.1.1.1
|
||||
- 1.0.0.1
|
||||
|
||||
google:
|
||||
urls:
|
||||
- https://raw.githubusercontent.com/lord-alfred/ipranges/main/google/ipv4.txt
|
||||
|
||||
xray_domain_sets:
|
||||
v2ray:
|
||||
urls:
|
||||
- https://raw.githubusercontent.com/v2ray/domain-list-community/refs/heads/master/data/spotify
|
||||
- https://raw.githubusercontent.com/v2ray/domain-list-community/refs/heads/master/data/microsoft
|
||||
- https://raw.githubusercontent.com/v2ray/domain-list-community/refs/heads/master/data/openai
|
||||
|
||||
torrent:
|
||||
static:
|
||||
- bt.t-ru.org
|
||||
- bt2.t-ru.org
|
||||
- bt3.t-ru.org
|
||||
- bt4.t-ru.org
|
||||
- rutracker.org
|
||||
- rutracker.net
|
||||
- tapochek.net
|
||||
- nnmclub.to
|
||||
- rutor.info
|
||||
- bigfangroup.org
|
||||
|
||||
vps:
|
||||
static:
|
||||
- dev.oyacoi.ru
|
||||
- vector.oyacoi.ru
|
||||
|
||||
terraform:
|
||||
static:
|
||||
- terraform.io
|
||||
- hashicorp.com
|
||||
|
||||
xray_static_sets:
|
||||
- private
|
||||
|
||||
xray_lists_global:
|
||||
cache_dir: /var/lib/xray-lists/cache
|
||||
output_dir: /var/lib/xray-lists/generated
|
||||
dnsmasq_output: /var/lib/xray-lists/generated/nftsets.conf
|
||||
proxy: "socks5h://127.0.0.1:1080"
|
||||
proxy_user: "{{ lookup('env', 'SOCKS5_USERNAME') }}"
|
||||
proxy_pass: "{{ lookup('env', 'SOCKS5_PASSWORD') }}"
|
||||
http_timeout: 20
|
||||
|
||||
xray_tproxy_port: 61219
|
||||
xray_fwmark: "0x00000001"
|
||||
@@ -0,0 +1,5 @@
|
||||
ansible_connection: community.proxmox.proxmox_pct_remote
|
||||
ansible_host: 10.1.0.4
|
||||
ansible_user: root
|
||||
ansible_ssh_private_key_file: "~/.ssh/id_ed25519"
|
||||
ansible_python_interpreter: /usr/bin/python3
|
||||
@@ -0,0 +1,4 @@
|
||||
nft_to:
|
||||
- to: [workuter,oyacoi-odcm]
|
||||
proto: tcp
|
||||
port: 5000
|
||||
@@ -0,0 +1,3 @@
|
||||
dnsmasq:
|
||||
- name: asf.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,3 @@
|
||||
dnsmasq:
|
||||
- name: bananawrt.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,3 @@
|
||||
dnsmasq:
|
||||
- name: bylampa.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,4 @@
|
||||
nft_from:
|
||||
- iface: [eth1,eth0.2]
|
||||
to: camera0
|
||||
proto: [tcp,udp]
|
||||
@@ -0,0 +1,12 @@
|
||||
nft_dst:
|
||||
- iface: [eth0,eth0.2]
|
||||
proto: [tcp,udp]
|
||||
port: [3478,5349]
|
||||
|
||||
nft_from:
|
||||
- iface: [eth0,eth0.2,eth0.3,eth0.4,wg0]
|
||||
proto: [tcp,udp]
|
||||
port: [3478,5349]
|
||||
- iface: [eth0,eth0.2,eth0.3,eth0.4,wg0]
|
||||
proto: udp
|
||||
port: ["49152-65535"]
|
||||
@@ -0,0 +1,3 @@
|
||||
dnsmasq:
|
||||
- name: proxmox.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,8 @@
|
||||
nft_from:
|
||||
- iface: wg0
|
||||
proto: tcp
|
||||
port: 22
|
||||
|
||||
dnsmasq:
|
||||
- name: gitea.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,4 @@
|
||||
nft_to:
|
||||
- to: nginx
|
||||
proto: tcp
|
||||
port: [80, 81, 443, 444, 24445]
|
||||
@@ -0,0 +1,3 @@
|
||||
dnsmasq:
|
||||
- name: jellyfin.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,13 @@
|
||||
nft_dst:
|
||||
- iface: [eth0,eth0.2]
|
||||
proto: tcp
|
||||
port: 25565
|
||||
|
||||
nft_from:
|
||||
- iface: [eth0,wg0]
|
||||
proto: tcp
|
||||
port: 25565
|
||||
|
||||
dnsmasq:
|
||||
- name: mcsmanager.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,7 @@
|
||||
nft_to:
|
||||
- to: workuter
|
||||
proto: [tcp, udp]
|
||||
port: 32765
|
||||
- to: oyacoi-odcm
|
||||
proto: [tcp, udp]
|
||||
port: 32765
|
||||
@@ -0,0 +1,42 @@
|
||||
nft_to:
|
||||
- to: vaultwarden
|
||||
proto: tcp
|
||||
port: 8000
|
||||
- to: gitea
|
||||
proto: tcp
|
||||
port: 3000
|
||||
- to: radicale
|
||||
proto: tcp
|
||||
port: 5232
|
||||
- to: slskd
|
||||
proto: tcp
|
||||
port: 5030
|
||||
- to: asf
|
||||
proto: tcp
|
||||
port: 1337
|
||||
- to: rtorrent
|
||||
proto: tcp
|
||||
port: 80
|
||||
- to: jellyfin
|
||||
proto: tcp
|
||||
port: 8096
|
||||
- to: prosody
|
||||
proto: tcp
|
||||
port: 5280
|
||||
- to: torrserver
|
||||
proto: tcp
|
||||
port: 8090
|
||||
- to: prowlarr
|
||||
proto: tcp
|
||||
port: 9696
|
||||
- to: prowlarr #jackett
|
||||
proto: tcp
|
||||
port: 9117
|
||||
- to: bylampa
|
||||
proto: tcp
|
||||
port: 80
|
||||
|
||||
nft_from:
|
||||
- iface: [eth0,eth0.2]
|
||||
proto: tcp
|
||||
port: [80,443,24444]
|
||||
@@ -0,0 +1,3 @@
|
||||
dnsmasq:
|
||||
- name: ntfy.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,15 @@
|
||||
nft_to:
|
||||
- to: nfs
|
||||
proto: [tcp, udp]
|
||||
port: [2049, 111, 32765, 32767]
|
||||
- to: [zone:eth0.10,zone:eth0.11,zone:eth0.12]
|
||||
proto: tcp
|
||||
port: 22
|
||||
- to: [xiawrt,rbpi4]
|
||||
proto: tcp
|
||||
port: 22
|
||||
|
||||
xray_policy:
|
||||
- bypass: private
|
||||
- bypass: russian_whitelist
|
||||
- proxy: all
|
||||
@@ -0,0 +1,20 @@
|
||||
nft_dst:
|
||||
- iface: [eth0,eth0.2]
|
||||
proto: tcp
|
||||
port: [5000,5222,5223,5280,5270,5269]
|
||||
|
||||
nft_to:
|
||||
- to: pgsql
|
||||
proto: tcp
|
||||
port: 5432
|
||||
|
||||
nft_from:
|
||||
- iface: [eth0,eth0.2,wg0]
|
||||
proto: tcp
|
||||
port: [5000,5222,5223,5269,5270,5280]
|
||||
|
||||
dnsmasq:
|
||||
- name: talk.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
- name: upload.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,5 @@
|
||||
dnsmasq:
|
||||
- name: prowlarr.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
- name: jackett.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,8 @@
|
||||
nft_to:
|
||||
- to: ps3netsrv
|
||||
proto: tcp
|
||||
port: 38008
|
||||
|
||||
dnsmasq:
|
||||
- name: ps3.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,3 @@
|
||||
dnsmasq:
|
||||
- name: radicale.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,3 @@
|
||||
dnsmasq:
|
||||
- name: rustdesk.dttx.ru
|
||||
ip: 176.119.157.97
|
||||
@@ -0,0 +1,6 @@
|
||||
ansible_host: 10.1.0.1
|
||||
ansible_connection: ssh
|
||||
ansible_user: root
|
||||
ansible_ssh_private_key_file: ~/.ssh/id_ed25519
|
||||
zone_iface: eth0
|
||||
container_ip: 10.1.0.1
|
||||
@@ -0,0 +1,13 @@
|
||||
nft_dst:
|
||||
- iface: eth1
|
||||
proto: tcp
|
||||
port: ["6890-6899"]
|
||||
|
||||
nft_from:
|
||||
- iface: eth1
|
||||
proto: tcp
|
||||
port: ["6890-6899"]
|
||||
|
||||
dnsmasq:
|
||||
- name: rutorrent.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,4 @@
|
||||
nft_to:
|
||||
- to: firebat
|
||||
proto: tcp
|
||||
port: [22, 8006]
|
||||
@@ -0,0 +1,13 @@
|
||||
nft_dst:
|
||||
- iface: eth1
|
||||
proto: tcp
|
||||
port: 50300
|
||||
|
||||
nft_from:
|
||||
- iface: eth1
|
||||
proto: tcp
|
||||
port: 50300
|
||||
|
||||
dnsmasq:
|
||||
- name: slskd.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,9 @@
|
||||
nft_dst:
|
||||
- iface: eth0
|
||||
proto: udp
|
||||
port: 2456
|
||||
|
||||
nft_from:
|
||||
- iface: [eth0,wg0]
|
||||
proto: udp
|
||||
port: [2456,2457]
|
||||
@@ -0,0 +1,18 @@
|
||||
nft_dst:
|
||||
- iface: eth1
|
||||
proto: [tcp, udp]
|
||||
port: 6990
|
||||
|
||||
nft_to:
|
||||
- to: flaresolverr
|
||||
proto: tcp
|
||||
port: 8191
|
||||
|
||||
nft_from:
|
||||
- iface: eth1
|
||||
proto: [tcp,udp]
|
||||
port: 6990
|
||||
|
||||
dnsmasq:
|
||||
- name: torrserver.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,8 @@
|
||||
nft_to:
|
||||
- to: pgsql
|
||||
proto: tcp
|
||||
port: 5432
|
||||
|
||||
dnsmasq:
|
||||
- name: vaultwarden.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,10 @@
|
||||
nft_to:
|
||||
- to: nfs
|
||||
proto: [tcp, udp]
|
||||
port: [2049, 111, 32765, 32767]
|
||||
- to: [zone:eth0.10,zone:eth0.11,zone:eth0.12]
|
||||
proto: tcp
|
||||
port: 22
|
||||
- to: [xiawrt,rbpi4]
|
||||
proto: tcp
|
||||
port: 22
|
||||
@@ -0,0 +1,8 @@
|
||||
nft_to:
|
||||
- to: zabbix
|
||||
proto: tcp
|
||||
port: 10051
|
||||
|
||||
dnsmasq:
|
||||
- name: xiawrt.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,11 @@
|
||||
nft_to:
|
||||
- to: "zone:eth0.11"
|
||||
proto: tcp
|
||||
port: 10050
|
||||
- to: xiawrt
|
||||
proto: tcp
|
||||
port: 10050
|
||||
|
||||
dnsmasq:
|
||||
- name: zabbix.oyacoi.ru
|
||||
ip: 10.10.0.2
|
||||
@@ -0,0 +1,13 @@
|
||||
plugin: community.proxmox.proxmox
|
||||
url: https://10.1.0.4:8006
|
||||
user: root@pam
|
||||
password: "{{ lookup('env', 'PROXMOX_PASSWORD') }}"
|
||||
validate_certs: false
|
||||
want_facts: true
|
||||
|
||||
filter_by_types:
|
||||
- lxc
|
||||
|
||||
compose:
|
||||
zone_iface: "'eth0.' ~ proxmox_net0.tag"
|
||||
container_ip: "proxmox_net0.ip | default('') | regex_replace('/.*', '')"
|
||||
@@ -0,0 +1,82 @@
|
||||
all:
|
||||
children:
|
||||
static:
|
||||
hosts:
|
||||
workuter:
|
||||
container_ip: "10.1.0.2"
|
||||
zone_iface: "eth0"
|
||||
|
||||
oyacoi-odcm:
|
||||
container_ip: "10.1.0.3"
|
||||
zone_iface: "eth0"
|
||||
|
||||
firebat:
|
||||
container_ip: "10.1.0.4"
|
||||
zone_iface: "eth0"
|
||||
ansible_host: 10.1.0.4
|
||||
ansible_user: root
|
||||
ansible_ssh_private_key_file: "~/.ssh/id_ed25519"
|
||||
|
||||
ps2:
|
||||
container_ip: "10.1.0.5"
|
||||
zone_iface: "eth0"
|
||||
|
||||
ps3:
|
||||
container_ip: "10.1.0.6"
|
||||
zone_iface: "eth0"
|
||||
|
||||
tanix:
|
||||
container_ip: "10.1.0.8"
|
||||
zone_iface: "eth0"
|
||||
|
||||
bananawrt:
|
||||
container_ip: "10.1.0.100"
|
||||
zone_iface: "eth0"
|
||||
|
||||
ps4:
|
||||
container_ip: "10.2.0.2"
|
||||
zone_iface: "eth0.2"
|
||||
|
||||
note13:
|
||||
container_ip: "10.2.0.3"
|
||||
zone_iface: "eth0.2"
|
||||
|
||||
iphone11:
|
||||
container_ip: "10.2.0.4"
|
||||
zone_iface: "eth0.2"
|
||||
|
||||
huawei-tablet:
|
||||
container_ip: "10.2.0.5"
|
||||
zone_iface: "eth0.2"
|
||||
|
||||
uni:
|
||||
container_ip: "10.2.0.6"
|
||||
zone_iface: "eth0.2"
|
||||
|
||||
papperwhite:
|
||||
container_ip: "10.2.0.7"
|
||||
zone_iface: "eth0.2"
|
||||
|
||||
psp:
|
||||
container_ip: "10.2.0.8"
|
||||
zone_iface: "eth0.2"
|
||||
|
||||
dsi:
|
||||
container_ip: "10.2.0.9"
|
||||
zone_iface: "eth0.2"
|
||||
|
||||
3ds:
|
||||
container_ip: "10.2.0.10"
|
||||
zone_iface: "eth0.2"
|
||||
|
||||
camera0:
|
||||
container_ip: "10.3.0.5"
|
||||
zone_iface: "eth0.3"
|
||||
|
||||
xiawrt:
|
||||
container_ip: "10.250.250.1"
|
||||
zone_iface: "wg0"
|
||||
|
||||
rbpi4:
|
||||
container_ip: "10.250.250.5"
|
||||
zone_iface: "wg0"
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
- hosts: router
|
||||
become: true
|
||||
roles:
|
||||
- dnsmasq
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- hosts: router
|
||||
become: true
|
||||
roles:
|
||||
- xray-lists
|
||||
- dnsmasq
|
||||
- nftables
|
||||
|
||||
tasks:
|
||||
- name: enable update timer
|
||||
systemd:
|
||||
name: xray-lists.timer
|
||||
enabled: yes
|
||||
state: started
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- hosts: router
|
||||
become: yes
|
||||
roles:
|
||||
- router
|
||||
- xray-lists
|
||||
- dnsmasq
|
||||
- nftables
|
||||
|
||||
tasks:
|
||||
- name: enable update timer
|
||||
systemd:
|
||||
name: xray-lists.timer
|
||||
enabled: yes
|
||||
state: started
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
- hosts: router
|
||||
become: true
|
||||
roles:
|
||||
- xray-lists
|
||||
@@ -0,0 +1,2 @@
|
||||
collections:
|
||||
- name: community.proxmox
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: restart dnsmasq
|
||||
ansible.builtin.service:
|
||||
name: dnsmasq
|
||||
state: restarted
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
- name: ensure /etc/dnsmasq.d exists
|
||||
ansible.builtin.file:
|
||||
path: /etc/dnsmasq.d
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: render local
|
||||
ansible.builtin.template:
|
||||
src: 90-local.conf.j2
|
||||
dest: /etc/dnsmasq.d/90-local.conf
|
||||
mode: "0644"
|
||||
notify: restart dnsmasq
|
||||
|
||||
- name: render domain
|
||||
ansible.builtin.template:
|
||||
src: 90-domains.conf.j2
|
||||
dest: /etc/dnsmasq.d/90-domains.conf
|
||||
mode: "0644"
|
||||
notify: restart dnsmasq
|
||||
@@ -0,0 +1,15 @@
|
||||
#jinja2: trim_blocks: True, lstrip_blocks: True
|
||||
{% for item in groups[dnsmasq_managed_group] | sort %}
|
||||
{% set client = hostvars[item] %}
|
||||
{% if 'dnsmasq' in client and client.dnsmasq %}
|
||||
{% set default_ip = client.container_ip | default(client.ansible_host | default(none)) %}
|
||||
{% set domains = client.dnsmasq if (client.dnsmasq is iterable and client.dnsmasq is not string) else [client.dnsmasq] %}
|
||||
{% for d in domains %}
|
||||
{% set entry = d if (d is mapping) else {'name': d} %}
|
||||
{% set ip = entry.ip | default(default_ip) %}
|
||||
{% if ip %}
|
||||
host-record={{ entry.name }},{{ ip }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
@@ -0,0 +1,8 @@
|
||||
#jinja2: trim_blocks: True, lstrip_blocks: True
|
||||
{% for item in groups[dnsmasq_managed_group] | sort %}
|
||||
{% set client = hostvars[item] %}
|
||||
{% set ip = client.container_ip | default(client.ansible_host | default(none)) %}
|
||||
{% if ip %}
|
||||
host-record={{ item }},{{ item }}.lan,{{ ip }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
@@ -0,0 +1,49 @@
|
||||
flowtable ft {
|
||||
hook ingress priority filter
|
||||
devices = { eth0, eth1 }
|
||||
}
|
||||
|
||||
chain input {
|
||||
type filter hook input priority filter; policy drop;
|
||||
|
||||
ct state established,related accept
|
||||
ct state invalid drop
|
||||
|
||||
iif lo accept
|
||||
ip protocol icmp accept
|
||||
ip6 nexthdr icmpv6 accept
|
||||
|
||||
meta mark 0x00000001 accept
|
||||
|
||||
iifname eth0 tcp dport 22 accept
|
||||
iifname eth0.11 tcp dport 22 accept
|
||||
|
||||
iifname eth1 udp dport 51820 accept
|
||||
iifname { eth0, eth0.2, eth0.3, eth0.4, eth0.10, eth0.11, eth0.12 } udp dport 53 accept
|
||||
iifname { eth0, eth0.2, eth0.3, eth0.4, eth0.10, eth0.11, eth0.12 } tcp dport 53 accept
|
||||
|
||||
iifname eth0.3 udp dport 67 accept
|
||||
iifname eth1 udp dport 68 accept
|
||||
|
||||
#include "/etc/nftables.d/90-input.nft"
|
||||
}
|
||||
|
||||
chain forward {
|
||||
type filter hook forward priority filter; policy drop;
|
||||
|
||||
ct state established,related accept
|
||||
ct state invalid drop
|
||||
|
||||
iifname { eth0, eth0.2, eth0.3, eth0.4, eth0.10, eth0.11, eth0.12 } oifname eth1 ct state new flow add @ft
|
||||
iifname { eth0, eth0.2, eth0.3, eth0.4, eth0.10, eth0.11, eth0.12 } oifname eth1 accept
|
||||
|
||||
tcp flags syn tcp option maxseg size set rt mtu
|
||||
|
||||
include "/etc/nftables.d/90-forward.nft"
|
||||
}
|
||||
|
||||
chain output {
|
||||
type route hook output priority filter; policy accept;
|
||||
|
||||
#include "/etc/nftables.d/90-output.nft"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
chain postrouting {
|
||||
type nat hook postrouting priority srcnat; policy accept;
|
||||
oifname eth1 masquerade
|
||||
}
|
||||
|
||||
chain prerouting {
|
||||
type nat hook prerouting priority dstnat; policy accept;
|
||||
include "/etc/nftables.d/90-dstnat.nft"
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
chain vpn_prerouting_dnat {
|
||||
type nat hook prerouting priority dstnat - 5; policy accept;
|
||||
|
||||
iifname wg0 ip daddr 10.250.251.0/24 counter dnat ip prefix to 10.1.0.0/24
|
||||
iifname wg0 ip daddr 10.250.252.0/24 counter dnat ip prefix to 10.2.0.0/24
|
||||
iifname wg0 ip daddr 10.250.253.0/24 counter dnat ip prefix to 10.10.0.0/24
|
||||
iifname wg0 ip daddr 10.250.254.0/24 counter dnat ip prefix to 10.11.0.0/24
|
||||
iifname wg0 ip daddr 10.250.255.0/24 counter dnat ip prefix to 10.12.0.0/24
|
||||
iifname wg0 ip daddr 10.250.249.0/24 counter dnat ip prefix to 10.13.0.0/24
|
||||
}
|
||||
|
||||
chain vpn_postrouting_snat {
|
||||
type nat hook postrouting priority srcnat; policy accept;
|
||||
|
||||
oifname wg0 ip saddr 10.1.0.0/24 counter snat ip prefix to 10.250.251.0/24
|
||||
oifname wg0 ip saddr 10.2.0.0/24 counter snat ip prefix to 10.250.252.0/24
|
||||
oifname wg0 ip saddr 10.10.0.0/24 counter snat ip prefix to 10.250.253.0/24
|
||||
oifname wg0 ip saddr 10.11.0.0/24 counter snat ip prefix to 10.250.254.0/24
|
||||
oifname wg0 ip saddr 10.12.0.0/24 counter snat ip prefix to 10.250.255.0/24
|
||||
oifname wg0 ip saddr 10.13.0.0/24 counter snat ip prefix to 10.250.249.0/24
|
||||
}
|
||||
|
||||
chain vpn_prerouting_pbr {
|
||||
type filter hook prerouting priority mangle - 10; policy accept;
|
||||
|
||||
iifname wg0 ct state new counter ct mark set 0x000000c7
|
||||
ip daddr 10.0.0.0/8 return
|
||||
iifname != "wg0" ct mark 0x000000c7 counter mark set 0x000000c7
|
||||
}
|
||||
|
||||
chain vpn_output_pbr {
|
||||
type route hook output priority mangle - 10; policy accept;
|
||||
|
||||
ct mark 0x000000c7 counter meta mark set 0x000000c7
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
chain proxy_prerouting {
|
||||
type filter hook prerouting priority filter - 50; policy accept;
|
||||
|
||||
fib daddr type local accept
|
||||
|
||||
include "/etc/nftables.d/90-proxy.nft"
|
||||
}
|
||||
|
||||
chain proxy_output {
|
||||
type route hook output priority mangle; policy accept;
|
||||
|
||||
#meta mark 0x000000ff return
|
||||
|
||||
#meta l4proto { tcp, udp } ip daddr @cloudflare_ip meta mark set 0x00000001 accept
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
set private_ip {
|
||||
type ipv4_addr
|
||||
flags interval
|
||||
auto-merge
|
||||
elements = { 10.0.0.0/8, 100.64.0.0/10, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.0.0.0/24, 192.0.2.0/24, 192.88.99.0/24, 192.168.0.0/16, 198.18.0.0/15, 198.51.100.0/24, 203.0.113.0/24, 224.0.0.0/4, 240.0.0.0/4 }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/usr/sbin/nft -f
|
||||
|
||||
flush ruleset
|
||||
|
||||
table inet filter {
|
||||
include "/etc/nftables.d/40-sets.nft"
|
||||
include "/etc/nftables.d/90-sets.nft"
|
||||
include "/etc/nftables.d/10-filter.nft"
|
||||
include "/etc/nftables.d/20-vpn.nft"
|
||||
include "/etc/nftables.d/30-proxy.nft"
|
||||
}
|
||||
|
||||
table ip nat {
|
||||
include "/etc/nftables.d/10-nat.nft"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
- name: reload nftables
|
||||
ansible.builtin.command: nft -f /etc/nftables.conf
|
||||
listen: reload nftables
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
- name: ensure /etc/nftables.d exists
|
||||
ansible.builtin.file:
|
||||
path: /etc/nftables.d
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: deploy nftables rule
|
||||
ansible.builtin.copy:
|
||||
src: "{{ item }}"
|
||||
dest: "/etc/nftables.d/{{ item }}"
|
||||
mode: "0644"
|
||||
loop:
|
||||
- 10-filter.nft
|
||||
- 10-nat.nft
|
||||
- 20-vpn.nft
|
||||
- 30-proxy.nft
|
||||
- 40-sets.nft
|
||||
notify: reload nftables
|
||||
|
||||
- name: render forward
|
||||
ansible.builtin.template:
|
||||
src: 90-forward.nft.j2
|
||||
dest: /etc/nftables.d/90-forward.nft
|
||||
mode: "0644"
|
||||
notify: reload nftables
|
||||
|
||||
- name: render dstnat
|
||||
ansible.builtin.template:
|
||||
src: 90-dstnat.nft.j2
|
||||
dest: /etc/nftables.d/90-dstnat.nft
|
||||
mode: "0644"
|
||||
notify: reload nftables
|
||||
|
||||
- name: deploy nftables.conf
|
||||
ansible.builtin.copy:
|
||||
src: nftables.conf
|
||||
dest: /etc/nftables.conf
|
||||
mode: "0644"
|
||||
validate: "nft -c -f %s"
|
||||
notify: reload nftables
|
||||
@@ -0,0 +1,31 @@
|
||||
#jinja2: trim_blocks: True, lstrip_blocks: True
|
||||
{% macro render_dstnat_rule(ifaces, proto, port, target_ip, item_name) %}
|
||||
{% set lines = [] %}
|
||||
{% set active_ifaces = ifaces if (ifaces is iterable and ifaces is not string) else [ifaces] %}
|
||||
{% for current_iface in active_ifaces %}
|
||||
{% set comment_str = ' comment "' ~ current_iface ~ ' -> ' ~ item_name ~ '"' %}
|
||||
{% set rule_line = 'iifname "' ~ current_iface ~ '" ' ~ proto ~ ' dport ' ~ port ~ ' counter dnat ip to ' ~ target_ip ~ ':' ~ port ~ comment_str %}
|
||||
{% set _ = lines.append(rule_line) %}
|
||||
{% endfor %}
|
||||
{{ lines | join('\n') }}
|
||||
{% endmacro %}
|
||||
{% filter regex_replace('\n[ \t]*\n+', '\n') %}
|
||||
{% for item in groups[nft_managed_group] | sort %}
|
||||
{% set client = hostvars[item] %}
|
||||
{% if 'nft_dst' in client and client.nft_dst is not none %}
|
||||
{% set target_ip = client.container_ip | default(client.ansible_host | default(item)) %}
|
||||
{% set raw_expose = client.nft_dst %}
|
||||
{% set exposes = raw_expose if (raw_expose is iterable and raw_expose is not string and raw_expose is not mapping) else [raw_expose] %}
|
||||
{% for expose in exposes %}
|
||||
{% set protos = expose.proto if (expose.proto is defined and expose.proto is iterable and expose.proto is not string) else [expose.proto | default('tcp')] %}
|
||||
{% set ports = expose.port if (expose.port is defined and expose.port is iterable and expose.port is not string) else [expose.port] %}
|
||||
{% set ifaces = expose.iface %}
|
||||
{% for p in protos | sort %}
|
||||
{% for port in ports | sort %}
|
||||
{{ render_dstnat_rule(ifaces, p, port, target_ip, item) }}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfilter %}
|
||||
@@ -0,0 +1,95 @@
|
||||
#jinja2: trim_blocks: True, lstrip_blocks: True
|
||||
{% set ip_to_host = {} %}
|
||||
{% for host in groups['all'] | default([]) %}
|
||||
{% set hv = hostvars[host] | default({}) %}
|
||||
{% if hv.ansible_host is defined and (hv.ansible_connection | default('')) != 'community.proxmox.proxmox_pct_remote' %}
|
||||
{% set _ = ip_to_host.update({(hv.ansible_host | string): host}) %}
|
||||
{% endif %}
|
||||
{% if hv.container_ip is defined and hv.container_ip %}
|
||||
{% set _ = ip_to_host.update({(hv.container_ip | string): host}) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% macro render_rule(service_name, iif, saddr, oif, daddr, protos, ports, dest_name) %}
|
||||
{% set lines = [] %}
|
||||
{% set iifs = iif if (iif is iterable and iif is not string) else [iif] %}
|
||||
{% set oifs = oif if (oif is iterable and oif is not string) else [oif] %}
|
||||
{% set active_protos = protos | sort if protos | length > 0 else [none] %}
|
||||
{% set active_ports = ports if ports | length > 0 else [none] %}
|
||||
{% for current_iif in iifs %}
|
||||
{% for current_oif in oifs %}
|
||||
{% for p in active_protos %}
|
||||
{% for port in active_ports %}
|
||||
{% set proto_rule = '' %}
|
||||
{% if p and port %}
|
||||
{% set proto_rule = p ~ ' dport ' ~ port %}
|
||||
{% elif p %}
|
||||
{% set proto_rule = 'meta l4proto ' ~ p %}
|
||||
{% endif %}
|
||||
{# Resolve source name: prefer an explicit host resolved via saddr, otherwise fall back
|
||||
to the current interface for this specific line (not the whole iif list/service_name) #}
|
||||
{% set resolved_service_name = service_name if service_name else current_iif %}
|
||||
{% if saddr and ip_to_host[saddr | string] is defined %}
|
||||
{% set resolved_service_name = ip_to_host[saddr | string] %}
|
||||
{% endif %}
|
||||
{# Resolve destination IP to inventory hostname only for comment #}
|
||||
{% set resolved_dest_name = dest_name %}
|
||||
{% if daddr and ip_to_host[daddr | string] is defined %}
|
||||
{% set resolved_dest_name = ip_to_host[daddr | string] %}
|
||||
{% endif %}
|
||||
{% set comment_text = resolved_service_name ~ ' -> ' ~ resolved_dest_name %}
|
||||
{% set comment_str = ' comment "' ~ comment_text ~ '"' %}
|
||||
{% set parts = ['iifname "' ~ current_iif ~ '"'] %}
|
||||
{% if saddr %}
|
||||
{% set _ = parts.append('ip saddr ' ~ saddr) %}
|
||||
{% endif %}
|
||||
{% if current_oif %}
|
||||
{% set _ = parts.append('oifname "' ~ current_oif ~ '"') %}
|
||||
{% endif %}
|
||||
{% if daddr %}
|
||||
{% set _ = parts.append('ip daddr ' ~ daddr) %}
|
||||
{% endif %}
|
||||
{% if proto_rule %}
|
||||
{% set _ = parts.append(proto_rule) %}
|
||||
{% endif %}
|
||||
{% set _ = parts.append('counter accept' ~ comment_str) %}
|
||||
{% set _ = lines.append(parts | join(' ')) %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{{ lines | join('\n') }}
|
||||
{% endmacro %}
|
||||
{% filter regex_replace('\n[ \t]*\n+', '\n') %}
|
||||
{# === Managed Hosts Forward Rules === #}
|
||||
{% for item in groups[nft_managed_group] | sort %}
|
||||
{% set client = hostvars[item] %}
|
||||
{% if client.nft_to is defined and client.nft_to is not none %}
|
||||
{% set raw_rules = client.nft_to if (client.nft_to is iterable and client.nft_to is not string and client.nft_to is not mapping) else [client.nft_to] %}
|
||||
{% for r in raw_rules %}
|
||||
{% set rule_dict = r if (r is mapping) else {'to': r} %}
|
||||
{% set raw_dests = rule_dict.to if (rule_dict.to is iterable and rule_dict.to is not string) else [rule_dict.to] %}
|
||||
{% set protos = rule_dict.proto if (rule_dict.proto is defined and rule_dict.proto is iterable and rule_dict.proto is not string) else ([rule_dict.proto] if rule_dict.proto is defined else []) %}
|
||||
{% set ports = rule_dict.port if (rule_dict.port is defined and rule_dict.port is iterable and rule_dict.port is not string) else ([rule_dict.port] if rule_dict.port is defined else []) %}
|
||||
{% for dest in raw_dests %}
|
||||
{% set dest_name = dest | regex_replace('^zone:', '') %}
|
||||
{% if dest.startswith('zone:') %}
|
||||
{{ render_rule(item, client.zone_iface, client.container_ip, dest.split(':')[1], none, protos, ports, dest_name) }}
|
||||
{% else %}
|
||||
{{ render_rule(item, client.zone_iface, client.container_ip, hostvars[dest].zone_iface, hostvars[dest].container_ip, protos, ports, dest_name) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for item in groups[nft_managed_group] | sort %}
|
||||
{% set client = hostvars[item] %}
|
||||
{% if client.nft_from is defined and client.nft_from is not none %}
|
||||
{% set raw_from_rules = client.nft_from if (client.nft_from is iterable and client.nft_from is not string and client.nft_from is not mapping) else [client.nft_from] %}
|
||||
{% for r in raw_from_rules %}
|
||||
{% set protos = r.proto if (r.proto is defined and r.proto is iterable and r.proto is not string) else ([r.proto] if r.proto is defined else []) %}
|
||||
{% set ports = r.port if (r.port is defined and r.port is iterable and r.port is not string) else ([r.port] if r.port is defined else []) %}
|
||||
{{ render_rule(none, r.iface, none, client.zone_iface, client.container_ip, protos, ports, item) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfilter %}
|
||||
@@ -0,0 +1,52 @@
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
post-up ip rule add fwmark 0x1 lookup 100 2>/dev/null || true
|
||||
post-up ip route add local 0.0.0.0/0 dev lo table 100 2>/dev/null || true
|
||||
pre-down ip route del local 0.0.0.0/0 dev lo table 100 2>/dev/null || true
|
||||
pre-down ip rule del fwmark 0x1 lookup 100 2>/dev/null || true
|
||||
|
||||
auto eth0
|
||||
iface eth0 inet manual
|
||||
address 10.1.0.1/24
|
||||
|
||||
auto eth0.2
|
||||
iface eth0.2 inet static
|
||||
address 10.2.0.1/24
|
||||
vlan-raw-device eth0
|
||||
|
||||
auto eth0.3
|
||||
iface eth0.3 inet static
|
||||
address 10.3.0.1/24
|
||||
vlan-raw-device eth0
|
||||
|
||||
auto eth0.4
|
||||
iface eth0.4 inet static
|
||||
address 10.4.0.1/24
|
||||
vlan-raw-device eth0
|
||||
|
||||
auto eth0.10
|
||||
iface eth0.10 inet static
|
||||
address 10.10.0.1/24
|
||||
vlan-raw-device eth0
|
||||
|
||||
auto eth0.11
|
||||
iface eth0.11 inet static
|
||||
address 10.11.0.1/24
|
||||
vlan-raw-device eth0
|
||||
|
||||
auto eth0.12
|
||||
iface eth0.12 inet static
|
||||
address 10.12.0.1/24
|
||||
vlan-raw-device eth0
|
||||
|
||||
auto eth1
|
||||
iface eth1 inet dhcp
|
||||
|
||||
auto wg0
|
||||
iface wg0 inet manual
|
||||
post-up ip route add 10.250.250.0/24 dev wg0 2>/dev/null || true
|
||||
post-up ip rule add fwmark 0xc7 lookup 199 2>/dev/null || true
|
||||
post-up ip route add default dev wg0 table 199 2>/dev/null || true
|
||||
pre-down ip route del default dev wg0 table 199 2>/dev/null || true
|
||||
pre-down ip rule del fwmark 0xc7 lookup 199 2>/dev/null || true
|
||||
pre-down ip route del 10.250.250.0/24 dev wg0 2>/dev/null || true
|
||||
@@ -0,0 +1 @@
|
||||
net.ipv4.ip_forward=1
|
||||
@@ -0,0 +1,2 @@
|
||||
net.ipv4.conf.all.rp_filter = 0
|
||||
net.ipv4.conf.wg0.rp_filter = 0
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
- name: reload ifupdown2
|
||||
command: ifreload -a
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
- name: include network configuration
|
||||
include_tasks: network.yml
|
||||
|
||||
- name: include xray-lists configuration
|
||||
include_tasks: xray_lists.yml
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
- name: deploy ifupdown config
|
||||
copy:
|
||||
src: ifupdown2/interfaces
|
||||
dest: /etc/network/interfaces
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
notify: reload ifupdown2
|
||||
@@ -0,0 +1,99 @@
|
||||
---
|
||||
- name: install required system packages
|
||||
apt:
|
||||
name:
|
||||
- python3-venv
|
||||
- git
|
||||
state: present
|
||||
update_cache: yes
|
||||
|
||||
- name: ensure base directories exist
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0755'
|
||||
loop:
|
||||
- /opt/xray-lists
|
||||
- /var/lib/xray-lists
|
||||
|
||||
- name: clone xray-lists repository
|
||||
git:
|
||||
repo: 'https://gitea.oyacoi.ru/pyrschtjag/xray-lists'
|
||||
dest: /opt/xray-lists-src
|
||||
version: main
|
||||
force: yes
|
||||
|
||||
- name: check if xray-lists is installed
|
||||
command: /opt/xray-lists/venv/bin/pip show xray-lists
|
||||
register: pip_check
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: install xray-lists package into venv
|
||||
command: /opt/xray-lists/venv/bin/pip install -e /opt/xray-lists-src[socks]
|
||||
when: pip_check.rc != 0
|
||||
|
||||
- name: deploy update helper script
|
||||
copy:
|
||||
dest: /var/lib/xray-lists/update.sh
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0755'
|
||||
content: |
|
||||
#!/bin/sh
|
||||
set -e
|
||||
out=$(/opt/xray-lists/venv/bin/xray-lists)
|
||||
echo "$out"
|
||||
|
||||
dns_changed=0
|
||||
elements_changed=0
|
||||
|
||||
if echo "$out" | grep -A 10 "changed:" | grep -q "nftsets.conf"; then dns_changed=1; fi
|
||||
if echo "$out" | grep -A 10 "changed:" | grep -q "\.elements\.nft"; then elements_changed=1; fi
|
||||
|
||||
if [ "$dns_changed" -eq 1 ] && [ "$elements_changed" -eq 1 ]; then exit 12;
|
||||
elif [ "$dns_changed" -eq 1 ]; then exit 10;
|
||||
elif [ "$elements_changed" -eq 1 ]; then exit 11;
|
||||
fi
|
||||
exit 0
|
||||
|
||||
- name: deploy systemd service unit
|
||||
copy:
|
||||
dest: /etc/systemd/system/xray-lists.service
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
content: |
|
||||
[Unit]
|
||||
Description=Update Xray lists
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/sh -c '\
|
||||
/var/lib/xray-lists/update.sh; \
|
||||
rc=$$?; \
|
||||
case "$$rc" in \
|
||||
10) systemctl restart dnsmasq ;; \
|
||||
11) nft -f /etc/nftables.conf ;; \
|
||||
12) nft -f /etc/nftables.conf && systemctl restart dnsmasq ;; \
|
||||
esac'
|
||||
|
||||
- name: deploy systemd timer unit
|
||||
copy:
|
||||
dest: /etc/systemd/system/xray-lists.timer
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
content: |
|
||||
[Unit]
|
||||
Description=Run xray-lists update daily and on boot
|
||||
|
||||
[Timer]
|
||||
OnBootSec=5min
|
||||
OnUnitActiveSec=12h
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
- name: reload nftables
|
||||
ansible.builtin.command: nft -f /etc/nftables.conf
|
||||
listen: reload nftables
|
||||
|
||||
- name: restart dnsmasq
|
||||
ansible.builtin.service:
|
||||
name: dnsmasq
|
||||
state: restarted
|
||||
|
||||
- name: restart xray-lists timer
|
||||
ansible.builtin.systemd:
|
||||
name: xray-lists.timer
|
||||
state: restarted
|
||||
daemon_reload: yes
|
||||
listen: restart xray-lists timer
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
- name: collect xray policy hosts
|
||||
ansible.builtin.set_fact:
|
||||
_xray_hosts_with_policy: >-
|
||||
{{
|
||||
(_xray_hosts_with_policy | default([]))
|
||||
+ [{'inventory_hostname': item, 'xray_policy': hostvars[item].xray_policy}]
|
||||
}}
|
||||
loop: "{{ groups[xray_managed_group] }}"
|
||||
when: hostvars[item].xray_policy is defined
|
||||
|
||||
- name: validate xray policy sets
|
||||
ansible.builtin.assert:
|
||||
that: >-
|
||||
(item.1.bypass | default(item.1.proxy)) == 'all'
|
||||
or (item.1.bypass | default(item.1.proxy)) in xray_ip_sets
|
||||
or (item.1.bypass | default(item.1.proxy)) in xray_domain_sets
|
||||
or (item.1.bypass | default(item.1.proxy)) in (xray_static_sets | default([]))
|
||||
fail_msg: >-
|
||||
host {{ item.0.inventory_hostname }}: unknown xray set
|
||||
'{{ item.1.bypass | default(item.1.proxy) }}' in xray_policy
|
||||
loop: "{{ query('ansible.builtin.subelements', _xray_hosts_with_policy | default([]), 'xray_policy', {'skip_missing': True}) }}"
|
||||
loop_control:
|
||||
label: "{{ item.0.inventory_hostname }} -> {{ item.1 }}"
|
||||
|
||||
- name: render xray-lists config
|
||||
ansible.builtin.template:
|
||||
src: xray-config.yaml.j2
|
||||
dest: /etc/xray-lists/config.yaml
|
||||
mode: "0640"
|
||||
notify: restart xray-lists timer
|
||||
|
||||
- name: bootstrap empty config files
|
||||
ansible.builtin.copy:
|
||||
dest: "/etc/nftables.d/{{ item }}"
|
||||
content: ""
|
||||
force: false
|
||||
mode: "0644"
|
||||
loop:
|
||||
- 90-sets.nft
|
||||
- 90-proxy.nft
|
||||
|
||||
- name: render nft sets
|
||||
ansible.builtin.template:
|
||||
src: 90-sets.nft.j2
|
||||
dest: /etc/nftables.d/90-sets.nft
|
||||
mode: "0644"
|
||||
notify: reload nftables
|
||||
|
||||
- name: render proxy prerouting
|
||||
ansible.builtin.template:
|
||||
src: 90-proxy.nft.j2
|
||||
dest: /etc/nftables.d/90-proxy.nft
|
||||
mode: "0644"
|
||||
notify: reload nftables
|
||||
@@ -0,0 +1,31 @@
|
||||
#jinja2: trim_blocks: True, lstrip_blocks: True
|
||||
{%- macro set_ref(name) -%}
|
||||
{%- if name == 'all' -%}
|
||||
0.0.0.0/0
|
||||
{%- elif name in xray_ip_sets or name in (xray_static_sets | default([])) -%}
|
||||
@{{ name }}_ip
|
||||
{%- elif name in xray_domain_sets -%}
|
||||
@{{ name_dom }}_dom
|
||||
{%- else -%}
|
||||
INVALID_XRAY_SET_{{ name }}
|
||||
{%- endif -%}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- set rules_list = [] -%}
|
||||
{%- for item in groups[xray_managed_group] | default([]) | sort -%}
|
||||
{%- set client = hostvars[item] -%}
|
||||
{%- if client.xray_policy is defined -%}
|
||||
{%- set src_ip = client.container_ip | default(client.ansible_host | default(item)) -%}
|
||||
{%- for rule in client.xray_policy -%}
|
||||
{%- if rule.bypass is defined -%}
|
||||
{%- set _ = rules_list.append("meta l4proto { tcp, udp } ip saddr " ~ src_ip ~ " ip daddr " ~ set_ref(rule.bypass) ~ " accept") -%}
|
||||
{%- elif rule.proxy is defined -%}
|
||||
{%- set _ = rules_list.append("meta l4proto { tcp, udp } ip saddr " ~ src_ip ~ " ip daddr " ~ set_ref(rule.proxy) ~ " tproxy ip to :" ~ (xray_tproxy_port | default(61219) | string) ~ " meta mark set " ~ (xray_fwmark | default('0x00000001')) ~ " accept") -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
|
||||
{%- if rules_list | length > 0 -%}
|
||||
{{- rules_list | join('\n') -}}
|
||||
{%- endif -%}
|
||||
@@ -0,0 +1,15 @@
|
||||
#jinja2: trim_blocks: True, lstrip_blocks: True
|
||||
{%- for id, item in xray_ip_sets.items() -%}
|
||||
set {{ id }}_ip {
|
||||
type ipv4_addr
|
||||
flags interval
|
||||
auto-merge
|
||||
include "{{ xray_lists_global.output_dir }}/{{ id }}.elements.nft"
|
||||
}
|
||||
{% endfor -%}
|
||||
{%- for id, item in xray_domain_sets.items() -%}
|
||||
set {{ id }}_dom {
|
||||
type ipv4_addr
|
||||
flags interval
|
||||
}
|
||||
{% endfor -%}
|
||||
@@ -0,0 +1,47 @@
|
||||
#jinja2: trim_blocks: True, lstrip_blocks: True
|
||||
global:
|
||||
cache_dir: {{ xray_lists_global.cache_dir }}
|
||||
output_dir: {{ xray_lists_global.output_dir }}
|
||||
dnsmasq_output: {{ xray_lists_global.dnsmasq_output }}
|
||||
{% if xray_lists_global.proxy is defined %}
|
||||
proxy: "{{ xray_lists_global.proxy }}"
|
||||
{% endif %}
|
||||
{% if xray_lists_global.proxy_user is defined %}
|
||||
proxy_user: "{{ xray_lists_global.proxy_user }}"
|
||||
proxy_pass: "{{ xray_lists_global.proxy_pass }}"
|
||||
{% endif %}
|
||||
http_timeout: {{ xray_lists_global.http_timeout | default(20) }}
|
||||
ip_sets:
|
||||
{% for id, item in xray_ip_sets.items() %}
|
||||
- id: {{ id }}
|
||||
output: {{ id }}_ip.elements.nft
|
||||
{% if item.static is defined %}
|
||||
static:
|
||||
{% for s in item.static %}
|
||||
- {{ s }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if item.urls is defined %}
|
||||
urls:
|
||||
{% for u in item.urls %}
|
||||
- {{ u }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
domain_sets:
|
||||
{% for id, item in xray_domain_sets.items() %}
|
||||
- id: {{ id }}
|
||||
dnsmasq_target: "4#inet#filter#{{ id }}_dom"
|
||||
{% if item.static is defined %}
|
||||
static:
|
||||
{% for s in item.static %}
|
||||
- {{ s }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if item.urls is defined %}
|
||||
urls:
|
||||
{% for u in item.urls %}
|
||||
- {{ u }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
Reference in New Issue
Block a user