I have a script that use logger
to simulate some "fake" logins:
#!/bin/bash
{%- set maxretry = salt['pillar.get']('fail2ban:maxretry', 3) %}
tag="$1"
message="$2"
logger -p auth.info "The {{ maxretry + 1 }} \"$tag\" below lines are generated by logger to test Fail2ban"
for i in $(seq {{ maxretry + 1 }}); do
logger -p auth.warning -t "$tag" "$message"
done
It is called in a macro:
fake_{{ formula }}_login:
cmd:
- script
- source: salt://fail2ban/fake_login.jinja2
- template: jinja
- args: "{{ tag|default(formula) }} '{{ message }}'"
- require:
- sls: bash
- sls: fail2ban
The thing is {{ message }} can contain single/double quotes, space, square bracket,... According to the cmd.script doc, to pass a string containing a space, we will have to double-quote it. But if I have something like this:
{{ fail2ban_regex_test('mysql', tag='mysqld', message="150114 3:40:50 [Warning] Access denied for user 'root'@'5.6.7.8' (using password: YES)") }}
it will be logged to the syslog without the single quote around the user/host, just:
mysqld: 150114 3:40:50 [Warning] Access denied for user root@5.6.7.8 (using password: YES)
that make fail2ban failed to recognized as it does not match the filter regex.
I can change the single quote to double quote and use backslash to escape:
fake_{{ formula }}_login:
cmd:
- script
- source: salt://fail2ban/fake_login.jinja2
- template:
jinja
- args: "{{ tag|default(formula) }} \"{{ message|safe }}\""
- require:
- sls: bash
- sls: fail2ban
it handle the above case when message just contains the single quotes.
But if it contains the double quotes:
{{ fail2ban_regex_test('postfix', tag='postfix/smtpd[20228]', message="NOQUEUE: reject: RCPT from sender.com["5.6.7.8"]: 554 5.7.1 <us...@example.com>: Recipient address rejected: Access denied; from=<us...@sender.com> to=<us...@example.com> proto=ESMTP helo=<mg01d1.sender.com>") }}
I got this error:
local:
Data failed to compile:
----------
Rendering SLS "base:postfix.test" failed: Jinja syntax error: expected token ',', got 'float'; line 29
---
[...]
- sls: openldap
- sls: openldap.diamond
- sls: openldap.nrpe
{%- endcall %}
{{ fail2ban_regex_test('postfix', tag='postfix/smtpd[20228]', message="NOQUEUE: reject: RCPT from sender.com["5.6.7.8"]: 554 5.7.1 <us...@example.com>: Recipie
nt address rejected: Access denied; from=<us...@sender.com> to=<us...@example.com> proto=ESMTP helo=<mg01d1.sender.com>") }} <======================
If I tried to escape the double quote with a backslash:
... message="NOQUEUE: reject: RCPT from sender.com[\"5.6.7.8\"] ...
then I got another error:
local:
Data failed to compile:
----------
Rendering SLS postfix.test failed, render error: while parsing a block mapping
in "<unicode string>", line 84, column 7:
- args: "postfix/smtpd[20228] \"NO ...
^
expected <block end>, but found '<scalar>'
in "<unicode string>", line 84, column 76:
... : reject: RCPT from sender.com["5.6.7.8"]: 554 5.7.1 <user@examp ...
How to handle both cases?