From 6026f8d84ee4e93c5247559141f6a34943cdc1be Mon Sep 17 00:00:00 2001
From: Benjamin Graillot <graillot@crans.org>
Date: Sun, 28 Feb 2021 09:10:21 +0100
Subject: [PATCH] [inspircd] Deploy InspIRCd on irc

---
 host_vars/irc.adm.crans.org.yml               |   6 +
 plays/irc.yml                                 |   6 +
 roles/inspircd/handlers/main.yml              |   5 +
 roles/inspircd/tasks/main.yml                 |  18 +
 .../templates/inspircd/inspircd.conf.j2       | 213 ++++++++++++
 .../templates/inspircd/inspircd.motd.j2       |  20 ++
 .../inspircd/templates/inspircd/links.conf.j2 |  13 +
 .../templates/inspircd/modules.conf.j2        | 308 ++++++++++++++++++
 .../inspircd/templates/inspircd/opers.conf.j2 |  86 +++++
 .../inspircd/templates/inspircd/power.conf.j2 |   7 +
 10 files changed, 682 insertions(+)
 create mode 100644 roles/inspircd/handlers/main.yml
 create mode 100644 roles/inspircd/tasks/main.yml
 create mode 100644 roles/inspircd/templates/inspircd/inspircd.conf.j2
 create mode 100644 roles/inspircd/templates/inspircd/inspircd.motd.j2
 create mode 100644 roles/inspircd/templates/inspircd/links.conf.j2
 create mode 100644 roles/inspircd/templates/inspircd/modules.conf.j2
 create mode 100644 roles/inspircd/templates/inspircd/opers.conf.j2
 create mode 100644 roles/inspircd/templates/inspircd/power.conf.j2

diff --git a/host_vars/irc.adm.crans.org.yml b/host_vars/irc.adm.crans.org.yml
index a093bda0..722c6fcf 100644
--- a/host_vars/irc.adm.crans.org.yml
+++ b/host_vars/irc.adm.crans.org.yml
@@ -33,3 +33,9 @@ loc_nginx:
 
 loc_thelounge:
   public: "true"
+
+loc_inspircd:
+  cloak_key: "{{ vault.irc_inspircd_cloak_key }}"
+  diepass: "{{ vault.irc_inspircd_diepass }}"
+  restartpass: "{{ vault.irc_inspircd_restartpass }}"
+  opers: "{{ vault.irc_inspircd_opers }}"
diff --git a/plays/irc.yml b/plays/irc.yml
index 348f9d26..d3701060 100755
--- a/plays/irc.yml
+++ b/plays/irc.yml
@@ -13,3 +13,9 @@
   roles:
     - certbot
     - nginx
+
+- hosts: irc
+  vars:
+    inspircd: "{{ glob_inspircd | default({}) | combine(loc_inspircd | default({})) }}"
+  roles:
+    - inspircd
diff --git a/roles/inspircd/handlers/main.yml b/roles/inspircd/handlers/main.yml
new file mode 100644
index 00000000..2a02fe19
--- /dev/null
+++ b/roles/inspircd/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: Reload InspIRCd
+  service:
+    name: inspircd
+    state: reloaded
diff --git a/roles/inspircd/tasks/main.yml b/roles/inspircd/tasks/main.yml
new file mode 100644
index 00000000..375d81c1
--- /dev/null
+++ b/roles/inspircd/tasks/main.yml
@@ -0,0 +1,18 @@
+---
+#- name: Install InspIRCd
+
+- name: Deploy InspIRCd configuration
+  template:
+    src: "inspircd/{{ item.dest }}.j2"
+    dest: "/etc/inspircd/{{ item.dest }}"
+    mode: "{{ item.mode }}"
+    owner: irc
+    group: irc
+  loop:
+    - { dest: inspircd.conf, mode: "0644" }
+    - { dest: links.conf, mode: "0600" }
+    - { dest: power.conf, mode: "0600" }
+    - { dest: opers.conf, mode: "0600" }
+    - { dest: modules.conf, mode: "0600" }
+    - { dest: inspircd.motd, mode: "0644" }
+  notify: Reload InspIRCd
diff --git a/roles/inspircd/templates/inspircd/inspircd.conf.j2 b/roles/inspircd/templates/inspircd/inspircd.conf.j2
new file mode 100644
index 00000000..1d98c670
--- /dev/null
+++ b/roles/inspircd/templates/inspircd/inspircd.conf.j2
@@ -0,0 +1,213 @@
+{{ ansible_header | comment }}
+
+<pid file="/var/run/inspircd/inspircd.pid">
+
+<log
+	method="file"
+	type="* -USERINPUT -USEROUTPUT"
+	level="default"
+	target="/var/log/inspircd.log"
+>
+
+<server name="irc.crans.org"
+        description="Crans IRC server"
+        network="Crans"
+        sid="3AX">
+
+<admin name="Pierre-Elliott Bécue"
+       nick="PEB"
+       email="root@crans.org">
+
+<bind address="185.230.79.11" port="6667" type="clients">
+<bind address="185.230.79.11" port="6697" type="clients" ssl="openssl">
+<bind address="2a0c:700:2::ff:fe01:2902" port="6667" type="clients">
+<bind address="2a0c:700:2::ff:fe01:2902" port="6697" type="clients" ssl="openssl">
+<bind address="172.16.10.129" port="6667" type="clients">
+<bind address="127.0.0.1" port="6668" type="servers">
+
+<sslprofile
+	name="openssl"
+	provider="openssl"
+	certfile="/etc/inspircd/fullchain.pem"
+	keyfile="/etc/inspircd/privkey.pem"
+	hash="sha1"
+>
+
+<include file="/etc/inspircd/power.conf">
+
+<include file="/etc/inspircd/links.conf">
+
+<connect name="zamok-ipv4"
+         allow="185.230.79.1/32"
+         timeout="60"
+         threshold="1"
+         pingfreq="120"
+         sendq="262144"
+         recvq="8192"
+         maxchans="70"
+         localmax="1000"
+         globalmax="1000">
+
+<connect name="zamok-ipv6"
+         allow="2a0c:700:2:0:ec4:7aff:fe59:a1ad/128"
+         timeout="60"
+         threshold="1"
+         pingfreq="120"
+         sendq="262144"
+         recvq="8192"
+         maxchans="70"
+         localmax="1000"
+         globalmax="1000">
+
+<connect name="irc-ipv4"
+         allow="185.230.79.11/32"
+         timeout="60"
+         threshold="1"
+         pingfreq="120"
+         sendq="262144"
+         recvq="8192"
+         maxchans="70"
+         localmax="1000"
+         globalmax="1000">
+
+<connect name="irc-ipv6"
+         allow="2a0c:700:2::ff:fe01:2902/128"
+         timeout="60"
+         threshold="10"
+         pingfreq="120"
+         sendq="262144"
+         recvq="8192"
+         maxchans="70"
+         localmax="1000"
+         globalmax="1000">
+
+<connect name="gitlab-ipv4"
+         allow="185.230.79.14/32"
+         timeout="60"
+         threshold="10"
+         commandrate="10000"
+         pingfreq="120"
+         sendq="262144"
+         recvq="8192"
+         maxchans="70"
+         localmax="1000"
+         globalmax="1000">
+
+<connect name="gitlab-ipv6"
+         allow="2a0c:700:2::ff:fe01:502/128"
+         timeout="60"
+         threshold="10"
+         commandrate="10000"
+         pingfreq="120"
+         sendq="262144"
+         recvq="8192"
+         maxchans="70"
+         localmax="1000"
+         globalmax="1000">
+
+<connect name="monitoring-ipv4"
+         allow="172.16.10.121/32"
+         timeout="60"
+         threshold="10"
+         commandrate="10000"
+         pingfreq="120"
+         sendq="262144"
+         recvq="8192"
+         maxchans="70"
+         localmax="1000"
+         globalmax="1000"
+         modes="+x"
+         useident="no">
+
+<connect name="monitoring-ipv6"
+         allow="fd00::10:ff:fe01:2110/128"
+         timeout="60"
+         threshold="10"
+         commandrate="10000"
+         pingfreq="120"
+         sendq="262144"
+         recvq="8192"
+         maxchans="70"
+         localmax="1000"
+         globalmax="1000"
+         modes="+x"
+         useident="no">
+
+<connect name="default"
+         allow="*"
+         timeout="60"
+         threshold="1"
+         pingfreq="120"
+         sendq="262144"
+         recvq="8192"
+         maxchans="70"
+         localmax="1000"
+         globalmax="1000"
+         modes="+x"
+         useident="no">
+
+<include file="/etc/inspircd/opers.conf">
+
+<files motd="/etc/inspircd/inspircd.motd"
+       rules="/etc/inspircd/inspircd.rules">
+
+<include file="/etc/inspircd/modules.conf">
+
+<channels users="30"
+          opers="1000">
+
+<dns server="172.16.10.101" timeout="5">
+
+<options prefixquit="Quit: "
+         noservices="no"
+         qaprefixes="no"
+         deprotectself="no"
+         deprotectothers="no"
+         flatlinks="no"
+         hideulines="no"
+         syntaxhints="yes"
+         cyclehosts="yes"
+         ircumsgprefix="no"
+         announcets="yes"
+         disablehmac="no"
+         hostintopic="yes"
+         quietbursts="yes"
+         pingwarning="15"
+	 exemptchanops="">
+
+<security hidewhois=""
+          announceinvites="dynamic"
+          userstats="Pu"
+          customversion=""
+          hidesplits="no"
+          hidebans="no"
+          operspywhois="no"
+          hidemodes="eI"
+          maxtargets="20">
+
+<performance nouserdns="no"
+             maxwho="128"
+             softlimit="1024"
+             somaxconn="128"
+             netbuffersize="10240">
+
+<whowas groupsize="10"
+        maxgroups="100000"
+        maxkeep="3d">
+
+<limits maxnick="42"
+        maxchan="32"
+        maxmodes="20"
+        maxtopic="307"
+        maxkick="255"
+        maxaway="255"
+        maxident="25">
+
+<timesync enable="no" master="no">
+
+<badnick nick="ChanServ" reason="Reserved For Services">
+<badnick nick="NickServ" reason="Reserved For Services">
+<badnick nick="OperServ" reason="Reserved For Services">
+<badnick nick="MemoServ" reason="Reserved For Services">
+<badnick nick="Global" reason="Reserved For Services">
+<badnick nick="HostServ" reason="Reserved For Services">
diff --git a/roles/inspircd/templates/inspircd/inspircd.motd.j2 b/roles/inspircd/templates/inspircd/inspircd.motd.j2
new file mode 100644
index 00000000..0bef3a6a
--- /dev/null
+++ b/roles/inspircd/templates/inspircd/inspircd.motd.j2
@@ -0,0 +1,20 @@
+                  _________
+     ______      / _______ \                           ________  ______
+    / ____/___  / / ____  \ \ ____  _____             /  _/ __ \/ ____/
+   / /   / __ \/ / / __ `/ ) ) __ \/ ___/   ______    / // /_/ / /
+  / /___/ / /_/ / / /_/ /_/ / / / (__  )   /_____/  _/ // _, _/ /___
+  \____/_/   ( (  \__,_____/_/ /_/____/            /___/_/ |_|\____/
+              \ \___________________________________________________________
+               \___________________________________________________________/
+
+Bienvenue sur le serveur IRC du Cr@ns !
+Veuillez noter que :
+
+ * Il existe plusieurs canaux
+    - #crans pour tout ce qui concerne le Crans
+    - #general pour toute discussion ne concernant pas le Crans
+    - #flood si vous voulez flooder ou parler avec des bots
+ * L'encodage recommandé est l'UTF-8, si vous voyez des caractères bizarres au lieu d'accents, vous avez peut-être un mauvais encodage. Pour régler le problème, faites ceci :
+    - (sous weechat) /charset decode utf-8 et /charset encode utf-8
+    - (sous irssi) /set term_charset=UTF-8
+ * N'hésitez pas à nous solliciter en cas de problème sur <nounous AT crans DOT org>
diff --git a/roles/inspircd/templates/inspircd/links.conf.j2 b/roles/inspircd/templates/inspircd/links.conf.j2
new file mode 100644
index 00000000..8c4ae15c
--- /dev/null
+++ b/roles/inspircd/templates/inspircd/links.conf.j2
@@ -0,0 +1,13 @@
+{{ ansible_header | comment }}
+
+<link
+	name="services.irc.crans.org"
+	ipaddr="127.0.0.1"
+	port="6668"
+	sid="3AX"
+	allowmask="127.0.0.0/8"
+	sendpass="{{ anope.recvpass }}"
+	recvpass="{{ anope.sendpass }}"
+>
+
+<uline server="services.irc.crans.org">
diff --git a/roles/inspircd/templates/inspircd/modules.conf.j2 b/roles/inspircd/templates/inspircd/modules.conf.j2
new file mode 100644
index 00000000..25e3eb02
--- /dev/null
+++ b/roles/inspircd/templates/inspircd/modules.conf.j2
@@ -0,0 +1,308 @@
+{{ ansible_header | comment }}
+
+# Module pour protocole serveur-serveur
+<module name="m_spanningtree.so">
+
+<module name="m_md5.so">
+<module name="m_sha256.so">
+
+## Fancy aliases
+<module name="m_alias.so">
+<alias text="NICKSERV" replace="PRIVMSG NickServ :$2-" requires="NickServ" uline="yes">
+<alias text="CHANSERV" replace="PRIVMSG ChanServ :$2-" requires="ChanServ" uline="yes">
+<alias text="OPERSERV" replace="PRIVMSG OperServ :$2-" requires="OperServ" uline="yes" operonly="yes">
+<alias text="NS" replace="PRIVMSG NickServ :$2-" requires="NickServ" uline="yes">
+<alias text="CS" replace="PRIVMSG ChanServ :$2-" requires="ChanServ" uline="yes">
+<alias text="OS" replace="PRIVMSG OperServ :$2-" requires="OperServ" uline="yes" operonly="yes">
+<alias text="ID" format="#*" replace="PRIVMSG ChanServ :IDENTIFY $2 $3" requires="ChanServ" uline="yes">
+<alias text="ID" replace="PRIVMSG NickServ :IDENTIFY $2" requires="NickServ" uline="yes">
+<alias text="NICKSERV" format=":IDENTIFY *" replace="PRIVMSG NickServ :IDENTIFY $3-" requires="NickServ" uline="yes">
+
+<module name="m_alltime.so">
+<module name="m_allowinvite.so">
+<module name="m_auditorium.so">
+<auditorium  opvisible="yes" opcansee="no" opercansee="yes">
+<module name="m_banexception.so">
+<module name="m_banredirect.so">
+#<module name="m_blockamsg.so">
+#   <blockamsg delay="3" action="noticeopers">
+
+<module name="m_blockcaps.so">
+<blockcaps percent="50"
+           minlen="5"
+           capsmap="ABCDEFGHIJKLMNOPQRSTUVWXYZÉÇÀÈÌÒÙỲÄËÏÖÜŸÂÊÎÔÛŶĈẐ! ">
+
+<module name="m_blockcolor.so">
+<module name="m_botmode.so">
+<module name="m_cban.so">
+#<module name="m_censor.so">
+#<include file="censor.conf">
+
+#<module name="m_cgiirc.so">
+#<cgiirc opernotice="no">
+#<cgihost type="pass" mask="www.mysite.com">
+#<cgihost type="webirc" mask="somebox.mysite.com">
+#<cgihost type="ident" mask="otherbox.mysite.com">
+#<cgihost type="passfirst" mask="www.mysite.com">
+
+<module name="m_channelban.so">
+<module name="m_chanfilter.so">
+<module name="m_chanhistory.so">
+<module name="m_chanlog.so">
+<chanlog snomasks="aklx" channel="#services">
+
+#<module name="m_chanprotect.so">
+#<chanprotect noservices="no"
+#             deprotectself="yes"
+#             deprotectothers="no"
+#             qprefix="~"
+#             aprefix="&amp;">
+<module name="m_customprefix.so">
+<customprefix
+	name="founder"
+	letter="q"
+	prefix="~"
+	rank="50000"
+	ranktoset="50000"
+	ranktounset="50000"
+	depriv="yes"
+>
+
+<customprefix
+	name="admin"
+	letter="a"
+	prefix="&amp;"
+	rank="40000"
+	ranktoset="50000"
+	ranktounset="50000"
+	depriv="yes"
+>
+
+<module name="m_chghost.so">
+<module name="m_chgident.so">
+
+<module name="m_cloaking.so">
+<cloak
+	mode="full"
+	key="{{ inspircd.cloak_key }}"
+	prefix="crans"
+>
+
+#<module name="m_conn_join.so">
+#<autojoin channel="">
+
+<module name="m_conn_umodes.so">
+
+<module name="m_conn_waitpong.so">
+<waitpong sendsnotice="yes" killonbadreply="yes">
+
+#<module name="[[Modules/connflood|m_connflood.so">
+#<connflood seconds="30" maxconns="3" timeout="30"
+#   quitmsg="Throttled" bootwait="10">
+
+#Cf doc : permet de créer des préfixes avec des droits
+# halfops ou plus
+#<module name="m_customprefix.so">
+#<customprefix name="founder" letter="q" prefix="~" rank="50000" ranktoset="50000">
+#<customprefix name="admin" letter="a" prefix="&" rank="40000" ranktoset="50000">
+#<customprefix name="halfop" letter="h" prefix="%" rank="20000" ranktoset="30000">
+#<customprefix name="halfvoice" letter="V" prefix="-" rank="1" ranktoset="20000">
+
+#<module name="m_dccallow.so">
+#<dccallow blockchat="yes" length="5m" action="block">
+#<banfile pattern="*.exe" action="block">
+#<banfile pattern="*.txt" action="allow">
+
+<module name="m_deaf.so">
+
+<module name="m_denychans.so">
+
+#<module name="m_devoice.so">
+<customprefix name="voice"
+              change="yes"
+              depriv="yes">
+
+<module name="m_dnsbl.so">
+<dnsbl name="DroneBL"
+       type="bitmask"
+       domain="dnsbl.dronebl.org"
+       action="ZLINE"
+       reason="You are listed in DroneBL. Please visit http://dronebl.org/lookup.do?ip=%ip%"
+       duration="1h"
+       bitmask="253">
+
+<module name="m_regex_pcre.so">
+<module name="m_filter.so">
+<filteropts engine="pcre">
+
+#<module name="m_filter_pcre.so">
+#<include file="filter.conf">
+
+<module name="m_gecosban.so">
+<module name="m_globops.so">
+<module name="m_globalload.so">
+
+#<module name="m_halfop.so">
+<customprefix
+	name="halfop"
+	letter="h"
+	prefix="%"
+	rank="20000"
+	ranktoset="30000"
+	ranktounset="30000"
+	depriv="yes"
+>
+#<module name="m_helpop.so">
+#<include file="helpop.conf">
+
+<module name="m_hidechans.so">
+<module name="m_hideoper.so">
+
+#<module name="m_hostchange.so">
+#<host suffix="polarbears.org">
+#<hostchange mask="*@fbi.gov" action="addnick">
+#<hostchange mask="*r00t@*" action="suffix">
+#<hostchange mask="a@b.com" action="set" value="blah.blah.blah">
+
+#<module name="m_httpd.so">
+#<http ip="192.168.1.10" host="brainwave" port="32006"
+#     index="/home/brain/inspircd/http/index.html">
+
+#<module name="m_httpd_stats.so">
+#<httpstats stylesheet="http://remote.style/sheet.css">
+
+<module name="m_ident.so">
+<ident timeout="5">
+
+<module name="m_inviteexception.so">
+
+<module name="cap">
+<module name="ircv3">
+<module name="ircv3_accounttag">
+<module name="ircv3_batch">
+<module name="ircv3_capnotify">
+<module name="ircv3_chghost">
+#<module name="ircv3_ctctags">
+<module name="ircv3_echomessage">
+<module name="ircv3_invitenotify">
+<module name="ircv3_labeledresponse">
+<module name="ircv3_msgid">
+<module name="ircv3_servertime">
+
+<module name="m_joinflood.so">
+#<module name="m_jumpserver.so">
+<module name="m_kicknorejoin.so">
+<module name="m_knock.so">
+#<module name="m_ldapoper.so">
+<module name="m_lockserv.so">
+<module name="m_messageflood.so">
+
+# Mode +b m:user pour le mute
+<module name="m_muteban.so">
+#<module name="m_mysql.so">
+#<database name="mydb" username="myuser" password="mypass" hostname="localhost" id="my_database2">
+
+<module name="m_namesx.so">
+<module name="m_nickflood.so">
+<module name="m_nicklock.so">
+<module name="m_noctcp.so">
+<module name="m_nokicks.so">
+<module name="m_nonicks.so">
+<module name="m_nopartmsg.so">
+<module name="m_nonotice.so">
+
+##
+<module name="m_operjoin.so">
+<operjoin channel="#opers">
+
+<module name="m_opermotd.so">
+<opermotd file="oper.motd">
+
+#<module name="m_override.so">
+#<override requirekey="yes">
+
+<module name="m_operchans.so">
+<module name="m_operlevels.so">
+<module name="m_operlog.so">
+<module name="m_opermodes.so">
+
+<module name="m_ojoin.so">
+<ojoin prefix="!" notice="yes" op="yes">
+
+#<module name="m_operprefix.so">
+#<operprefix prefix="$">
+
+<module name="m_password_hash.so">
+#<module name="m_pgsql.so">
+#<database name="mydb" username="myuser" password="mypass" hostname="localhost" id="my_database" ssl="no">
+
+#<module name="m_randquote.so">
+#<randquote file="randquotes.conf">
+
+<module name="m_redirect.so">
+<module name="m_remove.so">
+<remove supportnokicks="yes">
+
+#<module name="m_safelist.so">
+#<safelist throttle="60" maxlisters="50">
+
+<module name="m_sajoin.so">
+<module name="m_sakick.so">
+<module name="m_samode.so">
+<module name="m_sanick.so">
+<module name="m_sapart.so">
+<module name="m_saquit.so">
+<module name="m_satopic.so">
+
+#<module name="m_securelist.so">
+#<securelist exception="*@*.searchirc.org">
+#<securelist exception="*@*.netsplit.de">
+#<securelist exception="*@echo940.server4you.de">
+#<securelist waittime="60">
+
+<module name="m_seenicks.so">
+<module name="m_setidle.so">
+<module name="m_serverban.so">
+<module name="m_services_account.so">
+<module name="m_servprotect.so">
+<module name="m_sethost.so">
+<module name="m_setident.so">
+<module name="m_setname.so">
+
+<module name="m_shun.so">
+<shun enabledcommands="PING PONG QUIT" notifyuser="no">
+
+<module name="m_showwhois.so">
+<module name="m_sslmodes.so">
+<module name="m_sslrehashsignal.so">
+<module name="m_ssl_openssl.so">
+#<module name="m_ssl_gnutls.so">
+<module name="m_sslinfo.so">
+<module name="m_stripcolor.so">
+<module name="m_silence.so">
+
+#<module name="m_sqlite3.so">
+#<database hostname="/full/path/to/database.db" id="anytext">
+
+#<module name="m_sqlutils.so">
+#<module name="m_sqlauth.so">
+#<module name="m_sqllog.so">
+#<sqllog dbid="1">
+#<module name="m_sqloper.so">
+#<sqloper dbid="1">
+
+#<module name="m_svshold.so">
+
+<module name="m_swhois.so">
+<module name="m_timedbans.so">
+<module name="m_tline.so">
+<module name="m_uninvite.so">
+<module name="m_userip.so">
+
+#<module name="m_vhost.so">
+#<vhost user="some_username" pass="some_password" host="some.host">
+
+<module name="m_watch.so">
+
+<module name="m_xline_db.so">
+<xlinedb filename="/var/lib/inspircd/xline.db">
diff --git a/roles/inspircd/templates/inspircd/opers.conf.j2 b/roles/inspircd/templates/inspircd/opers.conf.j2
new file mode 100644
index 00000000..b2331218
--- /dev/null
+++ b/roles/inspircd/templates/inspircd/opers.conf.j2
@@ -0,0 +1,86 @@
+{{ ansible_header | comment }}
+
+# Class definitions
+
+<class
+	name="IRCOp"
+	commands="*"
+	privs="*"
+	usermodes="*"
+	chanmodes="*"
+>
+<class
+	name="Aus"
+	commands=""
+	privs="users/auspex"
+	usermodes="*"
+	chanmodes="*"
+>
+<class
+	name="Shutdown"
+	commands="DIE RESTART REHASH LOADMODULE UNLOADMODULE RELOAD"
+>
+<class
+	name="ServerLink"
+	commands="CONNECT SQUIT RCONNECT MKPASSWD MKSHA256"
+>
+<class
+	name="BanControl"
+	commands="KILL GLINE KLINE ZLINE QLINE ELINE"
+>
+<class
+	name="OperChat"
+	commands="WALLOPS GLOBOPS SETIDLE SPYLIST SPYNAMES"
+>
+<class
+	name="HostCloak"
+	commands="SETHOST SETIDENT SETNAME CHGHOST CHGIDENT"
+>
+
+<type
+	name="Deity"
+	classes="IRCOp Aus"
+	modes="+ows +*"
+	override="*"
+	level="4"
+>
+<type
+	name="NetAdmin"
+	classes="OperChat BanControl HostCloak Shutdown ServerLink"
+	modes="+ows +*"
+	level="3"
+>
+<type
+	name="GlobalOp"
+	classes="OperChat BanControl HostCloak ServerLink"
+	modes="+ows +*"
+	level="2"
+>
+<type
+	name="Helper"
+	classes="HostCloak"
+	modes="+hw"
+	level="1"
+>
+
+# Users with operator privileges.
+
+{% for oper in inspircd.opers %}
+<oper
+	name="{{ oper.name }}"
+	password="{{ oper.password }}"
+	hash="{{ oper.hash }}"
+	host="{{ oper.host }}"
+	type="{{ oper.type }}"
+{% if oper.vhost is defined %}
+	vhost="{{ oper.vhost }}"
+{% endif %}
+{% if oper.fingerprint is defined %}
+	fingerprint="{{ oper.fingerprint }}"
+{% endif %}
+{% if oper.autologin is defined %}
+	autologin="{{ oper.autologin }}"
+{% endif %}
+>
+
+{% endfor %}
diff --git a/roles/inspircd/templates/inspircd/power.conf.j2 b/roles/inspircd/templates/inspircd/power.conf.j2
new file mode 100644
index 00000000..850f0641
--- /dev/null
+++ b/roles/inspircd/templates/inspircd/power.conf.j2
@@ -0,0 +1,7 @@
+{{ ansible_header | comment }}
+
+<power
+	diepass="{{ inspircd.diepass }}"
+	restartpass="{{ inspircd.restartpass }}"
+	pause="2"
+>
-- 
GitLab