add xray-lists role
This commit is contained in:
@@ -0,0 +1,62 @@
|
|||||||
|
---
|
||||||
|
#- 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) }}'"
|
||||||
|
# quiet: true
|
||||||
|
# loop: "{{ query('ansible.builtin.subelements', _xray_hosts_with_policy | default([]), 'xray_policy', {'skip_missing': True}) }}"
|
||||||
|
# loop_control:
|
||||||
|
# label: "{{ item.0.inventory_hostname }} -> {{ item.1.bypass | default(item.1.proxy) }}"
|
||||||
|
|
||||||
|
- name: render xray-lists config
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: xray-config.yaml.j2
|
||||||
|
dest: /var/lib/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-prerouting.nft
|
||||||
|
- 90-proxy-output.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-prerouting.nft.j2
|
||||||
|
dest: /etc/nftables.d/90-proxy-prerouting.nft
|
||||||
|
mode: "0644"
|
||||||
|
notify: reload nftables
|
||||||
|
|
||||||
|
- name: render proxy output
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: 90-proxy-output.nft.j2
|
||||||
|
dest: /etc/nftables.d/90-proxy-output.nft
|
||||||
|
mode: "0644"
|
||||||
|
notify: reload nftables
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
---
|
||||||
|
- 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
|
||||||
|
|
||||||
|
- name: enable and start xray-lists
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: xray-lists.timer
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
@@ -1,55 +1,6 @@
|
|||||||
---
|
---
|
||||||
- name: collect xray policy hosts
|
- name: include xray-lists install
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.include_tasks: install.yml
|
||||||
_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
|
- name: include xray-lists configure
|
||||||
ansible.builtin.assert:
|
ansible.builtin.include_tasks: configure.yml
|
||||||
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,11 @@
|
|||||||
|
#jinja2: trim_blocks: True, lstrip_blocks: True
|
||||||
|
{% macro set_daddr(rule) %}
|
||||||
|
{%- if rule in (xray_ip_sets | default([])) or rule in (xray_static_sets | default([])) -%}
|
||||||
|
{{ rule }}_ip
|
||||||
|
{%- elif rule in (xray_domain_sets | default([])) -%}
|
||||||
|
{{ rule }}_dom
|
||||||
|
{%- endif -%}
|
||||||
|
{% endmacro %}
|
||||||
|
{% for rule in output_rules | default([]) | sort %}
|
||||||
|
ip daddr @{{ set_daddr(rule) }} meta mark set {{ xray_fwmark }} accept
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#jinja2: trim_blocks: True, lstrip_blocks: True
|
||||||
|
{% macro set_daddr(name) %}
|
||||||
|
{%- if name == 'all' %}
|
||||||
|
0.0.0.0/0
|
||||||
|
{%- elif name in (xray_ip_sets | default([])) or name in (xray_static_sets | default([])) %}
|
||||||
|
@{{ name }}_ip
|
||||||
|
{%- elif name in (xray_domain_sets | default([])) %}
|
||||||
|
@{{ name }}_dom
|
||||||
|
{%- else %}
|
||||||
|
invalid_xray_set_{{ name }}
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
{% 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 %}
|
||||||
|
{% for rule in client.xray_policy %}
|
||||||
|
{% set target_set = rule.bypass | default(rule.proxy) %}
|
||||||
|
{% if rule.bypass is defined %}
|
||||||
|
meta l4proto { tcp, udp } ip saddr {{ src_ip }} ip daddr {{ set_daddr(target_set) }} accept
|
||||||
|
{% elif rule.proxy is defined %}
|
||||||
|
meta l4proto { tcp, udp } ip saddr {{ src_ip }} ip daddr {{ set_daddr(target_set) }} tproxy ip to :{{ xray_tproxy_port }} meta mark set {{ xray_fwmark }} accept
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#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
|
|
||||||
{%- 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 -%}
|
|
||||||
@@ -45,3 +45,7 @@ domain_sets:
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
output_rules:
|
||||||
|
{% for rule in output_rules %}
|
||||||
|
- {{ rule }}
|
||||||
|
{% endfor %}
|
||||||
|
|||||||
Reference in New Issue
Block a user