forked from zentralwerk/network
rm -r salt
This commit is contained in:
parent
40e8b351d5
commit
27ff3c4516
|
@ -1,13 +0,0 @@
|
||||||
$ORIGIN {{ domain }}.
|
|
||||||
$TTL 10M
|
|
||||||
|
|
||||||
@ IN SOA {{ pillar['bind']['master-ns']['up1'] }}. astro.spaceboyz.net. (
|
|
||||||
3 ; serial
|
|
||||||
1H ; refresh
|
|
||||||
1M ; retry
|
|
||||||
2H ; expire
|
|
||||||
5M ; minimum
|
|
||||||
)
|
|
||||||
{%- for ns in pillar['bind']['public-ns']['up1'] %}
|
|
||||||
IN NS {{ ns }}.
|
|
||||||
{%- endfor %}
|
|
|
@ -1,78 +0,0 @@
|
||||||
bind9:
|
|
||||||
pkg.installed: []
|
|
||||||
service:
|
|
||||||
- running
|
|
||||||
- enable: True
|
|
||||||
- restart: True
|
|
||||||
- watch:
|
|
||||||
- file: /etc/bind/named.conf*
|
|
||||||
- file: /etc/bind/*.zone
|
|
||||||
- pkg: bind9
|
|
||||||
|
|
||||||
/etc/bind/named.conf.local:
|
|
||||||
file.managed:
|
|
||||||
- require:
|
|
||||||
- pkg: bind9
|
|
||||||
- source: salt://bind/named.conf
|
|
||||||
- template: 'jinja'
|
|
||||||
|
|
||||||
{%- for ctx, root_domain in pillar['bind']['root-domain'].items() %}
|
|
||||||
# zentralwerk.org
|
|
||||||
/etc/bind/{{ root_domain }}.zone:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://bind/root-domain.zone
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
domain: {{ root_domain }}
|
|
||||||
ctx: {{ ctx }}
|
|
||||||
|
|
||||||
# *.zentralwerk.org
|
|
||||||
{%- for net, subnet4 in pillar['subnets-inet'].items() %}
|
|
||||||
{%- set domain = net ~ '.' ~ root_domain %}
|
|
||||||
/etc/bind/{{ domain }}.zone:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://bind/net-domain.zone
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
domain: {{ domain }}
|
|
||||||
net: {{ net }}
|
|
||||||
ctx: {{ ctx }}
|
|
||||||
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
# dyn.zentralwerk.org
|
|
||||||
{%- set domain = 'dyn.' ~ pillar['bind']['root-domain']['up1'] %}
|
|
||||||
/etc/bind/{{ domain }}.zone:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://bind/dyn-domain.zone
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
domain: {{ domain }}
|
|
||||||
|
|
||||||
# IPv4 reverse
|
|
||||||
{%- for domain in pillar['bind']['reverse-zones-inet'] %}
|
|
||||||
/etc/bind/{{ domain }}.zone:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://bind/reverse.zone
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
domain: {{ domain }}
|
|
||||||
ctx: dn42
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
# IPv6 reverse
|
|
||||||
{%- for ctx, domains in pillar['bind']['reverse-zones-inet6'].items() %}
|
|
||||||
{%- for domain in domains %}
|
|
||||||
/etc/bind/{{ domain }}.zone:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://bind/reverse.zone
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
domain: {{ domain }}
|
|
||||||
ctx: {{ ctx }}
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
rndc reload:
|
|
||||||
cmd.run: []
|
|
|
@ -1,76 +0,0 @@
|
||||||
# Slaves rely on static IPv4 addrs over dn42. Do not contact them over
|
|
||||||
# their public addrs because our source addr is dynamic!
|
|
||||||
{% macro slaves() -%}
|
|
||||||
{%- if pillar['bind']['slaves'] -%}
|
|
||||||
allow-transfer {
|
|
||||||
{%- for addr in pillar['bind']['slaves'] -%}
|
|
||||||
{{ addr }};
|
|
||||||
{%- endfor -%}
|
|
||||||
};
|
|
||||||
also-notify {
|
|
||||||
{%- for addr in pillar['bind']['slaves'] -%}
|
|
||||||
{{ addr }};
|
|
||||||
{%- endfor -%}
|
|
||||||
};
|
|
||||||
{%- endif -%}
|
|
||||||
{%- endmacro %}
|
|
||||||
|
|
||||||
# root domain
|
|
||||||
{%- for ctx, root_domain in pillar['bind']['root-domain'].items() %}
|
|
||||||
zone "{{ root_domain }}" IN {
|
|
||||||
type master;
|
|
||||||
file "/etc/bind/{{ root_domain }}.zone";
|
|
||||||
{{ slaves() }}
|
|
||||||
};
|
|
||||||
|
|
||||||
# net zones
|
|
||||||
{%- for net, subnet4 in pillar['subnets-inet'].items() %}
|
|
||||||
{%- set domain = net ~ '.' ~ root_domain %}
|
|
||||||
zone "{{ domain }}" IN {
|
|
||||||
type master;
|
|
||||||
file "/etc/bind/{{ domain }}.zone";
|
|
||||||
{{ slaves() }}
|
|
||||||
};
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
# IPv4 reverse zones
|
|
||||||
{%- for domain in pillar['bind']['reverse-zones-inet'] %}
|
|
||||||
zone "{{ domain }}" IN {
|
|
||||||
type master;
|
|
||||||
file "/etc/bind/{{ domain }}.zone";
|
|
||||||
};
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
# IPv6 reverse zones
|
|
||||||
{%- for ctx, domains in pillar['bind']['reverse-zones-inet6'].items() %}
|
|
||||||
{%- for domain in domains %}
|
|
||||||
zone "{{ domain }}" IN {
|
|
||||||
type master;
|
|
||||||
file "/etc/bind/{{ domain }}.zone";
|
|
||||||
{{ slaves() }}
|
|
||||||
};
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
|
|
||||||
# DynDNS
|
|
||||||
{%- for name, conf in pillar['dyndns'].items() %}
|
|
||||||
key "{{ name }}" {
|
|
||||||
algorithm hmac-sha256;
|
|
||||||
secret "{{ conf['secret'] }}";
|
|
||||||
};
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
# DynDNS zone
|
|
||||||
{%- set domain = 'dyn.' ~ pillar['bind']['root-domain']['up1'] %}
|
|
||||||
zone "{{ domain }}" IN {
|
|
||||||
type master;
|
|
||||||
file "/etc/bind/{{ domain }}.zone";
|
|
||||||
{{ slaves() }}
|
|
||||||
update-policy {
|
|
||||||
{%- for name, conf in pillar['dyndns'].items() %}
|
|
||||||
grant {{ name }} name {{ name }}.{{ domain }} ANY;
|
|
||||||
{%- endfor %}
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,25 +0,0 @@
|
||||||
$ORIGIN {{ domain }}.
|
|
||||||
$TTL 10M
|
|
||||||
|
|
||||||
@ IN SOA {{ pillar['bind']['master-ns'][ctx] }}. astro.spaceboyz.net. (
|
|
||||||
{{ pillar['bind']['serial'] }} ; serial
|
|
||||||
1H ; refresh
|
|
||||||
1M ; retry
|
|
||||||
2H ; expire
|
|
||||||
5M ; minimum
|
|
||||||
)
|
|
||||||
{%- for ns in pillar['bind']['public-ns'][ctx] %}
|
|
||||||
IN NS {{ ns }}.
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- if pillar['hosts-inet'].get(net) %}
|
|
||||||
{%- for name, a in pillar['hosts-inet'][net].items() %}
|
|
||||||
{{ name }} IN A {{ a }}
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
{%- if pillar['hosts-inet6'][ctx].get(net) %}
|
|
||||||
{%- for name, aaaa in pillar['hosts-inet6'][ctx][net].items() %}
|
|
||||||
{{ name }} IN AAAA {{ aaaa }}
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endif %}
|
|
|
@ -1,33 +0,0 @@
|
||||||
$ORIGIN {{ domain }}.
|
|
||||||
$TTL 10M
|
|
||||||
|
|
||||||
@ IN SOA {{ pillar['bind']['master-ns'][ctx] }}. astro.spaceboyz.net. (
|
|
||||||
{{ pillar['bind']['serial'] }} ; serial
|
|
||||||
1H ; refresh
|
|
||||||
1M ; retry
|
|
||||||
2H ; expire
|
|
||||||
5M ; minimum
|
|
||||||
)
|
|
||||||
{%- for ns in pillar['bind']['public-ns'][ctx] %}
|
|
||||||
IN NS {{ ns }}.
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- if ctx == 'dn42' %}
|
|
||||||
{%- for net, hosts in pillar['hosts-inet'].items() %}
|
|
||||||
{%- for host, aaaa in hosts.items() %}
|
|
||||||
{%- set reverse = salt['network.reverse_ip'](aaaa) %}
|
|
||||||
{%- if reverse.endswith(domain) %}
|
|
||||||
{{ reverse.replace('.' ~ domain, '') }} IN PTR {{ host }}.{{ net }}.{{ pillar['bind']['root-domain'][ctx] }}.
|
|
||||||
{%- endif %}
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
{%- for net, hosts in pillar['hosts-inet6'][ctx].items() %}
|
|
||||||
{%- for host, aaaa in hosts.items() %}
|
|
||||||
{%- set reverse = salt['network.reverse_ip'](aaaa) %}
|
|
||||||
{%- if reverse.endswith(domain) %}
|
|
||||||
{{ reverse.replace('.' ~ domain, '') }} IN PTR {{ host }}.{{ net }}.{{ pillar['bind']['root-domain'][ctx] }}.
|
|
||||||
{%- endif %}
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endfor %}
|
|
|
@ -1,28 +0,0 @@
|
||||||
$ORIGIN {{ domain }}.
|
|
||||||
$TTL 10M
|
|
||||||
|
|
||||||
@ IN SOA {{ pillar['bind']['master-ns'][ctx] }}. astro.spaceboyz.net. (
|
|
||||||
{{ pillar['bind']['serial'] }} ; serial
|
|
||||||
1H ; refresh
|
|
||||||
1M ; retry
|
|
||||||
2H ; expire
|
|
||||||
5M ; minimum
|
|
||||||
)
|
|
||||||
{%- for ns in pillar['bind']['public-ns'][ctx] %}
|
|
||||||
IN NS {{ ns }}.
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- for net, hosts in pillar['hosts-inet'].items() %}
|
|
||||||
{%- for ns in pillar['bind']['public-ns'][ctx] %}
|
|
||||||
{{ net }} IN NS {{ ns }}.
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- for ns in pillar['bind']['public-ns'][ctx] %}
|
|
||||||
dyn IN NS {{ ns }}.
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- for name, a in pillar['hosts-inet-extra'].items() %}
|
|
||||||
{{ name }} IN A {{ a }}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
protocol kernel {
|
|
||||||
scan time 10;
|
|
||||||
import none;
|
|
||||||
export all;
|
|
||||||
}
|
|
||||||
|
|
||||||
protocol device {
|
|
||||||
scan time 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
protocol ospf ZW4 {
|
|
||||||
area 0 {
|
|
||||||
networks {
|
|
||||||
172.20.72.0/21;
|
|
||||||
};
|
|
||||||
{%- for iface, ips in salt['grains.get']('ip_interfaces').items() %}
|
|
||||||
{%- set subnet = pillar['subnets-inet'].get(iface) %}
|
|
||||||
{%- if iface == 'core' or iface == 'br-core' %}
|
|
||||||
interface "{{ iface }}" {
|
|
||||||
authentication cryptographic;
|
|
||||||
password "{{ pillar['ospf']['secret'] }}";
|
|
||||||
};
|
|
||||||
{%- elif subnet %}
|
|
||||||
stubnet {{ subnet }} {};
|
|
||||||
{%- endif %}
|
|
||||||
{%- endfor %}
|
|
||||||
{%- if pillar['ospf'].get('stubnets-inet') %}
|
|
||||||
{%- for stubnet in pillar['ospf']['stubnets-inet'] %}
|
|
||||||
stubnet {{ stubnet }} {};
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endif %}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
{%- if pillar.get('bgp') %}
|
|
||||||
protocol static {
|
|
||||||
route 172.20.72.0/21 unreachable;
|
|
||||||
}
|
|
||||||
|
|
||||||
protocol bgp {
|
|
||||||
local as {{ pillar['bgp']['asn'] }};
|
|
||||||
import all;
|
|
||||||
{%- for host, neighbor in pillar['bgp']['peers-inet'].items() %}
|
|
||||||
neighbor {{ host }} as {{ neighbor.asn }};
|
|
||||||
{%- endfor %}
|
|
||||||
export where source=RTS_STATIC;
|
|
||||||
}
|
|
||||||
{%- endif %}
|
|
|
@ -1,99 +0,0 @@
|
||||||
router id {{ pillar['hosts-inet']['core'][salt['grains.get']('id')] }};
|
|
||||||
|
|
||||||
protocol kernel {
|
|
||||||
scan time 10;
|
|
||||||
import none;
|
|
||||||
export all;
|
|
||||||
}
|
|
||||||
|
|
||||||
protocol device {
|
|
||||||
scan time 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
{%- set radv_ifaces = pillar.get('radv') and pillar['radv'].get(salt['grains.get']('id')) %}
|
|
||||||
{%- if radv_ifaces %}
|
|
||||||
protocol radv {
|
|
||||||
{%- for iface, conf in radv_ifaces.items() %}
|
|
||||||
interface "{{ iface }}" {
|
|
||||||
min ra interval 3;
|
|
||||||
max ra interval 10;
|
|
||||||
{%- for ctx, subnets in pillar['subnets-inet6'].items() %}
|
|
||||||
{%- set subnet6 = subnets.get(iface) %}
|
|
||||||
{%- if subnet6 %}
|
|
||||||
prefix {{ subnet6 }} {
|
|
||||||
preferred lifetime 20;
|
|
||||||
valid lifetime 60;
|
|
||||||
};
|
|
||||||
{%- endif %}
|
|
||||||
{%- endfor %}
|
|
||||||
{%- if conf.get('rdnss') %}
|
|
||||||
{%- for value in conf['rdnss'] %}
|
|
||||||
{%- set host = value.split('.')[0] %}
|
|
||||||
{%- set net = value.split('.')[1] %}
|
|
||||||
rdnss {{ pillar['hosts-inet6']['dn42'][net][host] }};
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endif %}
|
|
||||||
{%- if conf.get('dnssl') %}
|
|
||||||
dnssl {
|
|
||||||
{%- for value in conf['dnssl'] %}
|
|
||||||
domain "{{ value }}";
|
|
||||||
{%- endfor %}
|
|
||||||
};
|
|
||||||
{%- endif %}
|
|
||||||
};
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
}
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
protocol ospf ZW6 {
|
|
||||||
{%- if pillar.get('bgp') %}
|
|
||||||
export filter {
|
|
||||||
reject;
|
|
||||||
};
|
|
||||||
{%- endif %}
|
|
||||||
area 0 {
|
|
||||||
networks {
|
|
||||||
fd23:42:c3d2:500::/56;
|
|
||||||
2a02:8106:208:5200::/56;
|
|
||||||
2a02:8106:211:e900::/56;
|
|
||||||
};
|
|
||||||
{%- for iface, ips in salt['grains.get']('ip_interfaces').items() %}
|
|
||||||
{%- if iface == 'core' or iface == 'br-core' %}
|
|
||||||
interface "{{ iface }}" {
|
|
||||||
};
|
|
||||||
{%- else %}
|
|
||||||
{%- for ctx, subnets in pillar['subnets-inet6'].items() %}
|
|
||||||
{%- set subnet = subnets.get(iface) %}
|
|
||||||
{%- if subnet %}
|
|
||||||
stubnet {{ subnet }} {};
|
|
||||||
{%- endif %}
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endif %}
|
|
||||||
{%- endfor %}
|
|
||||||
{%- if pillar['ospf'].get('stubnets-inet6') %}
|
|
||||||
{%- for stubnet in pillar['ospf']['stubnets-inet6'] %}
|
|
||||||
stubnet {{ stubnet }} {};
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endif %}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protocol static {
|
|
||||||
# Zentralwerk DN42
|
|
||||||
route fd23:42:c3d2:580::/57 unreachable;
|
|
||||||
# Static Kabeldeutschland
|
|
||||||
route 2a02:8106:208:5200::/56 unreachable;
|
|
||||||
route 2a02:8106:211:e900::/56 unreachable;
|
|
||||||
}
|
|
||||||
|
|
||||||
{%- if pillar.get('bgp') %}
|
|
||||||
protocol bgp {
|
|
||||||
local as {{ pillar['bgp']['asn'] }};
|
|
||||||
import all;
|
|
||||||
{%- for host, neighbor in pillar['bgp']['peers-inet6'].items() %}
|
|
||||||
neighbor {{ host }} as {{ neighbor.asn }};
|
|
||||||
{%- endfor %}
|
|
||||||
export where source=RTS_STATIC;
|
|
||||||
}
|
|
||||||
{%- endif %}
|
|
|
@ -1,20 +0,0 @@
|
||||||
bird:
|
|
||||||
pkg.installed: []
|
|
||||||
|
|
||||||
{%- for daemon in ['bird', 'bird6'] %}
|
|
||||||
/etc/bird/{{ daemon }}.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://bird/{{ daemon }}.conf
|
|
||||||
- template: 'jinja'
|
|
||||||
- require:
|
|
||||||
- pkg: bird
|
|
||||||
|
|
||||||
service-{{ daemon }}:
|
|
||||||
service.running:
|
|
||||||
- name: {{ daemon }}
|
|
||||||
- enable: True
|
|
||||||
- watch:
|
|
||||||
- pkg: bird
|
|
||||||
- file: /etc/bird/{{ daemon }}.conf
|
|
||||||
|
|
||||||
{%- endfor %}
|
|
|
@ -1,10 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
F=/sys/class/net/$IFACE/bonding/slaves
|
|
||||||
[ -f "$F" ] || exit 0
|
|
||||||
|
|
||||||
for slave in `cat "$F"`; do
|
|
||||||
ip link set $slave up
|
|
||||||
# Disable offloading as it interferes with shaping
|
|
||||||
ethtool -K $slave gso off gro off tso off
|
|
||||||
done
|
|
|
@ -1,64 +0,0 @@
|
||||||
Hostname "{{ salt['grains.get']('id') }}"
|
|
||||||
FQDNLookup false
|
|
||||||
Interval 10
|
|
||||||
|
|
||||||
LoadPlugin logfile
|
|
||||||
<Plugin logfile>
|
|
||||||
LogLevel info
|
|
||||||
File STDOUT
|
|
||||||
</Plugin>
|
|
||||||
|
|
||||||
|
|
||||||
{%- for plugin, conf in pillar['collectd'].items() %}
|
|
||||||
|
|
||||||
{%- if plugin == 'network' and conf == 'client' %}
|
|
||||||
LoadPlugin network
|
|
||||||
<Plugin network>
|
|
||||||
Server "{{ pillar['hosts-inet6']['dn42']['serv']['stats'] }}" "25826"
|
|
||||||
</Plugin>
|
|
||||||
{%- elif plugin == 'network' and conf == 'server' %}
|
|
||||||
LoadPlugin network
|
|
||||||
<Plugin network>
|
|
||||||
Listen "::" "25826"
|
|
||||||
Forward true
|
|
||||||
Server "{{ pillar['hosts-inet']['serv']['spaceapi'] }}" "25826"
|
|
||||||
Server "{{ pillar['hosts-inet']['serv']['grafana'] }}" "25826"
|
|
||||||
</Plugin>
|
|
||||||
|
|
||||||
{%- elif plugin == 'ping' %}
|
|
||||||
LoadPlugin ping
|
|
||||||
<Plugin ping>
|
|
||||||
{%- for host in conf %}
|
|
||||||
Host "{{ host }}"
|
|
||||||
{%- endfor %}
|
|
||||||
Interval 10
|
|
||||||
</Plugin>
|
|
||||||
|
|
||||||
{%- elif plugin == 'dhcpcount' and conf %}
|
|
||||||
{%- set timeout = 180 %}
|
|
||||||
{%- for iface, ips in salt['grains.get']('ip_interfaces').items() %}
|
|
||||||
{%- set dhcp_conf = pillar['dhcp'].get(iface) %}
|
|
||||||
{%- if dhcp_conf and dhcp_conf.get('time') and dhcp_conf.get('time') > timeout %}
|
|
||||||
{%- set timeout = dhcp_conf['time'] %}
|
|
||||||
{%- endif %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
LoadPlugin exec
|
|
||||||
<Plugin exec>
|
|
||||||
Exec "nobody" "/usr/bin/dhcpcount.rb" "{{ timeout }}"
|
|
||||||
</Plugin>
|
|
||||||
|
|
||||||
{%- elif conf is mapping %}
|
|
||||||
LoadPlugin {{ plugin }}
|
|
||||||
|
|
||||||
<Plugin {{ plugin }}>
|
|
||||||
{%- for k, v in conf.items() %}
|
|
||||||
{{ k }} "{{ v }}"
|
|
||||||
{%- endfor %}
|
|
||||||
</Plugin>
|
|
||||||
{%- else %}
|
|
||||||
LoadPlugin {{ plugin }}
|
|
||||||
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
{%- endfor %}
|
|
|
@ -1,39 +0,0 @@
|
||||||
#!/usr/bin/env ruby
|
|
||||||
|
|
||||||
require 'date'
|
|
||||||
|
|
||||||
INTERVAL = 10
|
|
||||||
TIMEOUT = ARGV[0].to_i
|
|
||||||
hostname = `hostname`.strip
|
|
||||||
STDOUT.sync = true
|
|
||||||
|
|
||||||
loop do
|
|
||||||
seen = {}
|
|
||||||
count = 0
|
|
||||||
|
|
||||||
addr = nil
|
|
||||||
starts = nil
|
|
||||||
|
|
||||||
IO::readlines("/var/lib/dhcp/dhcpd.leases").each do |line|
|
|
||||||
if line =~ /^lease (.+) \{/
|
|
||||||
addr = $1
|
|
||||||
|
|
||||||
starts = nil
|
|
||||||
elsif line =~ /starts \d+ (.+?);/
|
|
||||||
starts = DateTime.parse($1).to_time
|
|
||||||
elsif line =~ /^\}/
|
|
||||||
now = Time.now
|
|
||||||
if starts and
|
|
||||||
now >= starts and now < starts + TIMEOUT
|
|
||||||
|
|
||||||
unless seen[addr]
|
|
||||||
count += 1
|
|
||||||
seen[addr] = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
puts "PUTVAL \"#{hostname}/exec-dhcpd/current_sessions-leases\" interval=#{INTERVAL} N:#{count}"
|
|
||||||
|
|
||||||
sleep INTERVAL
|
|
||||||
end
|
|
|
@ -1,27 +0,0 @@
|
||||||
collectd-core:
|
|
||||||
pkg.installed: []
|
|
||||||
|
|
||||||
liboping0:
|
|
||||||
pkg.installed: []
|
|
||||||
|
|
||||||
collectd:
|
|
||||||
service:
|
|
||||||
- running
|
|
||||||
- watch:
|
|
||||||
- pkg: collectd-core
|
|
||||||
- file: /etc/collectd/collectd.conf
|
|
||||||
|
|
||||||
/etc/collectd/collectd.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://collectd/collectd.conf
|
|
||||||
- template: 'jinja'
|
|
||||||
|
|
||||||
{%- if pillar['collectd'].get('dhcpcount') %}
|
|
||||||
ruby:
|
|
||||||
pkg.installed: []
|
|
||||||
|
|
||||||
/usr/bin/dhcpcount.rb:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://collectd/dhcpcount.rb
|
|
||||||
- mode: 755
|
|
||||||
{%- endif %}
|
|
492
salt/cpe/ap.sh
492
salt/cpe/ap.sh
|
@ -1,492 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
{% macro uci_network_mgmt(ifname) -%}
|
|
||||||
set network.mgmt=interface
|
|
||||||
set network.mgmt.ifname={{ ifname }}
|
|
||||||
set network.mgmt.proto=static
|
|
||||||
set network.mgmt.ipaddr={{ pillar['hosts-inet']['mgmt'][hostname] }}
|
|
||||||
set network.mgmt.netmask=255.255.255.0
|
|
||||||
set network.mgmt.gateway={{ pillar['hosts-inet']['mgmt']['mgmt-gw'] }}
|
|
||||||
set network.mgmt.ip6addr={{ pillar['hosts-inet6']['dn42']['mgmt'][hostname] }}/64
|
|
||||||
set network.mgmt.ip6gw={{ pillar['hosts-inet6']['dn42']['mgmt']['mgmt-gw'] }}
|
|
||||||
delete network.mgmt.dns
|
|
||||||
add_list network.mgmt.dns=172.20.73.8
|
|
||||||
add_list network.mgmt.dns={{ pillar['hosts-inet']['core']['upstream1'] }}
|
|
||||||
add_list network.mgmt.dns={{ pillar['hosts-inet6']['dn42']['core']['upstream1'] }}
|
|
||||||
add_list network.mgmt.dns={{ pillar['hosts-inet']['core']['upstream2'] }}
|
|
||||||
add_list network.mgmt.dns={{ pillar['hosts-inet6']['dn42']['core']['upstream2'] }}
|
|
||||||
{%- endmacro %}
|
|
||||||
|
|
||||||
{%- if conf.get('firstboot') %}
|
|
||||||
ssh-keygen -R 192.168.1.1
|
|
||||||
|
|
||||||
ssh root@192.168.1.1 \
|
|
||||||
"ash -e -x" <<__SSH__
|
|
||||||
{%- else %}
|
|
||||||
ssh root@{{ pillar['hosts-inet']['mgmt'][hostname] }} \
|
|
||||||
"ash -e -x" <<__SSH__
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
# Set root password
|
|
||||||
echo -e '{{ conf['password'] }}\n{{ conf['password'] }}' | passwd
|
|
||||||
|
|
||||||
# add ssh pubkey
|
|
||||||
echo "{{ pillar['ssh']['pubkey'] }}" > /etc/dropbear/authorized_keys
|
|
||||||
|
|
||||||
# System configuration
|
|
||||||
uci batch <<__UCI__
|
|
||||||
set system.@system[0].hostname={{ hostname }}
|
|
||||||
set dhcp.@dnsmasq[0].enabled=0
|
|
||||||
|
|
||||||
delete network.globals.ula_prefix
|
|
||||||
delete network.lan
|
|
||||||
delete network.wan
|
|
||||||
delete network.wan6
|
|
||||||
delete wireless.default_radio0
|
|
||||||
delete wireless.default_radio1
|
|
||||||
|
|
||||||
{%- set bridges = {} %}
|
|
||||||
{%- if conf.get('lan-access') %}
|
|
||||||
{%- do bridges.__setitem__(conf['lan-access'], True) %}
|
|
||||||
{%- endif %}
|
|
||||||
{%- for path, radio in conf['radios'].items() %}
|
|
||||||
{%- for ssid, ssidconf in radio['ssids'].items() %}
|
|
||||||
{%- do bridges.__setitem__(ssidconf['net'], True) %}
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- if conf['model'] == 'TL-WDR4300' %}
|
|
||||||
{# These models have a shared Ethernet chip for LAN/WAN and therefore need switching #}
|
|
||||||
set network.@switch[0]=switch
|
|
||||||
set network.@switch[0].reset=1
|
|
||||||
set network.@switch[0].enable=1
|
|
||||||
set network.@switch[0].enable_vlan=1
|
|
||||||
set network.@switch[0].name=switch0
|
|
||||||
set network.@switch_vlan[0]=switch_vlan
|
|
||||||
set network.@switch_vlan[0].device='switch0'
|
|
||||||
set network.@switch_vlan[0].vlan='1'
|
|
||||||
set network.@switch_vlan[0].ports='0t 1t'
|
|
||||||
set network.@switch_vlan[0].comment='mgmt'
|
|
||||||
{% set switchnum = 1 %}
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}]=switch_vlan
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].device='switch0'
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].vlan='{{ pillar['vlans'][net] }}'
|
|
||||||
{%- if conf.get('lan-access') == net %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].ports='0t 1t 2 3 4 5'
|
|
||||||
{%- else %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].ports='0t 1t'
|
|
||||||
{%- endif %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}'
|
|
||||||
{% set switchnum = switchnum + 1 %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{{ uci_network_mgmt('eth0.1') }}
|
|
||||||
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
set network.{{ net }}=interface
|
|
||||||
set network.{{ net }}.type=bridge
|
|
||||||
set network.{{ net }}.proto=static
|
|
||||||
set network.{{ net }}.ifname='eth0.{{ pillar['vlans'][net] }}'
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- elif conf['model'] == 'TL-WR1043ND' %}
|
|
||||||
{# These models have a shared Ethernet chip with separate CPU ports for LAN/WAN and therefore need switching #}
|
|
||||||
set network.@switch[0]=switch
|
|
||||||
set network.@switch[0].reset=1
|
|
||||||
set network.@switch[0].enable=1
|
|
||||||
set network.@switch[0].enable_vlan=1
|
|
||||||
set network.@switch[0].name=switch0
|
|
||||||
set network.@switch_vlan[0]=switch_vlan
|
|
||||||
set network.@switch_vlan[0].device='switch0'
|
|
||||||
set network.@switch_vlan[0].vlan='1'
|
|
||||||
set network.@switch_vlan[0].ports='5t 6t'
|
|
||||||
set network.@switch_vlan[0].comment='mgmt'
|
|
||||||
{% set switchnum = 1 %}
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}]=switch_vlan
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].device='switch0'
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].vlan='{{ pillar['vlans'][net] }}'
|
|
||||||
# 0: eth1; 1-4: LAN ports in reverse; 5: WAN port; 6: eth0
|
|
||||||
{%- if conf.get('lan-access') == net %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].ports='0 1 2 3 4 5t'
|
|
||||||
{%- else %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].ports='5t 6t'
|
|
||||||
{%- endif %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}'
|
|
||||||
{% set switchnum = switchnum + 1 %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{{ uci_network_mgmt('eth0.1') }}
|
|
||||||
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
set network.{{ net }}=interface
|
|
||||||
set network.{{ net }}.type=bridge
|
|
||||||
set network.{{ net }}.proto=static
|
|
||||||
{%- if conf.get('lan-access') == net %}
|
|
||||||
set network.{{ net }}.ifname='eth1'
|
|
||||||
{%- else %}
|
|
||||||
set network.{{ net }}.ifname='eth0.{{ pillar['vlans'][net] }}'
|
|
||||||
{%- endif %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- elif conf['model'] == 'TL-Archer-C7v2' %}
|
|
||||||
{# These models have a shared Ethernet chip with separate CPU ports for LAN/WAN and therefore need switching #}
|
|
||||||
set network.@switch[0]=switch
|
|
||||||
set network.@switch[0].reset=1
|
|
||||||
set network.@switch[0].enable=1
|
|
||||||
set network.@switch[0].enable_vlan=1
|
|
||||||
set network.@switch[0].name=switch0
|
|
||||||
set network.@switch_vlan[0]=switch_vlan
|
|
||||||
set network.@switch_vlan[0].device='switch0'
|
|
||||||
set network.@switch_vlan[0].vlan='1'
|
|
||||||
set network.@switch_vlan[0].ports='1t 6t'
|
|
||||||
set network.@switch_vlan[0].comment='mgmt'
|
|
||||||
{% set switchnum = 1 %}
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}]=switch_vlan
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].device='switch0'
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].vlan='{{ pillar['vlans'][net] }}'
|
|
||||||
# 0: eth1; 1: WAN port; 2-5: LAN ports; 6: eth0
|
|
||||||
{%- if conf.get('lan-access') == net %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].ports='0 1t 2 3 4 5'
|
|
||||||
{%- else %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].ports='1t 6t'
|
|
||||||
{%- endif %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}'
|
|
||||||
{% set switchnum = switchnum + 1 %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{{ uci_network_mgmt('eth0.1') }}
|
|
||||||
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
set network.{{ net }}=interface
|
|
||||||
set network.{{ net }}.type=bridge
|
|
||||||
set network.{{ net }}.proto=static
|
|
||||||
{%- if conf.get('lan-access') == net %}
|
|
||||||
set network.{{ net }}.ifname='eth1'
|
|
||||||
{%- else %}
|
|
||||||
set network.{{ net }}.ifname='eth0.{{ pillar['vlans'][net] }}'
|
|
||||||
{%- endif %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- elif conf['model'] == 'TL-Archer-C7v4' or conf['model'] == 'TL-Archer-C7v5' %}
|
|
||||||
set network.@switch[0]=switch
|
|
||||||
set network.@switch[0].reset=1
|
|
||||||
set network.@switch[0].enable=1
|
|
||||||
set network.@switch[0].enable_vlan=1
|
|
||||||
set network.@switch[0].name=switch0
|
|
||||||
set network.@switch_vlan[0]=switch_vlan
|
|
||||||
set network.@switch_vlan[0].device='switch0'
|
|
||||||
set network.@switch_vlan[0].vlan='1'
|
|
||||||
set network.@switch_vlan[0].ports='0t 1t'
|
|
||||||
set network.@switch_vlan[0].comment='mgmt'
|
|
||||||
{% set switchnum = 1 %}
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}]=switch_vlan
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].device='switch0'
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].vlan='{{ pillar['vlans'][net] }}'
|
|
||||||
# 0: eth0; 1: WAN port; 2-5: LAN ports
|
|
||||||
{%- if conf.get('lan-access') == net %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].ports='0t 1t 2 3 4 5'
|
|
||||||
{%- else %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].ports='0t 1t'
|
|
||||||
{%- endif %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}'
|
|
||||||
{% set switchnum = switchnum + 1 %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{{ uci_network_mgmt('eth0.1') }}
|
|
||||||
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
set network.{{ net }}=interface
|
|
||||||
set network.{{ net }}.type=bridge
|
|
||||||
set network.{{ net }}.proto=static
|
|
||||||
set network.{{ net }}.ifname='eth0.{{ pillar['vlans'][net] }}'
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- elif conf['model'] == 'TL-WR1043NDv4' or conf['model'] == 'TL-WR1043NDv5' %}
|
|
||||||
set network.@switch[0]=switch
|
|
||||||
set network.@switch[0].reset=1
|
|
||||||
set network.@switch[0].enable=1
|
|
||||||
set network.@switch[0].enable_vlan=1
|
|
||||||
set network.@switch[0].name=switch0
|
|
||||||
set network.@switch_vlan[0]=switch_vlan
|
|
||||||
set network.@switch_vlan[0].device='switch0'
|
|
||||||
set network.@switch_vlan[0].vlan='1'
|
|
||||||
set network.@switch_vlan[0].ports='0t 5t'
|
|
||||||
set network.@switch_vlan[0].comment='mgmt'
|
|
||||||
{% set switchnum = 1 %}
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}]=switch_vlan
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].device='switch0'
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].vlan='{{ pillar['vlans'][net] }}'
|
|
||||||
# 0: eth0; 1-4: LAN ports; 5: WAN port
|
|
||||||
{%- if conf.get('lan-access') == net %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].ports='0t 1 2 3 4 5t'
|
|
||||||
{%- else %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].ports='0t 5t'
|
|
||||||
{%- endif %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}'
|
|
||||||
{% set switchnum = switchnum + 1 %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{{ uci_network_mgmt('eth0.1') }}
|
|
||||||
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
set network.{{ net }}=interface
|
|
||||||
set network.{{ net }}.type=bridge
|
|
||||||
set network.{{ net }}.proto=static
|
|
||||||
set network.{{ net }}.ifname='eth0.{{ pillar['vlans'][net] }}'
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- elif conf['model'] == 'TL-WR841Nv8' %}
|
|
||||||
{# Like v9 but with eth0/1 switched #}
|
|
||||||
set network.@switch[0].reset=1
|
|
||||||
set network.@switch[0].enable=1
|
|
||||||
set network.@switch[0].enable_vlan=0
|
|
||||||
|
|
||||||
{{ uci_network_mgmt('eth0.1') }}
|
|
||||||
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
|
|
||||||
set network.{{ net }}=interface
|
|
||||||
set network.{{ net }}.type=bridge
|
|
||||||
set network.{{ net }}.proto=static
|
|
||||||
{# Add WAN VLAN to bridge #}
|
|
||||||
{%- set ports = ['eth0.' ~ pillar['vlans'][net]] %}
|
|
||||||
{# Add LAN ports to bridge #}
|
|
||||||
{%- if conf.get('lan-access') == net %}
|
|
||||||
{%- do ports.append('eth1') %}
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
set network.{{ net }}.ifname='{{ ' '.join(ports) }}'
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- elif conf['model'] == 'TL-WR740Nv4' %}
|
|
||||||
{# Separate eth0/1 interfaces for LAN/WAN #}
|
|
||||||
{# eth0 - Port 0: eth0, Port 2: LAN1, Port 3: LAN2, Port 4: LAN3, Port 1: LAN4 #}
|
|
||||||
{# eth1 - WAN #}
|
|
||||||
set network.@switch[0].reset=1
|
|
||||||
set network.@switch[0].enable=1
|
|
||||||
set network.@switch[0].enable_vlan=0
|
|
||||||
|
|
||||||
{{ uci_network_mgmt('eth1.1') }}
|
|
||||||
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
|
|
||||||
set network.{{ net }}=interface
|
|
||||||
set network.{{ net }}.type=bridge
|
|
||||||
set network.{{ net }}.proto=static
|
|
||||||
{# Add WAN VLAN to bridge #}
|
|
||||||
{%- set ports = ['eth1.' ~ pillar['vlans'][net]] %}
|
|
||||||
{# Add LAN ports to bridge #}
|
|
||||||
{%- if conf.get('lan-access') == net %}
|
|
||||||
{%- do ports.append('eth0') %}
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
set network.{{ net }}.ifname='{{ ' '.join(ports) }}'
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- elif conf['model'] == 'TL-WA901NDv3' or conf['model'] == 'Ubnt-UniFi-AP-AC-LR' %}
|
|
||||||
{# Only eth0 exists, no switch #}
|
|
||||||
|
|
||||||
{{ uci_network_mgmt('eth0.1') }}
|
|
||||||
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
|
|
||||||
set network.{{ net }}=interface
|
|
||||||
set network.{{ net }}.type=bridge
|
|
||||||
set network.{{ net }}.proto=static
|
|
||||||
{# Add WAN VLAN to bridge #}
|
|
||||||
set network.{{ net }}.ifname='{{ 'eth0.' ~ pillar['vlans'][net] }}'
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- elif conf['model'] == 'Ubnt-UAP-nanoHD' %}
|
|
||||||
{# no switch, eth0 exists but is not usable, using "lan" instead #}
|
|
||||||
|
|
||||||
{{ uci_network_mgmt('lan.1') }}
|
|
||||||
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
|
|
||||||
set network.{{ net }}=interface
|
|
||||||
set network.{{ net }}.type=bridge
|
|
||||||
set network.{{ net }}.proto=static
|
|
||||||
{# Add WAN VLAN to bridge #}
|
|
||||||
set network.{{ net }}.ifname='{{ 'lan.' ~ pillar['vlans'][net] }}'
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- elif conf['model'] == 'DIR-615H1' or conf['model'] == 'DIR-615D4' %}
|
|
||||||
{# All DIR-615 share the same port layout #}
|
|
||||||
delete network.lan_dev
|
|
||||||
delete network.wan_dev
|
|
||||||
{# switch is cpu port 6, wan:cpu port 4, lan port 1 is cpu port 3, lan port 2 is 2 etc #}
|
|
||||||
set network.@switch[0]=switch
|
|
||||||
set network.@switch[0].reset=1
|
|
||||||
set network.@switch[0].enable=1
|
|
||||||
set network.@switch[0].enable_vlan=1
|
|
||||||
set network.@switch[0].name=switch0
|
|
||||||
set network.@switch_vlan[0]=switch_vlan
|
|
||||||
set network.@switch_vlan[0].device='switch0'
|
|
||||||
set network.@switch_vlan[0].vlan='1'
|
|
||||||
set network.@switch_vlan[0].ports='4t 6t'
|
|
||||||
set network.@switch_vlan[0].comment='mgmt'
|
|
||||||
{% set switchnum = 1 %}
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}]=switch_vlan
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].device='switch0'
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].vlan='{{ pillar['vlans'][net] }}'
|
|
||||||
{%- if conf.get('lan-access') == net %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].ports='0 1 2 3 4t 6t'
|
|
||||||
{%- else %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].ports='4t 6t'
|
|
||||||
{%- endif %}
|
|
||||||
set network.@switch_vlan[{{ switchnum }}].comment='{{ net }}'
|
|
||||||
{% set switchnum = switchnum + 1 %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{{ uci_network_mgmt('eth0.1') }}
|
|
||||||
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
set network.{{ net }}=interface
|
|
||||||
set network.{{ net }}.type=bridge
|
|
||||||
set network.{{ net }}.proto=static
|
|
||||||
#TODO: this should consider lan-access
|
|
||||||
set network.{{ net }}.ifname='eth0.{{ pillar['vlans'][net] }}'
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- else %}
|
|
||||||
{# All other models may have separate Ethernet chips for LAN/WAN #}
|
|
||||||
set network.@switch[0].reset=1
|
|
||||||
set network.@switch[0].enable=1
|
|
||||||
set network.@switch[0].enable_vlan=0
|
|
||||||
|
|
||||||
{{ uci_network_mgmt('eth1.1') }}
|
|
||||||
|
|
||||||
{%- for net in bridges.keys() %}
|
|
||||||
|
|
||||||
set network.{{ net }}=interface
|
|
||||||
set network.{{ net }}.type=bridge
|
|
||||||
set network.{{ net }}.proto=static
|
|
||||||
{# Add WAN VLAN to bridge #}
|
|
||||||
{%- set ports = ['eth1.' ~ pillar['vlans'][net]] %}
|
|
||||||
{# Add LAN ports to bridge #}
|
|
||||||
{%- if conf.get('lan-access') == net %}
|
|
||||||
{%- do ports.append('eth0') %}
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
set network.{{ net }}.ifname='{{ ' '.join(ports) }}'
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
{%- set index = { 'radio': 0, 'iface': 0 } %}
|
|
||||||
{%- for path, radio in conf['radios'].items() %}
|
|
||||||
set wireless.radio{{ index.radio }}=wifi-device
|
|
||||||
set wireless.radio{{ index.radio }}.type=mac80211
|
|
||||||
set wireless.radio{{ index.radio }}.country=DE
|
|
||||||
set wireless.radio{{ index.radio }}.channel={{ radio['channel'] }}
|
|
||||||
set wireless.radio{{ index.radio }}.path={{ path }}
|
|
||||||
set wireless.radio{{ index.radio }}.hwmode={{ radio.get('hwmode') or '11n' }}
|
|
||||||
set wireless.radio{{ index.radio }}.htmode={{ radio.get('htmode') or 'HT20' }}
|
|
||||||
set wireless.radio{{ index.radio }}.noscan=1
|
|
||||||
delete wireless.radio{{ index.radio }}.disabled
|
|
||||||
|
|
||||||
{%- for ssid, ssidconf in radio['ssids'].items() %}
|
|
||||||
set wireless.wifi{{ index.iface }}=wifi-iface
|
|
||||||
{%- if radio['channel'] < 15 %}
|
|
||||||
{%- if conf['version'] == "nightly" %}
|
|
||||||
{%- set ifprefix = 'wlan2_' %}
|
|
||||||
{%- else %}
|
|
||||||
{%- set ifprefix = 'wlan2-' %}
|
|
||||||
{%- endif %}
|
|
||||||
{%- else %}
|
|
||||||
{%- if conf['version'] == "nightly" %}
|
|
||||||
{%- set ifprefix = 'wlan5_' %}
|
|
||||||
{%- else %}
|
|
||||||
{%- set ifprefix = 'wlan5-' %}
|
|
||||||
{%- endif %}
|
|
||||||
{%- endif %}
|
|
||||||
{%- if ssidconf.get('wpa-eap') %}
|
|
||||||
{%- if conf['version'] == "nightly" %}
|
|
||||||
{%- set ifsuffix = '_eap' %}
|
|
||||||
{%- else %}
|
|
||||||
{%- set ifsuffix = '-eap' %}
|
|
||||||
{%- endif %}
|
|
||||||
{%- else %}
|
|
||||||
{%- set ifsuffix = '' %}
|
|
||||||
{%- endif %}
|
|
||||||
set wireless.wifi{{ index.iface }}.ifname={{ ifprefix }}{{ ssidconf['net'] }}{{ ifsuffix }}
|
|
||||||
set wireless.wifi{{ index.iface }}.device=radio{{ index.radio }}
|
|
||||||
set wireless.wifi{{ index.iface }}.ssid='{{ ssid }}'
|
|
||||||
set wireless.wifi{{ index.iface }}.mode=ap
|
|
||||||
set wireless.wifi{{ index.iface }}.network={{ ssidconf['net'] }}
|
|
||||||
{%- if ssidconf.get('psk') %}
|
|
||||||
set wireless.wifi{{ index.iface }}.encryption=psk2
|
|
||||||
set wireless.wifi{{ index.iface }}.key='{{ ssidconf['psk'] }}'
|
|
||||||
{%- elif ssidconf.get('wpa-eap') %}
|
|
||||||
set wireless.wifi{{ index.iface }}.encryption=wpa2
|
|
||||||
set wireless.wifi{{ index.iface }}.server='{{ ssidconf['wpa-eap']['server'] }}'
|
|
||||||
set wireless.wifi{{ index.iface }}.port='{{ ssidconf['wpa-eap']['port'] }}'
|
|
||||||
set wireless.wifi{{ index.iface }}.auth_secret='{{ ssidconf['wpa-eap']['secret'] }}'
|
|
||||||
{%- else %}
|
|
||||||
set wireless.wifi{{ index.iface }}.encryption=none
|
|
||||||
delete wireless.wifi{{ index.iface }}.key
|
|
||||||
{%- endif %}
|
|
||||||
set wireless.wifi{{ index.iface }}.mcast_rate=18000
|
|
||||||
|
|
||||||
{%- set x = index.update({ 'iface': index.iface + 1 }) %}
|
|
||||||
{%- endfor %}
|
|
||||||
{%- set x = index.update({ 'radio': index.radio + 1 }) %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
commit
|
|
||||||
__UCI__
|
|
||||||
|
|
||||||
# Cronjob that makes sure WiFi is only visible when server with all
|
|
||||||
# the gateways is reachable
|
|
||||||
cat >/etc/crontabs/root <<__CRON__
|
|
||||||
* * * * * /usr/sbin/wifi-on-link.sh
|
|
||||||
__CRON__
|
|
||||||
cat >/usr/sbin/wifi-on-link.sh <<__SH__
|
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
if (ping -c 1 -W 3 {{ pillar['hosts-inet']['mgmt']['mgmt-gw'] }}) ; then
|
|
||||||
REACHABLE=y
|
|
||||||
else
|
|
||||||
REACHABLE=n
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "\\\$(cat /sys/class/net/wlan2-pub/operstate)" == "up" ] ; then
|
|
||||||
UP=y
|
|
||||||
else
|
|
||||||
UP=n
|
|
||||||
fi
|
|
||||||
|
|
||||||
{%- if conf.get("error-led") %}
|
|
||||||
ERROR_LED=/sys/class/leds/{{ conf["error-led"] }}/brightness
|
|
||||||
[ \\\$REACHABLE = y ] && echo 0 > \\\$ERROR_LED
|
|
||||||
[ \\\$REACHABLE = n ] && echo 1 > \\\$ERROR_LED
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
[ \\\$REACHABLE = y ] && [ \\\$UP = n ] && wifi up
|
|
||||||
[ \\\$REACHABLE = n ] && [ \\\$UP = y ] && wifi down
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
__SH__
|
|
||||||
chmod a+rx /usr/sbin/wifi-on-link.sh
|
|
||||||
/etc/init.d/cron restart
|
|
||||||
|
|
||||||
for svc in dnsmasq uhttpd ; do
|
|
||||||
rm /etc/rc.d/*\$svc
|
|
||||||
/etc/init.d/\$svc stop
|
|
||||||
done
|
|
||||||
|
|
||||||
{%- if conf.get('firstboot') %}
|
|
||||||
reboot
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
__SSH__
|
|
||||||
|
|
||||||
echo "Base configuration done \\o/"
|
|
||||||
echo "Later run: `dirname $0`/ap_install_collectd.sh {{ pillar['hosts-inet']['mgmt'][hostname] }}"
|
|
|
@ -1,34 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
for HOST in $@ ; do
|
|
||||||
ssh root@$HOST \
|
|
||||||
"ash -e -x" <<__SSH__
|
|
||||||
opkg update
|
|
||||||
opkg install collectd collectd-mod-interface collectd-mod-load collectd-mod-cpu collectd-mod-iwinfo collectd-mod-network
|
|
||||||
cat > /etc/collectd.conf <<EOF
|
|
||||||
Hostname "\$HOSTNAME"
|
|
||||||
FQDNLookup false
|
|
||||||
Interval 10
|
|
||||||
|
|
||||||
BaseDir "/var/run/collectd"
|
|
||||||
Include "/etc/collectd/conf.d"
|
|
||||||
PIDFile "/var/run/collectd.pid"
|
|
||||||
PluginDir "/usr/lib/collectd"
|
|
||||||
TypesDB "/usr/share/collectd/types.db"
|
|
||||||
|
|
||||||
LoadPlugin cpu
|
|
||||||
LoadPlugin load
|
|
||||||
LoadPlugin interface
|
|
||||||
LoadPlugin iwinfo
|
|
||||||
LoadPlugin network
|
|
||||||
<Plugin network>
|
|
||||||
Server "{{ pillar['hosts-inet6']['dn42']['serv']['stats'] }}" "25826"
|
|
||||||
</Plugin>
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
/etc/init.d/collectd restart
|
|
||||||
/etc/init.d/collectd enable
|
|
||||||
|
|
||||||
__SSH__
|
|
||||||
done
|
|
|
@ -1,17 +0,0 @@
|
||||||
{%- for hostname, conf in pillar['cpe'].items() %}
|
|
||||||
/root/{{ hostname }}.sh:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://cpe/ap.sh
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
hostname: {{ hostname }}
|
|
||||||
conf: {{ conf }}
|
|
||||||
- mode: 755
|
|
||||||
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
/root/ap_install_collectd.sh:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://cpe/ap_install_collectd.sh
|
|
||||||
- template: 'jinja'
|
|
||||||
- mode: 755
|
|
|
@ -1,9 +0,0 @@
|
||||||
{%- set ifaces = [] %}
|
|
||||||
{%- for iface, ips in salt['grains.get']('ip_interfaces').items() %}
|
|
||||||
{%- if iface not in ['core', 'lo'] and pillar['subnets-inet'].get(iface) %}
|
|
||||||
{%- set ifaces = ifaces.append(iface) %}
|
|
||||||
{%- endif %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
INTERFACESv4="{{ ' '.join(ifaces) }}"
|
|
||||||
INTERFACESv6=""
|
|
|
@ -1,39 +0,0 @@
|
||||||
{%- import_yaml "netmasks.yaml" as netmasks -%}
|
|
||||||
{%- for iface, ips in salt['grains.get']('ip_interfaces').items() %}
|
|
||||||
{%- if iface not in ['core', 'lo'] and pillar['subnets-inet'].get(iface) %}
|
|
||||||
group {
|
|
||||||
{%- set conf = pillar['dhcp'][iface] %}
|
|
||||||
default-lease-time {{ conf['time'] }};
|
|
||||||
max-lease-time {{ conf['max-time'] }};
|
|
||||||
{%- if conf.get('lower-max-time') and conf.get('time') %}
|
|
||||||
min-lease-time {{ conf['time'] }};
|
|
||||||
adaptive-lease-time-threshold {{ conf['lower-max-time'] }};
|
|
||||||
{%- endif %}
|
|
||||||
{%- for name, value in (conf.get('opts') or {}).items() %}
|
|
||||||
option {{ name }} {{ value }};
|
|
||||||
{%- endfor %}
|
|
||||||
{%- for name, value in (conf.get('host-opts') or {}).items() %}
|
|
||||||
{%- set host = value.split('.')[0] %}
|
|
||||||
{%- set net = value.split('.')[1] %}
|
|
||||||
option {{ name }} {{ pillar['hosts-inet'][net][host] }};
|
|
||||||
{%- endfor %}
|
|
||||||
{%- for name, value in (conf.get('string-opts') or {}).items() %}
|
|
||||||
option {{ name }} "{{ value }}";
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- set subnet = pillar['subnets-inet'][iface] %}
|
|
||||||
subnet {{ subnet.split('/')[0] }} netmask {{ netmasks[subnet.split('/')[1]] }} {
|
|
||||||
authoritative;
|
|
||||||
range {{ conf['start'] }} {{ conf['end'] }};
|
|
||||||
}
|
|
||||||
|
|
||||||
{%- for addr, hwaddr in (conf.get('fixed-hosts') or {}).items() %}
|
|
||||||
host {{ addr }} {
|
|
||||||
hardware ethernet {{ hwaddr }};
|
|
||||||
fixed-address {{ addr }};
|
|
||||||
}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
}
|
|
||||||
{%- endif %}
|
|
||||||
{%- endfor %}
|
|
|
@ -1,31 +0,0 @@
|
||||||
isc-dhcp-server:
|
|
||||||
pkg.installed: []
|
|
||||||
service:
|
|
||||||
- running
|
|
||||||
|
|
||||||
/etc/dhcp/dhcpd.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://dhcp/dhcpd.conf
|
|
||||||
- template: 'jinja'
|
|
||||||
|
|
||||||
/etc/default/isc-dhcp-server:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://dhcp/default
|
|
||||||
- template: 'jinja'
|
|
||||||
|
|
||||||
autostart-dhcpd:
|
|
||||||
service.enabled:
|
|
||||||
- name: isc-dhcp-server
|
|
||||||
require_in:
|
|
||||||
- file: /etc/dhcp/dhcpd.conf
|
|
||||||
- file: /etc/default/isc-dhcp-server
|
|
||||||
|
|
||||||
start-dhcpd:
|
|
||||||
service.running:
|
|
||||||
- name: isc-dhcp-server
|
|
||||||
require_in:
|
|
||||||
- file: /etc/dhcp/dhcpd.conf
|
|
||||||
- file: /etc/default/isc-dhcp-server
|
|
||||||
watch:
|
|
||||||
- pkg: isc-dhcp-server
|
|
||||||
- file: /etc/dhcp/dhcpd.conf
|
|
|
@ -1,32 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
|
||||||
|
|
||||||
if [ "$IFACE" = "{{ interface }}" ]; then
|
|
||||||
iptables -F FORWARD
|
|
||||||
ip6tables -F FORWARD
|
|
||||||
iptables -P FORWARD DROP
|
|
||||||
ip6tables -P FORWARD DROP
|
|
||||||
iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
|
|
||||||
ip6tables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
|
|
||||||
# loopback
|
|
||||||
iptables -A FORWARD -i lo -j ACCEPT
|
|
||||||
ip6tables -A FORWARD -i lo -j ACCEPT
|
|
||||||
# DNS
|
|
||||||
iptables -A FORWARD -i $IFACE -p udp --dport 53 -j ACCEPT
|
|
||||||
ip6tables -A FORWARD -i $IFACE -p udp --dport 53 -j ACCEPT
|
|
||||||
# NTP
|
|
||||||
iptables -A FORWARD -i $IFACE -p udp --dport 123 -j ACCEPT
|
|
||||||
ip6tables -A FORWARD -i $IFACE -p udp --dport 123 -j ACCEPT
|
|
||||||
# collectd
|
|
||||||
iptables -A FORWARD -i $IFACE -p udp --dport 25826 -j ACCEPT
|
|
||||||
ip6tables -A FORWARD -i $IFACE -p udp --dport 25826 -j ACCEPT
|
|
||||||
# downloads.openwrt.org
|
|
||||||
iptables -A FORWARD -i $IFACE --dest 176.9.48.73 -j ACCEPT
|
|
||||||
ip6tables -A FORWARD -i $IFACE --dest 2a01:4f8:150:6449::2 -j ACCEPT
|
|
||||||
# radius.hq.c3d2.de
|
|
||||||
iptables -A FORWARD -i $IFACE --dest 172.22.99.22 -j ACCEPT
|
|
||||||
# Deny by default
|
|
||||||
iptables -A FORWARD -j REJECT
|
|
||||||
ip6tables -A FORWARD -j REJECT
|
|
||||||
fi
|
|
|
@ -1,12 +0,0 @@
|
||||||
iptables:
|
|
||||||
pkg.installed: []
|
|
||||||
|
|
||||||
/etc/network/if-pre-up.d/firewall:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://firewall/mgmt-gw.sh
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
interface: mgmt
|
|
||||||
- mode: 744
|
|
||||||
- require:
|
|
||||||
- pkg: iptables
|
|
|
@ -1,21 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
|
||||||
|
|
||||||
if echo "$IFACE" | grep priv >/dev/null; then
|
|
||||||
iptables -F FORWARD
|
|
||||||
ip6tables -F FORWARD
|
|
||||||
iptables -P FORWARD DROP
|
|
||||||
ip6tables -P FORWARD DROP
|
|
||||||
iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
|
|
||||||
ip6tables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
|
|
||||||
# loopback
|
|
||||||
iptables -A FORWARD -i lo -j ACCEPT
|
|
||||||
ip6tables -A FORWARD -i lo -j ACCEPT
|
|
||||||
# Trust priv
|
|
||||||
iptables -A FORWARD -i $IFACE -j ACCEPT
|
|
||||||
ip6tables -A FORWARD -i $IFACE -j ACCEPT
|
|
||||||
# Deny by default
|
|
||||||
iptables -A FORWARD -j REJECT
|
|
||||||
ip6tables -A FORWARD -j REJECT
|
|
||||||
fi
|
|
|
@ -1,10 +0,0 @@
|
||||||
iptables:
|
|
||||||
pkg.installed: []
|
|
||||||
|
|
||||||
/etc/network/if-pre-up.d/firewall:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://firewall/priv-stateful.sh
|
|
||||||
- template: 'jinja'
|
|
||||||
- mode: 744
|
|
||||||
- require:
|
|
||||||
- pkg: iptables
|
|
|
@ -1 +0,0 @@
|
||||||
fs.inotify.max_user_instances=512
|
|
|
@ -1,10 +0,0 @@
|
||||||
/etc/sysctl.d/20-lxc-inotify.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: "salt://fixes/lxc-inotify.conf"
|
|
||||||
|
|
||||||
apply-lxc-inotify:
|
|
||||||
cmd.run:
|
|
||||||
- name: sysctl -p /etc/sysctl.d/20-lxc-inotify.conf
|
|
||||||
require:
|
|
||||||
- file: /etc/sysctl.d/20-lxc-inotify.conf
|
|
||||||
- pkg: procps
|
|
|
@ -1,4 +0,0 @@
|
||||||
net.ipv4.conf.all.forwarding = 1
|
|
||||||
net.ipv4.conf.default.forwarding = 1
|
|
||||||
net.ipv6.conf.all.forwarding = 1
|
|
||||||
net.ipv6.conf.default.forwarding = 1
|
|
|
@ -1,13 +0,0 @@
|
||||||
procps:
|
|
||||||
pkg.installed: []
|
|
||||||
|
|
||||||
/etc/sysctl.d/80-forwarding.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: "salt://forwarding/forwarding.conf"
|
|
||||||
|
|
||||||
apply-forwarding:
|
|
||||||
cmd.run:
|
|
||||||
- name: sysctl -p /etc/sysctl.d/80-forwarding.conf
|
|
||||||
require:
|
|
||||||
- file: /etc/sysctl.d/80-forwarding.conf
|
|
||||||
- pkg: procps
|
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
cd ${LXC_ROOTFS_MOUNT}/dev
|
|
||||||
|
|
||||||
mkdir net
|
|
||||||
mknod net/tun c 10 200
|
|
||||||
chmod 0666 net/tun
|
|
|
@ -1,70 +0,0 @@
|
||||||
# For lxcfs and sane defaults
|
|
||||||
lxc.include = /usr/share/lxc/config/common.conf
|
|
||||||
|
|
||||||
lxc.utsname = {{ id }}
|
|
||||||
# Handled by lxc@.service
|
|
||||||
lxc.start.auto = 0
|
|
||||||
lxc.rootfs = /var/lib/lxc/{{ id }}/rootfs
|
|
||||||
lxc.rootfs.backend = dir
|
|
||||||
|
|
||||||
lxc.autodev = 1
|
|
||||||
lxc.kmsg = 0
|
|
||||||
|
|
||||||
{%- set n = 0 %}
|
|
||||||
{%- for net, conf in container['interfaces'].items() %}
|
|
||||||
lxc.network.type={{ conf['type'] }}
|
|
||||||
lxc.network.flags=up
|
|
||||||
{%- if conf.get('hwaddr') %}
|
|
||||||
lxc.network.hwaddr={{ conf['hwaddr'] }}
|
|
||||||
{%- else %}
|
|
||||||
lxc.network.hwaddr={{ hwaddr_prefix }}:{{ n.__str__().rjust(2, '0') }}
|
|
||||||
{%- endif %}
|
|
||||||
{%- if conf['type'] == 'veth' %}
|
|
||||||
lxc.network.veth.pair={{ id }}-{{ net }}
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
{%- set hosts = pillar['hosts-inet'].get(net) %}
|
|
||||||
{%- set inet_addr = hosts and hosts.get(id) %}
|
|
||||||
{%- if inet_addr %}
|
|
||||||
{%- set prefix_len = pillar['subnets-inet'][net].split('/')[1] %}
|
|
||||||
lxc.network.ipv4={{ inet_addr }}/{{ prefix_len }}
|
|
||||||
{%- endif %}
|
|
||||||
{%- set gw = conf.get('gw') %}
|
|
||||||
{%- if gw %}
|
|
||||||
lxc.network.ipv4.gateway={{ pillar['hosts-inet'][net][gw] }}
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
{%- for ctx, hosts in pillar['hosts-inet6'].items() %}
|
|
||||||
{%- set hosts6 = hosts.get(net) %}
|
|
||||||
{%- set inet6_addr = hosts6 and hosts6.get(id) %}
|
|
||||||
{%- set prefix6 = pillar['subnets-inet6'][ctx].get(net) %}
|
|
||||||
{%- if inet6_addr and prefix6 %}
|
|
||||||
{%- set prefix6_len = prefix6.split('/')[1] %}
|
|
||||||
lxc.network.ipv6={{ inet6_addr }}/{{ prefix6_len }}
|
|
||||||
{%- endif %}
|
|
||||||
{%- set gw6 = conf.get('gw6') %}
|
|
||||||
{%- if gw6 and hosts.get(net) and hosts[net].get(gw6) %}
|
|
||||||
lxc.network.ipv6.gateway={{ hosts[net][gw6] }}
|
|
||||||
{%- endif %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- if conf['type'] == 'veth' %}
|
|
||||||
lxc.network.link=br-{{ net }}
|
|
||||||
{%- elif conf['type'] == 'phys' %}
|
|
||||||
lxc.network.link=bond0.{{ pillar['vlans'].get(net) }}
|
|
||||||
{%- endif %}
|
|
||||||
lxc.network.name={{ net }}
|
|
||||||
|
|
||||||
{%- set n = n + 1 %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
|
|
||||||
lxc.cap.drop = sys_module sys_time sys_nice sys_pacct sys_rawio sys_time mknod
|
|
||||||
|
|
||||||
lxc.cgroup.memory.limit_in_bytes = 4G
|
|
||||||
lxc.cgroup.memory.kmem.tcp.limit_in_bytes = 512M
|
|
||||||
|
|
||||||
|
|
||||||
# tuntap
|
|
||||||
lxc.cgroup.devices.allow = c 10:200 rw
|
|
||||||
lxc.hook.autodev = /var/lib/lxc/autodev.sh
|
|
|
@ -1,10 +0,0 @@
|
||||||
127.0.0.1 localhost
|
|
||||||
::1 localhost ip6-localhost ip6-loopback
|
|
||||||
|
|
||||||
{% for net, hosts in pillar['hosts-inet'].items() %}
|
|
||||||
{% if hosts.get(id) %}
|
|
||||||
{{ hosts[id] }} {{ id }}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{{ pillar['hosts-inet']['core']['server1'] }} salt
|
|
|
@ -1,53 +0,0 @@
|
||||||
lxc:
|
|
||||||
pkg.installed: []
|
|
||||||
|
|
||||||
/var/lib/lxc/autodev.sh:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://lxc-containers/autodev.sh
|
|
||||||
mode: 0755
|
|
||||||
|
|
||||||
{%- set n = 0 %}
|
|
||||||
{%- for id, container in pillar['containers'].items() %}
|
|
||||||
|
|
||||||
/var/lib/lxc/{{ id }}:
|
|
||||||
cmd.run:
|
|
||||||
- name: lxc-create -n {{ id }} -B dir -t debian -- -r stretch --packages=salt-minion
|
|
||||||
- require:
|
|
||||||
- pkg: lxc
|
|
||||||
- creates: /var/lib/lxc/{{ id }}
|
|
||||||
|
|
||||||
/var/lib/lxc/{{ id }}/config:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://lxc-containers/config
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
id: {{ id }}
|
|
||||||
container: {{ container }}
|
|
||||||
hwaddr_prefix: '0A:14:48:01:{{ n.__str__().rjust(2, '0') }}'
|
|
||||||
- require:
|
|
||||||
- cmd: /var/lib/lxc/{{ id }}
|
|
||||||
|
|
||||||
/var/lib/lxc/{{ id }}/rootfs/etc/hosts:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://lxc-containers/hosts
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
id: {{ id }}
|
|
||||||
container: {{ container }}
|
|
||||||
- require:
|
|
||||||
- cmd: /var/lib/lxc/{{ id }}
|
|
||||||
|
|
||||||
autostart-{{ id }}:
|
|
||||||
service.enabled:
|
|
||||||
- name: lxc@{{ id }}
|
|
||||||
require_in:
|
|
||||||
file: /var/lib/lxc/{{ id }}/config
|
|
||||||
|
|
||||||
start-{{ id }}:
|
|
||||||
service.running:
|
|
||||||
- name: lxc@{{ id }}
|
|
||||||
require:
|
|
||||||
- service: autostart-{{ id }}
|
|
||||||
|
|
||||||
{%- set n = n + 1 %}
|
|
||||||
{% endfor %}
|
|
|
@ -1,2 +0,0 @@
|
||||||
lxc:
|
|
||||||
pkg.installed: []
|
|
|
@ -1,3 +0,0 @@
|
||||||
ip6table_nat
|
|
||||||
ip6t_MASQUERADE
|
|
||||||
wireguard
|
|
|
@ -1,33 +0,0 @@
|
||||||
'0': 0.0.0.0
|
|
||||||
'1': 128.0.0.0
|
|
||||||
'2': 192.0.0.0
|
|
||||||
'3': 224.0.0.0
|
|
||||||
'4': 240.0.0.0
|
|
||||||
'5': 248.0.0.0
|
|
||||||
'6': 252.0.0.0
|
|
||||||
'7': 254.0.0.0
|
|
||||||
'8': 255.0.0.0
|
|
||||||
'9': 255.128.0.0
|
|
||||||
'10': 255.192.0.0
|
|
||||||
'11': 255.224.0.0
|
|
||||||
'12': 255.240.0.0
|
|
||||||
'13': 255.248.0.0
|
|
||||||
'14': 255.252.0.0
|
|
||||||
'15': 255.254.0.0
|
|
||||||
'16': 255.255.0.0
|
|
||||||
'17': 255.255.128.0
|
|
||||||
'18': 255.255.192.0
|
|
||||||
'19': 255.255.224.0
|
|
||||||
'20': 255.255.240.0
|
|
||||||
'21': 255.255.248.0
|
|
||||||
'22': 255.255.252.0
|
|
||||||
'23': 255.255.254.0
|
|
||||||
'24': 255.255.255.0
|
|
||||||
'25': 255.255.255.128
|
|
||||||
'26': 255.255.255.192
|
|
||||||
'27': 255.255.255.224
|
|
||||||
'28': 255.255.255.240
|
|
||||||
'29': 255.255.255.248
|
|
||||||
'30': 255.255.255.252
|
|
||||||
'31': 255.255.255.254
|
|
||||||
'32': 255.255.255.255
|
|
|
@ -1,2 +0,0 @@
|
||||||
openssh-server:
|
|
||||||
pkg.purged: []
|
|
|
@ -1,6 +0,0 @@
|
||||||
salt-master:
|
|
||||||
pkg.installed: []
|
|
||||||
service.running:
|
|
||||||
- require:
|
|
||||||
- pkg: salt-master
|
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
{%- import_yaml "netmasks.yaml" as netmasks -%}
|
|
||||||
{% set bond_slaves = ['enp3s0f0', 'enp3s0f1', 'enp4s0f0', 'enp4s0f1'] %}
|
|
||||||
|
|
||||||
/etc/modules-load.d/server1.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://modules.conf
|
|
||||||
- mode: 644
|
|
||||||
|
|
||||||
/etc/network/if-up.d/bond-slaves:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://bond-slaves
|
|
||||||
- mode: 755
|
|
||||||
|
|
||||||
bond0:
|
|
||||||
network.managed:
|
|
||||||
- name: bond0
|
|
||||||
proto: manual
|
|
||||||
type: bond
|
|
||||||
mode: 802.3ad
|
|
||||||
slaves: {{ ' '.join(bond_slaves) }}
|
|
||||||
miimon: 100
|
|
||||||
updelay: 1000
|
|
||||||
downdelay: 1000
|
|
||||||
lacp_rate: 1
|
|
||||||
xmit_hash_policy: layer3+4
|
|
||||||
require:
|
|
||||||
- file: /etc/network/if-up.d/bond-slaves
|
|
||||||
|
|
||||||
{% for name, vlan in pillar['vlans'].items() %}
|
|
||||||
bond0.{{ vlan }}:
|
|
||||||
network.managed:
|
|
||||||
- type: vlan
|
|
||||||
proto: manual
|
|
||||||
use:
|
|
||||||
- network: bond0
|
|
||||||
require:
|
|
||||||
- network: bond0
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{%- set bridge_nets = ['mgmt', 'core', 'serv', 'pub', 'c3d2'] %}
|
|
||||||
{%- for net in bridge_nets %}
|
|
||||||
{%- set vlan = pillar['vlans'][net] %}
|
|
||||||
br-{{ net }}:
|
|
||||||
network.managed:
|
|
||||||
- type: bridge
|
|
||||||
ports: bond0.{{ vlan }}
|
|
||||||
delay: 0
|
|
||||||
{%- set ip_addr = pillar['hosts-inet'].get(net) and pillar['hosts-inet'][net].get('server1') %}
|
|
||||||
{%- if ip_addr %}
|
|
||||||
{%- set prefix_len = pillar['subnets-inet'][net].split('/')[1] %}
|
|
||||||
proto: static
|
|
||||||
address: {{ ip_addr }}
|
|
||||||
netmask: {{ netmasks[prefix_len] }}
|
|
||||||
{%- if net == 'core' %}
|
|
||||||
gateway: {{ pillar['hosts-inet']['core']['upstream1'] }}
|
|
||||||
dns-nameservers: "{{ pillar['hosts-inet']['core']['upstream1'] }} {{ pillar['hosts-inet']['core']['upstream2'] }}"
|
|
||||||
{%- endif %}
|
|
||||||
{%- else %}
|
|
||||||
proto: manual
|
|
||||||
ipv6_autoconf: no
|
|
||||||
enable_ipv6: false
|
|
||||||
{%- endif %}
|
|
||||||
use:
|
|
||||||
- network: bond0.{{ vlan }}
|
|
||||||
require:
|
|
||||||
- network: bond0.{{ vlan}}
|
|
||||||
{%- endfor %}
|
|
|
@ -1,12 +0,0 @@
|
||||||
{%- for hostname, switch in pillar['switches'].items() %}
|
|
||||||
/root/{{ hostname }}.expect:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://switches/{{ switch['model'] }}.expect
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
hostname: {{ hostname }}
|
|
||||||
switch: {{ switch }}
|
|
||||||
logging: {{ pillar['hosts-inet']['mgmt']['logging'] }}
|
|
||||||
- mode: 755
|
|
||||||
|
|
||||||
{%- endfor %}
|
|
62
salt/top.sls
62
salt/top.sls
|
@ -1,62 +0,0 @@
|
||||||
base:
|
|
||||||
'server1':
|
|
||||||
- salt-master
|
|
||||||
- server1-network
|
|
||||||
- lxc-containers
|
|
||||||
- bird
|
|
||||||
- switches
|
|
||||||
- cpe
|
|
||||||
- collectd
|
|
||||||
- 'fixes.lxc-inotify'
|
|
||||||
'priv*-gw':
|
|
||||||
- no-ssh
|
|
||||||
- forwarding
|
|
||||||
- bird
|
|
||||||
- dhcp
|
|
||||||
- collectd
|
|
||||||
'priv13-gw':
|
|
||||||
- firewall.priv-stateful
|
|
||||||
'pub-gw':
|
|
||||||
- dhcp
|
|
||||||
- collectd
|
|
||||||
'pub-gw or serv-gw or cls-gw or c3d2-gw* or c3d2-anon or mgmt-gw':
|
|
||||||
- no-ssh
|
|
||||||
- forwarding
|
|
||||||
- bird
|
|
||||||
'mgmt-gw':
|
|
||||||
- firewall.mgmt-gw
|
|
||||||
'bgp':
|
|
||||||
- no-ssh
|
|
||||||
- forwarding
|
|
||||||
- bird
|
|
||||||
'upstream*':
|
|
||||||
- no-ssh
|
|
||||||
- forwarding
|
|
||||||
- bird
|
|
||||||
- upstream.dhcp
|
|
||||||
- upstream.shaping
|
|
||||||
- upstream.dyndns
|
|
||||||
- upstream.port-forwarding
|
|
||||||
- collectd
|
|
||||||
'upstream2':
|
|
||||||
- upstream.ipv6-tunnel
|
|
||||||
'upstream1':
|
|
||||||
- upstream.6slac
|
|
||||||
- upstream.dhcp6
|
|
||||||
- upstream.routes
|
|
||||||
'anon*':
|
|
||||||
- no-ssh
|
|
||||||
- forwarding
|
|
||||||
- bird
|
|
||||||
- wireguard
|
|
||||||
- upstream.masquerade
|
|
||||||
- upstream.shaping
|
|
||||||
- upstream.nat66
|
|
||||||
- upstream.dyndns
|
|
||||||
- collectd
|
|
||||||
'dns':
|
|
||||||
- no-ssh
|
|
||||||
- bind
|
|
||||||
'stats':
|
|
||||||
- no-ssh
|
|
||||||
- collectd
|
|
|
@ -1,38 +0,0 @@
|
||||||
# https://dn42.net/services/dns/Configuration#forwarder-setup_unbound
|
|
||||||
|
|
||||||
server:
|
|
||||||
domain-insecure: "dn42"
|
|
||||||
domain-insecure: "20.172.in-addr.arpa"
|
|
||||||
domain-insecure: "21.172.in-addr.arpa"
|
|
||||||
domain-insecure: "22.172.in-addr.arpa"
|
|
||||||
domain-insecure: "23.172.in-addr.arpa"
|
|
||||||
domain-insecure: "d.f.ip6.arpa"
|
|
||||||
local-zone: "20.172.in-addr.arpa." nodefault
|
|
||||||
local-zone: "21.172.in-addr.arpa." nodefault
|
|
||||||
local-zone: "22.172.in-addr.arpa." nodefault
|
|
||||||
local-zone: "23.172.in-addr.arpa." nodefault
|
|
||||||
local-zone: "d.f.ip6.arpa." nodefault
|
|
||||||
|
|
||||||
forward-zone:
|
|
||||||
name: "dn42"
|
|
||||||
forward-addr: 172.23.0.53
|
|
||||||
|
|
||||||
forward-zone:
|
|
||||||
name: "20.172.in-addr.arpa"
|
|
||||||
forward-addr: 172.23.0.53
|
|
||||||
|
|
||||||
forward-zone:
|
|
||||||
name: "22.172.in-addr.arpa"
|
|
||||||
forward-addr: 172.23.0.53
|
|
||||||
|
|
||||||
forward-zone:
|
|
||||||
name: "99.22.172.in-addr.arpa"
|
|
||||||
forward-host: "ns.c3d2.de"
|
|
||||||
|
|
||||||
forward-zone:
|
|
||||||
name: "23.172.in-addr.arpa"
|
|
||||||
forward-addr: 172.23.0.53
|
|
||||||
|
|
||||||
forward-zone:
|
|
||||||
name: "d.f.ip6.arpa"
|
|
||||||
forward-addr: 172.23.0.53
|
|
|
@ -1,15 +0,0 @@
|
||||||
server:
|
|
||||||
# DNS-over-TLS
|
|
||||||
ssl-upstream: yes
|
|
||||||
|
|
||||||
forward-zone:
|
|
||||||
name: "."
|
|
||||||
forward-addr: 9.9.9.9@853 # quad9.net primary
|
|
||||||
forward-addr: 149.112.112.112@853 # quad9.net secondary
|
|
||||||
forward-addr: 145.100.185.15@853 # dnsovertls.sinodun.com US
|
|
||||||
forward-addr: 145.100.185.16@853 # dnsovertls1.sinodun.com US
|
|
||||||
forward-addr: 184.105.193.78@853 # tls-dns-u.odvr.dns-oarc.net US
|
|
||||||
forward-addr: 185.49.141.37@853 # getdnsapi.net US
|
|
||||||
forward-addr: 199.58.81.218@853 # dns.cmrg.net US
|
|
||||||
forward-addr: 146.185.167.43@853 # securedns.eu Europe
|
|
||||||
forward-addr: 89.233.43.71@853 # unicast.censurfridns.dk Europe
|
|
|
@ -1,36 +0,0 @@
|
||||||
unbound:
|
|
||||||
pkg.installed: []
|
|
||||||
service:
|
|
||||||
- running
|
|
||||||
- watch:
|
|
||||||
- pkg: unbound
|
|
||||||
- file: /etc/unbound/unbound.conf.d/listen.conf
|
|
||||||
|
|
||||||
dns-root-data:
|
|
||||||
pkg.installed: []
|
|
||||||
|
|
||||||
/etc/unbound/unbound.conf.d/listen.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://unbound/listen.conf
|
|
||||||
|
|
||||||
/etc/unbound/unbound.conf.d/root.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://unbound/root.conf
|
|
||||||
|
|
||||||
/etc/unbound/unbound.conf.d/forward.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://unbound/forward.conf
|
|
||||||
|
|
||||||
/etc/unbound/unbound.conf.d/verbose.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://unbound/verbose.conf
|
|
||||||
|
|
||||||
/etc/unbound/unbound.conf.d/local-zones.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://unbound/local-zones.conf
|
|
||||||
- template: 'jinja'
|
|
||||||
|
|
||||||
/etc/unbound/unbound.conf.d/dn42-zones.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://unbound/dn42-zones.conf
|
|
||||||
- template: 'jinja'
|
|
|
@ -1,16 +0,0 @@
|
||||||
server:
|
|
||||||
interface: 0.0.0.0
|
|
||||||
access-control: 172.20.72.0/21 allow
|
|
||||||
access-control: 10.0.0.0/24 allow
|
|
||||||
access-control: 172.22.99.0/24 allow
|
|
||||||
access-control: 127.0.0.0/8 allow
|
|
||||||
access-control: 0.0.0.0/0 refuse
|
|
||||||
|
|
||||||
interface: ::
|
|
||||||
access-control: fd23:42:c3d2:500::/56 allow
|
|
||||||
access-control: 2a02:8106:208:5200::/56 allow
|
|
||||||
access-control: 2a02:8106:211:e900::/56 allow
|
|
||||||
access-control: ::172.20.72.0/117 allow
|
|
||||||
access-control: ::172.22.99.0/120 allow
|
|
||||||
access-control: ::1/128 allow
|
|
||||||
access-control: ::/0 deny
|
|
|
@ -1,27 +0,0 @@
|
||||||
server:
|
|
||||||
{%- for ctx, domain in pillar['bind']['root-domain'].items() %}
|
|
||||||
domain-insecure: "{{ domain }}"
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- for ctx, domain in pillar['bind']['root-domain'].items() %}
|
|
||||||
forward-zone:
|
|
||||||
name: "{{ domain }}"
|
|
||||||
forward-addr: {{ pillar['hosts-inet']['serv']['dns'] }}
|
|
||||||
forward-addr: {{ pillar['hosts-inet6'][ctx]['serv']['dns'] }}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- for domain in pillar['bind']['reverse-zones-inet'] %}
|
|
||||||
forward-zone:
|
|
||||||
name: "{{ domain }}"
|
|
||||||
forward-addr: {{ pillar['hosts-inet']['serv']['dns'] }}
|
|
||||||
forward-addr: {{ pillar['hosts-inet6']['dn42']['serv']['dns'] }}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- for ctx, domains in pillar['bind']['reverse-zones-inet6'].items() %}
|
|
||||||
{%- for domain in domains %}
|
|
||||||
forward-zone:
|
|
||||||
name: "{{ domain }}"
|
|
||||||
forward-addr: {{ pillar['hosts-inet']['serv']['dns'] }}
|
|
||||||
forward-addr: {{ pillar['hosts-inet6'][ctx]['serv']['dns'] }}
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endfor %}
|
|
|
@ -1,2 +0,0 @@
|
||||||
server:
|
|
||||||
root-hints: "/usr/share/dns/root.hints"
|
|
|
@ -1,2 +0,0 @@
|
||||||
server:
|
|
||||||
verbosity: 1
|
|
|
@ -1 +0,0 @@
|
||||||
net.ipv6.conf.{{ interface }}.accept_ra=2
|
|
|
@ -1,15 +0,0 @@
|
||||||
{%- set interface = pillar['upstream']['interface'] %}
|
|
||||||
|
|
||||||
/etc/sysctl.d/70-upstream-6slac.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: "salt://upstream/6slac.conf"
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
interface: {{ interface }}
|
|
||||||
|
|
||||||
apply-6slac:
|
|
||||||
cmd.run:
|
|
||||||
- name: sysctl -p /etc/sysctl.d/70-upstream-6slac.conf
|
|
||||||
require:
|
|
||||||
- file: /etc/sysctl.d/70-upstream-6slac.conf
|
|
||||||
- pkg: procps
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
|
||||||
|
|
||||||
ip tunnel del 6to4
|
|
|
@ -1,13 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
|
||||||
|
|
||||||
INET=$(ip addr show dev {{ interface }} | \
|
|
||||||
egrep -oe '[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+' | \
|
|
||||||
head -n 1)
|
|
||||||
PREFIX=$(printf "2002:%02x%02x:%02x%02x:\n" $(echo $INET | tr . ' '))
|
|
||||||
|
|
||||||
ip tunnel add 6to4 mode sit remote 192.88.99.1 local $INET
|
|
||||||
ip addr add "${PREFIX}:1/128" dev 6to4
|
|
||||||
ip link set 6to4 up
|
|
||||||
ip route add 2000::/3 dev 6to4 via ::192.88.99.1
|
|
|
@ -1,17 +0,0 @@
|
||||||
{%- set interface = pillar['upstream']['interface'] %}
|
|
||||||
|
|
||||||
/etc/network/if-up.d/6to4:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://upstream/6to4-up
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
interface: {{ interface }}
|
|
||||||
- mode: 755
|
|
||||||
|
|
||||||
/etc/network/if-down.d/6to4:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://upstream/6to4-down
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
interface: {{ interface }}
|
|
||||||
- mode: 755
|
|
|
@ -1,19 +0,0 @@
|
||||||
{%- set interface = pillar['upstream']['interface'] %}
|
|
||||||
{{ interface }}:
|
|
||||||
network.managed:
|
|
||||||
- enabled: True
|
|
||||||
type: eth
|
|
||||||
proto: dhcp
|
|
||||||
|
|
||||||
include:
|
|
||||||
- upstream.masquerade
|
|
||||||
|
|
||||||
/etc/network/if-pre-up.d/iptables:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://upstream/iptables
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
interface: {{ interface }}
|
|
||||||
- mode: 744
|
|
||||||
- require:
|
|
||||||
- pkg: iptables
|
|
|
@ -1,19 +0,0 @@
|
||||||
{%- set interface = pillar['upstream']['interface'] %}
|
|
||||||
|
|
||||||
/etc/wide-dhcpv6/dhcp6c.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://upstream/dhcp6c.conf
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
interface: {{ interface }}
|
|
||||||
- mode: 744
|
|
||||||
|
|
||||||
wide-dhcpv6-client:
|
|
||||||
pkg.installed: []
|
|
||||||
service:
|
|
||||||
- running
|
|
||||||
- enable: True
|
|
||||||
- restart: True
|
|
||||||
- watch:
|
|
||||||
- file: /etc/wide-dhcpv6/dhcp6c.conf
|
|
||||||
- pkg: wide-dhcpv6-client
|
|
|
@ -1,21 +0,0 @@
|
||||||
interface {{ interface }} {
|
|
||||||
send rapid-commit;
|
|
||||||
send ia-pd 0;
|
|
||||||
send ia-na 0;
|
|
||||||
request sip-server-domain-name;
|
|
||||||
request sip-server-address;
|
|
||||||
};
|
|
||||||
|
|
||||||
id-assoc pd 0 {
|
|
||||||
prefix ::/56 infinity;
|
|
||||||
prefix-interface core {
|
|
||||||
# 0x81 in decimal
|
|
||||||
sla-id 129;
|
|
||||||
# 64 - 56
|
|
||||||
sla-len 8;
|
|
||||||
# …::b:0/64
|
|
||||||
ifid 720896;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
id-assoc na 0 {
|
|
||||||
};
|
|
|
@ -1,14 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
|
||||||
|
|
||||||
if [ "$IFACE" = "{{ interface }}" ]; then
|
|
||||||
IP=`ip a| grep inet |grep $IFACE|awk '{print $2}'|sed -e 's#/.*##'`
|
|
||||||
|
|
||||||
nsupdate -k /etc/dyndns.key << EOF
|
|
||||||
server {{ pillar['hosts-inet']['serv']['dns'] }}
|
|
||||||
update delete {{ hostname }}. IN A
|
|
||||||
update add {{ hostname }}. 10 IN A $IP
|
|
||||||
send
|
|
||||||
EOF
|
|
||||||
fi
|
|
|
@ -1,4 +0,0 @@
|
||||||
key "{{ name }}" {
|
|
||||||
algorithm hmac-sha256;
|
|
||||||
secret "{{ secret }}";
|
|
||||||
};
|
|
|
@ -1,26 +0,0 @@
|
||||||
{%- set conf = pillar['dyndns'][salt['grains.get']('id')] %}
|
|
||||||
|
|
||||||
/etc/network/if-up.d/dyndns:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://upstream/dyndns
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
interface: {{ conf['interface'] }}
|
|
||||||
hostname: {{ salt['grains.get']('id') }}.dyn.{{ pillar['bind']['root-domain']['up1'] }}
|
|
||||||
- mode: 755
|
|
||||||
- require:
|
|
||||||
- pkg: dnsutils
|
|
||||||
|
|
||||||
/etc/dyndns.key:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://upstream/dyndns.key
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
name: {{ salt['grains.get']('id') }}
|
|
||||||
secret: "{{ conf['secret'] }}"
|
|
||||||
- mode: 600
|
|
||||||
- require:
|
|
||||||
- pkg: dnsutils
|
|
||||||
|
|
||||||
dnsutils:
|
|
||||||
pkg.installed: []
|
|
|
@ -1,20 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
|
||||||
|
|
||||||
if [ "$IFACE" = "lo" ]; then
|
|
||||||
iptables -I INPUT -i lo -j ACCEPT
|
|
||||||
ip6tables -I INPUT -i lo -j ACCEPT
|
|
||||||
fi
|
|
||||||
if [ "$IFACE" = "{{ interface }}" ]; then
|
|
||||||
iptables -A INPUT -i "$IFACE" -m state --state ESTABLISHED,RELATED -j ACCEPT
|
|
||||||
ip6tables -A INPUT -i "$IFACE" -m state --state ESTABLISHED,RELATED -j ACCEPT
|
|
||||||
iptables -A INPUT -i "$IFACE" -p icmp -j ACCEPT
|
|
||||||
ip6tables -A INPUT -i "$IFACE" -p icmpv6 -j ACCEPT
|
|
||||||
# DHCPv6
|
|
||||||
ip6tables -A INPUT -i "$IFACE" -p udp --sport 547 --dport 546 -j ACCEPT
|
|
||||||
iptables -A INPUT -i "$IFACE" -j DROP
|
|
||||||
ip6tables -A INPUT -i "$IFACE" -j DROP
|
|
||||||
iptables -P INPUT ACCEPT
|
|
||||||
ip6tables -P INPUT ACCEPT
|
|
||||||
fi
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
/usr/bin/curl "https://{{ username }}:{{ key }}@ipv4.tunnelbroker.net/nic/update?hostname={{ tunnel_id }}"
|
|
|
@ -1,57 +0,0 @@
|
||||||
ifupdown:
|
|
||||||
pkg.installed: []
|
|
||||||
|
|
||||||
curl:
|
|
||||||
pkg.installed: []
|
|
||||||
|
|
||||||
/etc/systemd/network/ipv6.netdev:
|
|
||||||
file.append:
|
|
||||||
- text: |
|
|
||||||
[NetDev]
|
|
||||||
Name=ipv6
|
|
||||||
Kind=sit
|
|
||||||
[Tunnel]
|
|
||||||
Remote={{ pillar['ipv6-tunnel']['endpoint'] }}
|
|
||||||
|
|
||||||
/etc/systemd/network/ipv6.network:
|
|
||||||
file.append:
|
|
||||||
- text: |
|
|
||||||
[Match]
|
|
||||||
Name=ipv6
|
|
||||||
[Network]
|
|
||||||
Address={{ pillar['ipv6-tunnel']['address'] }}
|
|
||||||
Gateway={{ pillar['ipv6-tunnel']['gateway'] }}
|
|
||||||
|
|
||||||
/etc/systemd/network/ipv6-up.network:
|
|
||||||
file.append:
|
|
||||||
- text: |
|
|
||||||
[Match]
|
|
||||||
Name={{ pillar['upstream']['interface'] }}
|
|
||||||
[Network]
|
|
||||||
Tunnel=ipv6
|
|
||||||
|
|
||||||
{% if pillar['ipv6-tunnel'].get('tunnelbroker') %}
|
|
||||||
/etc/cron.hourly/ipv6-tunnel-update.sh:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://upstream/ipv6-tunnel-update.sh
|
|
||||||
- template: 'jinja'
|
|
||||||
- mode: 744
|
|
||||||
- context: {{ pillar['ipv6-tunnel']['tunnelbroker'] }}
|
|
||||||
- require:
|
|
||||||
- pkg: curl
|
|
||||||
|
|
||||||
cron:
|
|
||||||
service.running:
|
|
||||||
- enable: True
|
|
||||||
- reload: True
|
|
||||||
- watch:
|
|
||||||
- file: /etc/cron.hourly/ipv6-tunnel-update.sh
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
autostart-systemd-networkd:
|
|
||||||
service.running:
|
|
||||||
- name: systemd-networkd
|
|
||||||
watch:
|
|
||||||
- file: /etc/systemd/network/ipv6.netdev
|
|
||||||
- file: /etc/systemd/network/ipv6.network
|
|
||||||
- file: /etc/systemd/network/ipv6-up.network
|
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
|
||||||
|
|
||||||
if [ "$IFACE" = "{{ interface }}" ]; then
|
|
||||||
iptables -t nat -A POSTROUTING -o "$IFACE" -j MASQUERADE
|
|
||||||
fi
|
|
|
@ -1,14 +0,0 @@
|
||||||
{%- set interface = pillar['upstream']['interface'] %}
|
|
||||||
|
|
||||||
iptables:
|
|
||||||
pkg.installed: []
|
|
||||||
|
|
||||||
/etc/network/if-pre-up.d/masquerade:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://upstream/masquerade
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
interface: {{ interface }}
|
|
||||||
- mode: 755
|
|
||||||
- require:
|
|
||||||
- pkg: iptables
|
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
|
||||||
|
|
||||||
if [ "$IFACE" = "{{ interface }}" ]; then
|
|
||||||
ip6tables -t nat -A POSTROUTING -o "$IFACE" -j MASQUERADE
|
|
||||||
fi
|
|
|
@ -1,11 +0,0 @@
|
||||||
{%- set interface = pillar['upstream']['nat66-interface'] %}
|
|
||||||
|
|
||||||
/etc/network/if-pre-up.d/nat66:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://upstream/nat66
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
interface: {{ interface }}
|
|
||||||
- mode: 755
|
|
||||||
- require:
|
|
||||||
- pkg: iptables
|
|
|
@ -1,9 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
|
||||||
|
|
||||||
if [ "$IFACE" = "{{ interface }}" ]; then
|
|
||||||
{%- for fwd in ports %}
|
|
||||||
iptables -t nat -A PREROUTING -i {{ interface }} -p {{ fwd.proto }} --dport {{ fwd.port }} -j DNAT --to-destination {{ fwd.to }}
|
|
||||||
{%- endfor %}
|
|
||||||
fi
|
|
|
@ -1,13 +0,0 @@
|
||||||
{%- set interface = pillar['upstream']['interface'] %}
|
|
||||||
{%- set ports = pillar['port-forwarding'] %}
|
|
||||||
|
|
||||||
/etc/network/if-up.d/port-forwarding:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://upstream/port-forwarding
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
interface: {{ interface }}
|
|
||||||
ports: {{ ports }}
|
|
||||||
- mode: 755
|
|
||||||
- require:
|
|
||||||
- pkg: iptables
|
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
|
||||||
|
|
||||||
if [ "$IFACE" = "{{ interface }}" ]; then
|
|
||||||
ip -6 r a 2000::/3 via fe80::1 dev "$IFACE"
|
|
||||||
fi
|
|
|
@ -1,17 +0,0 @@
|
||||||
{%- set interface = pillar['upstream']['interface'] %}
|
|
||||||
|
|
||||||
/etc/network/if-post-up.d:
|
|
||||||
file.directory:
|
|
||||||
- user: root
|
|
||||||
- require_in:
|
|
||||||
- file: /etc/network/if-post-up.d/routes
|
|
||||||
|
|
||||||
/etc/network/if-post-up.d/routes:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://upstream/routes
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
interface: {{ interface }}
|
|
||||||
- mode: 744
|
|
||||||
- require:
|
|
||||||
- pkg: iproute2
|
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
|
||||||
|
|
||||||
if [ "$IFACE" = "{{ iface }}" ]; then
|
|
||||||
tc qdisc del dev $IFACE root 2> /dev/null > /dev/null
|
|
||||||
tc qdisc add dev $IFACE root handle 1 hfsc default 1
|
|
||||||
tc class add dev $IFACE parent 1: classid 1:1 hfsc sc rate {{ bandwidth }}kbit ul rate {{ bandwidth }}kbit
|
|
||||||
tc qdisc add dev $IFACE parent 1:1 handle 11: fq_codel flows {{ pillar['upstream']['flows'] }}
|
|
||||||
tc filter add dev $IFACE parent 11: handle 11 protocol all flow hash keys {{ flow_keys }} divisor {{ pillar['upstream']['flows'] }}
|
|
||||||
fi
|
|
|
@ -1,32 +0,0 @@
|
||||||
{%- set upstream = pillar['upstream'] %}
|
|
||||||
|
|
||||||
iproute2:
|
|
||||||
pkg.installed: []
|
|
||||||
|
|
||||||
{%- if upstream.get('up-bandwidth') %}
|
|
||||||
/etc/network/if-up.d/up-shaping:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://upstream/shaping
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
iface: {{ pillar['upstream']['interface'] }}
|
|
||||||
bandwidth: {{ pillar['upstream']['up-bandwidth'] }}
|
|
||||||
flow_keys: nfct-src
|
|
||||||
- mode: 755
|
|
||||||
- require:
|
|
||||||
- pkg: iproute2
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
{%- if upstream.get('down-bandwidth') %}
|
|
||||||
/etc/network/if-up.d/down-shaping:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://upstream/shaping
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
iface: core
|
|
||||||
bandwidth: {{ pillar['upstream']['down-bandwidth'] }}
|
|
||||||
flow_keys: nfct-dst
|
|
||||||
- mode: 755
|
|
||||||
- require:
|
|
||||||
- pkg: iproute2
|
|
||||||
{%- endif %}
|
|
|
@ -1,3 +0,0 @@
|
||||||
{%- set conf = pillar['openvpn'][name] -%}
|
|
||||||
{{ conf['user'] }}
|
|
||||||
{{ conf['password'] }}
|
|
|
@ -1,58 +0,0 @@
|
||||||
{%- set conf = pillar['openvpn'][name] %}
|
|
||||||
client
|
|
||||||
dev {{ name }}
|
|
||||||
dev-type tun
|
|
||||||
proto udp
|
|
||||||
|
|
||||||
remote {{ conf['server'] }}
|
|
||||||
resolv-retry infinite
|
|
||||||
nobind
|
|
||||||
|
|
||||||
user nobody
|
|
||||||
group nogroup
|
|
||||||
persist-key
|
|
||||||
persist-tun
|
|
||||||
|
|
||||||
log /var/log/openvpn-{{ name }}.log
|
|
||||||
|
|
||||||
#ifconfig-noexec
|
|
||||||
route 0.0.0.0 0.0.0.0
|
|
||||||
#route-nopull
|
|
||||||
up /etc/openvpn/{{ name }}.up
|
|
||||||
script-security 2
|
|
||||||
|
|
||||||
auth-user-pass /etc/openvpn/{{ name }}.auth
|
|
||||||
auth-retry nointeract
|
|
||||||
|
|
||||||
ca [inline]
|
|
||||||
|
|
||||||
tls-client
|
|
||||||
tls-auth [inline]
|
|
||||||
setenv CLIENT_CERT 0
|
|
||||||
tun-mtu 1500
|
|
||||||
tun-mtu-extra 32
|
|
||||||
mssfix 1450
|
|
||||||
persist-key
|
|
||||||
persist-tun
|
|
||||||
|
|
||||||
reneg-sec 0
|
|
||||||
|
|
||||||
remote-cert-tls server
|
|
||||||
|
|
||||||
keepalive 10 30
|
|
||||||
cipher AES-256-CBC
|
|
||||||
comp-lzo
|
|
||||||
|
|
||||||
|
|
||||||
passtos
|
|
||||||
verb 1
|
|
||||||
|
|
||||||
|
|
||||||
<ca>
|
|
||||||
{{ conf['ca'] }}
|
|
||||||
</ca>
|
|
||||||
|
|
||||||
key-direction 1
|
|
||||||
<tls-auth>
|
|
||||||
{{ conf['key'] }}
|
|
||||||
</tls-auth>
|
|
|
@ -1,67 +0,0 @@
|
||||||
openvpn:
|
|
||||||
pkg.installed: []
|
|
||||||
|
|
||||||
{%- for name, conf in pillar['openvpn'].items() %}
|
|
||||||
|
|
||||||
hostroutes-{{ name }}:
|
|
||||||
network.routes:
|
|
||||||
- name: core
|
|
||||||
- routes:
|
|
||||||
{%- for a in salt.dnsutil.A(conf['server']) %}
|
|
||||||
- ipaddr: {{ a }}
|
|
||||||
netmask: 255.255.255.255
|
|
||||||
gateway: {{ pillar['hosts-inet']['core']['upstream1'] }}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
/etc/openvpn/{{ name }}.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://vpn/openvpn.conf
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
name: {{ name }}
|
|
||||||
|
|
||||||
/etc/openvpn/{{ name }}.auth:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://vpn/auth
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
name: {{ name }}
|
|
||||||
- mode: 600
|
|
||||||
|
|
||||||
/etc/openvpn/{{ name }}.up:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://vpn/up
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
name: {{ name }}
|
|
||||||
- mode: 755
|
|
||||||
|
|
||||||
/etc/systemd/system/openvpn@{{ name }}.service.d:
|
|
||||||
file.directory:
|
|
||||||
- user: root
|
|
||||||
|
|
||||||
/etc/systemd/system/openvpn@{{ name }}.service.d/restart.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://vpn/systemd-restart.conf
|
|
||||||
- mode: 644
|
|
||||||
- require:
|
|
||||||
- file: /etc/systemd/system/openvpn@{{ name }}.service.d
|
|
||||||
|
|
||||||
autostart-{{ name }}:
|
|
||||||
service.enabled:
|
|
||||||
- name: openvpn@{{ name }}
|
|
||||||
require_in:
|
|
||||||
- file: /etc/openvpn/{{ name }}.conf
|
|
||||||
- file: /etc/openvpn/{{ name }}.auth
|
|
||||||
|
|
||||||
start-{{ name }}:
|
|
||||||
service.running:
|
|
||||||
- name: openvpn@{{ name }}
|
|
||||||
require_in:
|
|
||||||
- file: /etc/openvpn/{{ name }}.conf
|
|
||||||
- file: /etc/openvpn/{{ name }}.auth
|
|
||||||
watch:
|
|
||||||
- file: /etc/openvpn/{{ name }}.conf
|
|
||||||
- file: /etc/openvpn/{{ name }}.auth
|
|
||||||
|
|
||||||
{%- endfor %}
|
|
|
@ -1,3 +0,0 @@
|
||||||
[Service]
|
|
||||||
Restart=always
|
|
||||||
RestartSec=10s
|
|
|
@ -1,9 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
export IFACE={{ name }}
|
|
||||||
for f in /etc/network/if-pre-up.d/*; do
|
|
||||||
$f
|
|
||||||
done
|
|
||||||
for f in /etc/network/if-up.d/*; do
|
|
||||||
$f
|
|
||||||
done
|
|
|
@ -1,38 +0,0 @@
|
||||||
wireguard-tools:
|
|
||||||
pkg.installed: []
|
|
||||||
|
|
||||||
/etc/systemd/system/wireguard@.service:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://wireguard/wireguard.service
|
|
||||||
- template: 'jinja'
|
|
||||||
- context:
|
|
||||||
gateway: {{ pillar['hosts-inet']['core']['upstream1'] }}
|
|
||||||
endpoints:
|
|
||||||
{%- for instance, conf in pillar['wireguard-instances'].items() %}
|
|
||||||
{%- for peer in conf['peers'] %}
|
|
||||||
- {{ peer['endpoint'] }}
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endfor %}
|
|
||||||
|
|
||||||
{%- for instance, conf in pillar['wireguard-instances'].items() %}
|
|
||||||
/etc/wireguard/{{ instance }}.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://wireguard/wireguard.conf
|
|
||||||
- template: 'jinja'
|
|
||||||
- context: {{ conf }}
|
|
||||||
- mode: 600
|
|
||||||
|
|
||||||
autostart-wg-{{ instance }}:
|
|
||||||
service.enabled:
|
|
||||||
- name: wireguard@{{ instance }}
|
|
||||||
require:
|
|
||||||
- file: /etc/wireguard/{{ instance }}.conf
|
|
||||||
|
|
||||||
start-wg-{{ instance }}:
|
|
||||||
service.running:
|
|
||||||
- name: wireguard@{{ instance }}
|
|
||||||
require:
|
|
||||||
- service: autostart-wg-{{ instance }}
|
|
||||||
watch:
|
|
||||||
- file: /etc/wireguard/{{ instance }}.conf
|
|
||||||
{%- endfor %}
|
|
|
@ -1,14 +0,0 @@
|
||||||
[Interface]
|
|
||||||
PrivateKey = {{ private_key }}
|
|
||||||
Address = {{ addr }}
|
|
||||||
#DNS = 193.138.219.228
|
|
||||||
PostUp = iptables -t nat -A POSTROUTING -o %i -j MASQUERADE; ip6tables -t nat -A POSTROUTING -o %i -j MASQUERADE
|
|
||||||
PostDown = iptables -t nat -D POSTROUTING -o %i -j MASQUERADE; ip6tables -t nat -D POSTROUTING -o %i -j MASQUERADE
|
|
||||||
|
|
||||||
{%- for peer in peers %}
|
|
||||||
[Peer]
|
|
||||||
PublicKey = {{ peer['public_key'] }}
|
|
||||||
AllowedIPs = 0.0.0.0/0,::0/0
|
|
||||||
Endpoint = {{ peer['endpoint'] }}
|
|
||||||
|
|
||||||
{%- endfor %}
|
|
|
@ -1,15 +0,0 @@
|
||||||
[Unit]
|
|
||||||
Description=Call wg-quick
|
|
||||||
PartOf=wireguard.service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
{%- for endpoint in endpoints %}
|
|
||||||
ExecStart=-/bin/ip route add {{ endpoint.split(':')[0] }}/32 via {{ gateway }}
|
|
||||||
{%- endfor %}
|
|
||||||
ExecStart=/usr/bin/wg-quick up /etc/wireguard/%i.conf
|
|
||||||
ExecStop=/usr/bin/wg-quick down /etc/wireguard/%i.conf
|
|
||||||
RemainAfterExit=true
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
Loading…
Reference in New Issue