From c640406c107574ecc8ea89b991bbc2148f58977b Mon Sep 17 00:00:00 2001 From: pyrschtjag Date: Sun, 20 Sep 2026 22:14:56 +0000 Subject: [PATCH] add nginx, sshd, ssl roles --- inventory/group_vars/all/locales.yml | 2 +- inventory/group_vars/all/vault.yml | 125 ------------------ inventory/group_vars/external.yml | 15 +++ inventory/group_vars/proxmox_all_lxc.yml | 20 ++- inventory/host_vars/coturn.yml | 6 +- inventory/host_vars/gitea.yml | 2 +- inventory/host_vars/liqueur/certbot.yml | 9 ++ inventory/host_vars/liqueur/main.yml | 2 + inventory/host_vars/liqueur/openvpn.yml | 1 + inventory/host_vars/liqueur/ssh.yml | 6 + inventory/host_vars/localhost.yml | 23 ++++ inventory/host_vars/mcsmanager.yml | 4 +- inventory/host_vars/nginx.yml | 2 +- inventory/host_vars/prosody.yml | 4 +- inventory/host_vars/rbpi4.yml | 4 +- inventory/host_vars/router/ifupdown2.yml | 38 +----- inventory/host_vars/router/logrotate.yml | 13 -- inventory/host_vars/router/managed_group.yml | 6 +- inventory/host_vars/router/nftables.yml | 1 + inventory/host_vars/router/openvpn.yaml | 1 + inventory/host_vars/router/sysctl.yml | 5 - inventory/host_vars/router/user.yml | 6 + inventory/host_vars/router/xray-core.yml | 100 ++++++++++++++ inventory/host_vars/router/zerotier-one.yml | 7 - inventory/host_vars/steamcmd/main.yml | 4 +- inventory/host_vars/workuter.yml | 5 + inventory/static.yml | 46 ++++--- playbooks/easy-rsa.yml | 29 ++++ playbooks/liqueur.yml | 23 ++++ playbooks/router.yml | 5 +- playbooks/xray-test.yml | 5 - roles/apt/tasks/apt.yml | 5 - roles/apt/tasks/main.yml | 3 - roles/certbot/tasks/configure.yml | 20 +++ .../tasks/install.yml | 4 +- .../tasks/main.yml | 4 +- roles/dnsmasq/files/10-upstream.conf | 2 +- roles/dnsmasq/templates/90-dhcp-host.conf.j2 | 18 +-- roles/dnsmasq/templates/90-domains.conf.j2 | 16 +-- roles/dnsmasq/templates/90-local.conf.j2 | 8 +- roles/easy-rsa/tasks/client-certs.yml | 18 +++ roles/easy-rsa/tasks/configure.yml | 82 ++++++++++++ roles/easy-rsa/tasks/install.yml | 35 +++++ roles/easy-rsa/tasks/main.yml | 9 ++ .../templates/client-certs/tap0.conf.j2 | 26 ++++ .../templates/client-certs/tun0.conf.j2 | 21 +++ roles/haproxy/handlers/main.yml | 13 ++ roles/haproxy/tasks/configure.yml | 10 ++ roles/haproxy/tasks/install.yml | 6 + .../{zerotier-one => haproxy}/tasks/main.yml | 0 .../haproxy/templates/liqueur/haproxy.cfg.j2 | 90 +++++++++++++ roles/ifupdown2/files/router/interfaces | 50 +++++++ .../tasks/{network.yml => configure.yml} | 6 +- roles/ifupdown2/tasks/main.yml | 8 +- roles/ifupdown2/tasks/prerequisites.yml | 17 +++ roles/ifupdown2/templates/interfaces | 20 --- roles/locales/tasks/configure.yml | 8 -- roles/logrotate/files/router/xray-core | 9 ++ roles/logrotate/tasks/configure.yml | 13 +- roles/logrotate/templates/logrotate.conf.j2 | 5 - roles/nftables/files/10-filter.nft | 50 ------- roles/nftables/files/20-vpn.nft | 35 ----- roles/nftables/files/nftables.conf | 15 --- .../files/{40-sets.nft => router/10-sets.nft} | 0 .../files/{10-nat.nft => router/30-nat.nft} | 1 - roles/nftables/files/router/40-filter.nft | 34 +++++ .../{30-proxy.nft => router/50-proxy.nft} | 5 - roles/nftables/tasks/configure.yml | 59 ++++++--- roles/nftables/templates/90-dstnat.nft.j2 | 19 --- roles/nftables/templates/90-forward.nft.j2 | 47 ------- .../templates/liqueur/nftables.conf.j2 | 53 ++++++++ .../templates/router/20-sets.nft.j2} | 0 .../templates/router/90-dstnat.nft.j2 | 19 +++ .../templates/router/90-forward.nft.j2 | 47 +++++++ .../templates/router}/90-proxy-output.nft.j2 | 10 +- .../router/90-proxy-prerouting.nft.j2 | 28 ++++ .../templates/router/nftables.conf.j2 | 11 ++ roles/nginx/handlers/main.yml | 14 ++ roles/nginx/tasks/configure.yml | 10 ++ roles/nginx/tasks/install.yml | 81 ++++++++++++ roles/nginx/tasks/main.yml | 6 + roles/nginx/templates/liqueur/nginx.conf.j2 | 37 ++++++ .../openvpn/files/liqueur/ccd/liqueur/matr10 | 1 + roles/openvpn/files/liqueur/ccd/liqueur/mur89 | 7 + roles/openvpn/tasks/configure-client.yml | 19 +++ roles/openvpn/tasks/configure-server.yml | 27 ++++ roles/openvpn/tasks/install.yml | 6 + roles/openvpn/tasks/main.yml | 11 ++ .../templates/liqueur/absinthe.conf.j2 | 27 ++++ .../openvpn/templates/liqueur/liqueur.conf.j2 | 44 ++++++ .../templates/router/ltrefilov.conf.j2 | 24 ++++ roles/openvpn/templates/router/mur89.conf.j2 | 21 +++ roles/sshd/handlers/main.yml | 5 + roles/sshd/tasks/configure.yml | 16 +++ roles/{xray-client => sshd}/tasks/main.yml | 2 +- roles/stunnel4/files/liqueur/absinthe.conf | 9 ++ roles/stunnel4/files/liqueur/liqueur.conf | 9 ++ roles/stunnel4/handlers/main.yml | 6 + roles/stunnel4/tasks/configure.yml | 36 +++++ roles/stunnel4/tasks/install.yml | 6 + roles/stunnel4/tasks/main.yml | 6 + .../templates/router/absinthe.conf.j2 | 9 ++ .../stunnel4/templates/router/liqueur.conf.j2 | 9 ++ roles/sysctl/files/liqueur/99-custom.conf | 2 + roles/sysctl/files/router/99-custom.conf | 6 + roles/sysctl/tasks/configure.yml | 6 +- roles/sysctl/templates/sysctl.conf.j2 | 3 - roles/wireguard-tools/handlers/main.yml | 7 - roles/wireguard-tools/tasks/configure.yml | 21 --- roles/wireguard-tools/templates/wg0.conf.j2 | 17 --- roles/xray-client/tasks/configure.yml | 43 ------ .../files/router}/dns.jsonc | 0 .../files/router}/inbounds.jsonc | 4 +- .../files/router}/log.jsonc | 0 .../files/router}/policy.jsonc | 0 roles/xray-core/files/xray-core.service | 6 +- roles/xray-core/handlers/main.yml | 13 ++ roles/xray-core/tasks/configure.yml | 36 +++++ roles/xray-core/tasks/install.yml | 7 +- roles/xray-core/tasks/main.yml | 6 + roles/xray-core/tasks/user.yml | 16 +++ .../templates/router}/observatory.jsonc.j2 | 0 .../templates/router}/outbounds.jsonc.j2 | 10 -- .../templates/router}/routing.jsonc.j2 | 2 +- roles/xray-lists/tasks/configure.yml | 32 ----- .../templates/90-proxy-prerouting.nft.j2 | 26 ---- .../xray-lists/templates/xray-config.yaml.j2 | 52 ++++---- roles/zerotier-one/handlers/main.yml | 10 -- roles/zerotier-one/tasks/configure.yml | 31 ----- roles/zerotier-one/tasks/install.yml | 16 --- roles/zerotier-one/templates/wg0.conf.j2 | 17 --- 131 files changed, 1535 insertions(+), 780 deletions(-) delete mode 100644 inventory/group_vars/all/vault.yml create mode 100644 inventory/group_vars/external.yml create mode 100644 inventory/host_vars/liqueur/certbot.yml create mode 100644 inventory/host_vars/liqueur/main.yml create mode 100644 inventory/host_vars/liqueur/openvpn.yml create mode 100644 inventory/host_vars/liqueur/ssh.yml create mode 100644 inventory/host_vars/localhost.yml delete mode 100644 inventory/host_vars/router/logrotate.yml create mode 100644 inventory/host_vars/router/nftables.yml create mode 100644 inventory/host_vars/router/openvpn.yaml delete mode 100644 inventory/host_vars/router/sysctl.yml create mode 100644 inventory/host_vars/router/user.yml create mode 100644 inventory/host_vars/router/xray-core.yml delete mode 100644 inventory/host_vars/router/zerotier-one.yml create mode 100644 playbooks/easy-rsa.yml create mode 100644 playbooks/liqueur.yml delete mode 100644 playbooks/xray-test.yml delete mode 100644 roles/apt/tasks/apt.yml delete mode 100644 roles/apt/tasks/main.yml create mode 100644 roles/certbot/tasks/configure.yml rename roles/{wireguard-tools => certbot}/tasks/install.yml (53%) rename roles/{wireguard-tools => certbot}/tasks/main.yml (53%) create mode 100644 roles/easy-rsa/tasks/client-certs.yml create mode 100644 roles/easy-rsa/tasks/configure.yml create mode 100644 roles/easy-rsa/tasks/install.yml create mode 100644 roles/easy-rsa/tasks/main.yml create mode 100644 roles/easy-rsa/templates/client-certs/tap0.conf.j2 create mode 100644 roles/easy-rsa/templates/client-certs/tun0.conf.j2 create mode 100644 roles/haproxy/handlers/main.yml create mode 100644 roles/haproxy/tasks/configure.yml create mode 100644 roles/haproxy/tasks/install.yml rename roles/{zerotier-one => haproxy}/tasks/main.yml (100%) create mode 100644 roles/haproxy/templates/liqueur/haproxy.cfg.j2 create mode 100644 roles/ifupdown2/files/router/interfaces rename roles/ifupdown2/tasks/{network.yml => configure.yml} (64%) create mode 100644 roles/ifupdown2/tasks/prerequisites.yml delete mode 100644 roles/ifupdown2/templates/interfaces create mode 100644 roles/logrotate/files/router/xray-core delete mode 100644 roles/logrotate/templates/logrotate.conf.j2 delete mode 100644 roles/nftables/files/10-filter.nft delete mode 100644 roles/nftables/files/20-vpn.nft delete mode 100644 roles/nftables/files/nftables.conf rename roles/nftables/files/{40-sets.nft => router/10-sets.nft} (100%) rename roles/nftables/files/{10-nat.nft => router/30-nat.nft} (99%) create mode 100644 roles/nftables/files/router/40-filter.nft rename roles/nftables/files/{30-proxy.nft => router/50-proxy.nft} (98%) delete mode 100644 roles/nftables/templates/90-dstnat.nft.j2 delete mode 100644 roles/nftables/templates/90-forward.nft.j2 create mode 100644 roles/nftables/templates/liqueur/nftables.conf.j2 rename roles/{xray-lists/templates/90-sets.nft.j2 => nftables/templates/router/20-sets.nft.j2} (100%) create mode 100644 roles/nftables/templates/router/90-dstnat.nft.j2 create mode 100644 roles/nftables/templates/router/90-forward.nft.j2 rename roles/{xray-lists/templates => nftables/templates/router}/90-proxy-output.nft.j2 (52%) create mode 100644 roles/nftables/templates/router/90-proxy-prerouting.nft.j2 create mode 100644 roles/nftables/templates/router/nftables.conf.j2 create mode 100644 roles/nginx/handlers/main.yml create mode 100644 roles/nginx/tasks/configure.yml create mode 100644 roles/nginx/tasks/install.yml create mode 100644 roles/nginx/tasks/main.yml create mode 100644 roles/nginx/templates/liqueur/nginx.conf.j2 create mode 100644 roles/openvpn/files/liqueur/ccd/liqueur/matr10 create mode 100644 roles/openvpn/files/liqueur/ccd/liqueur/mur89 create mode 100644 roles/openvpn/tasks/configure-client.yml create mode 100644 roles/openvpn/tasks/configure-server.yml create mode 100644 roles/openvpn/tasks/install.yml create mode 100644 roles/openvpn/tasks/main.yml create mode 100644 roles/openvpn/templates/liqueur/absinthe.conf.j2 create mode 100644 roles/openvpn/templates/liqueur/liqueur.conf.j2 create mode 100644 roles/openvpn/templates/router/ltrefilov.conf.j2 create mode 100644 roles/openvpn/templates/router/mur89.conf.j2 create mode 100644 roles/sshd/handlers/main.yml create mode 100644 roles/sshd/tasks/configure.yml rename roles/{xray-client => sshd}/tasks/main.yml (57%) create mode 100644 roles/stunnel4/files/liqueur/absinthe.conf create mode 100644 roles/stunnel4/files/liqueur/liqueur.conf create mode 100644 roles/stunnel4/handlers/main.yml create mode 100644 roles/stunnel4/tasks/configure.yml create mode 100644 roles/stunnel4/tasks/install.yml create mode 100644 roles/stunnel4/tasks/main.yml create mode 100644 roles/stunnel4/templates/router/absinthe.conf.j2 create mode 100644 roles/stunnel4/templates/router/liqueur.conf.j2 create mode 100644 roles/sysctl/files/liqueur/99-custom.conf create mode 100644 roles/sysctl/files/router/99-custom.conf delete mode 100644 roles/sysctl/templates/sysctl.conf.j2 delete mode 100644 roles/wireguard-tools/handlers/main.yml delete mode 100644 roles/wireguard-tools/tasks/configure.yml delete mode 100644 roles/wireguard-tools/templates/wg0.conf.j2 delete mode 100644 roles/xray-client/tasks/configure.yml rename roles/{xray-client/files => xray-core/files/router}/dns.jsonc (100%) rename roles/{xray-client/files => xray-core/files/router}/inbounds.jsonc (94%) rename roles/{xray-client/files => xray-core/files/router}/log.jsonc (100%) rename roles/{xray-client/files => xray-core/files/router}/policy.jsonc (100%) create mode 100644 roles/xray-core/handlers/main.yml create mode 100644 roles/xray-core/tasks/configure.yml create mode 100644 roles/xray-core/tasks/user.yml rename roles/{xray-client/templates => xray-core/templates/router}/observatory.jsonc.j2 (100%) rename roles/{xray-client/templates => xray-core/templates/router}/outbounds.jsonc.j2 (85%) rename roles/{xray-client/templates => xray-core/templates/router}/routing.jsonc.j2 (97%) delete mode 100644 roles/xray-lists/templates/90-proxy-prerouting.nft.j2 delete mode 100644 roles/zerotier-one/handlers/main.yml delete mode 100644 roles/zerotier-one/tasks/configure.yml delete mode 100644 roles/zerotier-one/tasks/install.yml delete mode 100644 roles/zerotier-one/templates/wg0.conf.j2 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