Initial commit
This commit is contained in:
commit
466fb54aab
3
README.md
Normal file
3
README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Ansible Roles
|
||||||
|
|
||||||
|
A collection of roles I find useful for different playbooks.
|
10
system/base/fail2ban/meta/argument_specs.yml
Normal file
10
system/base/fail2ban/meta/argument_specs.yml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
options:
|
||||||
|
ansible_port:
|
||||||
|
type: "int"
|
||||||
|
required: true
|
||||||
|
system_base_fail2ban_ignoreip:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
38
system/base/fail2ban/tasks/main.yml
Normal file
38
system/base/fail2ban/tasks/main.yml
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
- name: "install fail2ban"
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: "fail2ban"
|
||||||
|
|
||||||
|
- name: "configure fail2ban"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./jail.local.j2"
|
||||||
|
dest: "/etc/fail2ban/jail.local"
|
||||||
|
mode: 0644
|
||||||
|
register: system_base_fail2ban_conf
|
||||||
|
|
||||||
|
- name: "configure fail2ban sshd jail"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./jail.d/sshd.local.j2"
|
||||||
|
dest: "/etc/fail2ban/jail.d/sshd.local"
|
||||||
|
mode: 0644
|
||||||
|
register: system_base_fail2ban_sshd_jail
|
||||||
|
|
||||||
|
- name: "enable fail2ban"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "fail2ban"
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
- name: "start fail2ban"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "fail2ban"
|
||||||
|
state: "started"
|
||||||
|
register: system_base_fail2ban_start
|
||||||
|
|
||||||
|
- name: "restart fail2ban"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "fail2ban"
|
||||||
|
state: "restarted"
|
||||||
|
when:
|
||||||
|
(system_base_fail2ban_conf.changed or
|
||||||
|
system_base_fail2ban_sshd_jail.changed) and
|
||||||
|
not system_base_fail2ban_start.changed
|
5
system/base/fail2ban/templates/jail.d/sshd.local.j2
Normal file
5
system/base/fail2ban/templates/jail.d/sshd.local.j2
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[sshd]
|
||||||
|
enabled = true
|
||||||
|
port = {{ ansible_port }}
|
||||||
|
findtime = 1d
|
||||||
|
bantime = 2w
|
32
system/base/fail2ban/templates/jail.local.j2
Normal file
32
system/base/fail2ban/templates/jail.local.j2
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
|
||||||
|
# "ignoreip" can be a list of IP addresses, CIDR masks or DNS hosts. Fail2ban
|
||||||
|
# will not ban a host which matches an address in this list. Several addresses
|
||||||
|
# can be defined using space (and/or comma) separator.
|
||||||
|
ignoreip = 127.0.0.1/8 ::1 {{ system_base_fail2ban_ignoreip }}
|
||||||
|
|
||||||
|
# "bantime" is the number of seconds that a host is banned.
|
||||||
|
bantime = 1d
|
||||||
|
|
||||||
|
# Destination email address used solely for the interpolations in jail.{conf,local,d/*}
|
||||||
|
# configuration files.
|
||||||
|
destemail = root
|
||||||
|
|
||||||
|
# Sender email address used solely for some actions
|
||||||
|
sender = fail2ban
|
||||||
|
|
||||||
|
# Specify chain where jumps would need to be added in ban-actions expecting parameter chain. Chain
|
||||||
|
# variable needs to be overridden in jail.local, as the uppercase `chain = INPUT` declaration in
|
||||||
|
# jail.conf shadows proper lowercase declaration in nftables-common.conf.
|
||||||
|
chain = input
|
||||||
|
|
||||||
|
# Default banning action (e.g. iptables, iptables-new, iptables-multiport, shorewall, etc) It is
|
||||||
|
# used to define action_* variables. Can be overridden globally or per section within jail.local
|
||||||
|
# file. Use nftables instead of iptables.
|
||||||
|
banaction = nftables[type=multiport]
|
||||||
|
banaction_allports = nftables[type=allports]
|
||||||
|
|
||||||
|
# Choose default action. To change, just override value of 'action' with the interpolation to the
|
||||||
|
# chosen action shortcut (e.g. action_mw, action_mwl, etc) in jail.local globally (section
|
||||||
|
# [DEFAULT]) or per specific section.
|
||||||
|
action = %(action_mw)s
|
6
system/base/fstrim/tasks/main.yml
Normal file
6
system/base/fstrim/tasks/main.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
- name: "enable fstrim.timer"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "fstrim.timer"
|
||||||
|
enabled: true
|
||||||
|
state: "started"
|
12
system/base/logs/files/ignore
Normal file
12
system/base/logs/files/ignore
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
^[[:alpha:]]{3} [ :[:digit:]]{11} [._[:alnum:]\-]+ systemd\[[0-9]+\]: (Starting|Stopping) [ +[:alnum:]/\-]+\.(\.\.)?$
|
||||||
|
^[[:alpha:]]{3} [ :[:digit:]]{11} [._[:alnum:]\-]+ systemd\[[0-9]+\]: Finished (Cleanup of Temporary Directories|Online ext4 Metadata Check for All Filesystems|Podman auto-update service)\.$
|
||||||
|
^[[:alpha:]]{3} [ :[:digit:]]{11} [._[:alnum:]\-]+ systemd\[[0-9]+\]: (apt-daily\.service|apt-daily-upgrade\.service|man-db\.service|sanoid\.service|syncoid-batch\.service): Consumed ([0-9]{1,2}min )?[0-9]{1,2}\.[0-9]{3}s CPU time\.$
|
||||||
|
^[[:alpha:]]{3} [ :[:digit:]]{11} [._[:alnum:]\-]+ systemd\[[0-9]+\]: rsyslog\.service: Sent signal SIGHUP to main process [[:digit:]]+ (rsyslogd) on client request\.$
|
||||||
|
^[[:alpha:]]{3} [ :[:digit:]]{11} [._[:alnum:]\-]+ systemd\[[0-9]+\]: var-lib-containers-storage-overlay\.mount: Succeeded\.$
|
||||||
|
^[[:alpha:]]{3} [ :[:digit:]]{11} [._[:alnum:]\-]+ sanoid\[[0-9]+\]: INFO: .*$
|
||||||
|
^[[:alpha:]]{3} [ :[:digit:]]{11} [._[:alnum:]\-]+ sanoid\[[0-9]+\]: taking snapshot .*$
|
||||||
|
^[[:alpha:]]{3} [ :[:digit:]]{11} [._[:alnum:]\-]+ syncoid-batch\[[0-9]+\]: INFO: .*$
|
||||||
|
^[[:alpha:]]{3} [ :[:digit:]]{11} [._[:alnum:]\-]+ syncoid-batch\[[0-9]+\]: NEWEST SNAPSHOT: .*$
|
||||||
|
^[[:alpha:]]{3} [ :[:digit:]]{11} [._[:alnum:]\-]+ syncoid-batch\[[0-9]+\]: Sending incremental .*$
|
||||||
|
^[[:alpha:]]{3} [ :[:digit:]]{11} [._[:alnum:]\-]+ systemd\[[0-9]+\]: Finished (Snapshot ZFS filesystems|Prune ZFS snapshots|Replicate snapshots using syncoid)\.$
|
||||||
|
^[[:alpha:]]{3} [ :[:digit:]]{11} [._[:alnum:]\-]+ kernel: \[[0-9]+\.[0-9]+\] audit: type=1326 audit\([.:0-9]+): auid=[0-9]+ uid=[0-9]+ gid=[0-9]+ ses=[0-9]+ subj=unconfined pid=[0-9]+ comm="git-remote-http" exe="/usr/libexec/git-core/git-remote-https" sig=0 arch=c000003e syscall=324 compat=0 ip=[[:alnum:]]+ code=0x50000$
|
96
system/base/logs/files/logcheck.conf
Normal file
96
system/base/logs/files/logcheck.conf
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
# The following variable settings are the initial default values,
|
||||||
|
# which can be uncommented and modified to alter logcheck's behaviour
|
||||||
|
|
||||||
|
# Controls the format of date-/time-stamps in subject lines:
|
||||||
|
# Alternatively, set the format to suit your locale
|
||||||
|
|
||||||
|
#DATE="$(date +'%Y-%m-%d %H:%M')"
|
||||||
|
|
||||||
|
# Controls the presence of boilerplate at the top of each message:
|
||||||
|
# Alternatively, set to "0" to disable the introduction.
|
||||||
|
#
|
||||||
|
# If the files /etc/logcheck/header.txt and /etc/logcheck/footer.txt
|
||||||
|
# are present their contents will be read and used as the header and
|
||||||
|
# footer of any generated mails.
|
||||||
|
|
||||||
|
#INTRO=1
|
||||||
|
|
||||||
|
# Controls the level of filtering:
|
||||||
|
# Can be Set to "workstation", "server" or "paranoid" for different
|
||||||
|
# levels of filtering. Defaults to server if not set.
|
||||||
|
|
||||||
|
REPORTLEVEL="server"
|
||||||
|
|
||||||
|
# Controls the address mail goes to:
|
||||||
|
# *NOTE* the script does not set a default value for this variable!
|
||||||
|
# Should be set to an offsite "emailaddress@some.domain.tld"
|
||||||
|
|
||||||
|
SENDMAILTO="root"
|
||||||
|
|
||||||
|
# Send the results as attachment or not.
|
||||||
|
# 0=not as attachment; 1=as attachment; 2=as gzip attachment
|
||||||
|
# Default is 0
|
||||||
|
|
||||||
|
MAILASATTACH=0
|
||||||
|
|
||||||
|
# Should the hostname in the subject of generated mails be fully qualified?
|
||||||
|
|
||||||
|
FQDN=1
|
||||||
|
|
||||||
|
# Controls whether "sort -u" is used on log entries (which will
|
||||||
|
# eliminate duplicates but destroy the original ordering); the
|
||||||
|
# default is to use "sort -k 1,3 -s":
|
||||||
|
# Alternatively, set to "1" to enable unique sorting
|
||||||
|
|
||||||
|
#SORTUNIQ=0
|
||||||
|
|
||||||
|
# Controls whether /etc/logcheck/cracking.ignore.d is scanned for
|
||||||
|
# exceptions to the rules in /etc/logcheck/cracking.d:
|
||||||
|
# Alternatively, set to "1" to enable cracking.ignore support
|
||||||
|
|
||||||
|
#SUPPORT_CRACKING_IGNORE=0
|
||||||
|
|
||||||
|
# Controls the base directory for rules file location
|
||||||
|
# This must be an absolute path
|
||||||
|
|
||||||
|
#RULEDIR="/etc/logcheck"
|
||||||
|
|
||||||
|
# Controls if syslog-summary is run over each section.
|
||||||
|
# Alternatively, set to "1" to enable extra summary.
|
||||||
|
# HINT: syslog-summary needs to be installed.
|
||||||
|
|
||||||
|
#SYSLOGSUMMARY=0
|
||||||
|
|
||||||
|
# Controls Subject: lines on logcheck reports:
|
||||||
|
|
||||||
|
#ATTACKSUBJECT="Security Alerts"
|
||||||
|
#SECURITYSUBJECT="Security Events"
|
||||||
|
#EVENTSSUBJECT="System Events"
|
||||||
|
|
||||||
|
# Controls [logcheck] prefix on Subject: lines
|
||||||
|
|
||||||
|
#ADDTAG="no"
|
||||||
|
|
||||||
|
# Previous versions of logcheck always sent messages in 7bit encoding,
|
||||||
|
# even if that resulted in RFC-violating messages. For example, really
|
||||||
|
# long syslog lines would generate too-long SMTP lines, which are
|
||||||
|
# rejected at least by Debian's default exim configuration. The new
|
||||||
|
# default is to let mime-construct pick an appropriate encoding, but you
|
||||||
|
# can override it by setting the below (to any of the encodings
|
||||||
|
# supported by mime-construct). You may need to do this if you have
|
||||||
|
# tools handling logcheck emails that don't understand MIME encoding.
|
||||||
|
|
||||||
|
#MIMEENCODING=
|
||||||
|
|
||||||
|
# Set a different location for temporary files than /tmp
|
||||||
|
# this is useful if your /tmp is small and you are getting
|
||||||
|
# errors such as:
|
||||||
|
# cp: writing `/tmp/logcheck.y12449/checked': No space left on device
|
||||||
|
# /usr/sbin/logcheck: line 161: cannot create temp file for here document: No space left on device
|
||||||
|
# mail: /tmp/mail.RsXXXXpc2eAx: No space left on device
|
||||||
|
# Null message body; hope that's ok
|
||||||
|
#
|
||||||
|
# If this is happening, likely you will want to change the following to be some other
|
||||||
|
# location, such as /var/tmp
|
||||||
|
|
||||||
|
TMP="/tmp"
|
19
system/base/logs/tasks/main.yml
Normal file
19
system/base/logs/tasks/main.yml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
- name: "install logcheck and logrotate"
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- "logcheck"
|
||||||
|
- "logrotate"
|
||||||
|
|
||||||
|
- name: "configure logcheck"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "./logcheck.conf"
|
||||||
|
dest: "/etc/logcheck/logcheck.conf"
|
||||||
|
mode: 0640
|
||||||
|
|
||||||
|
- name: "logs : configure logcheck ignores"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "./ignore"
|
||||||
|
dest: "/etc/logcheck/ignore.d.server/{{ ansible_hostname }}"
|
||||||
|
group: "logcheck"
|
||||||
|
mode: 0644
|
25
system/base/mail/meta/argument_specs.yml
Normal file
25
system/base/mail/meta/argument_specs.yml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
options:
|
||||||
|
ansible_hostname:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
||||||
|
system_base_mail_disable_dns:
|
||||||
|
type: "bool"
|
||||||
|
required: true
|
||||||
|
system_mail_domain:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
||||||
|
system_mail_smtp_server:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
||||||
|
system_mail_smtp_port:
|
||||||
|
type: "int"
|
||||||
|
required: true
|
||||||
|
system_mail_smtp_user:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
||||||
|
system_mail_smtp_pass:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
80
system/base/mail/tasks/main.yml
Normal file
80
system/base/mail/tasks/main.yml
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
---
|
||||||
|
- name: "configure mailname"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./mailname.j2"
|
||||||
|
dest: "/etc/mailname"
|
||||||
|
mode: 0644
|
||||||
|
register: system_mail_mailname
|
||||||
|
|
||||||
|
- name: "configure mailutils"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./mailutils.conf.j2"
|
||||||
|
dest: "/etc/mailutils.conf"
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
- name: "install postfix"
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- "postfix"
|
||||||
|
- "ca-certificates"
|
||||||
|
- "libsasl2-modules"
|
||||||
|
|
||||||
|
- name: "configure aliases"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./aliases.j2"
|
||||||
|
dest: "/etc/aliases"
|
||||||
|
mode: 0644
|
||||||
|
register: system_mail_aliases
|
||||||
|
|
||||||
|
- name: "update aliases"
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "newaliases"
|
||||||
|
when:
|
||||||
|
system_mail_aliases.changed
|
||||||
|
|
||||||
|
- name: "configure postfix"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./postfix/main.cf.j2"
|
||||||
|
dest: "/etc/postfix/main.cf"
|
||||||
|
mode: 0644
|
||||||
|
register: system_mail_postfix_conf
|
||||||
|
|
||||||
|
- name: "configure credentials"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./postfix/sasl_passwd.j2"
|
||||||
|
dest: "/etc/postfix/sasl_passwd"
|
||||||
|
mode: 0600
|
||||||
|
register: system_mail_postfix_credentials
|
||||||
|
|
||||||
|
- name: "create hash database"
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "postmap /etc/postfix/sasl_passwd"
|
||||||
|
when:
|
||||||
|
system_mail_postfix_credentials.changed
|
||||||
|
|
||||||
|
- name: "set hash database permissions"
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/etc/postfix/sasl_passwd.db"
|
||||||
|
mode: 0600
|
||||||
|
|
||||||
|
- name: "enable postfix"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "postfix"
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
- name: "start postfix"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "postfix"
|
||||||
|
state: "started"
|
||||||
|
register: system_mail_postfix_start
|
||||||
|
|
||||||
|
- name: "restart postfix"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "postfix"
|
||||||
|
state: "restarted"
|
||||||
|
when:
|
||||||
|
(system_mail_mailname.changed or
|
||||||
|
system_mail_aliases.changed or
|
||||||
|
system_mail_postfix_conf.changed or
|
||||||
|
system_mail_postfix_credentials.changed) and
|
||||||
|
not system_mail_postfix_start.changed
|
14
system/base/mail/templates/aliases.j2
Normal file
14
system/base/mail/templates/aliases.j2
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# /etc/aliases
|
||||||
|
mailer-daemon: postmaster
|
||||||
|
postmaster: root
|
||||||
|
nobody: root
|
||||||
|
hostmaster: root
|
||||||
|
usenet: root
|
||||||
|
news: root
|
||||||
|
webmaster: root
|
||||||
|
www: root
|
||||||
|
ftp: root
|
||||||
|
abuse: root
|
||||||
|
noc: root
|
||||||
|
security: root
|
||||||
|
root: root@{{ system_mail_domain }}
|
1
system/base/mail/templates/mailname.j2
Normal file
1
system/base/mail/templates/mailname.j2
Normal file
@ -0,0 +1 @@
|
|||||||
|
{{ ansible_hostname }}.{{ system_mail_domain }}
|
3
system/base/mail/templates/mailutils.conf.j2
Normal file
3
system/base/mail/templates/mailutils.conf.j2
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
address {
|
||||||
|
email-domain {{ ansible_hostname }}.{{ system_mail_domain }};
|
||||||
|
};
|
58
system/base/mail/templates/postfix/main.cf.j2
Normal file
58
system/base/mail/templates/postfix/main.cf.j2
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# See /usr/share/postfix/main.cf.dist for a commented, more complete version
|
||||||
|
|
||||||
|
|
||||||
|
# Debian specific: Specifying a file name will cause the first
|
||||||
|
# line of that file to be used as the name. The Debian default
|
||||||
|
# is /etc/mailname.
|
||||||
|
myorigin = /etc/mailname
|
||||||
|
|
||||||
|
smtpd_banner = $myhostname ESMTP
|
||||||
|
biff = no
|
||||||
|
|
||||||
|
# appending .domain is the MUA's job.
|
||||||
|
append_dot_mydomain = no
|
||||||
|
|
||||||
|
# Uncomment the next line to generate "delayed mail" warnings
|
||||||
|
#delay_warning_time = 4h
|
||||||
|
|
||||||
|
readme_directory = no
|
||||||
|
|
||||||
|
# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on
|
||||||
|
# fresh installs.
|
||||||
|
compatibility_level = 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# TLS parameters
|
||||||
|
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
|
||||||
|
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
|
||||||
|
smtpd_tls_security_level=may
|
||||||
|
|
||||||
|
smtp_tls_CApath=/etc/ssl/certs
|
||||||
|
smtp_tls_security_level=encrypt
|
||||||
|
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
|
||||||
|
smtp_tls_wrappermode = yes
|
||||||
|
|
||||||
|
|
||||||
|
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
|
||||||
|
myhostname = {{ ansible_hostname }}.{{ system_mail_domain }}
|
||||||
|
alias_maps = hash:/etc/aliases
|
||||||
|
alias_database = hash:/etc/aliases
|
||||||
|
mydestination = $myhostname, {{ ansible_hostname }}, localhost
|
||||||
|
relayhost = [{{ system_mail_smtp_server }}]:{{ system_mail_smtp_port }}
|
||||||
|
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
|
||||||
|
mailbox_size_limit = 0
|
||||||
|
recipient_delimiter = +
|
||||||
|
inet_interfaces = loopback-only
|
||||||
|
inet_protocols = all
|
||||||
|
|
||||||
|
# SASL parameters
|
||||||
|
smtp_sasl_auth_enable = yes
|
||||||
|
smtp_sasl_security_options = noanonymous
|
||||||
|
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
|
||||||
|
{% if system_base_mail_disable_dns %}
|
||||||
|
|
||||||
|
smtp_host_lookup=native
|
||||||
|
disable_dns_lookups = yes
|
||||||
|
ignore_mx_lookup_error = yes
|
||||||
|
{% endif %}
|
1
system/base/mail/templates/postfix/sasl_passwd.j2
Normal file
1
system/base/mail/templates/postfix/sasl_passwd.j2
Normal file
@ -0,0 +1 @@
|
|||||||
|
[{{ system_mail_smtp_server }}]:{{ system_mail_smtp_port }} {{ system_mail_smtp_user }}:{{ system_mail_smtp_pass }}
|
10
system/base/motd/meta/argument_specs.yml
Normal file
10
system/base/motd/meta/argument_specs.yml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
options:
|
||||||
|
ansible_hostname:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
||||||
|
system_base_motd_dir:
|
||||||
|
type: "str"
|
||||||
|
required: false
|
11
system/base/motd/tasks/main.yml
Normal file
11
system/base/motd/tasks/main.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
- name: "set motd"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ item }}"
|
||||||
|
dest: "/etc/motd"
|
||||||
|
mode: 0644
|
||||||
|
loop: "{{ [lookup('ansible.builtin.first_found', _file_path, skip=true)] | flatten }}"
|
||||||
|
vars:
|
||||||
|
_file_path: "{{ system_base_motd_dir }}/{{ ansible_hostname }}"
|
||||||
|
when:
|
||||||
|
system_base_motd_dir is defined
|
3
system/base/nftables/defaults/main.yml
Normal file
3
system/base/nftables/defaults/main.yml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
system_base_additional_tcp_ports: []
|
||||||
|
system_base_udp_ports: []
|
15
system/base/nftables/meta/argument_specs.yml
Normal file
15
system/base/nftables/meta/argument_specs.yml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
options:
|
||||||
|
ansible_port:
|
||||||
|
type: "int"
|
||||||
|
required: true
|
||||||
|
system_base_additional_tcp_ports:
|
||||||
|
type: "list"
|
||||||
|
elements: "int"
|
||||||
|
required: true
|
||||||
|
system_base_udp_ports:
|
||||||
|
type: "list"
|
||||||
|
elements: "int"
|
||||||
|
required: true
|
29
system/base/nftables/tasks/main.yml
Normal file
29
system/base/nftables/tasks/main.yml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
- name: "install nftables"
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: "nftables"
|
||||||
|
|
||||||
|
- name: "configure nftables"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./nftables.conf.j2"
|
||||||
|
dest: "/etc/nftables.conf"
|
||||||
|
mode: 0755
|
||||||
|
register: system_base_nftables_conf
|
||||||
|
|
||||||
|
- name: "enable nftables"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "nftables"
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
- name: "start nftables"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "nftables"
|
||||||
|
state: "started"
|
||||||
|
register: system_base_nftables_start
|
||||||
|
|
||||||
|
- name: "reload nftables configuration"
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "nft -f /etc/nftables.conf"
|
||||||
|
when:
|
||||||
|
system_base_nftables_conf.changed and
|
||||||
|
not system_base_nftables_start.changed
|
41
system/base/nftables/templates/nftables.conf.j2
Executable file
41
system/base/nftables/templates/nftables.conf.j2
Executable file
@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/sbin/nft -f
|
||||||
|
|
||||||
|
table inet filter
|
||||||
|
delete table inet filter
|
||||||
|
|
||||||
|
table inet filter {
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority 0;
|
||||||
|
|
||||||
|
# Accept any localhost traffic.
|
||||||
|
iif lo accept;
|
||||||
|
|
||||||
|
# Accept traffic originated from us.
|
||||||
|
ct state established,related accept;
|
||||||
|
|
||||||
|
# Allow ICMP packets.
|
||||||
|
# Note that for IPv6 nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert are needed to not break connectivity.
|
||||||
|
ip6 nexthdr icmpv6 icmpv6 type { echo-request, destination-unreachable, packet-too-big, time-exceeded, parameter-problem, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept;
|
||||||
|
ip protocol icmp icmp type { echo-request, destination-unreachable, router-advertisement, time-exceeded, parameter-problem } accept;
|
||||||
|
|
||||||
|
# Drop invalid connections.
|
||||||
|
ct state invalid drop;
|
||||||
|
|
||||||
|
# TCP ports.
|
||||||
|
tcp dport { {{ [ansible_port] | union(system_base_additional_tcp_ports) | join(", ") }} } ct state new accept;
|
||||||
|
|
||||||
|
{% if system_base_udp_ports %}
|
||||||
|
# UDP ports.
|
||||||
|
udp dport { {{ system_base_udp_ports | join(", ") }} } accept;
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
# Count and drop any other traffic.
|
||||||
|
counter drop;
|
||||||
|
}
|
||||||
|
chain forward {
|
||||||
|
type filter hook forward priority 0;
|
||||||
|
}
|
||||||
|
chain output {
|
||||||
|
type filter hook output priority 0;
|
||||||
|
}
|
||||||
|
}
|
7
system/base/ntp/meta/argument_specs.yml
Normal file
7
system/base/ntp/meta/argument_specs.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
options:
|
||||||
|
system_base_ntp_timezone:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
14
system/base/ntp/tasks/main.yml
Normal file
14
system/base/ntp/tasks/main.yml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
- name: "install systemd-timesyncd"
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: "systemd-timesyncd"
|
||||||
|
|
||||||
|
- name: "enable systemd-timesyncd"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "systemd-timesyncd"
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
|
|
||||||
|
- name: "set timezone"
|
||||||
|
community.general.timezone:
|
||||||
|
name: "{{ system_base_ntp_timezone }}"
|
61
system/base/root/files/su
Normal file
61
system/base/root/files/su
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#
|
||||||
|
# The PAM configuration file for the Shadow `su' service
|
||||||
|
#
|
||||||
|
|
||||||
|
# This allows root to su without passwords (normal operation)
|
||||||
|
auth sufficient pam_rootok.so
|
||||||
|
|
||||||
|
# Uncomment this to force users to be a member of group wheel
|
||||||
|
# before they can use `su'. You can also add "group=foo"
|
||||||
|
# to the end of this line if you want to use a group other
|
||||||
|
# than the default "wheel" (but this may have side effect of
|
||||||
|
# denying "root" user, unless she's a member of "foo" or explicitly
|
||||||
|
# permitted earlier by e.g. "sufficient pam_rootok.so").
|
||||||
|
# (Replaces the `SU_WHEEL_ONLY' option from login.defs)
|
||||||
|
auth required pam_wheel.so
|
||||||
|
|
||||||
|
# Uncomment this if you want wheel members to be able to
|
||||||
|
# su without a password.
|
||||||
|
# auth sufficient pam_wheel.so trust
|
||||||
|
|
||||||
|
# Uncomment this if you want members of a specific group to not
|
||||||
|
# be allowed to use su at all.
|
||||||
|
# auth required pam_wheel.so deny group=nosu
|
||||||
|
|
||||||
|
# Uncomment and edit /etc/security/time.conf if you need to set
|
||||||
|
# time restrainst on su usage.
|
||||||
|
# (Replaces the `PORTTIME_CHECKS_ENAB' option from login.defs
|
||||||
|
# as well as /etc/porttime)
|
||||||
|
# account requisite pam_time.so
|
||||||
|
|
||||||
|
# This module parses environment configuration file(s)
|
||||||
|
# and also allows you to use an extended config
|
||||||
|
# file /etc/security/pam_env.conf.
|
||||||
|
#
|
||||||
|
# parsing /etc/environment needs "readenv=1"
|
||||||
|
session required pam_env.so readenv=1
|
||||||
|
# locale variables are also kept into /etc/default/locale in etch
|
||||||
|
# reading this file *in addition to /etc/environment* does not hurt
|
||||||
|
session required pam_env.so readenv=1 envfile=/etc/default/locale
|
||||||
|
|
||||||
|
# Defines the MAIL environment variable
|
||||||
|
# However, userdel also needs MAIL_DIR and MAIL_FILE variables
|
||||||
|
# in /etc/login.defs to make sure that removing a user
|
||||||
|
# also removes the user's mail spool file.
|
||||||
|
# See comments in /etc/login.defs
|
||||||
|
#
|
||||||
|
# "nopen" stands to avoid reporting new mail when su'ing to another user
|
||||||
|
session optional pam_mail.so nopen
|
||||||
|
|
||||||
|
# Sets up user limits according to /etc/security/limits.conf
|
||||||
|
# (Replaces the use of /etc/limits in old login)
|
||||||
|
session required pam_limits.so
|
||||||
|
|
||||||
|
# The standard Unix authentication modules, used with
|
||||||
|
# NIS (man nsswitch) as well as normal /etc/passwd and
|
||||||
|
# /etc/shadow entries.
|
||||||
|
@include common-auth
|
||||||
|
@include common-account
|
||||||
|
@include common-session
|
||||||
|
|
||||||
|
|
11
system/base/root/tasks/main.yml
Normal file
11
system/base/root/tasks/main.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
- name: "disable root shell"
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "root"
|
||||||
|
shell: "/usr/sbin/nologin"
|
||||||
|
|
||||||
|
- name: "disable su for non-wheel users"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "./su"
|
||||||
|
dest: "/etc/pam.d/su"
|
||||||
|
mode: 0644
|
2
system/base/sshd/defaults/main.yml
Normal file
2
system/base/sshd/defaults/main.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
system_base_additional_ssh_users: []
|
14
system/base/sshd/meta/argument_specs.yml
Normal file
14
system/base/sshd/meta/argument_specs.yml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
options:
|
||||||
|
ansible_port:
|
||||||
|
type: "int"
|
||||||
|
required: true
|
||||||
|
system_base_ssh_user:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
||||||
|
system_base_additional_ssh_users:
|
||||||
|
type: "list"
|
||||||
|
elements: "str"
|
||||||
|
required: true
|
28
system/base/sshd/tasks/main.yml
Normal file
28
system/base/sshd/tasks/main.yml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
# SSH must be installed so we don't bother with installing it.
|
||||||
|
|
||||||
|
- name: "configure sshd"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./99-local.conf.j2"
|
||||||
|
dest: "/etc/ssh/sshd_config.d/99-local.conf"
|
||||||
|
mode: 0600
|
||||||
|
register: system_base_sshd_conf
|
||||||
|
|
||||||
|
- name: "enable sshd"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "sshd"
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
- name: "start sshd"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "sshd"
|
||||||
|
state: "started"
|
||||||
|
register: system_base_sshd_start
|
||||||
|
|
||||||
|
- name: "restart sshd"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "sshd"
|
||||||
|
state: "restarted"
|
||||||
|
when:
|
||||||
|
system_base_sshd_conf.changed and
|
||||||
|
not system_base_sshd_start.changed
|
19
system/base/sshd/templates/99-local.conf.j2
Normal file
19
system/base/sshd/templates/99-local.conf.j2
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# SSH daemon configuration. Note that sshd_config(5) states "For each keyword, the first obtained
|
||||||
|
# value will be used." This is why files < 00 which are read earlier override the settings below.
|
||||||
|
|
||||||
|
Port {{ ansible_port }}
|
||||||
|
|
||||||
|
# Completely disable root login via ssh.
|
||||||
|
PermitRootLogin no
|
||||||
|
|
||||||
|
# Explicitly set the list of allowed ssh users.
|
||||||
|
AllowUsers {{ [system_base_ssh_user] | union(system_base_additional_ssh_users) | join(" ") }}
|
||||||
|
|
||||||
|
# SSH enabled only via ssh-key.
|
||||||
|
PasswordAuthentication no
|
||||||
|
|
||||||
|
# No X window forwarding.
|
||||||
|
X11Forwarding no
|
||||||
|
|
||||||
|
# Check in with the client every now and then.
|
||||||
|
ClientAliveInterval 120
|
@ -0,0 +1,7 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Status email for %i
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/local/sbin/systemd-mail-systemctl-status %i
|
||||||
|
Group=systemd-journal
|
6
system/base/systemd_mail/files/user/status-mail@.service
Normal file
6
system/base/systemd_mail/files/user/status-mail@.service
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Status email for %i
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/local/bin/systemd-mail-systemctl-status %i
|
7
system/base/systemd_mail/meta/argument_specs.yml
Normal file
7
system/base/systemd_mail/meta/argument_specs.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
options:
|
||||||
|
ansible_hostname:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
33
system/base/systemd_mail/tasks/main.yml
Normal file
33
system/base/systemd_mail/tasks/main.yml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
- name: "systemd mail root script"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./system/systemd-mail-systemctl-status.j2"
|
||||||
|
dest: "/usr/local/sbin/systemd-mail-systemctl-status"
|
||||||
|
mode: 0755
|
||||||
|
|
||||||
|
- name: "systemd mail user script"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./user/systemd-mail-systemctl-status.j2"
|
||||||
|
dest: "/usr/local/bin/systemd-mail-systemctl-status"
|
||||||
|
mode: 0755
|
||||||
|
|
||||||
|
- name: "systemd mail root service"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "./system/status-mail@.service"
|
||||||
|
dest: "/etc/systemd/system/status-mail@.service"
|
||||||
|
mode: 0644
|
||||||
|
register: system_base_system_status_mail_service_file
|
||||||
|
|
||||||
|
- name: "systemd mail user service"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "./user/status-mail@.service"
|
||||||
|
dest: "/etc/systemd/user/status-mail@.service"
|
||||||
|
mode: 0644
|
||||||
|
register: system_base_user_status_mail_service_file
|
||||||
|
|
||||||
|
- name: "systemd daemon reload"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
daemon_reload: true
|
||||||
|
when:
|
||||||
|
system_base_system_status_mail_service_file.changed or
|
||||||
|
system_base_user_status_mail_service_file.changed
|
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
/usr/sbin/sendmail -t <<SYSTEMDMAIL
|
||||||
|
To: root
|
||||||
|
From: systemd <systemd>
|
||||||
|
Subject: systemctl status $1 on {{ ansible_hostname }}
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
|
||||||
|
$(systemctl status --full "$1")
|
||||||
|
SYSTEMDMAIL
|
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
/usr/sbin/sendmail -t <<SYSTEMDMAIL
|
||||||
|
To: root
|
||||||
|
From: $(whoami).systemd <systemd>
|
||||||
|
Subject: systemctl --user status $1 on {{ ansible_hostname }}
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
|
||||||
|
$(systemctl --user status --full "$1")
|
||||||
|
SYSTEMDMAIL
|
2
system/base/unattended_upgrades/files/20auto-upgrades
Normal file
2
system/base/unattended_upgrades/files/20auto-upgrades
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
APT::Periodic::Update-Package-Lists "1";
|
||||||
|
APT::Periodic::Unattended-Upgrade "1";
|
164
system/base/unattended_upgrades/files/50unattended-upgrades
Normal file
164
system/base/unattended_upgrades/files/50unattended-upgrades
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
// Unattended-Upgrade::Origins-Pattern controls which packages are
|
||||||
|
// upgraded.
|
||||||
|
//
|
||||||
|
// Lines below have the format "keyword=value,...". A
|
||||||
|
// package will be upgraded only if the values in its metadata match
|
||||||
|
// all the supplied keywords in a line. (In other words, omitted
|
||||||
|
// keywords are wild cards.) The keywords originate from the Release
|
||||||
|
// file, but several aliases are accepted. The accepted keywords are:
|
||||||
|
// a,archive,suite (eg, "stable")
|
||||||
|
// c,component (eg, "main", "contrib", "non-free")
|
||||||
|
// l,label (eg, "Debian", "Debian-Security")
|
||||||
|
// o,origin (eg, "Debian", "Unofficial Multimedia Packages")
|
||||||
|
// n,codename (eg, "jessie", "jessie-updates")
|
||||||
|
// site (eg, "http.debian.net")
|
||||||
|
// The available values on the system are printed by the command
|
||||||
|
// "apt-cache policy", and can be debugged by running
|
||||||
|
// "unattended-upgrades -d" and looking at the log file.
|
||||||
|
//
|
||||||
|
// Within lines unattended-upgrades allows 2 macros whose values are
|
||||||
|
// derived from /etc/debian_version:
|
||||||
|
// ${distro_id} Installed origin.
|
||||||
|
// ${distro_codename} Installed codename (eg, "buster")
|
||||||
|
Unattended-Upgrade::Origins-Pattern {
|
||||||
|
// Codename based matching:
|
||||||
|
// This will follow the migration of a release through different
|
||||||
|
// archives (e.g. from testing to stable and later oldstable).
|
||||||
|
// Software will be the latest available for the named release,
|
||||||
|
// but the Debian release itself will not be automatically upgraded.
|
||||||
|
// "origin=Debian,codename=${distro_codename}-updates";
|
||||||
|
// "origin=Debian,codename=${distro_codename}-proposed-updates";
|
||||||
|
"origin=Debian,codename=${distro_codename},label=Debian";
|
||||||
|
"origin=Debian,codename=${distro_codename},label=Debian-Security";
|
||||||
|
"origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
|
||||||
|
|
||||||
|
// Archive or Suite based matching:
|
||||||
|
// Note that this will silently match a different release after
|
||||||
|
// migration to the specified archive (e.g. testing becomes the
|
||||||
|
// new stable).
|
||||||
|
// "o=Debian,a=stable";
|
||||||
|
// "o=Debian,a=stable-updates";
|
||||||
|
// "o=Debian,a=proposed-updates";
|
||||||
|
// "o=Debian Backports,a=${distro_codename}-backports,l=Debian Backports";
|
||||||
|
};
|
||||||
|
|
||||||
|
// Python regular expressions, matching packages to exclude from upgrading
|
||||||
|
Unattended-Upgrade::Package-Blacklist {
|
||||||
|
// The following matches all packages starting with linux-
|
||||||
|
// "linux-";
|
||||||
|
|
||||||
|
// Use $ to explicitely define the end of a package name. Without
|
||||||
|
// the $, "libc6" would match all of them.
|
||||||
|
// "libc6$";
|
||||||
|
// "libc6-dev$";
|
||||||
|
// "libc6-i686$";
|
||||||
|
|
||||||
|
// Special characters need escaping
|
||||||
|
// "libstdc\+\+6$";
|
||||||
|
|
||||||
|
// The following matches packages like xen-system-amd64, xen-utils-4.1,
|
||||||
|
// xenstore-utils and libxenstore3.0
|
||||||
|
// "(lib)?xen(store)?";
|
||||||
|
|
||||||
|
// For more information about Python regular expressions, see
|
||||||
|
// https://docs.python.org/3/howto/regex.html
|
||||||
|
};
|
||||||
|
|
||||||
|
// This option allows you to control if on a unclean dpkg exit
|
||||||
|
// unattended-upgrades will automatically run
|
||||||
|
// dpkg --force-confold --configure -a
|
||||||
|
// The default is true, to ensure updates keep getting installed
|
||||||
|
//Unattended-Upgrade::AutoFixInterruptedDpkg "true";
|
||||||
|
|
||||||
|
// Split the upgrade into the smallest possible chunks so that
|
||||||
|
// they can be interrupted with SIGTERM. This makes the upgrade
|
||||||
|
// a bit slower but it has the benefit that shutdown while a upgrade
|
||||||
|
// is running is possible (with a small delay)
|
||||||
|
//Unattended-Upgrade::MinimalSteps "true";
|
||||||
|
|
||||||
|
// Install all updates when the machine is shutting down
|
||||||
|
// instead of doing it in the background while the machine is running.
|
||||||
|
// This will (obviously) make shutdown slower.
|
||||||
|
// Unattended-upgrades increases logind's InhibitDelayMaxSec to 30s.
|
||||||
|
// This allows more time for unattended-upgrades to shut down gracefully
|
||||||
|
// or even install a few packages in InstallOnShutdown mode, but is still a
|
||||||
|
// big step back from the 30 minutes allowed for InstallOnShutdown previously.
|
||||||
|
// Users enabling InstallOnShutdown mode are advised to increase
|
||||||
|
// InhibitDelayMaxSec even further, possibly to 30 minutes.
|
||||||
|
//Unattended-Upgrade::InstallOnShutdown "false";
|
||||||
|
|
||||||
|
// Send email to this address for problems or packages upgrades
|
||||||
|
// If empty or unset then no email is sent, make sure that you
|
||||||
|
// have a working mail setup on your system. A package that provides
|
||||||
|
// 'mailx' must be installed. E.g. "user@example.com"
|
||||||
|
Unattended-Upgrade::Mail "root";
|
||||||
|
|
||||||
|
// Set this value to one of:
|
||||||
|
// "always", "only-on-error" or "on-change"
|
||||||
|
// If this is not set, then any legacy MailOnlyOnError (boolean) value
|
||||||
|
// is used to chose between "only-on-error" and "on-change"
|
||||||
|
//Unattended-Upgrade::MailReport "on-change";
|
||||||
|
|
||||||
|
// Remove unused automatically installed kernel-related packages
|
||||||
|
// (kernel images, kernel headers and kernel version locked tools).
|
||||||
|
//Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
|
||||||
|
|
||||||
|
// Do automatic removal of newly unused dependencies after the upgrade
|
||||||
|
//Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
|
||||||
|
|
||||||
|
// Do automatic removal of unused packages after the upgrade
|
||||||
|
// (equivalent to apt-get autoremove)
|
||||||
|
//Unattended-Upgrade::Remove-Unused-Dependencies "false";
|
||||||
|
|
||||||
|
// Automatically reboot *WITHOUT CONFIRMATION* if
|
||||||
|
// the file /var/run/reboot-required is found after the upgrade
|
||||||
|
//Unattended-Upgrade::Automatic-Reboot "false";
|
||||||
|
|
||||||
|
// Automatically reboot even if there are users currently logged in
|
||||||
|
// when Unattended-Upgrade::Automatic-Reboot is set to true
|
||||||
|
//Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
|
||||||
|
|
||||||
|
// If automatic reboot is enabled and needed, reboot at the specific
|
||||||
|
// time instead of immediately
|
||||||
|
// Default: "now"
|
||||||
|
//Unattended-Upgrade::Automatic-Reboot-Time "02:00";
|
||||||
|
|
||||||
|
// Use apt bandwidth limit feature, this example limits the download
|
||||||
|
// speed to 70kb/sec
|
||||||
|
//Acquire::http::Dl-Limit "70";
|
||||||
|
|
||||||
|
// Enable logging to syslog. Default is False
|
||||||
|
// Unattended-Upgrade::SyslogEnable "false";
|
||||||
|
|
||||||
|
// Specify syslog facility. Default is daemon
|
||||||
|
// Unattended-Upgrade::SyslogFacility "daemon";
|
||||||
|
|
||||||
|
// Download and install upgrades only on AC power
|
||||||
|
// (i.e. skip or gracefully stop updates on battery)
|
||||||
|
// Unattended-Upgrade::OnlyOnACPower "true";
|
||||||
|
|
||||||
|
// Download and install upgrades only on non-metered connection
|
||||||
|
// (i.e. skip or gracefully stop updates on a metered connection)
|
||||||
|
// Unattended-Upgrade::Skip-Updates-On-Metered-Connections "true";
|
||||||
|
|
||||||
|
// Verbose logging
|
||||||
|
// Unattended-Upgrade::Verbose "false";
|
||||||
|
|
||||||
|
// Print debugging information both in unattended-upgrades and
|
||||||
|
// in unattended-upgrade-shutdown
|
||||||
|
// Unattended-Upgrade::Debug "false";
|
||||||
|
|
||||||
|
// Allow package downgrade if Pin-Priority exceeds 1000
|
||||||
|
// Unattended-Upgrade::Allow-downgrade "false";
|
||||||
|
|
||||||
|
// When APT fails to mark a package to be upgraded or installed try adjusting
|
||||||
|
// candidates of related packages to help APT's resolver in finding a solution
|
||||||
|
// where the package can be upgraded or installed.
|
||||||
|
// This is a workaround until APT's resolver is fixed to always find a
|
||||||
|
// solution if it exists. (See Debian bug #711128.)
|
||||||
|
// The fallback is enabled by default, except on Debian's sid release because
|
||||||
|
// uninstallable packages are frequent there.
|
||||||
|
// Disabling the fallback speeds up unattended-upgrades when there are
|
||||||
|
// uninstallable packages at the expense of rarely keeping back packages which
|
||||||
|
// could be upgraded or installed.
|
||||||
|
// Unattended-Upgrade::Allow-APT-Mark-Fallback "true";
|
16
system/base/unattended_upgrades/tasks/main.yml
Normal file
16
system/base/unattended_upgrades/tasks/main.yml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
- name: "install unattended-upgrades"
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: "unattended-upgrades"
|
||||||
|
|
||||||
|
- name: "configure unattended-upgrades"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "./50unattended-upgrades"
|
||||||
|
dest: "/etc/apt/apt.conf.d/50unattended-upgrades"
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
- name: "enable unattended-upgrades"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "./20auto-upgrades"
|
||||||
|
dest: "/etc/apt/apt.conf.d/20auto-upgrades"
|
||||||
|
mode: 0644
|
119
system/base/user/files/bashrc
Normal file
119
system/base/user/files/bashrc
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
# ~/.bashrc: executed by bash(1) for non-login shells.
|
||||||
|
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
|
||||||
|
# for examples
|
||||||
|
|
||||||
|
# If not running interactively, don't do anything
|
||||||
|
case $- in
|
||||||
|
*i*) ;;
|
||||||
|
*) return;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# TMUX
|
||||||
|
if which tmux >/dev/null 2>&1; then
|
||||||
|
# If not inside a tmux session, and if no session is started, start a new session
|
||||||
|
test -z "$TMUX" && (tmux attach || tmux new-session)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# don't put duplicate lines or lines starting with space in the history.
|
||||||
|
# See bash(1) for more options
|
||||||
|
HISTCONTROL=ignoreboth
|
||||||
|
|
||||||
|
# append to the history file, don't overwrite it
|
||||||
|
shopt -s histappend
|
||||||
|
|
||||||
|
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
|
||||||
|
HISTSIZE=1000
|
||||||
|
HISTFILESIZE=2000
|
||||||
|
|
||||||
|
# check the window size after each command and, if necessary,
|
||||||
|
# update the values of LINES and COLUMNS.
|
||||||
|
shopt -s checkwinsize
|
||||||
|
|
||||||
|
# If set, the pattern "**" used in a pathname expansion context will
|
||||||
|
# match all files and zero or more directories and subdirectories.
|
||||||
|
#shopt -s globstar
|
||||||
|
|
||||||
|
# make less more friendly for non-text input files, see lesspipe(1)
|
||||||
|
#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
|
||||||
|
|
||||||
|
# set variable identifying the chroot you work in (used in the prompt below)
|
||||||
|
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
|
||||||
|
debian_chroot=$(cat /etc/debian_chroot)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# set a fancy prompt (non-color, unless we know we "want" color)
|
||||||
|
case "$TERM" in
|
||||||
|
xterm-color|*-256color) color_prompt=yes;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# uncomment for a colored prompt, if the terminal has the capability; turned
|
||||||
|
# off by default to not distract the user: the focus in a terminal window
|
||||||
|
# should be on the output of commands, not on the prompt
|
||||||
|
#force_color_prompt=yes
|
||||||
|
|
||||||
|
if [ -n "$force_color_prompt" ]; then
|
||||||
|
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
|
||||||
|
# We have color support; assume it's compliant with Ecma-48
|
||||||
|
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
|
||||||
|
# a case would tend to support setf rather than setaf.)
|
||||||
|
color_prompt=yes
|
||||||
|
else
|
||||||
|
color_prompt=
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$color_prompt" = yes ]; then
|
||||||
|
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
|
||||||
|
else
|
||||||
|
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
|
||||||
|
fi
|
||||||
|
unset color_prompt force_color_prompt
|
||||||
|
|
||||||
|
# If this is an xterm set the title to user@host:dir
|
||||||
|
case "$TERM" in
|
||||||
|
xterm*|rxvt*)
|
||||||
|
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# enable color support of ls and also add handy aliases
|
||||||
|
if [ -x /usr/bin/dircolors ]; then
|
||||||
|
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
|
||||||
|
alias ls='ls --color=auto'
|
||||||
|
#alias dir='dir --color=auto'
|
||||||
|
#alias vdir='vdir --color=auto'
|
||||||
|
|
||||||
|
#alias grep='grep --color=auto'
|
||||||
|
#alias fgrep='fgrep --color=auto'
|
||||||
|
#alias egrep='egrep --color=auto'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# colored GCC warnings and errors
|
||||||
|
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
|
||||||
|
|
||||||
|
# some more ls aliases
|
||||||
|
#alias ll='ls -l'
|
||||||
|
#alias la='ls -A'
|
||||||
|
#alias l='ls -CF'
|
||||||
|
|
||||||
|
# Alias definitions.
|
||||||
|
# You may want to put all your additions into a separate file like
|
||||||
|
# ~/.bash_aliases, instead of adding them here directly.
|
||||||
|
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
|
||||||
|
|
||||||
|
if [ -f ~/.bash_aliases ]; then
|
||||||
|
. ~/.bash_aliases
|
||||||
|
fi
|
||||||
|
|
||||||
|
# enable programmable completion features (you don't need to enable
|
||||||
|
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
|
||||||
|
# sources /etc/bash.bashrc).
|
||||||
|
if ! shopt -oq posix; then
|
||||||
|
if [ -f /usr/share/bash-completion/bash_completion ]; then
|
||||||
|
. /usr/share/bash-completion/bash_completion
|
||||||
|
elif [ -f /etc/bash_completion ]; then
|
||||||
|
. /etc/bash_completion
|
||||||
|
fi
|
||||||
|
fi
|
1
system/base/user/files/tmux.conf
Normal file
1
system/base/user/files/tmux.conf
Normal file
@ -0,0 +1 @@
|
|||||||
|
source ~/.tmux/tmux.conf
|
23
system/base/user/tasks/main.yml
Normal file
23
system/base/user/tasks/main.yml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
- block:
|
||||||
|
|
||||||
|
- name: "clone tmux dotfiles"
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: "https://git.wojciechkozlowski.eu/config/tmux.git"
|
||||||
|
dest: ".tmux"
|
||||||
|
recursive: true
|
||||||
|
|
||||||
|
# On first tmux launch install plugins with <Ctrl + a + I>
|
||||||
|
- name: "configure tmux"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "./tmux.conf"
|
||||||
|
dest: ".tmux.conf"
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
- name: "configure bashrc"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "./bashrc"
|
||||||
|
dest: ".bashrc"
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
become: false
|
13
system/base/utils/tasks/main.yml
Normal file
13
system/base/utils/tasks/main.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
- name: "install utility programs"
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- "acl"
|
||||||
|
- "git"
|
||||||
|
- "htop"
|
||||||
|
- "man"
|
||||||
|
- "perl"
|
||||||
|
- "rsync"
|
||||||
|
- "tmux"
|
||||||
|
- "tcpdump"
|
||||||
|
- "traceroute"
|
8
vpn/base/files/ip-link-add.sh
Normal file
8
vpn/base/files/ip-link-add.sh
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
if ! ip link show dev "${1}" > /dev/null 2>&1
|
||||||
|
then
|
||||||
|
ip link add "${@}"
|
||||||
|
fi
|
13
vpn/base/tasks/main.yml
Normal file
13
vpn/base/tasks/main.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
- name: "enable ipv4 forwarding"
|
||||||
|
ansible.posix.sysctl:
|
||||||
|
name: "net.ipv4.ip_forward"
|
||||||
|
value: "1"
|
||||||
|
sysctl_file: "/etc/sysctl.d/local.conf"
|
||||||
|
reload: true
|
||||||
|
|
||||||
|
- name: "script for creating virtual interfaces"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "./ip-link-add.sh"
|
||||||
|
dest: "/usr/local/sbin/ip-link-add.sh"
|
||||||
|
mode: 0755
|
4
vpn/bridge/files/pre-down-br0-inet.nft
Normal file
4
vpn/bridge/files/pre-down-br0-inet.nft
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env -S nft -f
|
||||||
|
|
||||||
|
flush table inet br0_inet
|
||||||
|
delete table inet br0_inet
|
4
vpn/bridge/files/pre-down-br0-ipv4.nft
Normal file
4
vpn/bridge/files/pre-down-br0-ipv4.nft
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env -S nft -f
|
||||||
|
|
||||||
|
flush table ip br0_ipv4
|
||||||
|
delete table ip br0_ipv4
|
27
vpn/bridge/meta/argument_specs.yml
Normal file
27
vpn/bridge/meta/argument_specs.yml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
options:
|
||||||
|
ansible_default_ipv4:
|
||||||
|
interface:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
||||||
|
local_network:
|
||||||
|
type: "str"
|
||||||
|
required: false
|
||||||
|
vpn_bridge_dnat:
|
||||||
|
type: "list"
|
||||||
|
elements: "dict"
|
||||||
|
required: true
|
||||||
|
vpn_bridge_address:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
||||||
|
vpn_bridge_broadcast:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
||||||
|
vpn_bridge_netmask:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
||||||
|
vpn_bridge_routing_table:
|
||||||
|
type: "int"
|
||||||
|
required: false
|
52
vpn/bridge/tasks/main.yml
Normal file
52
vpn/bridge/tasks/main.yml
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
- name: "post-up nftables inet script"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./post-up-br0-inet.nft.j2"
|
||||||
|
dest: "/usr/local/sbin/post-up-br0-inet.nft"
|
||||||
|
mode: 0755
|
||||||
|
register: vpn_bridge_post_up_br0_inet_nft
|
||||||
|
|
||||||
|
- name: "post-up nftables ipv4 script"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./post-up-br0-ipv4.nft.j2"
|
||||||
|
dest: "/usr/local/sbin/post-up-br0-ipv4.nft"
|
||||||
|
mode: 0755
|
||||||
|
register: vpn_bridge_post_up_br0_ipv4_nft
|
||||||
|
|
||||||
|
- name: "configure interface"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./br0.j2"
|
||||||
|
dest: "/etc/network/interfaces.d/br0"
|
||||||
|
mode: 0644
|
||||||
|
validate: >
|
||||||
|
bash -c
|
||||||
|
'if ! diff %s /etc/network/interfaces.d/br0 && ip link show dev br0 ;
|
||||||
|
then
|
||||||
|
ifdown br0 ;
|
||||||
|
fi'
|
||||||
|
register: vpn_bridge_intf
|
||||||
|
|
||||||
|
- name: "restart interface"
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
if ip link show dev br0
|
||||||
|
then
|
||||||
|
ifdown br0 && ifup br0
|
||||||
|
else
|
||||||
|
ifup br0
|
||||||
|
fi
|
||||||
|
when:
|
||||||
|
vpn_bridge_post_up_br0_inet_nft.changed or
|
||||||
|
vpn_bridge_post_up_br0_ipv4_nft.changed or
|
||||||
|
vpn_bridge_intf.changed
|
||||||
|
|
||||||
|
- name: "pre-down nftables inet script"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "./pre-down-br0-inet.nft"
|
||||||
|
dest: "/usr/local/sbin/pre-down-br0-inet.nft"
|
||||||
|
mode: 0755
|
||||||
|
|
||||||
|
- name: "pre-down nftables ipv4 script"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "./pre-down-br0-ipv4.nft"
|
||||||
|
dest: "/usr/local/sbin/pre-down-br0-ipv4.nft"
|
||||||
|
mode: 0755
|
26
vpn/bridge/templates/br0.j2
Normal file
26
vpn/bridge/templates/br0.j2
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
auto br0
|
||||||
|
iface br0 inet static
|
||||||
|
pre-up /usr/local/sbin/ip-link-add.sh $IFACE type bridge
|
||||||
|
|
||||||
|
post-up /usr/local/sbin/post-up-$IFACE-inet.nft
|
||||||
|
post-up /usr/local/sbin/post-up-$IFACE-ipv4.nft
|
||||||
|
{% if vpn_bridge_routing_table is defined %}
|
||||||
|
post-up ip rule add dev $IFACE table {{ vpn_bridge_routing_table }}
|
||||||
|
post-up ip rule add dev $IFACE to {{ local_network }} table main priority 1
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if vpn_bridge_routing_table is defined %}
|
||||||
|
pre-down ip rule del dev $IFACE to {{ local_network }} table main priority 1
|
||||||
|
pre-down ip rule del dev $IFACE table {{ vpn_bridge_routing_table }}
|
||||||
|
{% endif %}
|
||||||
|
pre-down /usr/local/sbin/pre-down-$IFACE-ipv4.nft
|
||||||
|
pre-down /usr/local/sbin/pre-down-$IFACE-inet.nft
|
||||||
|
|
||||||
|
bridge_stp off
|
||||||
|
bridge_waitport 0
|
||||||
|
bridge_fd 0
|
||||||
|
bridge_ports none
|
||||||
|
|
||||||
|
address {{ vpn_bridge_address }}
|
||||||
|
broadcast {{ vpn_bridge_broadcast }}
|
||||||
|
netmask {{ vpn_bridge_netmask }}
|
5
vpn/bridge/templates/post-up-br0-inet.nft.j2
Normal file
5
vpn/bridge/templates/post-up-br0-inet.nft.j2
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env -S nft -f
|
||||||
|
|
||||||
|
table inet br0_inet {
|
||||||
|
|
||||||
|
}
|
23
vpn/bridge/templates/post-up-br0-ipv4.nft.j2
Normal file
23
vpn/bridge/templates/post-up-br0-ipv4.nft.j2
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env -S nft -f
|
||||||
|
|
||||||
|
table ip br0_ipv4 {
|
||||||
|
chain prerouting {
|
||||||
|
type nat hook prerouting priority -100;
|
||||||
|
{% for forward in vpn_bridge_dnat %}
|
||||||
|
iif {{ ansible_default_ipv4.interface }} tcp dport { {{ forward.ports | join(", ") }} } dnat to {{ forward.address }};
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
|
||||||
|
{% if local_network is defined %}
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority 0;
|
||||||
|
ct state established,related accept;
|
||||||
|
iif br0 ip daddr {{ local_network }} drop;
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
chain postrouting {
|
||||||
|
type nat hook postrouting priority 100;
|
||||||
|
iif br0 oif {{ ansible_default_ipv4.interface }} masquerade;
|
||||||
|
}
|
||||||
|
}
|
4
vpn/wireguard/files/pre-down-wg0-inet.nft
Normal file
4
vpn/wireguard/files/pre-down-wg0-inet.nft
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env -S nft -f
|
||||||
|
|
||||||
|
flush table inet wg0_inet
|
||||||
|
delete table inet wg0_inet
|
4
vpn/wireguard/files/pre-down-wg0-ipv4.nft
Normal file
4
vpn/wireguard/files/pre-down-wg0-ipv4.nft
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env -S nft -f
|
||||||
|
|
||||||
|
flush table ip wg0_ipv4
|
||||||
|
delete table ip wg0_ipv4
|
42
vpn/wireguard/meta/argument_specs.yml
Normal file
42
vpn/wireguard/meta/argument_specs.yml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
options:
|
||||||
|
ansible_default_ipv4:
|
||||||
|
interface:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
||||||
|
vpn_wireguard_role:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
||||||
|
vpn_wireguard_address:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
||||||
|
vpn_wireguard_netmask:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
||||||
|
vpn_wireguard_port:
|
||||||
|
type: "int"
|
||||||
|
required: true
|
||||||
|
vpn_wireguard_interface_private_key:
|
||||||
|
type: "str"
|
||||||
|
required: true
|
||||||
|
vpn_wireguard_subnet:
|
||||||
|
type: "str"
|
||||||
|
required: false
|
||||||
|
vpn_wireguard_clients:
|
||||||
|
type: "list"
|
||||||
|
elem: "dict"
|
||||||
|
required: "{{ vpn_wireguard_role == 'server' }}"
|
||||||
|
vpn_wireguard_routing_table:
|
||||||
|
type: "int"
|
||||||
|
required: "{{ vpn_wireguard_role == 'client' }}"
|
||||||
|
vpn_wireguard_server_public_key:
|
||||||
|
type: "str"
|
||||||
|
required: "{{ vpn_wireguard_role == 'client' }}"
|
||||||
|
vpn_wireguard_server_preshared_key:
|
||||||
|
type: "str"
|
||||||
|
required: "{{ vpn_wireguard_role == 'client' }}"
|
||||||
|
vpn_wireguard_server_address:
|
||||||
|
type: "str"
|
||||||
|
required: "{{ vpn_wireguard_role == 'client' }}"
|
64
vpn/wireguard/tasks/main.yml
Normal file
64
vpn/wireguard/tasks/main.yml
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
---
|
||||||
|
- name: "install wireguard"
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: "wireguard"
|
||||||
|
|
||||||
|
- name: "configure wireguard"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./wg0.conf.j2"
|
||||||
|
dest: "/etc/wireguard/wg0.conf"
|
||||||
|
mode: 0600
|
||||||
|
register: vpn_wireguard_conf
|
||||||
|
|
||||||
|
- name: "post-up nftables inet script"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./post-up-wg0-inet.nft.j2"
|
||||||
|
dest: "/usr/local/sbin/post-up-wg0-inet.nft"
|
||||||
|
mode: 0755
|
||||||
|
register: vpn_wireguard_post_up_wg0_inet_nft
|
||||||
|
|
||||||
|
- name: "post-up nftables ipv4 script"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./post-up-wg0-ipv4.nft.j2"
|
||||||
|
dest: "/usr/local/sbin/post-up-wg0-ipv4.nft"
|
||||||
|
mode: 0755
|
||||||
|
register: vpn_wireguard_post_up_wg0_ipv4_nft
|
||||||
|
|
||||||
|
- name: "configure interface"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "./wg0.j2"
|
||||||
|
dest: "/etc/network/interfaces.d/wg0"
|
||||||
|
mode: 0644
|
||||||
|
validate: >
|
||||||
|
bash -c
|
||||||
|
'if ! diff %s /etc/network/interfaces.d/wg0 && ip link show dev wg0 ;
|
||||||
|
then
|
||||||
|
ifdown wg0 ;
|
||||||
|
fi'
|
||||||
|
register: vpn_wireguard_intf
|
||||||
|
|
||||||
|
- name: "restart interface"
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
if ip link show dev wg0
|
||||||
|
then
|
||||||
|
ifdown wg0 && ifup wg0
|
||||||
|
else
|
||||||
|
ifup wg0
|
||||||
|
fi
|
||||||
|
when:
|
||||||
|
vpn_wireguard_conf.changed or
|
||||||
|
vpn_wireguard_post_up_wg0_inet_nft.changed or
|
||||||
|
vpn_wireguard_post_up_wg0_ipv4_nft.changed or
|
||||||
|
vpn_wireguard_intf.changed
|
||||||
|
|
||||||
|
- name: "pre-down nftables inet script"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "./pre-down-wg0-inet.nft"
|
||||||
|
dest: "/usr/local/sbin/pre-down-wg0-inet.nft"
|
||||||
|
mode: 0755
|
||||||
|
|
||||||
|
- name: "pre-down nftables ipv4 script"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "./pre-down-wg0-ipv4.nft"
|
||||||
|
dest: "/usr/local/sbin/pre-down-wg0-ipv4.nft"
|
||||||
|
mode: 0755
|
9
vpn/wireguard/templates/post-up-wg0-inet.nft.j2
Normal file
9
vpn/wireguard/templates/post-up-wg0-inet.nft.j2
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env -S nft -f
|
||||||
|
|
||||||
|
table inet wg0_inet {
|
||||||
|
chain forward {
|
||||||
|
type filter hook forward priority 0;
|
||||||
|
iif wg0 tcp flags syn tcp option maxseg size set rt mtu;
|
||||||
|
oif wg0 tcp flags syn tcp option maxseg size set rt mtu;
|
||||||
|
}
|
||||||
|
}
|
12
vpn/wireguard/templates/post-up-wg0-ipv4.nft.j2
Normal file
12
vpn/wireguard/templates/post-up-wg0-ipv4.nft.j2
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env -S nft -f
|
||||||
|
|
||||||
|
table ip wg0_ipv4 {
|
||||||
|
|
||||||
|
{% if vpn_wireguard_role == "server" %}
|
||||||
|
chain postrouting {
|
||||||
|
type nat hook postrouting priority 100;
|
||||||
|
iif wg0 oif {{ ansible_default_ipv4.interface }} masquerade;
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
}
|
27
vpn/wireguard/templates/wg0.conf.j2
Normal file
27
vpn/wireguard/templates/wg0.conf.j2
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
[Interface]
|
||||||
|
PrivateKey = {{ vpn_wireguard_interface_private_key }}
|
||||||
|
{% if vpn_wireguard_role == "server" %}
|
||||||
|
ListenPort = {{ vpn_wireguard_port }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if vpn_wireguard_role == "server" %}
|
||||||
|
{% for client in vpn_wireguard_clients %}
|
||||||
|
[Peer]
|
||||||
|
PublicKey = {{ client.public_key }}
|
||||||
|
PresharedKey = {{ client.preshared_key }}
|
||||||
|
{% if 'subnet' in client %}
|
||||||
|
AllowedIPs = {{ vpn_wireguard_subnet }},{{ client.subnet }}
|
||||||
|
{% else %}
|
||||||
|
AllowedIPs = {{ vpn_wireguard_subnet }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% elif vpn_wireguard_role == "client" %}
|
||||||
|
[Peer]
|
||||||
|
PublicKey = {{ vpn_wireguard_server_public_key }}
|
||||||
|
PresharedKey = {{ vpn_wireguard_server_preshared_key }}
|
||||||
|
Endpoint = {{ vpn_wireguard_server_address }}:{{ vpn_wireguard_port }}
|
||||||
|
AllowedIPs = 0.0.0.0/0
|
||||||
|
PersistentKeepalive = 15
|
||||||
|
|
||||||
|
{% endif %}
|
32
vpn/wireguard/templates/wg0.j2
Normal file
32
vpn/wireguard/templates/wg0.j2
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
auto wg0
|
||||||
|
iface wg0 inet static
|
||||||
|
pre-up /usr/local/sbin/ip-link-add.sh $IFACE type wireguard
|
||||||
|
pre-up wg setconf $IFACE /etc/wireguard/$IFACE.conf
|
||||||
|
pre-up ip link set mtu 1420 dev $IFACE
|
||||||
|
|
||||||
|
post-up /usr/local/sbin/post-up-$IFACE-inet.nft
|
||||||
|
post-up /usr/local/sbin/post-up-$IFACE-ipv4.nft
|
||||||
|
{% if vpn_wireguard_role == "server" %}
|
||||||
|
{% for client in vpn_wireguard_clients %}
|
||||||
|
{% if 'subnet' in client %}
|
||||||
|
post-up ip route add {{ client.subnet }} dev $IFACE
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% elif vpn_wireguard_role == "client" %}
|
||||||
|
post-up ip route add default dev $IFACE table {{ vpn_wireguard_routing_table }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if vpn_wireguard_role == "server" %}
|
||||||
|
{% for client in vpn_wireguard_clients %}
|
||||||
|
{% if 'subnet' in client %}
|
||||||
|
pre-down ip route del {{ client.subnet }} dev $IFACE
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% elif vpn_wireguard_role == "client" %}
|
||||||
|
pre-down ip route del default dev $IFACE table {{ vpn_wireguard_routing_table }}
|
||||||
|
{% endif %}
|
||||||
|
pre-down /usr/local/sbin/pre-down-$IFACE-ipv4.nft
|
||||||
|
pre-down /usr/local/sbin/pre-down-$IFACE-inet.nft
|
||||||
|
|
||||||
|
address {{ vpn_wireguard_address }}
|
||||||
|
netmask {{ vpn_wireguard_netmask }}
|
Loading…
Reference in New Issue
Block a user