Exim 在 exim.conf 中获取随机凭证
Exim getting random credential in exim.conf
我一直在尝试获取 perl 子例程值和替换以从 exim.conf 中的 randomips 子例程中获取所需的字符串部分。但是,当我使用字符串替换时,出现如下错误:
Here is what I am trying to achieve
我正在尝试用冒号拆分字符串并获得第一次出现的 "interface"。我将使用第二次出现作为“helo_data.
exim.pl
sub randomhosts {
@inet = ("x.x.x.1:hostname1.domain.com","x.x.x.2:hostname2.domain.com","x.x.x.3:hostname3.domain.com"
);
return $inet[int rand($#inet+1)];
}
exim.conf
dkim_remote_smtp:
driver = smtp
interface = "${perl{randomhosts}%:*}"
helo_data = "${sender_address_domain}"
我得到的错误如下:
"failed to expand "interface" option for dkim_remote_smtp transport: missing '}' after 'perl'".
大概是语法。
有帮助吗?
首先,我想说明一下,我没有使用过 exim,所以我不能说出您到底想做什么以及为什么要这样做。
在您发布的 link 中,一个名为 'randinet' 的方法被添加到 exim.pl 并且 exim.conf 中的接口行被替换为
interface = "${perl{randinet}}"
您已经实现了一个'randomhosts'方法,并将接口行替换为
interface = "${perl{randomhosts}%:*}"
现在解析器抱怨找不到右括号。这可能是由于您可以随意添加符号,但解析器没有忽略的自由。
我建议你试试
interface = "${perl{randomhosts}}"
您试图复制的代码是由不太了解 Perl 的人编写的。它包括这一行:
return $inet[int rand($#inet+1)];
Perl 程序员会这样写
return $inet[rand @inet];
我认为这里有几个问题 - 一个与您的 Exim 语法有关,另一个与您的 Perl 语法有关。
Exim 给你这个错误:
failed to expand "interface" option for dkim_remote_smtp transport: missing '}' after 'perl'
我对从 Exim 调用 Perl 一无所知,但 this page 提到了一种语法,如 ${perl{foo}}
(类似于您正在从中复制的页面中使用的语法)和一个像 ${perl{foo}{argument}}
调用子例程并向其传递参数。它没有提到像你这样的语法:
${perl{randomhosts}%:*}
我不确定您是从哪里获得该语法的,但这似乎是导致您出现第一个错误的原因。
在评论中,你说
I am stying to get first part of string before colon for each random array value for "interface" and part after colon for "helo_data"
在我看来,Exim 不支持此要求。您需要调用该函数两次才能获得所需的两条信息。您也许可以在 Perl 中使用 state
变量之类的东西来执行此操作 - 但它会比您当前拥有的代码复杂得多。
其次,您的 Perl 代码存在语法错误,因此即使 Exim 能够调用您的代码,它也无法正常工作。
您正在复制的代码设置 @inet
如下:
@inet = ("x.x.x.1", "x.x.x.2", "x.x.x.3", "x.x.x.4");
你的等效代码是这样的:
@inet = (
"x.x.x.1:hostname1.domain.com",
"x.x.x.2:hostname2.domain.com,
x.x.x.3:hostname3.domain.com
);
我重新格式化了它,使问题更加明显。您缺少数组元素周围的许多引号。 (注:我看到在我写这个答案的时候,你已经修复了。)
更新: 好的,这里有一些代码可以放入 exim.pl
中,它可以满足您的需求。
use feature qw[state];
sub randomhosts {
state $current;
my @inet = (
"x.x.x.1:hostname1.domain.com",
"x.x.x.2:hostname2.domain.com",
"x.x.x.3:hostname3.domain.com"
);
if ($_[0] eq 'generate') {
shift;
@{$current}{qw[ip host]} = split /:/, $inet[rand @inet];
}
return $current->{$_[0]};
}
如果它的第一个参数是 'generate',它会生成一个新的 ip/host 对。然后它将 return 来自生成的对的主机名或 ip 地址。我想你可以像这样从你的 Exim 配置文件中调用它:
dkim_remote_smtp:
driver = smtp
interface = "${perl{randomhosts}{generate}{ip}}"
helo_data = "${perl{randomhosts}{host}}"
但我不是 Exim 专家,因此语法可能需要调整。
我一直在尝试获取 perl 子例程值和替换以从 exim.conf 中的 randomips 子例程中获取所需的字符串部分。但是,当我使用字符串替换时,出现如下错误:
Here is what I am trying to achieve
我正在尝试用冒号拆分字符串并获得第一次出现的 "interface"。我将使用第二次出现作为“helo_data.
exim.pl
sub randomhosts {
@inet = ("x.x.x.1:hostname1.domain.com","x.x.x.2:hostname2.domain.com","x.x.x.3:hostname3.domain.com"
);
return $inet[int rand($#inet+1)];
}
exim.conf
dkim_remote_smtp:
driver = smtp
interface = "${perl{randomhosts}%:*}"
helo_data = "${sender_address_domain}"
我得到的错误如下:
"failed to expand "interface" option for dkim_remote_smtp transport: missing '}' after 'perl'".
大概是语法。
有帮助吗?
首先,我想说明一下,我没有使用过 exim,所以我不能说出您到底想做什么以及为什么要这样做。
在您发布的 link 中,一个名为 'randinet' 的方法被添加到 exim.pl 并且 exim.conf 中的接口行被替换为
interface = "${perl{randinet}}"
您已经实现了一个'randomhosts'方法,并将接口行替换为
interface = "${perl{randomhosts}%:*}"
现在解析器抱怨找不到右括号。这可能是由于您可以随意添加符号,但解析器没有忽略的自由。
我建议你试试
interface = "${perl{randomhosts}}"
您试图复制的代码是由不太了解 Perl 的人编写的。它包括这一行:
return $inet[int rand($#inet+1)];
Perl 程序员会这样写
return $inet[rand @inet];
我认为这里有几个问题 - 一个与您的 Exim 语法有关,另一个与您的 Perl 语法有关。
Exim 给你这个错误:
failed to expand "interface" option for dkim_remote_smtp transport: missing '}' after 'perl'
我对从 Exim 调用 Perl 一无所知,但 this page 提到了一种语法,如 ${perl{foo}}
(类似于您正在从中复制的页面中使用的语法)和一个像 ${perl{foo}{argument}}
调用子例程并向其传递参数。它没有提到像你这样的语法:
${perl{randomhosts}%:*}
我不确定您是从哪里获得该语法的,但这似乎是导致您出现第一个错误的原因。
在评论中,你说
I am stying to get first part of string before colon for each random array value for "interface" and part after colon for "helo_data"
在我看来,Exim 不支持此要求。您需要调用该函数两次才能获得所需的两条信息。您也许可以在 Perl 中使用 state
变量之类的东西来执行此操作 - 但它会比您当前拥有的代码复杂得多。
其次,您的 Perl 代码存在语法错误,因此即使 Exim 能够调用您的代码,它也无法正常工作。
您正在复制的代码设置 @inet
如下:
@inet = ("x.x.x.1", "x.x.x.2", "x.x.x.3", "x.x.x.4");
你的等效代码是这样的:
@inet = (
"x.x.x.1:hostname1.domain.com",
"x.x.x.2:hostname2.domain.com,
x.x.x.3:hostname3.domain.com
);
我重新格式化了它,使问题更加明显。您缺少数组元素周围的许多引号。 (注:我看到在我写这个答案的时候,你已经修复了。)
更新: 好的,这里有一些代码可以放入 exim.pl
中,它可以满足您的需求。
use feature qw[state];
sub randomhosts {
state $current;
my @inet = (
"x.x.x.1:hostname1.domain.com",
"x.x.x.2:hostname2.domain.com",
"x.x.x.3:hostname3.domain.com"
);
if ($_[0] eq 'generate') {
shift;
@{$current}{qw[ip host]} = split /:/, $inet[rand @inet];
}
return $current->{$_[0]};
}
如果它的第一个参数是 'generate',它会生成一个新的 ip/host 对。然后它将 return 来自生成的对的主机名或 ip 地址。我想你可以像这样从你的 Exim 配置文件中调用它:
dkim_remote_smtp:
driver = smtp
interface = "${perl{randomhosts}{generate}{ip}}"
helo_data = "${perl{randomhosts}{host}}"
但我不是 Exim 专家,因此语法可能需要调整。