diff --git a/inventory/group_vars/all/locales.yml b/inventory/group_vars/all/locales.yml
index fe68a2f..7965084 100644
--- a/inventory/group_vars/all/locales.yml
+++ b/inventory/group_vars/all/locales.yml
@@ -1,4 +1,4 @@
+locale_default: en_US.UTF-8
locales_list:
- en_US.UTF-8
- ru_RU.UTF-8
-locale_default: en_US.UTF-8
diff --git a/inventory/group_vars/all/vault.yml b/inventory/group_vars/all/vault.yml
deleted file mode 100644
index afc2365..0000000
--- a/inventory/group_vars/all/vault.yml
+++ /dev/null
@@ -1,125 +0,0 @@
-$ANSIBLE_VAULT;1.1;AES256
-64303032323732383634613632656438656637373538316134623639346132306337356632316263
-6536663939336664353530313331326436393335303933340a626637346333353363316531613037
-61323139653638343331666235653136306237633464643832326164663463313135623836656236
-6462316234316537350a653235373462636130383235616165363730303463366234333838653361
-37336333643961656637396434303839323065633564346635363734316165316463306364396665
-38666463313164326461303933353765346230623164646232316463396232666435326435633863
-31663563653733336433373836326637323061383435643831363038386638333261333934313465
-33313930616561336436653961306262343730306638386531663564396136633232356133363566
-34313635626333363632373530373334373335653035353734623065393034616235613663383533
-37393362343736643630323134666166666662313333386132366165386535343635376337386665
-34306663666261303035626539393064656234616463303130303037343738626561653732643038
-62663339366465326639663164656239393234643763313935636131303165633765386330653263
-31336562656530356433626664303361636230396262633435356632376637363461643035613831
-39326566626533616538316232656336333166313833363038626338633131383230313961636634
-36386366353639326532393362323330626336303731393661306531623065303465303963376134
-34636261333837396364656237393033373639323063393839363732633963306262303232333935
-37346531653730306361646562396233346161353964326534646465386364636230616231653730
-32326664653566353030663666386162616136386436346565666464663661646463376632633230
-66353039373536643431323533636238666533643431636165633265383733633238633237313830
-35386438613239353539636637353366633062306562633733303666656565313366343461326236
-30393232656264323530623031346536646235323738313462396432376333623137613138303130
-30386461366265336230303530363564336363663262386335313366613634356230333336383936
-33643936613266353636313234393761633363353530396333393937393261326364383032653930
-63666137363564386566393564373263636436353838633538333133376364616434653839633662
-66396239386537663266383462373838346137306232613637313063353664313931313362313035
-36343463363165306635303064346531643933313564376635633231316363663931643635623061
-31366163386536336339656637626533656639396161363136306136373262356436393839386537
-39663439633338356136623235633430663932316561343830336634623137386161623733303465
-61373965636262346436343431373032656131393535386537353066393935303335623639316166
-65613266363362376631376537373764333562633336353836333132633533616161313032383536
-61386538326335326535306430643339303936633532303865363431366537373637313335313639
-32386434366638323433663332373233333865636233333261313038353633343661663164656237
-32336361653039363931316232613737306264386462383332393266373665653364316530383733
-65663335346533653534646133393139666435363036646135353933343834643064353161333033
-62656133343930626433643434336362643035343039633831643264613739333037666338636633
-31623963343565333538353233313537616236393864333566393932626466646534376536623430
-61636262313035393862316430313934633262616534656433316538386664333730343165343931
-65363532616662323262643863323631623938343433623066316231303734613533393039663035
-62646665666634663930383362303137623532373338343764613962343532313161613765383436
-36363432326433303363303736643733623061663663326434643162616235303461353961383462
-35323964353036373334323464336462313435646236333266333233303933356636636637633064
-32626135353862316265376163336637396633326265323761353765663931356461666563613163
-66393264303133613530623164663764643163353163313232623335373231626237636165646631
-32646363323265353336363063653334333062626462663961373463306638373437373836396566
-63346564626134666632393132303464616233323565363734396432373339653336646139323330
-34393761366363363132316231616536643638316138396665633262646438366539346337646266
-65383739343931313038653230343432643863633035636538386239363962663365326265383934
-35346263306361343932383763373737396565306438363362343733653865343162373833326338
-36386433383935613336353833396561633030646232316463333430316535373136353966643336
-65343431313935656630666630383664396134326666643733653463333162613034333061343035
-62313338646639306362343533616563396531363466373231626662313136373234646430613434
-64356430303362376531373336653836653039643165633538666661633134636165643962316437
-30326465633761353034316434623164636561313836323163613439633364636662373163633838
-62333565656237303464346461343534326463616264336265393835343837366335626364653264
-39393338346532383132613331353839373937396538303863326637616333356161386433373230
-38666265336361616233656633613234653232613833376131613865643832386665613236386236
-31363638303366326165396566343566623765633133626666656132366465613432383235306233
-38623733303932623730343638393137663665326134303462666462373639323730656637646663
-32656335323634316432373039653463333737323732646461366565626262373332333861323838
-66343337373437623366373464613532313665343830306465623433616330656165306166643837
-39323335303766353364636365646266333139313530303633353764643964363466633661366335
-31396335313435386135393232363633366239303765666435663733323532346338336562663562
-30313836343366663564623036303334383537343435396634323130663834643364306132363838
-36653564366463323936393035633866633431363134396361623366666231376566646562303739
-61633831353034356431643738633862383466613466626534313962323639663562373031623339
-61396566613134323137333039363330636663353439653964353934656532306563613536623038
-31333065353763303062363836313037313362393132313630366362656133663936303836363366
-37383561636437396364383037643136613066376162363864386336663731333463623563343630
-65326238656237663634656332316230646338393436353239373663386561626162333164356363
-31333364663463656662303134383430356235386436376438646236303966383733353738666365
-36623839623865366637626463626164303735316439336437383231323238636561633261616138
-39313463653030313932663733343135313736326132376161653534383131613066303438333034
-66376264626439636131313135326163333032343635333562663761653539363833616464376465
-62336237656139326161616636393435346663346162646237333935373263616530376135656635
-63383862666533373639663838333930343931383137363565633264623036353462663333373733
-64303933396337633961303064353066363161636233353165393833373861653839303333376336
-65386133663863396634393832626436653766623537663934616463393966346233386433343664
-63333232623764326132636637666437333636303633663430643339623530633664656130636466
-33363536393261626461646161373234383237376564663039343065316232646130636334653763
-37336237613361633931326639663436393033633434326239393232346166393035633034646135
-64636365613138333534333038373932653339383761653735396430336163613565383238383166
-30656632303130376633656536323264373661363765633162353138626530353539643463626532
-32363933633733393736623131633339363962663864393431653232303763333735393138623936
-33616133326261356432396264653339323030386463366434393837336530326338613461646530
-61333430376633666461356230316464326265636634343634636664393230383266363834346234
-66313161366262313362653662383334353763663437336565356331353230383262396236613261
-36336431366234616263326330366239616533613036353735303533653339636161393836353139
-32636162356536366231346631666236653935666265633637363566626235333838353936613764
-36306361336432346463336235626666356137363438626135393065623238316661643637363762
-64653466363165656330383134626230353034653963346532376166653735633634316366303036
-30353561646437636263636132346235656338316466363331396539616537343137303065633638
-63386630393533663638633935376235396133646462343762363931396638363263393236373731
-63643135343235333830383661643539393733306333316630663262313732373235663133663531
-65616264386264313739393161386637323336653336346436636563393561636530303632343030
-35303234323737653965333266623539313863376362633931313838323964633137336435306666
-37326232396362396131353561323932336530643865633831613939383763366137373734303339
-38356663346164643665326334613839646539353261306165316162366630363765306530623730
-35303364656436336135396365616132376433383764356363333035396661623936333865356635
-66663234636533386532623161386632366666393730643231613135356631646636343332646261
-32623237356264623430666330306433313165626633636137666433323566633666383938623362
-61346439323535643766643132326261383734386337363337303435326663326537303533336266
-39363361386235306365366366323562336634643335383861623066653937336362383662356535
-39636233346331376664356334663561383963616536636537656339373332613766626337613436
-36383361646436306562323862376165356436646339643030303132663430373330663064626230
-34393561393464626531626138326161353530393964663933653238393361373766376434653464
-32656338356332626261323363396433343263623831366363346161376434666261323534383466
-30363237653439663036313035383536303566376334386262623963356366333563326236343461
-31636266393864613935633235613462313931633635366333343835656366613832633035393331
-32393633303939386138376363653934653031303362653139636238383732643834376633643830
-64653132393166346464343062613033383837643466316534646334313263386238646432333330
-32646537613762326361663863353339633631333562383231323165663338383931313961386634
-33653232353931383635366265396266663531386239373931383563393130666237316539346563
-61303563306161663065383332306563313136616265383866373139376332636363326563386539
-62323363643432303561373130623863306365363961663838613633303135623036333134623939
-62646363333335386366623264633937396232613339663165613963393463303132323933656330
-38623038303934343835353731656234626138323963393136383261306630343138303963343036
-64353664646465626331346334336636313462303366643665316163346361323363393032343336
-32623066363935346538323364356135323964393738383539373861663934653735396637333934
-64626631663264373065396436323334323638356139356465346463333231646331326130383061
-63313335333062336131623339333665356237663862393734343661613465393430626465326564
-64663838363033323665613732633334356532316665646338333333613465643637656661663634
-65326565663339316634383632386430653461663930633466303232636536303039303731396363
-66363063383832303165396261313030663636333938663134323030396139373539663833326637
-33373961646466663639
diff --git a/inventory/group_vars/external.yml b/inventory/group_vars/external.yml
new file mode 100644
index 0000000..014b6d0
--- /dev/null
+++ b/inventory/group_vars/external.yml
@@ -0,0 +1,15 @@
+$ANSIBLE_VAULT;1.1;AES256
+37633533653037393835663435613364366430616366386631383963363265643963626232666132
+3564383139306565306131636561356234643066313261620a623230643766353564343231303232
+62303435393932303333666434373764366463633838636533363532363732333739313437376566
+3936633633373066610a386334626637376162656637653764323163306365393438666164353332
+32316330363134383761373966636464336532373863643666336363376230366237373636323234
+34623265306362343765643435356236326363393431313832623937323239613834636434303938
+34353763373761373739366431326162636134636135633735643930346565623430323931386239
+31353762646435343639616138303130663735373932386631643834633864366638613431643966
+33643833313331373735393864333665376663316534316638656363376365383834313566613037
+64373764363634326463303631643231616435383738353032323537633230633063653331633734
+39336265326138636232323762633936383864303565376361663664316364343039623730376234
+30396435396433613532623332663335633132356662336239653536383638376435393738643439
+39663537343231343734656265383762623731383336663234636638373962363535656539343765
+6163656436303665346232643162383338326333386465303564
diff --git a/inventory/group_vars/proxmox_all_lxc.yml b/inventory/group_vars/proxmox_all_lxc.yml
index 9168cb0..014b6d0 100644
--- a/inventory/group_vars/proxmox_all_lxc.yml
+++ b/inventory/group_vars/proxmox_all_lxc.yml
@@ -1,5 +1,15 @@
-ansible_connection: community.proxmox.proxmox_pct_remote
-ansible_host: 10.1.0.4
-ansible_user: root
-ansible_ssh_private_key_file: "~/.ssh/id_ed25519"
-ansible_python_interpreter: /usr/bin/python3
+$ANSIBLE_VAULT;1.1;AES256
+37633533653037393835663435613364366430616366386631383963363265643963626232666132
+3564383139306565306131636561356234643066313261620a623230643766353564343231303232
+62303435393932303333666434373764366463633838636533363532363732333739313437376566
+3936633633373066610a386334626637376162656637653764323163306365393438666164353332
+32316330363134383761373966636464336532373863643666336363376230366237373636323234
+34623265306362343765643435356236326363393431313832623937323239613834636434303938
+34353763373761373739366431326162636134636135633735643930346565623430323931386239
+31353762646435343639616138303130663735373932386631643834633864366638613431643966
+33643833313331373735393864333665376663316534316638656363376365383834313566613037
+64373764363634326463303631643231616435383738353032323537633230633063653331633734
+39336265326138636232323762633936383864303565376361663664316364343039623730376234
+30396435396433613532623332663335633132356662336239653536383638376435393738643439
+39663537343231343734656265383762623731383336663234636638373962363535656539343765
+6163656436303665346232643162383338326333386465303564
diff --git a/inventory/host_vars/coturn.yml b/inventory/host_vars/coturn.yml
index ae772c4..6f962b5 100644
--- a/inventory/host_vars/coturn.yml
+++ b/inventory/host_vars/coturn.yml
@@ -1,12 +1,12 @@
nft_dst:
- - iface: [eth0,eth0.2]
+ - iface: [br-eth0,eth0.2]
proto: [tcp,udp]
port: [3478,5349]
nft_from:
- - iface: [eth0,eth0.2,eth0.3,eth0.4,wg0]
+ - iface: [br-eth0,eth0.2,eth0.3,eth0.4,tun0]
proto: [tcp,udp]
port: [3478,5349]
- - iface: [eth0,eth0.2,eth0.3,eth0.4,wg0]
+ - iface: [br-eth0,eth0.2,eth0.3,eth0.4,tun0]
proto: udp
port: ["49152-65535"]
diff --git a/inventory/host_vars/gitea.yml b/inventory/host_vars/gitea.yml
index 4514264..6086b57 100644
--- a/inventory/host_vars/gitea.yml
+++ b/inventory/host_vars/gitea.yml
@@ -4,7 +4,7 @@ nft_to:
port: 5432
nft_from:
- - iface: wg0
+ - iface: tun0
proto: tcp
port: 22
diff --git a/inventory/host_vars/liqueur/certbot.yml b/inventory/host_vars/liqueur/certbot.yml
new file mode 100644
index 0000000..0616f32
--- /dev/null
+++ b/inventory/host_vars/liqueur/certbot.yml
@@ -0,0 +1,9 @@
+certbot_certs:
+ - domains:
+ - liqueur.oyacoi.ru
+ pre_hook: "systemctl stop stunnel4 && systemctl stop nginx"
+ post_hook: "systemctl start nginx && systemctl start stunnel4"
+ - domains:
+ - absinthe.oyacoi.ru
+ pre_hook: "systemctl stop stunnel4 && systemctl stop nginx"
+ post_hook: "systemctl start nginx && systemctl start stunnel4"
diff --git a/inventory/host_vars/liqueur/main.yml b/inventory/host_vars/liqueur/main.yml
new file mode 100644
index 0000000..b0e1dec
--- /dev/null
+++ b/inventory/host_vars/liqueur/main.yml
@@ -0,0 +1,2 @@
+ansible_python_interpreter: /usr/bin/python3
+ansible_password: "{{ ssh_password }}"
diff --git a/inventory/host_vars/liqueur/openvpn.yml b/inventory/host_vars/liqueur/openvpn.yml
new file mode 100644
index 0000000..18d5071
--- /dev/null
+++ b/inventory/host_vars/liqueur/openvpn.yml
@@ -0,0 +1 @@
+openvpn_role: server
diff --git a/inventory/host_vars/liqueur/ssh.yml b/inventory/host_vars/liqueur/ssh.yml
new file mode 100644
index 0000000..d89aa73
--- /dev/null
+++ b/inventory/host_vars/liqueur/ssh.yml
@@ -0,0 +1,6 @@
+$ANSIBLE_VAULT;1.1;AES256
+37353538363139326635383437313831346265623562383533386261623437366462343663363261
+3264363465656165343038656631373436613235343232620a663633636264383736303030323938
+30336565383337613637613963343132646665613932393237323437373434646335383531303461
+6134393232336132350a393333613362306462613839333732343963363961653561666437383037
+35366561393537643463396462356464663162316632613331316230643932666233
diff --git a/inventory/host_vars/localhost.yml b/inventory/host_vars/localhost.yml
new file mode 100644
index 0000000..712e087
--- /dev/null
+++ b/inventory/host_vars/localhost.yml
@@ -0,0 +1,23 @@
+openvpn_client_bundle_dir: /etc/easy-rsa/ovpn
+openvpn_instances:
+ - name: tun0
+ pki_dir: /etc/easy-rsa/pki/tun0
+ clients:
+ - name: mur89
+ - name: matr10
+ - name: tap0
+ pki_dir: /etc/easy-rsa/pki/tap0
+ clients:
+ - name: ltrefilov
+ - name: lnosov
+ ip: 10.1.0.220
+ route_metric: 50
+ - name: aborovlev
+ ip: 10.1.0.221
+ route_metric: 50
+ - name: dperesypkin
+ ip: 10.1.0.222
+ route_metric: 50
+ - name: dkarpcov
+ ip: 10.1.0.223
+ route_metric: 50
diff --git a/inventory/host_vars/mcsmanager.yml b/inventory/host_vars/mcsmanager.yml
index ee03853..987c053 100644
--- a/inventory/host_vars/mcsmanager.yml
+++ b/inventory/host_vars/mcsmanager.yml
@@ -1,10 +1,10 @@
nft_dst:
- - iface: [eth0,eth0.2]
+ - iface: [br-eth0,eth0.2]
proto: tcp
port: 25565
nft_from:
- - iface: [eth0,wg0]
+ - iface: [br-eth0,tun0]
proto: tcp
port: 25565
diff --git a/inventory/host_vars/nginx.yml b/inventory/host_vars/nginx.yml
index 7c8cc80..7c228f1 100644
--- a/inventory/host_vars/nginx.yml
+++ b/inventory/host_vars/nginx.yml
@@ -46,6 +46,6 @@ nft_to:
port: [23333,24444]
nft_from:
- - iface: [eth0,eth0.2]
+ - iface: [br-eth0,eth0.2]
proto: tcp
port: [80,443,24444]
diff --git a/inventory/host_vars/prosody.yml b/inventory/host_vars/prosody.yml
index 4987c27..9345839 100644
--- a/inventory/host_vars/prosody.yml
+++ b/inventory/host_vars/prosody.yml
@@ -1,5 +1,5 @@
nft_dst:
- - iface: [eth0,eth0.2]
+ - iface: [br-eth0,eth0.2]
proto: tcp
port: [5000,5222,5223,5280,5270,5269]
@@ -9,7 +9,7 @@ nft_to:
port: 5432
nft_from:
- - iface: [eth0,eth0.2,wg0]
+ - iface: [br-eth0,eth0.2,tun0]
proto: tcp
port: [5000,5222,5223,5269,5270,5280]
diff --git a/inventory/host_vars/rbpi4.yml b/inventory/host_vars/rbpi4.yml
index 0b61889..a291df3 100644
--- a/inventory/host_vars/rbpi4.yml
+++ b/inventory/host_vars/rbpi4.yml
@@ -1,3 +1,5 @@
dnsmasq:
- name: rustdesk.dttx.ru
- ip: 176.119.157.97
+ ip_from: liqueur
+ - name: fs.dttx.ru
+ ip_from: liqueur
diff --git a/inventory/host_vars/router/ifupdown2.yml b/inventory/host_vars/router/ifupdown2.yml
index 196f5fa..28452b7 100644
--- a/inventory/host_vars/router/ifupdown2.yml
+++ b/inventory/host_vars/router/ifupdown2.yml
@@ -1,37 +1 @@
-ifupdown2:
- - iface: lo
- method: loopback
- routing:
- - "post-up ip rule add fwmark 0x1 lookup 100 2>/dev/null || true"
- - "post-up ip route add local 0.0.0.0/0 dev lo table 100 2>/dev/null || true"
- - "pre-down ip route del local 0.0.0.0/0 dev lo table 100 2>/dev/null || true"
- - "pre-down ip rule del fwmark 0x1 lookup 100 2>/dev/null || true"
- - iface: eth0
- method: static
- address: 10.1.0.1/24
- - iface: eth0.2
- method: static
- address: 10.2.0.1/24
- vlan-raw-device: eth0
- - iface: eth0.3
- method: static
- address: 10.3.0.1/24
- vlan-raw-device: eth0
- - iface: eth0.4
- method: static
- address: 10.4.0.1/24
- vlan-raw-device: eth0
- - iface: eth0.10
- method: static
- address: 10.10.0.1/24
- vlan-raw-device: eth0
- - iface: eth0.11
- method: static
- address: 10.11.0.1/24
- vlan-raw-device: eth0
- - iface: eth0.12
- method: static
- address: 10.12.0.1/24
- vlan-raw-device: eth0
- - iface: eth1
- method: dhcp
+ifupdown2_manage_prerequisites: true
diff --git a/inventory/host_vars/router/logrotate.yml b/inventory/host_vars/router/logrotate.yml
deleted file mode 100644
index d358efe..0000000
--- a/inventory/host_vars/router/logrotate.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-logrotate:
- - name: xray-core
- paths:
- - /var/log/xray-core/access.log
- - /var/log/xray-core/error.log
- options:
- - daily
- - rotate 4
- - compress
- - delaycompress
- - missingok
- - notifempty
- - copytruncate
diff --git a/inventory/host_vars/router/managed_group.yml b/inventory/host_vars/router/managed_group.yml
index 32255d3..dfcd446 100644
--- a/inventory/host_vars/router/managed_group.yml
+++ b/inventory/host_vars/router/managed_group.yml
@@ -1,3 +1,3 @@
-nft_managed_group: "{{ groups['static'] + groups['proxmox_all_lxc'] }}"
-dnsmasq_managed_group: "{{ groups['static'] + groups['proxmox_all_lxc'] }}"
-xray_managed_group: "{{ groups['static'] + groups['proxmox_all_lxc'] }}"
+nft_managed_group: "{{ groups['internal'] + groups['proxmox_all_lxc'] }}"
+dnsmasq_managed_group: "{{ groups['internal'] + groups['proxmox_all_lxc'] }}"
+xray_managed_group: "{{ groups['internal'] + groups['proxmox_all_lxc'] }}"
diff --git a/inventory/host_vars/router/nftables.yml b/inventory/host_vars/router/nftables.yml
new file mode 100644
index 0000000..af8dd51
--- /dev/null
+++ b/inventory/host_vars/router/nftables.yml
@@ -0,0 +1 @@
+nftables_bootstrap_files: true
diff --git a/inventory/host_vars/router/openvpn.yaml b/inventory/host_vars/router/openvpn.yaml
new file mode 100644
index 0000000..0835621
--- /dev/null
+++ b/inventory/host_vars/router/openvpn.yaml
@@ -0,0 +1 @@
+openvpn_role: client
diff --git a/inventory/host_vars/router/sysctl.yml b/inventory/host_vars/router/sysctl.yml
deleted file mode 100644
index 699c8fb..0000000
--- a/inventory/host_vars/router/sysctl.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-sysctl:
- net.ipv4.ip_forward: 1
- net.ipv4.conf.lo.rp_filter: 0
- net.ipv4.conf.all.rp_filter: 0
- net.ipv4.conf.wg0.rp_filter: 0
diff --git a/inventory/host_vars/router/user.yml b/inventory/host_vars/router/user.yml
new file mode 100644
index 0000000..5ed4d4d
--- /dev/null
+++ b/inventory/host_vars/router/user.yml
@@ -0,0 +1,6 @@
+user:
+ - name: steamcmd
+ create_home: true
+ home: /var/lib/steamcmd
+ shell: /bin/bash
+ system: true
diff --git a/inventory/host_vars/router/xray-core.yml b/inventory/host_vars/router/xray-core.yml
new file mode 100644
index 0000000..f440cfc
--- /dev/null
+++ b/inventory/host_vars/router/xray-core.yml
@@ -0,0 +1,100 @@
+$ANSIBLE_VAULT;1.1;AES256
+65616666356261363366373733653631636132613931366637383432656566366636313864666230
+6136653839653366336561613365383535616231613064660a343139643135653933343731363038
+36396436353033396265646338666537623237323166373664626633366432373037613631636236
+6134633533636361310a663966353432366436383333666266666238636239666136316665353665
+33353161626637353063613738376130333533393565383065613732663637653334636130383663
+65376666373861326639343362353136303038396535303234326135633665366164393239376430
+38343932613935343930376131373837376235633432373535356162616333653432666131333261
+30313436613465626330393936613166663563636435356136613930303933323238336565663232
+35616665333339313365323837383832393563353238326234643934393234323462336363303232
+30383863366331656331336135313362303235396266613661356562333064653736396531323463
+63353736633139353764356634376531613738393965393264623462333232366233396233643533
+65653364643235373837303731363565656265616633336236313266373635646233623362636161
+61346432336636633030616232343738666136366666353135656237653437663565643032663562
+31633764343537666633386237633662306362303732353761353937323039623238353439383336
+39356236646333666535326337616337313233646365333830343637376533373661636364313362
+35333132353364343836366639356465323636313564636433393361636536323432363232376337
+37653835666664386437316163323261336135613330636537633934633839633538343238323035
+38653163626266316137383433656630313234326530313533376337393865643162613532326463
+38613533373263303138333237303739393261396364646330646334386338636538343265393238
+64653036366237396233323064323732393831343563643238363964333633636362303866373530
+35383433643163366534613931666563376133336663393332666465616436343562613833653766
+32663237383466356433383065336664393664326536346364313536656565613635666665643133
+35366165643163636166613735313036326232656330313637353133323265646162333565643930
+38643666396431316165626433383236653663376263663736323838343435396639636162663738
+64366238363532363433313336393937353561643635343466393761623161643235663366633932
+30303339306333643331323962333035393933653431383139653531626533396131663564353237
+65346637383133626630376639663630333265346434656361386463343162393131393631396638
+64353931643733356362376139633037363434316366396266363665613563663565366466616336
+65663561666163613639643136613132303662396661653830363862346535656436613739376363
+61633562346331333566313165373133633137663831313534323737623564306437346562356362
+66363965313337303265343966656330356361326666353134636465613833356134383833323537
+63353965346666656364633230333539383464613637333131356637326535333733356139396363
+64393938366533346165386165333336333638316166663236373131366334363037626662323737
+39376162616333623638383038396465356130353261303730613632623265333764633330303238
+34653338346430636231376339306632376236613865383737663530353465366536313864636639
+39663237383564363063663266396537393536353466643564613432646663373263306164646336
+38626334373138376436336130386266343766363636636437363862303635356231323336306135
+61353561643761336133623565306233383333363963393765363163323139373935313636663065
+30333237313738633338663630363430373232343939303134363436653563393231656262333033
+38323837646131626162383237373736306634386631613864623338303235666132353837626665
+35303533623533366437656133653239613563363232343535363234346466343936393132376332
+64626137363564656661653466396631346364356561313562373965623539616362383835383234
+30323262353833336332623863626465376238383133633462303465393463663337356464613236
+31313232383738313136303439623563393861623039393536373539303838623832323238336432
+39633661626364313034623832363763313031333565373363323636393265333530633837623934
+64626535646661333266303461633664346461396237333633613736303239336530616236336561
+65626532303063396131376335663738393362633937393131396134316235376338623165643233
+39373533373033633838626239343232323733336633333837383834666661383162366337303435
+61666638393938653666643834313831613134633731353665366133633334356535343464373461
+61303632663936363866353764653130386233326362343466623338326234386363653432303437
+30333361653662633863323731383438373764653834363062613665613862623338336233663263
+37353738373131333333353662636561323234393634643734376539383965346530386265323063
+32636364653365656236396665623735656630393632333330653738643736383664396230663033
+64303763336339623638653831653039353731356430626530636335623235366635313339386137
+64613239653538653262393265356463643739383634663432393231636561376139653834646664
+65356534336264643039303762623533616431353130353332663230336133383461386161333737
+33316438303935663937373335323339656535393163616166346535313830343462303738313133
+36653038343639373336663961396137366632653138396139346431363431336331376339333135
+30343331626636323332393337626231326463316665373734653934653531663663393937333838
+37656534626639343639366366653131313137633534316137333730346531326232353137633332
+34303236386138623038303263613966346532323637303665353931333930613339626362666433
+36666335356464373962376335653266663138373130303639633661393036663663323538343837
+32613837636166646634626137346532656364343730616663646130356631333634353766623938
+32366431623032353937363462633661396365353962393931623538366365353761353365643231
+35656361393162663066393539363262663966653032356465326534616230313438323437346638
+37356661376361396164646135666161373732393830343932626565663535346437346236343361
+34346134343438643338636437613733323065646638646364663930353062653233353066383530
+33633731396562663338393838376639363034373965353465643263613632646135346432323235
+64353435363032343537633035613739336637356339373164383964313062313932653336616366
+30666465613263373561373366326630366636643639616138366363346561346363646139333838
+30316266376330393861666137356263336638323939666431336131383339306437333832306235
+37366135613230666165396136343030643630356462333830623230613133356563666533373763
+66353637393430306465373465316433386131373431343436663533663264333662333865616139
+65643738656666333830383833346334383430666537313733613833356239383730666437326532
+38393061326136333533653565343962333336616665633034356334653366313435383630623537
+32323065363137656336626130633361353763653664303636373736326363306439346263383437
+33636139656437303965353362313865333535366337666466366430353837353930656638393334
+32313561306132386331383633333931353336313639366434313931333733663630386436336230
+32376365613061383636326366326265623038373766316561643163646564396638336537303131
+39383163323337336561616666336637316435323534353961623834656664316262623834346336
+36343536336439363762333538376261663934636566323962313565303137653036653434376434
+61623732613936393838386163366561373539393635303664333931396565633437393931353965
+62313838636461343037626332613530663336353562656563323939323636373164363930616265
+62656465366330363466386261323039323766376237303263666634653561643439323630666431
+62316162366436383065623961323062353034653935626638393862366535616330356135303761
+34613438393730663562633239373935383264366361376536633331323062343535626262326133
+63383731613664663339613830353231643866326362663336653336666530343633376465376161
+37313666346261313137363864396531643765363166663931633338383037363933646436323863
+34333862613730326630356437373531373838383265383238383863373339326439643035626431
+63313537623339343564326534636234646635653434356161303530393236663832316233306261
+63663864383862393634656630393533326438396164623037623961363833616664666437626563
+63363334323930363930326231363339363233646263643861393034656562363434383034633961
+36663865393430333964626231396431663634623536656237326430356334653739333339336337
+36306663316638376631323165383963636562336438383639333632316133323933653539336664
+38636531326230333665653937303639616338303063666561353435353764373431643234623338
+66313963373964613237346238303566316138383364666238616333663437323135376466366166
+39376130336635646131653237363461663664633336663837356265616133653031613662323861
+38303266613934376136366430313934373462363630633037323461306134653637623035383936
+343164306335323561333737633538633333
diff --git a/inventory/host_vars/router/zerotier-one.yml b/inventory/host_vars/router/zerotier-one.yml
deleted file mode 100644
index a9982dc..0000000
--- a/inventory/host_vars/router/zerotier-one.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-$ANSIBLE_VAULT;1.1;AES256
-30313538656633333565613030356534313035646337323763663565326431323437623636656365
-3139663263383363626438396133623639636565386230640a333166373634343630663566396264
-64613435643864373264323061336438396339326466663637363536663165373231333738313466
-6532343566653238620a336633376336303439656163393165323364663033663432643034396262
-61383431663836613335623761366433366364363938643935636634313631653935306230346234
-3934303233633837356437636639353563376563613237646133
diff --git a/inventory/host_vars/steamcmd/main.yml b/inventory/host_vars/steamcmd/main.yml
index bd1642a..99e69c4 100644
--- a/inventory/host_vars/steamcmd/main.yml
+++ b/inventory/host_vars/steamcmd/main.yml
@@ -4,10 +4,10 @@ nft_dst:
port: [2456,2457]
nft_from:
- - iface: [eth0,wg0]
+ - iface: [br-eth0,tun0]
proto: tcp
port: [5000,5222,5223,5269,5270,5280]
- - iface: [eth0,wg0]
+ - iface: [br-eth0,tun0]
proto: udp
port: [2302,2304,2456,2457,27016]
- iface: eth1
diff --git a/inventory/host_vars/workuter.yml b/inventory/host_vars/workuter.yml
index 838a64b..8871ebe 100644
--- a/inventory/host_vars/workuter.yml
+++ b/inventory/host_vars/workuter.yml
@@ -8,3 +8,8 @@ nft_to:
- to: [xiawrt,rbpi4]
proto: tcp
port: 22
+
+xray_policy:
+ - bypass: private
+ - bypass: russian_whitelist
+ - proxy: all
diff --git a/inventory/static.yml b/inventory/static.yml
index e0fed4e..e6704be 100644
--- a/inventory/static.yml
+++ b/inventory/static.yml
@@ -1,34 +1,34 @@
all:
children:
- static:
+ internal:
hosts:
workuter:
container_ip: "10.1.0.2"
- zone_iface: "eth0"
+ zone_iface: "br-eth0"
oyacoi-odcm:
container_ip: "10.1.0.3"
- zone_iface: "eth0"
+ zone_iface: "br-eth0"
firebat:
container_ip: "10.1.0.4"
- zone_iface: "eth0"
+ zone_iface: "br-eth0"
ps2:
container_ip: "10.1.0.5"
- zone_iface: "eth0"
+ zone_iface: "br-eth0"
ps3:
container_ip: "10.1.0.6"
- zone_iface: "eth0"
+ zone_iface: "br-eth0"
tanix:
container_ip: "10.1.0.8"
- zone_iface: "eth0"
+ zone_iface: "br-eth0"
bananawrt:
container_ip: "10.1.0.100"
- zone_iface: "eth0"
+ zone_iface: "br-eth0"
ps4:
container_ip: "10.2.0.2"
@@ -82,14 +82,28 @@ all:
container_ip: "10.4.0.3"
zone_iface: "eth0.4"
- haproxy:
- container_ip: "10.255.255.100"
- zone_iface: "wg0"
-
xiawrt:
- container_ip: "10.250.250.1"
- zone_iface: "wg0"
+ container_ip: "192.168.1.1"
+ zone_iface: "tun0"
rbpi4:
- container_ip: "10.250.250.5"
- zone_iface: "wg0"
+ container_ip: "192.168.1.5"
+ zone_iface: "tun0"
+
+ haproxy:
+ container_ip: "172.168.0.1"
+ zone_iface: "tun0"
+
+ external:
+ hosts:
+ liqueur:
+ container_ip: "130.49.213.132"
+ zone_iface: "eht1"
+
+ vector:
+ container_ip: "144.31.155.100"
+ zone_iface: "eht1"
+
+ dev:
+ container_ip: "178.173.249.148"
+ zone_iface: "eht1"
diff --git a/playbooks/easy-rsa.yml b/playbooks/easy-rsa.yml
new file mode 100644
index 0000000..4d3fb32
--- /dev/null
+++ b/playbooks/easy-rsa.yml
@@ -0,0 +1,29 @@
+---
+- name: deploy rasy-rsa
+ hosts: localhost
+ connection: local
+ become: true
+ roles:
+ - easy-rsa
+
+- name: configure liqueur openvpn
+ hosts: liqueur
+ vars:
+ ansible_connection: ssh
+ ansible_host: "{{ container_ip }}"
+ ansible_user: root
+ ansible_ssh_private_key_file: ~/.ssh/id_ed25519
+ ansible_ssh_common_args: '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
+ roles:
+ - openvpn
+
+- name: configure router openvpn
+ hosts: router
+ vars:
+ ansible_connection: ssh
+ ansible_host: "{{ container_ip }}"
+ ansible_user: root
+ ansible_ssh_private_key_file: ~/.ssh/id_ed25519
+ ansible_ssh_common_args: '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
+ roles:
+ - openvpn
diff --git a/playbooks/liqueur.yml b/playbooks/liqueur.yml
new file mode 100644
index 0000000..13669fe
--- /dev/null
+++ b/playbooks/liqueur.yml
@@ -0,0 +1,23 @@
+---
+- name: configure over ssh
+ hosts: liqueur
+ vars:
+ ansible_connection: ssh
+ ansible_host: "{{ container_ip }}"
+ ansible_user: root
+ ansible_ssh_private_key_file: ~/.ssh/id_ed25519
+ ansible_ssh_common_args: >-
+ -o UserKnownHostsFile=/dev/null
+ -o StrictHostKeyChecking=no
+ -o PreferredAuthentications=publickey,password
+ -o PubkeyAuthentication=yes
+ roles:
+ - authorized_key
+ - sshd
+ - certbot
+ - sysctl
+ - nginx
+ - nftables
+ - stunnel4
+ - openvpn
+ - haproxy
diff --git a/playbooks/router.yml b/playbooks/router.yml
index c6c1522..784205d 100644
--- a/playbooks/router.yml
+++ b/playbooks/router.yml
@@ -18,12 +18,11 @@
- timezone
- locales
- sysctl
+ - stunnel4
+ - openvpn
- xray-core
- - xray-client
- logrotate
- dnsmasq
- xray-lists
- unbound
- - wireguard-tools
- - zerotier-one
- nftables
diff --git a/playbooks/xray-test.yml b/playbooks/xray-test.yml
deleted file mode 100644
index e93c435..0000000
--- a/playbooks/xray-test.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-- hosts: router
- become: yes
- roles:
- - xray-core
diff --git a/roles/apt/tasks/apt.yml b/roles/apt/tasks/apt.yml
deleted file mode 100644
index fceac5c..0000000
--- a/roles/apt/tasks/apt.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-- name: install package
- ansible.builtin.apt:
- name: "{{ item }}"
- update_cache: true
- loop: "{{ apt }}"
diff --git a/roles/apt/tasks/main.yml b/roles/apt/tasks/main.yml
deleted file mode 100644
index 88e74a9..0000000
--- a/roles/apt/tasks/main.yml
+++ /dev/null
@@ -1,3 +0,0 @@
----
-- name: include apt install
- ansible.builtin.include_tasks: apt.yml
diff --git a/roles/certbot/tasks/configure.yml b/roles/certbot/tasks/configure.yml
new file mode 100644
index 0000000..1f0bf5f
--- /dev/null
+++ b/roles/certbot/tasks/configure.yml
@@ -0,0 +1,20 @@
+---
+- name: install certbot
+ ansible.builtin.apt:
+ name: certbot
+ state: present
+ update_cache: true
+
+- name: issue certificate if missing
+ ansible.builtin.command:
+ cmd: >
+ certbot certonly --standalone
+ --non-interactive --agree-tos
+ --register-unsafely-without-email
+ --pre-hook "{{ item.pre_hook }}"
+ --post-hook "{{ item.post_hook }}"
+ {{ item.domains | map('regex_replace', '^(.*)$', '-d \1') | join(' ') }}
+ creates: "/etc/letsencrypt/live/{{ item.domains[0] }}/fullchain.pem"
+ loop: "{{ certbot_certs }}"
+ loop_control:
+ label: "{{ item.domains | join(',') }}"
diff --git a/roles/wireguard-tools/tasks/install.yml b/roles/certbot/tasks/install.yml
similarity index 53%
rename from roles/wireguard-tools/tasks/install.yml
rename to roles/certbot/tasks/install.yml
index 4ad71c4..35c699c 100644
--- a/roles/wireguard-tools/tasks/install.yml
+++ b/roles/certbot/tasks/install.yml
@@ -1,6 +1,6 @@
---
-- name: install wireguard-tools
+- name: install certbot
ansible.builtin.apt:
- name: wireguard-tools
+ name: certbot
state: latest
update_cache: true
diff --git a/roles/wireguard-tools/tasks/main.yml b/roles/certbot/tasks/main.yml
similarity index 53%
rename from roles/wireguard-tools/tasks/main.yml
rename to roles/certbot/tasks/main.yml
index e2643fc..758fdf4 100644
--- a/roles/wireguard-tools/tasks/main.yml
+++ b/roles/certbot/tasks/main.yml
@@ -1,6 +1,6 @@
---
-- name: include wireguard-tools install
+- name: include certbot install
ansible.builtin.include_tasks: install.yml
-- name: include wireguard-tools configurure
+- name: include certbot configure
ansible.builtin.include_tasks: configure.yml
diff --git a/roles/dnsmasq/files/10-upstream.conf b/roles/dnsmasq/files/10-upstream.conf
index 49215f2..a9e3c93 100644
--- a/roles/dnsmasq/files/10-upstream.conf
+++ b/roles/dnsmasq/files/10-upstream.conf
@@ -1,5 +1,5 @@
interface=lo
-interface=eth0
+interface=br-eth0
interface=eth0.2
interface=eth0.3
interface=eth0.4
diff --git a/roles/dnsmasq/templates/90-dhcp-host.conf.j2 b/roles/dnsmasq/templates/90-dhcp-host.conf.j2
index 3a1b8d5..ef50bfe 100644
--- a/roles/dnsmasq/templates/90-dhcp-host.conf.j2
+++ b/roles/dnsmasq/templates/90-dhcp-host.conf.j2
@@ -1,13 +1,13 @@
#jinja2: trim_blocks: True, lstrip_blocks: True
{% for item in dnsmasq_managed_group | sort %}
- {% set client = hostvars[item] %}
- {% set ip = client.container_ip | default(client.ansible_host | default(none)) %}
- {% if client['dhcp-host'] is defined and client['dhcp-host'] and ip %}
- {% set entries = client['dhcp-host'] if (client['dhcp-host'] is iterable and client['dhcp-host'] is not string) else [client['dhcp-host']] %}
- {% for entry in entries %}
- {% if entry.mac %}
+{% set client = hostvars[item] %}
+{% set ip = client.container_ip | default(client.ansible_host | default(none)) %}
+{% if client['dhcp-host'] is defined and client['dhcp-host'] and ip %}
+{% set entries = client['dhcp-host'] if (client['dhcp-host'] is iterable and client['dhcp-host'] is not string) else [client['dhcp-host']] %}
+{% for entry in entries %}
+{% if entry.mac %}
dhcp-host={{ entry.mac }},{{ ip }},{{ item }}
- {% endif %}
- {% endfor %}
- {% endif %}
+{% endif %}
+{% endfor %}
+{% endif %}
{% endfor %}
diff --git a/roles/dnsmasq/templates/90-domains.conf.j2 b/roles/dnsmasq/templates/90-domains.conf.j2
index 1c63235..a9c6663 100644
--- a/roles/dnsmasq/templates/90-domains.conf.j2
+++ b/roles/dnsmasq/templates/90-domains.conf.j2
@@ -1,15 +1,9 @@
#jinja2: trim_blocks: True, lstrip_blocks: True
{% for item in dnsmasq_managed_group | sort %}
- {% set client = hostvars[item] %}
- {% if 'dnsmasq' in client and client.dnsmasq %}
- {% set default_ip = client.container_ip | default(client.ansible_host | default(none)) %}
- {% set domains = client.dnsmasq if (client.dnsmasq is iterable and client.dnsmasq is not string) else [client.dnsmasq] %}
- {% for d in domains %}
- {% set entry = d if (d is mapping) else {'name': d} %}
- {% set ip = entry.ip | default(default_ip) %}
- {% if ip %}
+{% for entry in hostvars[item].dnsmasq | default([]) %}
+{% set ip = entry.ip | default(hostvars[entry.ip_from].container_ip if entry.ip_from is defined else none) %}
+{% if ip %}
host-record={{ entry.name }},{{ ip }}
- {% endif %}
- {% endfor %}
- {% endif %}
+{% endif %}
+{% endfor %}
{% endfor %}
diff --git a/roles/dnsmasq/templates/90-local.conf.j2 b/roles/dnsmasq/templates/90-local.conf.j2
index e6dbdbb..6c4af2a 100644
--- a/roles/dnsmasq/templates/90-local.conf.j2
+++ b/roles/dnsmasq/templates/90-local.conf.j2
@@ -1,8 +1,8 @@
#jinja2: trim_blocks: True, lstrip_blocks: True
{% for item in dnsmasq_managed_group | sort %}
- {% set client = hostvars[item] %}
- {% set ip = client.container_ip | default(client.ansible_host | default(none)) %}
- {% if ip %}
+{% set client = hostvars[item] %}
+{% set ip = client.container_ip | default(client.ansible_host | default(none)) %}
+{% if ip %}
host-record={{ item }},{{ item }}.lan,{{ ip }}
- {% endif %}
+{% endif %}
{% endfor %}
diff --git a/roles/easy-rsa/tasks/client-certs.yml b/roles/easy-rsa/tasks/client-certs.yml
new file mode 100644
index 0000000..4628f53
--- /dev/null
+++ b/roles/easy-rsa/tasks/client-certs.yml
@@ -0,0 +1,18 @@
+---
+- name: ensure local output directory exists
+ ansible.builtin.file:
+ path: "{{ openvpn_client_bundle_dir }}/{{ item.0.name }}"
+ state: directory
+ mode: '0700'
+ loop: "{{ openvpn_instances | subelements('clients') }}"
+ delegate_to: localhost
+ become: false
+
+- name: render standalone client bundles
+ ansible.builtin.template:
+ src: "{{ role_path }}/templates/client-certs/{{ item.0.name }}.conf.j2"
+ dest: "{{ openvpn_client_bundle_dir }}/{{ item.0.name }}/{{ item.1.name }}.ovpn"
+ mode: '0600'
+ loop: "{{ openvpn_instances | subelements('clients') }}"
+ delegate_to: localhost
+ become: false
diff --git a/roles/easy-rsa/tasks/configure.yml b/roles/easy-rsa/tasks/configure.yml
new file mode 100644
index 0000000..078ef47
--- /dev/null
+++ b/roles/easy-rsa/tasks/configure.yml
@@ -0,0 +1,82 @@
+---
+- name: prepare list of client certificates
+ ansible.builtin.set_fact:
+ cert_list: "{{ cert_list | default([]) + [ {'instance': item.0.name, 'pki_dir': item.0.pki_dir, 'client': item.1} ] }}"
+ loop: "{{ openvpn_instances | subelements('clients') }}"
+
+- name: ensure local PKI directories exist
+ ansible.builtin.file:
+ path: "{{ item.pki_dir }}"
+ state: directory
+ mode: '0700'
+ loop: "{{ openvpn_instances }}"
+
+- name: init pki if missing
+ ansible.builtin.command:
+ cmd: /opt/easy-rsa/easyrsa --batch init-pki
+ creates: "{{ item.pki_dir }}/private"
+ environment:
+ EASYRSA_PKI: "{{ item.pki_dir }}"
+ loop: "{{ openvpn_instances }}"
+
+- name: build ca if missing
+ ansible.builtin.command:
+ cmd: /opt/easy-rsa/easyrsa --batch build-ca nopass
+ creates: "{{ item.pki_dir }}/ca.crt"
+ environment:
+ EASYRSA_PKI: "{{ item.pki_dir }}"
+ EASYRSA_REQ_CN: "CA-{{ item.name }}"
+ loop: "{{ openvpn_instances }}"
+
+- name: build server cert if missing
+ ansible.builtin.command:
+ cmd: /opt/easy-rsa/easyrsa --batch build-server-full server nopass
+ creates: "{{ item.pki_dir }}/issued/server.crt"
+ environment:
+ EASYRSA_PKI: "{{ item.pki_dir }}"
+ loop: "{{ openvpn_instances }}"
+
+- name: generate dh params if missing
+ ansible.builtin.command:
+ cmd: /opt/easy-rsa/easyrsa gen-dh
+ creates: "{{ item.pki_dir }}/dh.pem"
+ environment:
+ EASYRSA_PKI: "{{ item.pki_dir }}"
+ loop: "{{ openvpn_instances }}"
+
+- name: check client certificates validity
+ ansible.builtin.command:
+ cmd: "openssl x509 -checkend 2592000 -in {{ item.pki_dir }}/issued/{{ item.client.name }}.crt"
+ register: cert_check
+ failed_when: false
+ changed_when: false
+ loop: "{{ cert_list }}"
+
+- name: remove old cert file before reissue
+ ansible.builtin.file:
+ path: "{{ item.item.pki_dir }}/issued/{{ item.item.client.name }}.crt"
+ state: absent
+ loop: "{{ cert_check.results }}"
+ when: item.rc != 0
+
+- name: remove old req file before reissue
+ ansible.builtin.file:
+ path: "{{ item.item.pki_dir }}/reqs/{{ item.item.client.name }}.req"
+ state: absent
+ loop: "{{ cert_check.results }}"
+ when: item.rc != 0
+
+- name: remove old key file before reissue
+ ansible.builtin.file:
+ path: "{{ item.item.pki_dir }}/private/{{ item.item.client.name }}.key"
+ state: absent
+ loop: "{{ cert_check.results }}"
+ when: item.rc != 0
+
+- name: issue or renew client certificates
+ ansible.builtin.command:
+ cmd: /opt/easy-rsa/easyrsa --batch build-client-full "{{ item.item.client.name }}" nopass
+ environment:
+ EASYRSA_PKI: "{{ item.item.pki_dir }}"
+ when: item.rc != 0
+ loop: "{{ cert_check.results }}"
diff --git a/roles/easy-rsa/tasks/install.yml b/roles/easy-rsa/tasks/install.yml
new file mode 100644
index 0000000..2e6e6f4
--- /dev/null
+++ b/roles/easy-rsa/tasks/install.yml
@@ -0,0 +1,35 @@
+---
+- name: get latest easy-rsa release info
+ ansible.builtin.uri:
+ url: https://api.github.com/repos/OpenVPN/easy-rsa/releases/latest
+ return_content: true
+ register: easyrsa_release
+ run_once: true
+ check_mode: false
+
+- name: set current easy-rsa version
+ ansible.builtin.set_fact:
+ easyrsa_version: "{{ easyrsa_release.json.tag_name | replace('v', '') }}"
+ easyrsa_asset_url: "{{ easyrsa_release.json.assets | selectattr('name', 'search', 'EasyRSA.*\\.tgz') | map(attribute='browser_download_url') | first }}"
+
+- name: check easy-rsa installed version
+ ansible.builtin.command: /opt/easy-rsa/easyrsa version
+ register: easyrsa_current_version
+ changed_when: false
+ failed_when: false
+
+- name: ensure easy-rsa directory exists
+ ansible.builtin.file:
+ path: /opt/easy-rsa
+ state: directory
+ mode: '0755'
+ check_mode: false
+
+- name: update easy-rsa
+ ansible.builtin.unarchive:
+ src: "{{ easyrsa_asset_url }}"
+ dest: /opt/easy-rsa
+ remote_src: true
+ extra_opts:
+ - --strip-components=1
+ when: easyrsa_version not in (easyrsa_current_version.stdout | default(''))
diff --git a/roles/easy-rsa/tasks/main.yml b/roles/easy-rsa/tasks/main.yml
new file mode 100644
index 0000000..fe1bea0
--- /dev/null
+++ b/roles/easy-rsa/tasks/main.yml
@@ -0,0 +1,9 @@
+---
+- name: include install
+ ansible.builtin.include_tasks: install.yml
+
+- name: include configure
+ ansible.builtin.include_tasks: configure.yml
+
+- name: include client-certs.yml
+ ansible.builtin.include_tasks: client-certs.yml
diff --git a/roles/easy-rsa/templates/client-certs/tap0.conf.j2 b/roles/easy-rsa/templates/client-certs/tap0.conf.j2
new file mode 100644
index 0000000..1c16be1
--- /dev/null
+++ b/roles/easy-rsa/templates/client-certs/tap0.conf.j2
@@ -0,0 +1,26 @@
+client
+dev tap0
+proto tcp
+remote 127.0.0.1 1195
+resolv-retry infinite
+nobind
+persist-key
+persist-tun
+remote-cert-tls server
+auth SHA256
+cipher AES-256-GCM
+verb 3
+{% if item.1.ip is defined %}
+route-metric {{ item.1.route_metric | default(50) }}
+script-security 2
+up "C:\\Windows\\System32\\netsh.exe interface ip set address name="OpenVPN TAP-Windows6" static {{ item.1.ip }} 255.255.255.0"
+{% endif %}
+
+{{ lookup('file', item.0.pki_dir + '/ca.crt') }}
+
+
+{{ lookup('file', item.0.pki_dir + '/issued/' + item.1.name + '.crt') }}
+
+
+{{ lookup('file', item.0.pki_dir + '/private/' + item.1.name + '.key') }}
+
diff --git a/roles/easy-rsa/templates/client-certs/tun0.conf.j2 b/roles/easy-rsa/templates/client-certs/tun0.conf.j2
new file mode 100644
index 0000000..63beee8
--- /dev/null
+++ b/roles/easy-rsa/templates/client-certs/tun0.conf.j2
@@ -0,0 +1,21 @@
+client
+dev tun0
+proto tcp
+remote 127.0.0.1 1194
+resolv-retry infinite
+nobind
+persist-key
+persist-tun
+remote-cert-tls server
+auth SHA256
+cipher AES-256-GCM
+verb 3
+
+{{ lookup('file', item.0.pki_dir + '/ca.crt') }}
+
+
+{{ lookup('file', item.0.pki_dir + '/issued/' + item.1.name + '.crt') }}
+
+
+{{ lookup('file', item.0.pki_dir + '/private/' + item.1.name + '.key') }}
+
diff --git a/roles/haproxy/handlers/main.yml b/roles/haproxy/handlers/main.yml
new file mode 100644
index 0000000..3bfa56e
--- /dev/null
+++ b/roles/haproxy/handlers/main.yml
@@ -0,0 +1,13 @@
+---
+- name: validate haproxy config
+ ansible.builtin.command: haproxy -c -f /etc/haproxy/haproxy.cfg
+ changed_when: false
+ listen: restart haproxy
+
+- name: restart haproxy systemd service unit
+ ansible.builtin.systemd_service:
+ name: haproxy
+ daemon_reload: true
+ state: restarted
+ enabled: true
+ listen: restart haproxy
diff --git a/roles/haproxy/tasks/configure.yml b/roles/haproxy/tasks/configure.yml
new file mode 100644
index 0000000..1ee83b7
--- /dev/null
+++ b/roles/haproxy/tasks/configure.yml
@@ -0,0 +1,10 @@
+---
+- name: render haproxy config
+ ansible.builtin.template:
+ src: "{{ item }}"
+ dest: "/etc/haproxy/{{ item | basename | regex_replace('\\.j2$', '') }}"
+ owner: root
+ group: root
+ mode: '0644'
+ loop: "{{ query('fileglob', role_path + '/templates/' + inventory_hostname + '/*.cfg.j2') }}"
+ notify: restart haproxy
diff --git a/roles/haproxy/tasks/install.yml b/roles/haproxy/tasks/install.yml
new file mode 100644
index 0000000..5052a3a
--- /dev/null
+++ b/roles/haproxy/tasks/install.yml
@@ -0,0 +1,6 @@
+---
+- name: install haproxy
+ ansible.builtin.apt:
+ name: haproxy
+ state: latest
+ update_cache: true
diff --git a/roles/zerotier-one/tasks/main.yml b/roles/haproxy/tasks/main.yml
similarity index 100%
rename from roles/zerotier-one/tasks/main.yml
rename to roles/haproxy/tasks/main.yml
diff --git a/roles/haproxy/templates/liqueur/haproxy.cfg.j2 b/roles/haproxy/templates/liqueur/haproxy.cfg.j2
new file mode 100644
index 0000000..748a528
--- /dev/null
+++ b/roles/haproxy/templates/liqueur/haproxy.cfg.j2
@@ -0,0 +1,90 @@
+global
+ log /dev/log local2
+ chroot /var/lib/haproxy
+ maxconn 4000
+ user haproxy
+ group haproxy
+ daemon
+ stats socket /var/lib/haproxy/stats mode 660 level admin
+
+defaults
+ log global
+ mode tcp
+ option tcplog
+ option dontlognull
+ retries 3
+ timeout connect 5s
+ timeout client 1h
+ timeout server 1h
+ timeout check 10s
+
+frontend http_frontend
+ bind 127.0.0.1:10080
+ mode http
+ option httplog
+ acl host_dttx hdr_end(host) -m end dttx.ru
+ use_backend dttx_http_srv if host_dttx
+ default_backend oyacoi_http_srv
+
+backend oyacoi_http_srv
+ mode http
+ server oyacoi_srv {{ hostvars['nginx']['container_ip'] }}:81 send-proxy-v2
+
+backend dttx_http_srv
+ mode http
+ server dttx_srv {{ hostvars['rbpi4']['container_ip'] }}:81 send-proxy-v2
+
+frontend https_frontend
+ bind 127.0.0.1:10443
+ mode tcp
+ option tcplog
+ tcp-request inspect-delay 5s
+ tcp-request content accept if { req_ssl_hello_type 1 }
+ acl host_dttx req_ssl_sni -m end dttx.ru
+ acl host_telemt req_ssl_sni -m end regionculture.ru
+ use_backend dttx_https_srv if host_dttx
+ use_backend telemt_https_srv if host_telemt
+ default_backend oyacoi_https_srv
+
+backend oyacoi_https_srv
+ mode tcp
+ server nginx_srv {{ hostvars['nginx']['container_ip'] }}:444 send-proxy-v2
+
+backend dttx_https_srv
+ mode tcp
+ server dttx_srv {{ hostvars['rbpi4']['container_ip'] }}:444 send-proxy-v2
+
+backend telemt_https_srv
+ mode tcp
+ option tcp-check
+ server telemt_srv {{ hostvars['vector']['container_ip'] }}:8080 check send-proxy-v2
+ server telemt_srv_backup {{ hostvars['dev']['container_ip'] }}:8080 check send-proxy-v2 backup
+
+listen mcsmanager_service
+ bind {{ hostvars['liqueur']['container_ip'] }}:24444
+ mode tcp
+ server mcs_srv {{ hostvars['mcsmanager']['container_ip'] }}:24445 send-proxy-v2
+
+listen xmpp_c2s
+ bind {{ hostvars['liqueur']['container_ip'] }}:5222
+ server prosody_srv {{ hostvars['prosody']['container_ip'] }}:5222
+
+listen xmpp_legacy_ssl
+ bind {{ hostvars['liqueur']['container_ip'] }}:5223
+ server prosody_srv {{ hostvars['prosody']['container_ip'] }}:5223
+
+listen xmpp_s2s
+ bind {{ hostvars['liqueur']['container_ip'] }}:5269
+ server prosody_srv {{ hostvars['prosody']['container_ip'] }}:5269
+
+listen prosody_proxy65
+ bind {{ hostvars['liqueur']['container_ip'] }}:5000
+ server prosody_srv {{ hostvars['prosody']['container_ip'] }}:5000
+
+listen prosody_components
+ bind {{ hostvars['liqueur']['container_ip'] }}:5270
+ server prosody_srv {{ hostvars['prosody']['container_ip'] }}:5270
+
+listen prosody_bosh_http
+ bind {{ hostvars['liqueur']['container_ip'] }}:5280
+ server prosody_srv {{ hostvars['prosody']['container_ip'] }}:5280
diff --git a/roles/ifupdown2/files/router/interfaces b/roles/ifupdown2/files/router/interfaces
new file mode 100644
index 0000000..39baf10
--- /dev/null
+++ b/roles/ifupdown2/files/router/interfaces
@@ -0,0 +1,50 @@
+auto lo
+iface lo inet loopback
+ post-up ip rule add fwmark 0x1 lookup 100 2>/dev/null || true
+ post-up ip route add local 0.0.0.0/0 dev lo table 100 2>/dev/null || true
+ pre-down ip route del local 0.0.0.0/0 dev lo table 100 2>/dev/null || true
+ pre-down ip rule del fwmark 0x1 lookup 100 2>/dev/null || true
+
+auto br-eth0
+iface br-eth0 inet static
+ address 10.1.0.1/24
+ bridge_ports eth0 tap0
+ bridge_stp off
+ pre-up ip tuntap add dev tap0 mode tap || true
+ post-down ip tuntap del dev tap0 mode tap || true
+
+auto eth0
+iface eth0 inet manual
+
+auto eth0.2
+iface eth0.2 inet static
+ address 10.2.0.1/24
+ vlan-raw-device eth0
+
+auto eth0.3
+iface eth0.3 inet static
+ address 10.3.0.1/24
+ vlan-raw-device eth0
+
+auto eth0.4
+iface eth0.4 inet static
+ address 10.4.0.1/24
+ vlan-raw-device eth0
+
+auto eth0.10
+iface eth0.10 inet static
+ address 10.10.0.1/24
+ vlan-raw-device eth0
+
+auto eth0.11
+iface eth0.11 inet static
+ address 10.11.0.1/24
+ vlan-raw-device eth0
+
+auto eth0.12
+iface eth0.12 inet static
+ address 10.12.0.1/24
+ vlan-raw-device eth0
+
+auto eth1
+iface eth1 inet dhcp
diff --git a/roles/ifupdown2/tasks/network.yml b/roles/ifupdown2/tasks/configure.yml
similarity index 64%
rename from roles/ifupdown2/tasks/network.yml
rename to roles/ifupdown2/tasks/configure.yml
index 9f48892..09aefab 100644
--- a/roles/ifupdown2/tasks/network.yml
+++ b/roles/ifupdown2/tasks/configure.yml
@@ -1,7 +1,7 @@
---
-- name: deploy ifupdown interfaces config
- ansible.builtin.template:
- src: interfaces
+- name: deploy ifupdown interfaces
+ ansible.builtin.copy:
+ src: "{{ inventory_hostname }}/interfaces"
dest: /etc/network/interfaces
owner: root
group: root
diff --git a/roles/ifupdown2/tasks/main.yml b/roles/ifupdown2/tasks/main.yml
index d4b80f5..29203d7 100644
--- a/roles/ifupdown2/tasks/main.yml
+++ b/roles/ifupdown2/tasks/main.yml
@@ -1,3 +1,7 @@
---
-- name: include network configuration
- include_tasks: network.yml
+- name: include configure
+ ansible.builtin.include_tasks: configure.yml
+
+- name: include prerequisites
+ ansible.builtin.include_tasks: prerequisites.yml
+ tags: ifupdown2_prereqs
diff --git a/roles/ifupdown2/tasks/prerequisites.yml b/roles/ifupdown2/tasks/prerequisites.yml
new file mode 100644
index 0000000..31e8b86
--- /dev/null
+++ b/roles/ifupdown2/tasks/prerequisites.yml
@@ -0,0 +1,17 @@
+---
+- name: install bridge-utils
+ ansible.builtin.package:
+ name: bridge-utils
+ state: present
+ register: bridge_utils_install
+
+- name: ensure rt_tables.d directory exists
+ ansible.builtin.file:
+ path: /etc/iproute2/rt_tables.d
+ state: directory
+ mode: "0755"
+ register: rt_tables_dir
+
+- name: reload ifupdown2
+ ansible.builtin.command: ifreload -a
+ when: bridge_utils_install.changed or rt_tables_dir.changed
diff --git a/roles/ifupdown2/templates/interfaces b/roles/ifupdown2/templates/interfaces
deleted file mode 100644
index 15f9acb..0000000
--- a/roles/ifupdown2/templates/interfaces
+++ /dev/null
@@ -1,20 +0,0 @@
-{% for item in ifupdown2 %}
-auto {{ item.iface }}
-iface {{ item.iface }}{% if item.method is defined %} inet {{ item.method }}
-{% endif %}
-
-{% if item.address is defined %}
- address {{ item.address }}
-{% endif %}
-{% if item['vlan-raw-device'] is defined %}
- vlan-raw-device {{ item['vlan-raw-device'] }}
-{% endif %}
-{% if item.routing is defined %}
-{% for route in item.routing %}
- {{ route }}
-{% endfor %}
-{% endif %}
-{% if not loop.last %}
-
-{% endif %}
-{% endfor %}
diff --git a/roles/locales/tasks/configure.yml b/roles/locales/tasks/configure.yml
index 24b59b8..f72a0f0 100644
--- a/roles/locales/tasks/configure.yml
+++ b/roles/locales/tasks/configure.yml
@@ -5,14 +5,6 @@
state: present
loop: "{{ locales_list }}"
-- name: configure /etc/default/locale
- ansible.builtin.copy:
- dest: /etc/default/locale
- content: LANG={{ locale_default }}
- owner: root
- group: root
- mode: '0644'
-
- name: configure /etc/locale.conf
ansible.builtin.copy:
dest: /etc/locale.conf
diff --git a/roles/logrotate/files/router/xray-core b/roles/logrotate/files/router/xray-core
new file mode 100644
index 0000000..4775ebb
--- /dev/null
+++ b/roles/logrotate/files/router/xray-core
@@ -0,0 +1,9 @@
+/var/log/xray-core/*.log {
+ daily
+ rotate 4
+ compress
+ delaycompress
+ missingok
+ notifempty
+ copytruncate
+}
diff --git a/roles/logrotate/tasks/configure.yml b/roles/logrotate/tasks/configure.yml
index 3f06759..e4bd2ed 100644
--- a/roles/logrotate/tasks/configure.yml
+++ b/roles/logrotate/tasks/configure.yml
@@ -1,9 +1,8 @@
---
- name: deploy logrotate config
- ansible.builtin.template:
- src: logrotate.conf.j2
- dest: "/etc/logrotate.d/{{ item.name }}"
- mode: "0644"
- loop: "{{ logrotate }}"
- loop_control:
- label: "{{ item.name }}"
+ ansible.builtin.copy:
+ src: "{{ inventory_hostname }}/"
+ dest: "/etc/logrotate.d/"
+ owner: root
+ group: root
+ mode: '0644'
diff --git a/roles/logrotate/templates/logrotate.conf.j2 b/roles/logrotate/templates/logrotate.conf.j2
deleted file mode 100644
index 7fb2840..0000000
--- a/roles/logrotate/templates/logrotate.conf.j2
+++ /dev/null
@@ -1,5 +0,0 @@
-{{ item.paths | join(' ') }} {
-{% for opt in item.options %}
- {{ opt }}
-{% endfor %}
-}
diff --git a/roles/nftables/files/10-filter.nft b/roles/nftables/files/10-filter.nft
deleted file mode 100644
index cc9cc20..0000000
--- a/roles/nftables/files/10-filter.nft
+++ /dev/null
@@ -1,50 +0,0 @@
-flowtable ft {
- hook ingress priority filter
- devices = { eth0, eth1 }
-}
-
-chain input {
- type filter hook input priority filter; policy drop;
-
- ct state established,related accept
- ct state invalid drop
-
- iif lo accept
-
- meta mark 0x00000001 accept
-
- iifname eth0 tcp dport 22 accept
- iifname eth0.11 tcp dport 22 accept
-
- iifname eth1 udp dport 51820 accept
- iifname { eth0, eth0.2, eth0.3, eth0.4, eth0.10, eth0.11, eth0.12 } udp dport 53 accept
- iifname { eth0, eth0.2, eth0.3, eth0.4, eth0.10, eth0.11, eth0.12 } tcp dport 53 accept
-
- iifname eth0.3 udp dport 67 accept
- iifname eth1 udp dport 68 accept
-
- #include "/etc/nftables.d/90-input.nft"
-}
-
-chain forward {
- type filter hook forward priority filter; policy drop;
-
- ct state established,related accept
- ct state invalid drop
-
- iifname { eth0, eth0.2, eth0.3, eth0.4, eth0.10, eth0.11, eth0.12 } oifname eth1 ct state new flow add @ft
- iifname { eth0, eth0.2, eth0.3, eth0.4, eth0.10, eth0.11, eth0.12 } oifname eth1 accept
-
- iifname "zt*" oifname "eth0" accept
- iifname "eth0" oifname "zt*" accept
-
- tcp flags syn tcp option maxseg size set rt mtu
-
- include "/etc/nftables.d/90-forward.nft"
-}
-
-chain output {
- type route hook output priority filter; policy accept;
-
- #include "/etc/nftables.d/90-output.nft"
-}
diff --git a/roles/nftables/files/20-vpn.nft b/roles/nftables/files/20-vpn.nft
deleted file mode 100644
index 56cad03..0000000
--- a/roles/nftables/files/20-vpn.nft
+++ /dev/null
@@ -1,35 +0,0 @@
-chain vpn_prerouting_dnat {
- type nat hook prerouting priority dstnat - 5; policy accept;
-
- iifname wg0 ip daddr 10.250.251.0/24 counter dnat ip prefix to 10.1.0.0/24
- iifname wg0 ip daddr 10.250.252.0/24 counter dnat ip prefix to 10.2.0.0/24
- iifname wg0 ip daddr 10.250.253.0/24 counter dnat ip prefix to 10.10.0.0/24
- iifname wg0 ip daddr 10.250.254.0/24 counter dnat ip prefix to 10.11.0.0/24
- iifname wg0 ip daddr 10.250.255.0/24 counter dnat ip prefix to 10.12.0.0/24
- iifname wg0 ip daddr 10.250.249.0/24 counter dnat ip prefix to 10.13.0.0/24
-}
-
-chain vpn_postrouting_snat {
- type nat hook postrouting priority srcnat; policy accept;
-
- oifname wg0 ip saddr 10.1.0.0/24 counter snat ip prefix to 10.250.251.0/24
- oifname wg0 ip saddr 10.2.0.0/24 counter snat ip prefix to 10.250.252.0/24
- oifname wg0 ip saddr 10.10.0.0/24 counter snat ip prefix to 10.250.253.0/24
- oifname wg0 ip saddr 10.11.0.0/24 counter snat ip prefix to 10.250.254.0/24
- oifname wg0 ip saddr 10.12.0.0/24 counter snat ip prefix to 10.250.255.0/24
- oifname wg0 ip saddr 10.13.0.0/24 counter snat ip prefix to 10.250.249.0/24
-}
-
-chain vpn_prerouting_pbr {
- type filter hook prerouting priority mangle - 10; policy accept;
-
- iifname wg0 ct state new counter ct mark set 0x000000c7
- ip daddr 10.0.0.0/8 return
- iifname != "wg0" ct mark 0x000000c7 counter mark set 0x000000c7
-}
-
-chain vpn_output_pbr {
- type route hook output priority mangle - 10; policy accept;
-
- ct mark 0x000000c7 counter meta mark set 0x000000c7
-}
diff --git a/roles/nftables/files/nftables.conf b/roles/nftables/files/nftables.conf
deleted file mode 100644
index dcdee7a..0000000
--- a/roles/nftables/files/nftables.conf
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/sbin/nft -f
-
-flush ruleset
-
-table inet filter {
- include "/etc/nftables.d/40-sets.nft"
- include "/etc/nftables.d/90-sets.nft"
- include "/etc/nftables.d/10-filter.nft"
- include "/etc/nftables.d/20-vpn.nft"
- include "/etc/nftables.d/30-proxy.nft"
-}
-
-table ip nat {
- include "/etc/nftables.d/10-nat.nft"
-}
diff --git a/roles/nftables/files/40-sets.nft b/roles/nftables/files/router/10-sets.nft
similarity index 100%
rename from roles/nftables/files/40-sets.nft
rename to roles/nftables/files/router/10-sets.nft
diff --git a/roles/nftables/files/10-nat.nft b/roles/nftables/files/router/30-nat.nft
similarity index 99%
rename from roles/nftables/files/10-nat.nft
rename to roles/nftables/files/router/30-nat.nft
index 40a047d..eb7623c 100644
--- a/roles/nftables/files/10-nat.nft
+++ b/roles/nftables/files/router/30-nat.nft
@@ -2,7 +2,6 @@ chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oifname eth1 masquerade
}
-
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
include "/etc/nftables.d/90-dstnat.nft"
diff --git a/roles/nftables/files/router/40-filter.nft b/roles/nftables/files/router/40-filter.nft
new file mode 100644
index 0000000..4447a98
--- /dev/null
+++ b/roles/nftables/files/router/40-filter.nft
@@ -0,0 +1,34 @@
+flowtable ft {
+ hook ingress priority filter
+ devices = { eth0, eth1 }
+}
+chain input {
+ type filter hook input priority filter; policy drop;
+ ct state established,related accept
+ ct state invalid drop
+ iif lo accept
+ meta mark 0x00000001 accept
+ iifname br-eth0 tcp dport 22 accept
+ iifname eth0.11 tcp dport 22 accept
+ iifname tun0 tcp dport 22 accept
+ iifname { br-eth0, eth0.2, eth0.3, eth0.4, eth0.10, eth0.11, eth0.12 } tcp dport 61219 accept
+ iifname { br-eth0, eth0.2, eth0.3, eth0.4, eth0.10, eth0.11, eth0.12 } udp dport 61219 accept
+ iifname { br-eth0, eth0.2, eth0.3, eth0.4, eth0.10, eth0.11, eth0.12 } udp dport 53 accept
+ iifname { br-eth0, eth0.2, eth0.3, eth0.4, eth0.10, eth0.11, eth0.12 } tcp dport 53 accept
+ iifname eth0.3 udp dport 67 accept
+ iifname eth1 udp dport 68 accept
+ include "/etc/nftables.d/90-input.nft"
+}
+chain forward {
+ type filter hook forward priority filter; policy drop;
+ ct state established,related accept
+ ct state invalid drop
+ iifname { br-eth0, eth0.2, eth0.3, eth0.4, eth0.10, eth0.11, eth0.12 } oifname eth1 ct state new flow add @ft
+ iifname { br-eth0, eth0.2, eth0.3, eth0.4, eth0.10, eth0.11, eth0.12 } oifname eth1 accept
+ tcp flags syn tcp option maxseg size set rt mtu
+ include "/etc/nftables.d/90-forward.nft"
+}
+chain output {
+ type route hook output priority filter; policy accept;
+ include "/etc/nftables.d/90-output.nft"
+}
diff --git a/roles/nftables/files/30-proxy.nft b/roles/nftables/files/router/50-proxy.nft
similarity index 98%
rename from roles/nftables/files/30-proxy.nft
rename to roles/nftables/files/router/50-proxy.nft
index d3cf7dd..4d6e794 100644
--- a/roles/nftables/files/30-proxy.nft
+++ b/roles/nftables/files/router/50-proxy.nft
@@ -1,16 +1,11 @@
chain proxy_prerouting {
type filter hook prerouting priority filter - 50; policy accept;
-
fib daddr type local accept
-
meta mark 0x00000001 iif "lo" meta l4proto { tcp, udp } tproxy ip to :61219 counter accept
-
include "/etc/nftables.d/90-proxy-prerouting.nft"
}
-
chain proxy_output {
type route hook output priority mangle; policy accept;
-
meta mark != 0 return
include "/etc/nftables.d/90-proxy-output.nft"
}
diff --git a/roles/nftables/tasks/configure.yml b/roles/nftables/tasks/configure.yml
index b66b01c..578403a 100644
--- a/roles/nftables/tasks/configure.yml
+++ b/roles/nftables/tasks/configure.yml
@@ -4,38 +4,55 @@
path: /etc/nftables.d
state: directory
mode: "0755"
+ when: nftables_bootstrap_files | default(false)
-- name: deploy nftables rule
+- name: bootstrap empty config files
ansible.builtin.copy:
- src: "{{ item }}"
dest: "/etc/nftables.d/{{ item }}"
+ content: ""
+ force: false
mode: "0644"
loop:
- - 10-filter.nft
- - 10-nat.nft
- - 20-vpn.nft
- - 30-proxy.nft
- - 40-sets.nft
+ - 10-sets.nft
+ - 20-sets.nft
+ - 30-nat.nft
+ - 40-filter.nft
+ - 50-proxy.nft
+ - 90-dstnat.nft
+ - 90-forward.nft
+ - 90-input.nft
+ - 90-output.nft
+ - 90-proxy-output.nft
+ - 90-proxy-prerouting.nft
+ when: nftables_bootstrap_files | default(false)
+
+- name: deploy nftables rules
+ ansible.builtin.copy:
+ src: "{{ item }}"
+ dest: "/etc/nftables.d/{{ item | basename }}"
+ owner: root
+ group: root
+ mode: '0644'
+ loop: "{{ query('ansible.builtin.fileglob', role_path + '/files/' + inventory_hostname + '/*.nft') }}"
notify: restart nftables
-- name: render forward
+- name: render nftable rules
ansible.builtin.template:
- src: 90-forward.nft.j2
- dest: /etc/nftables.d/90-forward.nft
- mode: "0644"
- notify: restart nftables
-
-- name: render dstnat
- ansible.builtin.template:
- src: 90-dstnat.nft.j2
- dest: /etc/nftables.d/90-dstnat.nft
- mode: "0644"
+ src: "{{ item }}"
+ dest: "/etc/nftables.d/{{ item | basename | regex_replace('\\.j2$', '') }}"
+ owner: root
+ group: root
+ mode: '0644'
+ loop: "{{ query('ansible.builtin.fileglob', role_path + '/templates/' + inventory_hostname + '/*.nft.j2') }}"
notify: restart nftables
- name: deploy nftables.conf
- ansible.builtin.copy:
- src: nftables.conf
- dest: /etc/nftables.conf
+ ansible.builtin.template:
+ src: "{{ item }}"
+ dest: "/etc/{{ item | basename | regex_replace('\\.j2$', '') }}"
+ owner: root
+ group: root
mode: "0644"
validate: "nft -c -f %s"
+ loop: "{{ query('ansible.builtin.fileglob', role_path + '/templates/' + inventory_hostname + '/*.conf.j2') }}"
notify: restart nftables
diff --git a/roles/nftables/templates/90-dstnat.nft.j2 b/roles/nftables/templates/90-dstnat.nft.j2
deleted file mode 100644
index 1fe9eca..0000000
--- a/roles/nftables/templates/90-dstnat.nft.j2
+++ /dev/null
@@ -1,19 +0,0 @@
-#jinja2: trim_blocks: True, lstrip_blocks: True
-{% for item in nft_managed_group | sort %}
- {% set client = hostvars[item] %}
- {% if 'nft_dst' in client and client.nft_dst is not none %}
- {% set target_ip = client.container_ip %}
- {% for client in client.nft_dst %}
- {% set ports = client.port if (client.port is iterable and client.port is not string) else [client.port] %}
- {% set protos = client.proto if (client.proto is iterable and client.proto is not string) else [client.proto] %}
- {% set ifaces = client.iface if (client.iface is iterable and client.iface is not string) else [client.iface] %}
- {% for proto in protos %}
- {% for port in ports %}
- {% for iface in ifaces %}
-iifname "{{ iface }}" {{ proto }} dport {{ port }} counter dnat ip to {{ target_ip }}:{{ port }} comment "{{ iface }} -> {{ item }}"
- {% endfor %}
- {% endfor %}
- {% endfor %}
- {% endfor %}
- {% endif %}
-{% endfor %}
diff --git a/roles/nftables/templates/90-forward.nft.j2 b/roles/nftables/templates/90-forward.nft.j2
deleted file mode 100644
index 564d5d4..0000000
--- a/roles/nftables/templates/90-forward.nft.j2
+++ /dev/null
@@ -1,47 +0,0 @@
-#jinja2: trim_blocks: True, lstrip_blocks: True
-{% for item in nft_managed_group | sort %}
- {% set client = hostvars[item] %}
- {% if 'nft_to' in client and client.nft_to is not none %}
- {% set rules = client.nft_to if (client.nft_to is iterable and client.nft_to is not string) else [client.nft_to] %}
- {% for rule in rules %}
- {% set rule = rule if rule is mapping else {'to': rule} %}
- {% set dests = rule.to if (rule.to is iterable and rule.to is not string) else [rule.to] %}
- {% set protos = rule.proto if (rule.proto is iterable and rule.proto is not string) else [rule.proto | default(none)] %}
- {% set ports = rule.port if (rule.port is iterable and rule.port is not string) else [rule.port | default(none)] %}
- {% for dest in dests %}
- {% if dest.startswith('zone:') %}
- {% set oif = dest.split(':')[1] %}
- {% set daddr = none %}
- {% set dest_name = oif %}
- {% else %}
- {% set oif = hostvars[dest].zone_iface %}
- {% set daddr = hostvars[dest].container_ip %}
- {% set dest_name = dest %}
- {% endif %}
- {% for proto in protos %}
- {% for port in ports %}
-iifname "{{ client.zone_iface }}" ip saddr {{ client.container_ip }} oifname "{{ oif }}" {% if daddr %}ip daddr {{ daddr }} {% endif %}{% if proto and port %}{{ proto }} dport {{ port }} {% endif %}counter accept comment "{{ item }} -> {{ dest_name }}"
- {% endfor %}
- {% endfor %}
- {% endfor %}
- {% endfor %}
- {% endif %}
-{% endfor %}
-{% for item in nft_managed_group | sort %}
- {% set client = hostvars[item] %}
- {% if 'nft_from' in client and client.nft_from is not none %}
- {% set rules = client.nft_from if (client.nft_from is iterable and client.nft_from is not string) else [client.nft_from] %}
- {% for rule in rules %}
- {% set ifaces = rule.iface if (rule.iface is iterable and rule.iface is not string) else [rule.iface] %}
- {% set protos = rule.proto if (rule.proto is iterable and rule.proto is not string) else [rule.proto | default(none)] %}
- {% set ports = rule.port if (rule.port is iterable and rule.port is not string) else [rule.port | default(none)] %}
- {% for iface in ifaces %}
- {% for proto in protos %}
- {% for port in ports %}
-iifname "{{ iface }}" oifname "{{ client.zone_iface }}" ip daddr {{ client.container_ip }} {% if proto and port %}{{ proto }} dport {{ port }} {% endif %}counter accept comment "{{ iface }} -> {{ item }}"
- {% endfor %}
- {% endfor %}
- {% endfor %}
- {% endfor %}
- {% endif %}
-{% endfor %}
diff --git a/roles/nftables/templates/liqueur/nftables.conf.j2 b/roles/nftables/templates/liqueur/nftables.conf.j2
new file mode 100644
index 0000000..0c67135
--- /dev/null
+++ b/roles/nftables/templates/liqueur/nftables.conf.j2
@@ -0,0 +1,53 @@
+#!/usr/sbin/nft -f
+flush ruleset
+table inet filter {
+ chain input {
+ type filter hook input priority filter;
+ policy drop;
+ iif "lo" accept
+ ct state established,related accept
+ ct state invalid drop
+ tcp dport 22 counter accept comment "ssh"
+ tcp dport 80 counter accept comment "http"
+ tcp dport 443 counter accept comment "https"
+ tcp dport 24444 counter accept comment "mcsmanager"
+ tcp dport { 5222, 5223, 5269, 5000, 5270, 5280 } counter accept comment "xmpp"
+ }
+ chain forward {
+ type filter hook forward priority filter;
+ policy drop;
+ ct state established,related accept
+ ip daddr {{ hostvars['coturn']['container_ip'] }} udp dport { 3478, 5349, 49152-65535 } counter accept
+ ip daddr {{ hostvars['coturn']['container_ip'] }} tcp dport { 3478, 5349 } counter accept
+ ip daddr {{ hostvars['mcsmanager']['container_ip'] }} tcp dport 25565 counter accept
+ ip daddr {{ hostvars['steamcmd']['container_ip'] }} udp dport 2456 counter accept
+ ip daddr {{ hostvars['steamcmd']['container_ip'] }} udp dport 2457 counter accept
+ ip daddr {{ hostvars['rbpi4']['container_ip'] }} udp dport 21116 counter accept
+ ip daddr {{ hostvars['rbpi4']['container_ip'] }} tcp dport 21114-21119 counter accept
+ iifname tun0 ip saddr {{ hostvars['workuter']['container_ip'] }} oifname tun0 ip daddr {{ hostvars['xiawrt']['container_ip'] }} tcp dport 22 counter accept
+ iifname tun0 ip saddr {{ hostvars['workuter']['container_ip'] }} oifname tun0 ip daddr {{ hostvars['rbpi4']['container_ip'] }} tcp dport 22 counter accept
+ iifname tun0 ip saddr {{ hostvars['oyacoi-odcm']['container_ip'] }} oifname tun0 ip daddr {{ hostvars['xiawrt']['container_ip'] }} tcp dport 22 counter accept
+ iifname tun0 ip saddr {{ hostvars['oyacoi-odcm']['container_ip'] }} oifname tun0 ip daddr {{ hostvars['rbpi4']['container_ip'] }} tcp dport 22 counter accept
+ }
+ chain output {
+ type filter hook output priority filter;
+ policy accept;
+ }
+}
+table ip nat {
+ chain prerouting {
+ type nat hook prerouting priority dstnat;
+ policy accept;
+ ip daddr {{ container_ip }} udp dport { 3478, 5349, 49152-65535 } counter dnat to {{ hostvars['coturn']['container_ip'] }}
+ ip daddr {{ container_ip }} tcp dport { 3478, 5349 } counter dnat to {{ hostvars['coturn']['container_ip'] }}
+ ip daddr {{ container_ip }} tcp dport 25565 counter dnat to {{ hostvars['mcsmanager']['container_ip'] }}
+ ip daddr {{ container_ip }} udp dport 2456 counter dnat to {{ hostvars['steamcmd']['container_ip'] }}
+ ip daddr {{ container_ip }} udp dport 2457 counter dnat to {{ hostvars['steamcmd']['container_ip'] }}
+ ip daddr {{ container_ip }} udp dport 21116 counter dnat to {{ hostvars['rbpi4']['container_ip'] }}
+ ip daddr {{ container_ip }} tcp dport 21114-21119 counter dnat to {{ hostvars['rbpi4']['container_ip'] }}
+ }
+ chain postrouting {
+ type nat hook postrouting priority srcnat;
+ policy accept;
+ }
+}
diff --git a/roles/xray-lists/templates/90-sets.nft.j2 b/roles/nftables/templates/router/20-sets.nft.j2
similarity index 100%
rename from roles/xray-lists/templates/90-sets.nft.j2
rename to roles/nftables/templates/router/20-sets.nft.j2
diff --git a/roles/nftables/templates/router/90-dstnat.nft.j2 b/roles/nftables/templates/router/90-dstnat.nft.j2
new file mode 100644
index 0000000..5ec4ee0
--- /dev/null
+++ b/roles/nftables/templates/router/90-dstnat.nft.j2
@@ -0,0 +1,19 @@
+#jinja2: trim_blocks: True, lstrip_blocks: True
+{% for item in nft_managed_group | sort %}
+{% set client = hostvars[item] %}
+{% if 'nft_dst' in client and client.nft_dst is not none %}
+{% set target_ip = client.container_ip %}
+{% for client in client.nft_dst %}
+{% set ports = client.port if (client.port is iterable and client.port is not string) else [client.port] %}
+{% set protos = client.proto if (client.proto is iterable and client.proto is not string) else [client.proto] %}
+{% set ifaces = client.iface if (client.iface is iterable and client.iface is not string) else [client.iface] %}
+{% for proto in protos %}
+{% for port in ports %}
+{% for iface in ifaces %}
+iifname "{{ iface }}" {{ proto }} dport {{ port }} counter dnat ip to {{ target_ip }}:{{ port }} comment "{{ iface }} -> {{ item }}"
+{% endfor %}
+{% endfor %}
+{% endfor %}
+{% endfor %}
+{% endif %}
+{% endfor %}
diff --git a/roles/nftables/templates/router/90-forward.nft.j2 b/roles/nftables/templates/router/90-forward.nft.j2
new file mode 100644
index 0000000..fe059d3
--- /dev/null
+++ b/roles/nftables/templates/router/90-forward.nft.j2
@@ -0,0 +1,47 @@
+#jinja2: trim_blocks: True, lstrip_blocks: True
+{% for item in nft_managed_group | sort %}
+{% set client = hostvars[item] %}
+{% if 'nft_to' in client and client.nft_to is not none %}
+{% set rules = client.nft_to if (client.nft_to is iterable and client.nft_to is not string) else [client.nft_to] %}
+{% for rule in rules %}
+{% set rule = rule if rule is mapping else {'to': rule} %}
+{% set dests = rule.to if (rule.to is iterable and rule.to is not string) else [rule.to] %}
+{% set protos = rule.proto if (rule.proto is iterable and rule.proto is not string) else [rule.proto | default(none)] %}
+{% set ports = rule.port if (rule.port is iterable and rule.port is not string) else [rule.port | default(none)] %}
+{% for dest in dests %}
+{% if dest.startswith('zone:') %}
+{% set oif = dest.split(':')[1] %}
+{% set daddr = none %}
+{% set dest_name = oif %}
+{% else %}
+{% set oif = hostvars[dest].zone_iface %}
+{% set daddr = hostvars[dest].container_ip %}
+{% set dest_name = dest %}
+{% endif %}
+{% for proto in protos %}
+{% for port in ports %}
+iifname "{{ client.zone_iface }}" ip saddr {{ client.container_ip }} oifname "{{ oif }}" {% if daddr %}ip daddr {{ daddr }} {% endif %}{% if proto and port %}{{ proto }} dport {{ port }} {% endif %}counter accept comment "{{ item }} -> {{ dest_name }}"
+{% endfor %}
+{% endfor %}
+{% endfor %}
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% for item in nft_managed_group | sort %}
+{% set client = hostvars[item] %}
+{% if 'nft_from' in client and client.nft_from is not none %}
+{% set rules = client.nft_from if (client.nft_from is iterable and client.nft_from is not string) else [client.nft_from] %}
+{% for rule in rules %}
+{% set ifaces = rule.iface if (rule.iface is iterable and rule.iface is not string) else [rule.iface] %}
+{% set protos = rule.proto if (rule.proto is iterable and rule.proto is not string) else [rule.proto | default(none)] %}
+{% set ports = rule.port if (rule.port is iterable and rule.port is not string) else [rule.port | default(none)] %}
+{% for iface in ifaces %}
+{% for proto in protos %}
+{% for port in ports %}
+iifname "{{ iface }}" oifname "{{ client.zone_iface }}" ip daddr {{ client.container_ip }} {% if proto and port %}{{ proto }} dport {{ port }} {% endif %}counter accept comment "{{ iface }} -> {{ item }}"
+{% endfor %}
+{% endfor %}
+{% endfor %}
+{% endfor %}
+{% endif %}
+{% endfor %}
diff --git a/roles/xray-lists/templates/90-proxy-output.nft.j2 b/roles/nftables/templates/router/90-proxy-output.nft.j2
similarity index 52%
rename from roles/xray-lists/templates/90-proxy-output.nft.j2
rename to roles/nftables/templates/router/90-proxy-output.nft.j2
index 67579a1..fe1b334 100644
--- a/roles/xray-lists/templates/90-proxy-output.nft.j2
+++ b/roles/nftables/templates/router/90-proxy-output.nft.j2
@@ -1,11 +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([])) -%}
+{%- if rule in (xray_ip_sets | default([])) or rule in (xray_static_sets | default([])) -%}
{{ rule }}_ip
- {%- elif rule in (xray_domain_sets | default([])) -%}
+{%- elif rule in (xray_domain_sets | default([])) -%}
{{ rule }}_dom
- {%- endif -%}
+{%- endif -%}
{% endmacro %}
{% for rule in output_rules | default([]) | sort %}
-ip daddr @{{ set_daddr(rule) }} meta mark set {{ xray_fwmark }} accept
-{% endfor %}
+ip daddr @{{ set_daddr(rule) }} meta mark set {{ xray_fwmark }} counter accept comment "router -> tproxy"
+{% endfor %}
diff --git a/roles/nftables/templates/router/90-proxy-prerouting.nft.j2 b/roles/nftables/templates/router/90-proxy-prerouting.nft.j2
new file mode 100644
index 0000000..56b1fe1
--- /dev/null
+++ b/roles/nftables/templates/router/90-proxy-prerouting.nft.j2
@@ -0,0 +1,28 @@
+#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 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 ip saddr {{ src_ip }} ip daddr {{ set_daddr(target_set) }} counter accept comment "{{ item }} -> accept"
+meta l4proto udp ip saddr {{ src_ip }} ip daddr {{ set_daddr(target_set) }} counter accept comment "{{ item }} -> accept"
+{% elif rule.proxy is defined %}
+meta l4proto tcp ip saddr {{ src_ip }} ip daddr {{ set_daddr(target_set) }} tproxy ip to :{{ xray_tproxy_port }} meta mark set {{ xray_fwmark }} counter accept comment "{{ item }} -> trpoxy"
+meta l4proto udp ip saddr {{ src_ip }} ip daddr {{ set_daddr(target_set) }} tproxy ip to :{{ xray_tproxy_port }} meta mark set {{ xray_fwmark }} counter accept comment "{{ item }} -> tproxy"
+{% endif %}
+{% endfor %}
+{% endif %}
+{% endfor %}
diff --git a/roles/nftables/templates/router/nftables.conf.j2 b/roles/nftables/templates/router/nftables.conf.j2
new file mode 100644
index 0000000..0a71d03
--- /dev/null
+++ b/roles/nftables/templates/router/nftables.conf.j2
@@ -0,0 +1,11 @@
+#!/usr/sbin/nft -f
+flush ruleset
+table inet filter {
+ include "/etc/nftables.d/10-sets.nft"
+ include "/etc/nftables.d/20-sets.nft"
+ include "/etc/nftables.d/40-filter.nft"
+ include "/etc/nftables.d/50-proxy.nft"
+}
+table ip nat {
+ include "/etc/nftables.d/30-nat.nft"
+}
diff --git a/roles/nginx/handlers/main.yml b/roles/nginx/handlers/main.yml
new file mode 100644
index 0000000..5cc1ed6
--- /dev/null
+++ b/roles/nginx/handlers/main.yml
@@ -0,0 +1,14 @@
+# handlers/main.yml
+---
+- name: validate nginx config
+ ansible.builtin.command: nginx -t
+ changed_when: false
+ listen: restart nginx
+
+- name: restart nginx systemd service unit
+ ansible.builtin.systemd_service:
+ name: nginx
+ daemon_reload: true
+ state: restarted
+ enabled: true
+ listen: restart nginx
diff --git a/roles/nginx/tasks/configure.yml b/roles/nginx/tasks/configure.yml
new file mode 100644
index 0000000..6076838
--- /dev/null
+++ b/roles/nginx/tasks/configure.yml
@@ -0,0 +1,10 @@
+---
+- name: deploy nginx config
+ ansible.builtin.template:
+ src: "{{ item }}"
+ dest: "/etc/nginx/{{ item | basename | regex_replace('\\.j2$', '') }}"
+ owner: root
+ group: root
+ mode: '0644'
+ loop: "{{ query('ansible.builtin.fileglob', role_path + '/templates/' + inventory_hostname + '/*.conf.j2') }}"
+ notify: restart nginx
diff --git a/roles/nginx/tasks/install.yml b/roles/nginx/tasks/install.yml
new file mode 100644
index 0000000..b04aea8
--- /dev/null
+++ b/roles/nginx/tasks/install.yml
@@ -0,0 +1,81 @@
+---
+- name: install prerequisites for nginx repository
+ ansible.builtin.apt:
+ name:
+ - curl
+ - gnupg2
+ - ca-certificates
+ - lsb-release
+ - debian-archive-keyring
+ state: present
+ update_cache: true
+
+- name: check if nginx keyring already exists
+ ansible.builtin.stat:
+ path: /usr/share/keyrings/nginx-archive-keyring.gpg
+ register: nginx_keyring
+
+- name: download nginx gpg key
+ ansible.builtin.get_url:
+ url: https://nginx.org/keys/nginx_signing.key
+ dest: /tmp/nginx_signing.key
+ mode: '0644'
+ when: not nginx_keyring.stat.exists
+
+- name: dearmor nginx gpg key
+ ansible.builtin.command:
+ cmd: gpg --dearmor --yes -o /usr/share/keyrings/nginx-archive-keyring.gpg /tmp/nginx_signing.key
+ when: not nginx_keyring.stat.exists
+
+- name: ensure /root/.gnupg exists
+ ansible.builtin.file:
+ path: /root/.gnupg
+ state: directory
+ mode: '0700'
+ owner: root
+ group: root
+
+- name: verify nginx signing key fingerprint
+ ansible.builtin.command:
+ cmd: gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
+ register: nginx_key_check
+ changed_when: false
+
+- name: check nginx signing key fingerprint
+ ansible.builtin.fail:
+ msg: "nginx signing key fingerprint mismatch! Got: {{ nginx_key_check.stdout }}"
+ when: "'573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62' not in nginx_key_check.stdout"
+
+- name: add nginx apt repository
+ ansible.builtin.copy:
+ dest: /etc/apt/sources.list.d/nginx.list
+ content: >-
+ deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg]
+ https://nginx.org/packages/{{ 'mainline/' if (nginx_use_mainline | default(false)) else '' }}debian
+ {{ ansible_facts['distribution_release'] }} nginx
+ owner: root
+ group: root
+ mode: '0644'
+ register: nginx_repo_file
+
+- name: set up repository pinning for nginx
+ ansible.builtin.copy:
+ dest: /etc/apt/preferences.d/99nginx
+ content: |
+ Package: *
+ Pin: origin nginx.org
+ Pin: release o=nginx
+ Pin-Priority: 900
+ owner: root
+ group: root
+ mode: '0644'
+
+- name: update apt cache
+ ansible.builtin.apt:
+ update_cache: true
+ when: nginx_repo_file.changed
+
+- name: install nginx
+ ansible.builtin.apt:
+ name: nginx
+ state: present
diff --git a/roles/nginx/tasks/main.yml b/roles/nginx/tasks/main.yml
new file mode 100644
index 0000000..4b0637c
--- /dev/null
+++ b/roles/nginx/tasks/main.yml
@@ -0,0 +1,6 @@
+---
+- name: include install
+ ansible.builtin.include_tasks: install.yml
+
+- name: include configure
+ ansible.builtin.include_tasks: configure.yml
diff --git a/roles/nginx/templates/liqueur/nginx.conf.j2 b/roles/nginx/templates/liqueur/nginx.conf.j2
new file mode 100644
index 0000000..ebb60ab
--- /dev/null
+++ b/roles/nginx/templates/liqueur/nginx.conf.j2
@@ -0,0 +1,37 @@
+user www-data;
+worker_processes auto;
+worker_cpu_affinity auto;
+pid /run/nginx.pid;
+error_log /var/log/nginx/error.log;
+include /etc/nginx/modules-enabled/*.conf;
+events {
+ worker_connections 768;
+}
+stream {
+ upstream haproxy_http {
+ server 127.0.0.1:10080;
+ }
+ upstream haproxy_backend {
+ server 127.0.0.1:10443;
+ }
+ upstream stunnel_tun0_backend {
+ server 127.0.0.1:8443;
+ }
+ upstream stunnel_tap0_backend {
+ server 127.0.0.1:8444;
+ }
+ map $ssl_preread_server_name $backend {
+ liqueur.oyacoi.ru stunnel_tun0_backend;
+ absinthe.oyacoi.ru stunnel_tap0_backend;
+ default haproxy_backend;
+ }
+ server {
+ listen {{ container_ip }}:80;
+ proxy_pass haproxy_http;
+ }
+ server {
+ listen {{ container_ip }}:443;
+ proxy_pass $backend;
+ ssl_preread on;
+ }
+}
diff --git a/roles/openvpn/files/liqueur/ccd/liqueur/matr10 b/roles/openvpn/files/liqueur/ccd/liqueur/matr10
new file mode 100644
index 0000000..ba2bf1d
--- /dev/null
+++ b/roles/openvpn/files/liqueur/ccd/liqueur/matr10
@@ -0,0 +1 @@
+iroute 192.168.1.0 255.255.255.0
diff --git a/roles/openvpn/files/liqueur/ccd/liqueur/mur89 b/roles/openvpn/files/liqueur/ccd/liqueur/mur89
new file mode 100644
index 0000000..433dbb4
--- /dev/null
+++ b/roles/openvpn/files/liqueur/ccd/liqueur/mur89
@@ -0,0 +1,7 @@
+iroute 10.1.0.0 255.255.255.0
+iroute 10.2.0.0 255.255.255.0
+iroute 10.3.0.0 255.255.255.0
+iroute 10.4.0.0 255.255.255.0
+iroute 10.10.0.0 255.255.255.0
+iroute 10.11.0.0 255.255.255.0
+iroute 10.12.0.0 255.255.255.0
diff --git a/roles/openvpn/tasks/configure-client.yml b/roles/openvpn/tasks/configure-client.yml
new file mode 100644
index 0000000..edef22a
--- /dev/null
+++ b/roles/openvpn/tasks/configure-client.yml
@@ -0,0 +1,19 @@
+---
+- name: render openvpn client config
+ ansible.builtin.template:
+ src: "{{ item }}"
+ dest: "/etc/openvpn/{{ item | basename | regex_replace('\\.j2$', '') }}"
+ owner: root
+ group: root
+ mode: '0600'
+ loop: "{{ query('fileglob', role_path + '/templates/' + inventory_hostname + '/*.conf.j2') }}"
+ register: openvpn_client_configs
+
+- name: restart openvpn client
+ ansible.builtin.systemd_service:
+ name: "openvpn@{{ item.item | basename | regex_replace('\\.conf\\.j2$', '') }}"
+ state: restarted
+ enabled: true
+ daemon_reload: true
+ loop: "{{ openvpn_client_configs.results }}"
+ when: item.changed
diff --git a/roles/openvpn/tasks/configure-server.yml b/roles/openvpn/tasks/configure-server.yml
new file mode 100644
index 0000000..2230c79
--- /dev/null
+++ b/roles/openvpn/tasks/configure-server.yml
@@ -0,0 +1,27 @@
+---
+- name: deploy ccd files
+ ansible.builtin.copy:
+ src: "{{ role_path }}/files/{{ inventory_hostname }}/ccd/"
+ dest: /etc/openvpn/ccd/
+ owner: root
+ group: root
+ mode: '0644'
+
+- name: render openvpn config
+ ansible.builtin.template:
+ src: "{{ item }}"
+ dest: "/etc/openvpn/{{ item | basename | regex_replace('\\.j2$', '') }}"
+ owner: root
+ group: root
+ mode: '0600'
+ loop: "{{ query('ansible.builtin.fileglob', role_path + '/templates/' + inventory_hostname + '/*.conf.j2') }}"
+ register: openvpn_configs
+
+- name: restart openvpn
+ ansible.builtin.systemd_service:
+ name: "openvpn@{{ item.item | basename | regex_replace('\\.conf\\.j2$', '') }}"
+ state: restarted
+ enabled: true
+ daemon_reload: true
+ loop: "{{ openvpn_configs.results }}"
+ when: item.changed
diff --git a/roles/openvpn/tasks/install.yml b/roles/openvpn/tasks/install.yml
new file mode 100644
index 0000000..30886b1
--- /dev/null
+++ b/roles/openvpn/tasks/install.yml
@@ -0,0 +1,6 @@
+---
+- name: install openvpn
+ ansible.builtin.apt:
+ name: openvpn
+ state: latest
+ update_cache: true
diff --git a/roles/openvpn/tasks/main.yml b/roles/openvpn/tasks/main.yml
new file mode 100644
index 0000000..0e96fd6
--- /dev/null
+++ b/roles/openvpn/tasks/main.yml
@@ -0,0 +1,11 @@
+---
+- name: include install
+ ansible.builtin.include_tasks: install.yml
+
+- name: include server configuration
+ ansible.builtin.include_tasks: configure-server.yml
+ when: openvpn_role == 'server'
+
+- name: include client configuration
+ ansible.builtin.include_tasks: configure-client.yml
+ when: openvpn_role == 'client'
diff --git a/roles/openvpn/templates/liqueur/absinthe.conf.j2 b/roles/openvpn/templates/liqueur/absinthe.conf.j2
new file mode 100644
index 0000000..e0ef235
--- /dev/null
+++ b/roles/openvpn/templates/liqueur/absinthe.conf.j2
@@ -0,0 +1,27 @@
+port 1195
+proto tcp
+dev tap0
+dev-type tap
+server-bridge nogw
+client-to-client
+keepalive 10 60
+cipher AES-256-GCM
+auth SHA256
+persist-key
+persist-tun
+status openvpn-tap0-status.log
+verb 6
+tun-mtu 1500
+mssfix 1300
+
+{{ lookup('file', '/etc/easy-rsa/pki/tap0/ca.crt') }}
+
+
+{{ lookup('file', '/etc/easy-rsa/pki/tap0/issued/server.crt') }}
+
+
+{{ lookup('file', '/etc/easy-rsa/pki/tap0/private/server.key') }}
+
+
+{{ lookup('file', '/etc/easy-rsa/pki/tap0/dh.pem') }}
+
diff --git a/roles/openvpn/templates/liqueur/liqueur.conf.j2 b/roles/openvpn/templates/liqueur/liqueur.conf.j2
new file mode 100644
index 0000000..663a959
--- /dev/null
+++ b/roles/openvpn/templates/liqueur/liqueur.conf.j2
@@ -0,0 +1,44 @@
+port 1194
+proto tcp
+dev tun0
+server 172.168.0.0 255.255.255.0
+topology subnet
+ifconfig-pool-persist ipp.txt
+route 10.1.0.0 255.255.255.0
+route 10.2.0.0 255.255.255.0
+route 10.3.0.0 255.255.255.0
+route 10.4.0.0 255.255.255.0
+route 10.10.0.0 255.255.255.0
+route 10.11.0.0 255.255.255.0
+route 10.12.0.0 255.255.255.0
+route 192.168.1.0 255.255.255.0
+push "route 192.168.1.0 255.255.255.0"
+push "route 10.1.0.0 255.255.255.0"
+push "route 10.2.0.0 255.255.255.0"
+push "route 10.3.0.0 255.255.255.0"
+push "route 10.4.0.0 255.255.255.0"
+push "route 10.10.0.0 255.255.255.0"
+push "route 10.11.0.0 255.255.255.0"
+push "route 10.12.0.0 255.255.255.0"
+client-config-dir /etc/openvpn/ccd/liqueur
+keepalive 10 60
+cipher AES-256-GCM
+auth SHA256
+persist-key
+persist-tun
+status openvpn-status.log
+verb 3
+tun-mtu 1500
+mssfix 1300
+
+{{ lookup('file', '/etc/easy-rsa/pki/tun0/ca.crt') }}
+
+
+{{ lookup('file', '/etc/easy-rsa/pki/tun0/issued/server.crt') }}
+
+
+{{ lookup('file', '/etc/easy-rsa/pki/tun0/private/server.key') }}
+
+
+{{ lookup('file', '/etc/easy-rsa/pki/tun0/dh.pem') }}
+
diff --git a/roles/openvpn/templates/router/ltrefilov.conf.j2 b/roles/openvpn/templates/router/ltrefilov.conf.j2
new file mode 100644
index 0000000..2fc56e6
--- /dev/null
+++ b/roles/openvpn/templates/router/ltrefilov.conf.j2
@@ -0,0 +1,24 @@
+client
+dev tap0
+dev-type tap
+proto tcp
+remote 127.0.0.1 1195
+resolv-retry infinite
+nobind
+persist-key
+persist-tun
+remote-cert-tls server
+auth SHA256
+cipher AES-256-GCM
+tun-mtu 1500
+mssfix 1300
+verb 3
+
+{{ lookup('file', '/etc/easy-rsa/pki/tap0/ca.crt') }}
+
+
+{{ lookup('file', '/etc/easy-rsa/pki/tap0/issued/ltrefilov.crt') }}
+
+
+{{ lookup('file', '/etc/easy-rsa/pki/tap0/private/ltrefilov.key') }}
+
diff --git a/roles/openvpn/templates/router/mur89.conf.j2 b/roles/openvpn/templates/router/mur89.conf.j2
new file mode 100644
index 0000000..798c918
--- /dev/null
+++ b/roles/openvpn/templates/router/mur89.conf.j2
@@ -0,0 +1,21 @@
+client
+dev tun0
+proto tcp
+remote 127.0.0.1 1194
+resolv-retry infinite
+nobind
+persist-key
+persist-tun
+remote-cert-tls server
+auth SHA256
+cipher AES-256-GCM
+verb 3
+
+{{ lookup('file', '/etc/easy-rsa/pki/tun0/ca.crt') }}
+
+
+{{ lookup('file', '/etc/easy-rsa/pki/tun0/issued/mur89.crt') }}
+
+
+{{ lookup('file', '/etc/easy-rsa/pki/tun0/private/mur89.key') }}
+
diff --git a/roles/sshd/handlers/main.yml b/roles/sshd/handlers/main.yml
new file mode 100644
index 0000000..fb3d74a
--- /dev/null
+++ b/roles/sshd/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: restart sshd
+ ansible.builtin.service:
+ name: ssh
+ state: restarted
diff --git a/roles/sshd/tasks/configure.yml b/roles/sshd/tasks/configure.yml
new file mode 100644
index 0000000..42feb2d
--- /dev/null
+++ b/roles/sshd/tasks/configure.yml
@@ -0,0 +1,16 @@
+---
+- name: disable password authentication
+ ansible.builtin.lineinfile:
+ path: /etc/ssh/sshd_config
+ regexp: '^#?PasswordAuthentication\s'
+ line: 'PasswordAuthentication no'
+ validate: '/usr/sbin/sshd -t -f %s'
+ notify: restart sshd
+
+- name: enable root authentication
+ ansible.builtin.lineinfile:
+ path: /etc/ssh/sshd_config
+ regexp: '^#?PermitRootLogin\s'
+ line: 'PermitRootLogin prohibit-password'
+ validate: '/usr/sbin/sshd -t -f %s'
+ notify: restart sshd
diff --git a/roles/xray-client/tasks/main.yml b/roles/sshd/tasks/main.yml
similarity index 57%
rename from roles/xray-client/tasks/main.yml
rename to roles/sshd/tasks/main.yml
index feb73d0..9c0153e 100644
--- a/roles/xray-client/tasks/main.yml
+++ b/roles/sshd/tasks/main.yml
@@ -1,3 +1,3 @@
---
-- name: include xray-core configurure
+- name: include configure
ansible.builtin.include_tasks: configure.yml
diff --git a/roles/stunnel4/files/liqueur/absinthe.conf b/roles/stunnel4/files/liqueur/absinthe.conf
new file mode 100644
index 0000000..e09dd04
--- /dev/null
+++ b/roles/stunnel4/files/liqueur/absinthe.conf
@@ -0,0 +1,9 @@
+setuid = stunnel4
+setgid = stunnel4
+pid = /var/run/stunnel4/absinthe.pid
+output = /var/log/stunnel4/absinthe.log
+[openvpn]
+cert = /etc/letsencrypt/live/absinthe.oyacoi.ru/fullchain.pem
+key = /etc/letsencrypt/live/absinthe.oyacoi.ru/privkey.pem
+accept = 127.0.0.1:8444
+connect = 127.0.0.1:1195
diff --git a/roles/stunnel4/files/liqueur/liqueur.conf b/roles/stunnel4/files/liqueur/liqueur.conf
new file mode 100644
index 0000000..5850d90
--- /dev/null
+++ b/roles/stunnel4/files/liqueur/liqueur.conf
@@ -0,0 +1,9 @@
+setuid = stunnel4
+setgid = stunnel4
+pid = /var/run/stunnel4/liqueur.pid
+output = /var/log/stunnel4/liqueur.log
+[openvpn]
+cert = /etc/letsencrypt/live/liqueur.oyacoi.ru/fullchain.pem
+key = /etc/letsencrypt/live/liqueur.oyacoi.ru/privkey.pem
+accept = 127.0.0.1:8443
+connect = 127.0.0.1:1194
diff --git a/roles/stunnel4/handlers/main.yml b/roles/stunnel4/handlers/main.yml
new file mode 100644
index 0000000..a824e50
--- /dev/null
+++ b/roles/stunnel4/handlers/main.yml
@@ -0,0 +1,6 @@
+---
+- name: restart stunnel4
+ ansible.builtin.service:
+ name: stunnel4
+ state: restarted
+ listen: restart stunnel4
diff --git a/roles/stunnel4/tasks/configure.yml b/roles/stunnel4/tasks/configure.yml
new file mode 100644
index 0000000..037a908
--- /dev/null
+++ b/roles/stunnel4/tasks/configure.yml
@@ -0,0 +1,36 @@
+---
+- name: ensure /var/run/stunnel exists
+ ansible.builtin.file:
+ path: /var/run/stunnel
+ owner: stunnel4
+ group: stunnel4
+ state: directory
+ mode: "0755"
+
+- name: ensure /var/log/stunnel exists
+ ansible.builtin.file:
+ path: /var/log/stunnel
+ state: directory
+ owner: stunnel4
+ group: stunnel4
+ mode: "0755"
+
+- name: deploy stunnel config
+ ansible.builtin.copy:
+ src: "{{ item }}"
+ dest: "/etc/stunnel/{{ item | basename }}"
+ owner: root
+ group: root
+ mode: '0644'
+ loop: "{{ query('fileglob', role_path + '/files/' + inventory_hostname + '/*.conf') }}"
+ notify: restart stunnel4
+
+- name: render stunnel config
+ ansible.builtin.template:
+ src: "{{ item }}"
+ dest: "/etc/stunnel/{{ item | basename | regex_replace('\\.j2$', '') }}"
+ owner: root
+ group: root
+ mode: '0644'
+ loop: "{{ query('fileglob', role_path + '/templates/' + inventory_hostname + '/*.conf.j2') }}"
+ notify: restart stunnel4
diff --git a/roles/stunnel4/tasks/install.yml b/roles/stunnel4/tasks/install.yml
new file mode 100644
index 0000000..755179c
--- /dev/null
+++ b/roles/stunnel4/tasks/install.yml
@@ -0,0 +1,6 @@
+---
+- name: install stunnel4
+ ansible.builtin.apt:
+ name: stunnel4
+ state: latest
+ update_cache: true
diff --git a/roles/stunnel4/tasks/main.yml b/roles/stunnel4/tasks/main.yml
new file mode 100644
index 0000000..4b0637c
--- /dev/null
+++ b/roles/stunnel4/tasks/main.yml
@@ -0,0 +1,6 @@
+---
+- name: include install
+ ansible.builtin.include_tasks: install.yml
+
+- name: include configure
+ ansible.builtin.include_tasks: configure.yml
diff --git a/roles/stunnel4/templates/router/absinthe.conf.j2 b/roles/stunnel4/templates/router/absinthe.conf.j2
new file mode 100644
index 0000000..c9bf7e7
--- /dev/null
+++ b/roles/stunnel4/templates/router/absinthe.conf.j2
@@ -0,0 +1,9 @@
+setuid = stunnel4
+setgid = stunnel4
+pid = /var/run/stunnel/absinthe.pid
+output = /var/log/stunnel/absinthe.log
+client = yes
+[openvpn]
+sni = absinthe.oyacoi.ru
+accept = 127.0.0.1:1195
+connect = {{ hostvars['liqueur'].container_ip }}:443
diff --git a/roles/stunnel4/templates/router/liqueur.conf.j2 b/roles/stunnel4/templates/router/liqueur.conf.j2
new file mode 100644
index 0000000..72b9b58
--- /dev/null
+++ b/roles/stunnel4/templates/router/liqueur.conf.j2
@@ -0,0 +1,9 @@
+setuid = stunnel4
+setgid = stunnel4
+pid = /var/run/stunnel/liqueur.pid
+output = /var/log/stunnel/liqueur.log
+client = yes
+[openvpn]
+sni = liqueur.oyacoi.ru
+accept = 127.0.0.1:1194
+connect = {{ hostvars['liqueur'].container_ip }}:443
diff --git a/roles/sysctl/files/liqueur/99-custom.conf b/roles/sysctl/files/liqueur/99-custom.conf
new file mode 100644
index 0000000..493c88c
--- /dev/null
+++ b/roles/sysctl/files/liqueur/99-custom.conf
@@ -0,0 +1,2 @@
+net.ipv4.ip_forward = 1
+net.ipv4.conf.all.route_localnet = 1
diff --git a/roles/sysctl/files/router/99-custom.conf b/roles/sysctl/files/router/99-custom.conf
new file mode 100644
index 0000000..7d494f0
--- /dev/null
+++ b/roles/sysctl/files/router/99-custom.conf
@@ -0,0 +1,6 @@
+net.ipv4.ip_forward = 1
+net.ipv4.conf.lo.rp_filter = 0
+net.ipv4.conf.all.rp_filter = 0
+net.bridge.bridge-nf-call-iptables = 0
+net.bridge.bridge-nf-call-ip6tables = 0
+net.bridge.bridge-nf-call-arptables = 0
diff --git a/roles/sysctl/tasks/configure.yml b/roles/sysctl/tasks/configure.yml
index b0e871b..2e5882f 100644
--- a/roles/sysctl/tasks/configure.yml
+++ b/roles/sysctl/tasks/configure.yml
@@ -1,7 +1,7 @@
- name: deploy sysctl config
- ansible.builtin.template:
- src: sysctl.conf.j2
- dest: "/etc/sysctl.d/99-custom.conf"
+ ansible.builtin.copy:
+ src: "{{ inventory_hostname }}/"
+ dest: "/etc/sysctl.d/"
owner: root
group: root
mode: '0644'
diff --git a/roles/sysctl/templates/sysctl.conf.j2 b/roles/sysctl/templates/sysctl.conf.j2
deleted file mode 100644
index 3df6ce7..0000000
--- a/roles/sysctl/templates/sysctl.conf.j2
+++ /dev/null
@@ -1,3 +0,0 @@
-{% for key, value in sysctl.items() %}
-{{ key }} = {{ value }}
-{% endfor %}
diff --git a/roles/wireguard-tools/handlers/main.yml b/roles/wireguard-tools/handlers/main.yml
deleted file mode 100644
index f28943b..0000000
--- a/roles/wireguard-tools/handlers/main.yml
+++ /dev/null
@@ -1,7 +0,0 @@
----
-- name: restart wg0 systemd service unit
- ansible.builtin.systemd_service:
- name: wg-quick@wg0
- daemon_reload: true
- state: restarted
- enabled: true
diff --git a/roles/wireguard-tools/tasks/configure.yml b/roles/wireguard-tools/tasks/configure.yml
deleted file mode 100644
index e253ba5..0000000
--- a/roles/wireguard-tools/tasks/configure.yml
+++ /dev/null
@@ -1,21 +0,0 @@
----
-- name: ensure /etc/wireguard exists
- ansible.builtin.file:
- path: /etc/wireguard
- state: directory
- mode: "0700"
-
-- name: deploy wireguard config
- ansible.builtin.template:
- src: "wg0.conf.j2"
- dest: "/etc/wireguard/wg0.conf"
- mode: "0644"
- register: wg0_conf
-
-- name: restart wg0 systemd service unit
- ansible.builtin.systemd_service:
- name: wg-quick@wg0
- daemon_reload: true
- state: restarted
- enabled: true
- when: wg0_conf.changed
diff --git a/roles/wireguard-tools/templates/wg0.conf.j2 b/roles/wireguard-tools/templates/wg0.conf.j2
deleted file mode 100644
index 5ce31f5..0000000
--- a/roles/wireguard-tools/templates/wg0.conf.j2
+++ /dev/null
@@ -1,17 +0,0 @@
-[Interface]
-PrivateKey = {{ wg_private_key }}
-Address = {{ wg_address }}
-Table = off
-PostUp = ip route add 10.250.250.0/24 dev wg0 2>/dev/null || true
-PostUp = ip rule add fwmark 0xc7 lookup 199 2>/dev/null || true
-PostUp = ip route add default dev wg0 table 199 2>/dev/null || true
-PreDown = ip route del default dev wg0 table 199 2>/dev/null || true
-PreDown = ip rule del fwmark 0xc7 lookup 199 2>/dev/null || true
-PreDown = ip route del 10.250.250.0/24 dev wg0 2>/dev/null || true
-
-[Peer]
-PublicKey = {{ wg_public_key }}
-PresharedKey = {{ wg_presharedkey }}
-Endpoint = {{ wg_endpoint_address }}:{{ wg_endpoint_port }}
-PersistentKeepalive = 25
-AllowedIPs = 0.0.0.0/0
diff --git a/roles/xray-client/tasks/configure.yml b/roles/xray-client/tasks/configure.yml
deleted file mode 100644
index bd552f0..0000000
--- a/roles/xray-client/tasks/configure.yml
+++ /dev/null
@@ -1,43 +0,0 @@
----
-- name: ensure /opt/xray-core/config exists
- ansible.builtin.file:
- path: /opt/xray-core/config
- state: directory
- mode: 0755
-
-- name: ensure /var/log/xray-core exists
- ansible.builtin.file:
- path: /var/log/xray-core
- state: directory
- mode: 0755
-
-- name: deploy static xray-core config
- ansible.builtin.copy:
- src: "{{ item }}"
- dest: "/opt/xray-core/config/{{ item }}"
- mode: 0744
- loop:
- - dns.jsonc
- - inbounds.jsonc
- - log.jsonc
- - policy.jsonc
- register: xray_core_static_config
-
-- name: deploy dynamic xray-core config
- ansible.builtin.template:
- src: "{{ item }}.j2"
- dest: "/opt/xray-core/config/{{ item }}"
- mode: 0744
- loop:
- - observatory.jsonc
- - outbounds.jsonc
- - routing.jsonc
- register: xray_core_dynamic_config
-
-- name: restart xray-core systemd service unit
- ansible.builtin.systemd_service:
- name: xray-core
- daemon_reload: true
- state: restarted
- enabled: true
- when: xray_core_static_config.changed or xray_core_dynamic_config.changed
diff --git a/roles/xray-client/files/dns.jsonc b/roles/xray-core/files/router/dns.jsonc
similarity index 100%
rename from roles/xray-client/files/dns.jsonc
rename to roles/xray-core/files/router/dns.jsonc
diff --git a/roles/xray-client/files/inbounds.jsonc b/roles/xray-core/files/router/inbounds.jsonc
similarity index 94%
rename from roles/xray-client/files/inbounds.jsonc
rename to roles/xray-core/files/router/inbounds.jsonc
index e214aec..0666ac4 100644
--- a/roles/xray-client/files/inbounds.jsonc
+++ b/roles/xray-core/files/router/inbounds.jsonc
@@ -1,6 +1,7 @@
{
"inbounds": [
{
+ "tag": "tproxy-in",
"port": 61219,
"listen": "0.0.0.0",
"protocol": "dokodemo-door",
@@ -12,8 +13,7 @@
"sockopt": {
"tproxy": "tproxy"
}
- },
- "tag": "tproxy"
+ }
},
{
"tag": "socks-in",
diff --git a/roles/xray-client/files/log.jsonc b/roles/xray-core/files/router/log.jsonc
similarity index 100%
rename from roles/xray-client/files/log.jsonc
rename to roles/xray-core/files/router/log.jsonc
diff --git a/roles/xray-client/files/policy.jsonc b/roles/xray-core/files/router/policy.jsonc
similarity index 100%
rename from roles/xray-client/files/policy.jsonc
rename to roles/xray-core/files/router/policy.jsonc
diff --git a/roles/xray-core/files/xray-core.service b/roles/xray-core/files/xray-core.service
index 6583b13..b1fc670 100644
--- a/roles/xray-core/files/xray-core.service
+++ b/roles/xray-core/files/xray-core.service
@@ -6,12 +6,16 @@ Wants=network-online.target
[Service]
Type=simple
-User=root
+User=xray-core
+Group=xray-core
WorkingDirectory=/opt/xray-core
ExecStart=/opt/xray-core/xray -confdir /opt/xray-core/config
Restart=on-failure
RestartSec=3s
LimitNOFILE=65535
+AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_ADMIN
+CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_NET_ADMIN
+NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
diff --git a/roles/xray-core/handlers/main.yml b/roles/xray-core/handlers/main.yml
new file mode 100644
index 0000000..945cceb
--- /dev/null
+++ b/roles/xray-core/handlers/main.yml
@@ -0,0 +1,13 @@
+---
+- name: validate xray-core config
+ ansible.builtin.command: su -s /bin/sh xray-core -c "/opt/xray-core/xray run -test -confdir /opt/xray-core/config"
+ changed_when: false
+ listen: restart xray-core
+
+- name: restart xray-core systemd service unit
+ ansible.builtin.systemd_service:
+ name: xray-core
+ daemon_reload: true
+ state: restarted
+ enabled: true
+ listen: restart xray-core
diff --git a/roles/xray-core/tasks/configure.yml b/roles/xray-core/tasks/configure.yml
new file mode 100644
index 0000000..4588eac
--- /dev/null
+++ b/roles/xray-core/tasks/configure.yml
@@ -0,0 +1,36 @@
+---
+- name: ensure /opt/xray-core/config exists
+ ansible.builtin.file:
+ path: /opt/xray-core/config
+ state: directory
+ owner: xray-core
+ group: xray-core
+ mode: "0755"
+
+- name: ensure /var/log/xray-core exists
+ ansible.builtin.file:
+ path: /var/log/xray-core
+ state: directory
+ owner: xray-core
+ group: xray-core
+ mode: "0755"
+
+- name: deploy xray-core static config
+ ansible.builtin.copy:
+ src: "{{ item }}"
+ dest: "/opt/xray-core/config/{{ item | basename }}"
+ owner: xray-core
+ group: xray-core
+ mode: "0644"
+ loop: "{{ query('ansible.builtin.fileglob', role_path + '/files/' + inventory_hostname + '/*.jsonc') }}"
+ notify: restart xray-core
+
+- name: render xray-core dynamic config
+ ansible.builtin.template:
+ src: "{{ item }}"
+ dest: "/opt/xray-core/config/{{ item | basename | regex_replace('\\.j2$', '') }}"
+ owner: xray-core
+ group: xray-core
+ mode: "0644"
+ loop: "{{ query('ansible.builtin.fileglob', role_path + '/templates/' + inventory_hostname + '/*.jsonc.j2') }}"
+ notify: restart xray-core
diff --git a/roles/xray-core/tasks/install.yml b/roles/xray-core/tasks/install.yml
index 33fc3b0..8558f54 100644
--- a/roles/xray-core/tasks/install.yml
+++ b/roles/xray-core/tasks/install.yml
@@ -10,6 +10,7 @@
return_content: yes
register: xray_release
run_once: true
+ check_mode: false
- name: set current xray-core version
ansible.builtin.set_fact:
@@ -25,6 +26,8 @@
- name: ensure xray-core directory exists
ansible.builtin.file:
path: /opt/xray-core
+ owner: xray-core
+ group: xray-core
state: directory
mode: '0755'
@@ -33,10 +36,12 @@
src: "{{ xray_asset_url }}"
dest: /opt/xray-core
remote_src: yes
+ owner: xray-core
+ group: xray-core
when: xray_version not in (xray_current_version.stdout | default(''))
- name: deploy xray-core systemd service unit
ansible.builtin.copy:
src: xray-core.service
dest: /etc/systemd/system/xray-core.service
- mode: 755
+ mode: 0644
diff --git a/roles/xray-core/tasks/main.yml b/roles/xray-core/tasks/main.yml
index 615e362..3d6df25 100644
--- a/roles/xray-core/tasks/main.yml
+++ b/roles/xray-core/tasks/main.yml
@@ -1,3 +1,9 @@
---
+- name: include xray-core user
+ ansible.builtin.include_tasks: user.yml
+
- name: include xray-core install
ansible.builtin.include_tasks: install.yml
+
+- name: include xray-core configure
+ ansible.builtin.include_tasks: configure.yml
diff --git a/roles/xray-core/tasks/user.yml b/roles/xray-core/tasks/user.yml
new file mode 100644
index 0000000..0c60178
--- /dev/null
+++ b/roles/xray-core/tasks/user.yml
@@ -0,0 +1,16 @@
+---
+- name: create xray-core system group
+ ansible.builtin.group:
+ name: xray-core
+ system: true
+ state: present
+
+- name: create xray-core system user
+ ansible.builtin.user:
+ name: xray-core
+ group: xray-core
+ system: true
+ shell: /usr/sbin/nologin
+ home: /opt/xray-core
+ create_home: false
+ state: present
diff --git a/roles/xray-client/templates/observatory.jsonc.j2 b/roles/xray-core/templates/router/observatory.jsonc.j2
similarity index 100%
rename from roles/xray-client/templates/observatory.jsonc.j2
rename to roles/xray-core/templates/router/observatory.jsonc.j2
diff --git a/roles/xray-client/templates/outbounds.jsonc.j2 b/roles/xray-core/templates/router/outbounds.jsonc.j2
similarity index 85%
rename from roles/xray-client/templates/outbounds.jsonc.j2
rename to roles/xray-core/templates/router/outbounds.jsonc.j2
index dbf1b47..f46f7a3 100644
--- a/roles/xray-client/templates/outbounds.jsonc.j2
+++ b/roles/xray-core/templates/router/outbounds.jsonc.j2
@@ -33,9 +33,6 @@
"h3"
],
"fingerprint": "firefox"
- },
- "sockopt": {
- "mark": 255
}
}
},
@@ -45,13 +42,6 @@
"protocol": "freedom",
"settings": {
"domainStrategy": "UseIPv4"
- },
- "streamSettings": {
- "sockopt": {
- "mark": 255,
- "interface": "eth1",
- "tcpFastOpen": true
- }
}
},
{
diff --git a/roles/xray-client/templates/routing.jsonc.j2 b/roles/xray-core/templates/router/routing.jsonc.j2
similarity index 97%
rename from roles/xray-client/templates/routing.jsonc.j2
rename to roles/xray-core/templates/router/routing.jsonc.j2
index fa0b51d..0eae65b 100644
--- a/roles/xray-client/templates/routing.jsonc.j2
+++ b/roles/xray-core/templates/router/routing.jsonc.j2
@@ -31,7 +31,7 @@
{
"type": "field",
"inboundTag": [
- "tproxy",
+ "tproxy-in",
"socks-in"
],
"balancerTag": "{{ 'balancer-vless' if xray_outbounds | length > 1 else 'vless-' ~ xray_outbounds[0].tag }}"
diff --git a/roles/xray-lists/tasks/configure.yml b/roles/xray-lists/tasks/configure.yml
index 047d08c..c1455f6 100644
--- a/roles/xray-lists/tasks/configure.yml
+++ b/roles/xray-lists/tasks/configure.yml
@@ -17,35 +17,3 @@
name: xray-lists.service
state: started
when: xray_lists_config.changed
-
-- 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
diff --git a/roles/xray-lists/templates/90-proxy-prerouting.nft.j2 b/roles/xray-lists/templates/90-proxy-prerouting.nft.j2
deleted file mode 100644
index d50da1a..0000000
--- a/roles/xray-lists/templates/90-proxy-prerouting.nft.j2
+++ /dev/null
@@ -1,26 +0,0 @@
-#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 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 %}
diff --git a/roles/xray-lists/templates/xray-config.yaml.j2 b/roles/xray-lists/templates/xray-config.yaml.j2
index b29f5f2..865c619 100644
--- a/roles/xray-lists/templates/xray-config.yaml.j2
+++ b/roles/xray-lists/templates/xray-config.yaml.j2
@@ -3,49 +3,49 @@ global:
cache_dir: {{ xray_lists_global.cache_dir }}
output_dir: {{ xray_lists_global.output_dir }}
dnsmasq_output: {{ xray_lists_global.dnsmasq_output }}
- {% if xray_lists_global.proxy is defined %}
+{% if xray_lists_global.proxy is defined %}
proxy: "{{ xray_lists_global.proxy }}"
- {% endif %}
- {% if proxy_user is defined %}
+{% endif %}
+{% if proxy_user is defined %}
proxy_user: "{{ proxy_user }}"
proxy_pass: "{{ proxy_pass }}"
- {% endif %}
+{% endif %}
http_timeout: {{ xray_lists_global.http_timeout | default(20) }}
ip_sets:
- {% for id, item in xray_ip_sets.items() %}
+{% for id, item in xray_ip_sets.items() %}
- id: {{ id }}
output: {{ id }}_ip.elements.nft
- {% if item.static is defined %}
+{% if item.static is defined %}
static:
- {% for s in item.static %}
+{% for s in item.static %}
- {{ s }}
- {% endfor %}
- {% endif %}
- {% if item.urls is defined %}
+{% endfor %}
+{% endif %}
+{% if item.urls is defined %}
urls:
- {% for u in item.urls %}
+{% for u in item.urls %}
- {{ u }}
- {% endfor %}
- {% endif %}
- {% endfor %}
+{% endfor %}
+{% endif %}
+{% endfor %}
domain_sets:
- {% for id, item in xray_domain_sets.items() %}
+{% for id, item in xray_domain_sets.items() %}
- id: {{ id }}
dnsmasq_target: "4#inet#filter#{{ id }}_dom"
- {% if item.static is defined %}
+{% if item.static is defined %}
static:
- {% for s in item.static %}
+{% for s in item.static %}
- {{ s }}
- {% endfor %}
- {% endif %}
- {% if item.urls is defined %}
+{% endfor %}
+{% endif %}
+{% if item.urls is defined %}
urls:
- {% for u in item.urls %}
+{% for u in item.urls %}
- {{ u }}
- {% endfor %}
- {% endif %}
- {% endfor %}
+{% endfor %}
+{% endif %}
+{% endfor %}
output_rules:
- {% for rule in output_rules %}
+{% for rule in output_rules %}
- {{ rule }}
- {% endfor %}
+{% endfor %}
diff --git a/roles/zerotier-one/handlers/main.yml b/roles/zerotier-one/handlers/main.yml
deleted file mode 100644
index 8487597..0000000
--- a/roles/zerotier-one/handlers/main.yml
+++ /dev/null
@@ -1,10 +0,0 @@
----
-- name: reload nftables
- ansible.builtin.command: nft -f /etc/nftables.conf
-
-- name: restart zerotier-one systemd service unit
- ansible.builtin.systemd_service:
- name: zerotier-one
- daemon_reload: true
- state: restarted
- enabled: true
diff --git a/roles/zerotier-one/tasks/configure.yml b/roles/zerotier-one/tasks/configure.yml
deleted file mode 100644
index 56ace6e..0000000
--- a/roles/zerotier-one/tasks/configure.yml
+++ /dev/null
@@ -1,31 +0,0 @@
----
-- name: create networks.d directory
- ansible.builtin.file:
- path: /var/lib/zerotier-one/networks.d
- state: directory
- mode: 0700
- owner: zerotier-one
- group: zerotier-one
-
-- name: check if zerotier-one network config exists
- ansible.builtin.stat:
- path: "/var/lib/zerotier-one/networks.d/{{ zerotier_network_id }}.conf"
- register: zerotier_network_stat
-
-- name: create zerotier-one network config
- ansible.builtin.file:
- path: "/var/lib/zerotier-one/networks.d/{{ zerotier_network_id }}.conf"
- state: touch
- mode: "0600"
- owner: zerotier-one
- group: zerotier-one
- when: not zerotier_network_stat.stat.exists
- register: zerotier_network
-
-- name: restart zerotier-one systemd service unit
- ansible.builtin.systemd_service:
- name: zerotier-one
- daemon_reload: true
- state: restarted
- enabled: true
- when: zerotier_network.changed
diff --git a/roles/zerotier-one/tasks/install.yml b/roles/zerotier-one/tasks/install.yml
deleted file mode 100644
index b098284..0000000
--- a/roles/zerotier-one/tasks/install.yml
+++ /dev/null
@@ -1,16 +0,0 @@
----
-- name: add zerotier repository
- ansible.builtin.deb822_repository:
- name: zerotier
- types: deb
- uris: "http://download.zerotier.com/debian/trixie"
- suites: "trixie"
- components: main
- signed_by: "https://download.zerotier.com/contact%40zerotier.com.gpg"
- state: present
-
-- name: install zerotier-one
- ansible.builtin.apt:
- name: zerotier-one
- state: latest
- update_cache: true
diff --git a/roles/zerotier-one/templates/wg0.conf.j2 b/roles/zerotier-one/templates/wg0.conf.j2
deleted file mode 100644
index 5ce31f5..0000000
--- a/roles/zerotier-one/templates/wg0.conf.j2
+++ /dev/null
@@ -1,17 +0,0 @@
-[Interface]
-PrivateKey = {{ wg_private_key }}
-Address = {{ wg_address }}
-Table = off
-PostUp = ip route add 10.250.250.0/24 dev wg0 2>/dev/null || true
-PostUp = ip rule add fwmark 0xc7 lookup 199 2>/dev/null || true
-PostUp = ip route add default dev wg0 table 199 2>/dev/null || true
-PreDown = ip route del default dev wg0 table 199 2>/dev/null || true
-PreDown = ip rule del fwmark 0xc7 lookup 199 2>/dev/null || true
-PreDown = ip route del 10.250.250.0/24 dev wg0 2>/dev/null || true
-
-[Peer]
-PublicKey = {{ wg_public_key }}
-PresharedKey = {{ wg_presharedkey }}
-Endpoint = {{ wg_endpoint_address }}:{{ wg_endpoint_port }}
-PersistentKeepalive = 25
-AllowedIPs = 0.0.0.0/0