我有一个使用logger
来模拟某些“虚假”登录的脚本:
#!/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
在宏中调用:
fake_{{ formula }}_login:
cmd:
- script
- source: salt://fail2ban/fake_login.jinja2
- template: jinja
- args: "{{ tag|default(formula) }} '{{ message }}'"
- require:
- sls: bash
- sls: fail2ban
事情是{{message}}可以包含单/双引号,空格,方括号,...... 根据cmd.script文档,要传递包含空格的字符串,我们必须对其进行双引号。 但如果我有这样的事情:
{{ fail2ban_regex_test('mysql', tag='mysqld', message="150114 3:40:50 [Warning] Access denied for user 'root'@'5.6.7.8' (using password: YES)") }}
它将被记录到syslog中而没有围绕用户/主机的单引号,只是:
mysqld: 150114 3:40:50 [Warning] Access denied for user root@5.6.7.8 (using password: YES)
使fail2ban无法识别,因为它与过滤器正则表达式不匹配。
我可以将单引号更改为双引号并使用反斜杠转义:
fake_{{ formula }}_login:
cmd:
- script
- source: salt://fail2ban/fake_login.jinja2
- template:
jinja
- args: "{{ tag|default(formula) }} \"{{ message|safe }}\""
- require:
- sls: bash
- sls: fail2ban
当消息只包含单引号时,它处理上述情况。
但如果它包含双引号:
{{ 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>") }}
我收到了这个错误:
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>") }} <======================
如果我试图用反斜杠来逃避双引号:
... message="NOQUEUE: reject: RCPT from sender.com[\"5.6.7.8\"] ...
然后我又出了一个错误:
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 ...
如何处理这两种情况?
答案 0 :(得分:3)
saltstack
扩展jinja
个内置过滤器,其中包含一些custom filters:
yaml_dquote
:将字符串序列化为正确转义的YAML双引号字符串。yaml_encode
:将单个对象序列化为YAML标量,并具有转义特殊字符所需的任何处理。类似的东西:
{%- set foo = 7.7 %}
{%- set bar = none %}
{%- set baz = true %}
{%- set zap = 'The word of the day is "salty".' %}
{%- set zip = '"The quick brown fox . . ."' %}
foo: {{ foo|yaml_encode }}
bar: {{ bar|yaml_encode }}
baz: {{ baz|yaml_encode }}
zap: {{ zap|yaml_encode }}
zip: {{ zip|yaml_dquote }}
给你:
foo: 7.7
bar: null
baz: true
zap: "The word of the day is \"salty\"."
zip: "\"The quick brown fox . . .\""
使用任意字符串,即使{{ var|yaml_encode|yaml_decode }}
也可能无效。如果您可以对字符串进行编码然后在脚本中对其进行解码,那就更好了。
答案 1 :(得分:0)
您有消息变量,可以包含特殊字符。
- args: "{{ tag|default(formula) }} '{{ message }}'"
我的理解是你的bash脚本有两个参数:
#!/bin/bash
tag=$1
message=$2
echo "$message" #some use of message
您正在使用cmd.script调用脚本。
而不是这样,您可以更改脚本,如下所示:
- args: "{{ tag|default(formula) }}"
- stdin: "{{ message }}\n"
&安培; bash脚本:
#!/bin/bash
tag=$1
read message
echo "$message" #some use of message