Apache 管理:从 Apache 配置文件中提取主机名和虚拟主机 IP 地址

问题描述 投票:0回答:2

我需要管理域名(fqdn),将所有域名打印在某个地方,可能在文件 csv 中。所有信息都在apacheconf文件中,我需要将所有域名与ip和端口相关联。 这是示例文件。您可以在服务器名称和服务器别名中使用相同的 FQDN,两个参数之间可能有一些尾随空格,一些注释 (#)。这里是示例文件:

<VirtualHost 10.11.12.21:80>
ServerName host-6.mydomain.example.org
CustomLog "|/usr/sbin/rotatelogs /etc/httpd/logs/host-6.mydomain.example.org_access_log 86400" customssl
</VirtualHost>
<VirtualHost 10.11.12.21:80>
ServerName www.example.com
ServerAlias www.example.com
CustomLog "|/usr/sbin/rotatelogs /etc/httpd/logs/www.example.com/www.example.com_access_log 86400" customssl
</VirtualHost>
<VirtualHost 10.11.12.21:80>
ServerName gimbo.customexample.org
CustomLog "|/usr/sbin/rotatelogs /etc/httpd/logs/gimbo.customexample.org/gimbo.customexample.org_access_log 86400" customssl
</VirtualHost>
<VirtualHost 10.11.12.22:80>
ServerName host-6.mydomain.example.org
CustomLog "|/usr/sbin/rotatelogs /etc/httpd/logs/host-6.mydomain.example.org_access_log 86400" customssl
</VirtualHost>
<VirtualHost 10.11.12.22:443>
ServerName host-6.mydomain.example.org
CustomLog "|/usr/sbin/rotatelogs /etc/httpd/logs/host-6.mydomain.example.org_ssl_access_log 86400" customssl
IncludeOptional conf.d/star_mydomain_example_org.cnf
</VirtualHost>
<VirtualHost 10.11.12.22:8080>
ServerName host-6.mydomain.example.org
ServerAlias www.example.org www.pollo.biz www.pollone.mondo
CustomLog "|/usr/sbin/rotatelogs /etc/httpd/logs/host-6.mydomain.example.org_access_log 86400" customssl
</VirtualHost>
<VirtualHost 10.11.12.22:80>
ServerName host-7.mydomain.example.org
CustomLog "|/usr/sbin/rotatelogs /etc/httpd/logs/host-7.mydomain.example.org/host-7.mydomain.example.org_access_log 86400" customssl
</VirtualHost>
<VirtualHost 10.11.12.22:443>
ServerName host-7.mydomain.example.org
ErrorLog "|/usr/sbin/rotatelogs /etc/httpd/logs/host-7.mydomain.example.org/host-7.mydomain.example.org_ssl_error_log 86400"
CustomLog "|/usr/sbin/rotatelogs /etc/httpd/logs/host-7.mydomain.example.org/host-7.mydomain.example.org_ssl_access_log 86400" customssl
IncludeOptional conf.d/star_mydomain_example_org.cnf
</VirtualHost>

这些是域名 (fqdn)

gimbo.customexample.org
host-6.mydomain.example.org
host-7.mydomain.example.org
www.example.biz
www.example.com
www.example.org
www.pollo.biz
www.pollone.mondo

我需要这个输出:

host-6.mydomain.example.org,10.11.12.21,80
www.example.com,10.11.12.21,80
www.example.com,10.11.12.21,80
www.example.biz,10.11.12.21,80
gimbo.customexample.org,10.11.12.21,80
host-6.mydomain.example.org,10.11.12.22,80
host-6.mydomain.example.org,10.11.12.22,443
host-6.mydomain.example.org,10.11.12.22,8080
www.example.org,10.11.12.22,8080
www.pollo.biz,10.11.12.22,8080
www.pollone.mondo,10.11.12.22,8080
host-7.mydomain.example.org,10.11.12.22,80
host-7.mydomain.example.org,10.11.12.22,443

我尝试过的:

awk -v n=2 -e '/^\s*Server(Name|Alias)/ { for (i=n; i<=NF; i++) printf "%s%s",   $i, (i<NF ? OFS : ORS)}' $1 | awk -v RS='[\n ]' '{print}'

现在我可以打印所有的 FQDN。 如何添加正确的 IP 地址和端口?

shell apache awk
2个回答
2
投票

使用任何 awk:

$ cat tst.awk
BEGIN { OFS="," }

$1 == "<VirtualHost" {
    split($2,tmp,/:/)
    ip   = tmp[1]
    port = tmp[2]+0
}

$1 ~ /^Server(Name|Alias)$/ {
    for ( i=2; i<=NF; i++ ) {
        fqdns[$i]
    }
}

$1 == "</VirtualHost>" {
    for ( fqdn in fqdns ) {
        print fqdn, ip, port
        delete fqdns[fqdn]
    }
}

$ awk -f tst.awk file
host-6.mydomain.example.org,10.11.12.21,80
www.example.com,10.11.12.21,80
gimbo.customexample.org,10.11.12.21,80
host-6.mydomain.example.org,10.11.12.22,80
host-6.mydomain.example.org,10.11.12.22,443
host-6.mydomain.example.org,10.11.12.22,8080
www.pollo.biz,10.11.12.22,8080
www.pollone.mondo,10.11.12.22,8080
www.example.org,10.11.12.22,8080
host-7.mydomain.example.org,10.11.12.22,80
host-7.mydomain.example.org,10.11.12.22,443

0
投票

假设@Grobu 的答案更加优雅(而且可能也更有效),以下也应该达到目的:

grep "\(<VirtualHost \|ServerName \|ServerAlias \)" sample.input \
| sed ':a;N;s/\nServerAlias / / ; ba' \
| sed 's/\(<VirtualHost \|ServerName \)//;s/:\(.*\)>/,\1/' \
| sed 's/ /\n/g' \
| while read line; do if [[ "$line" =~ .+,.+ ]]; then address=$line; else echo "$line,$address"; fi; done

...哪里:
第 1 行 --> 使用 grep 仅提取 VirtualHost、ServerName 和 ServerAlias 行。它产生:

<VirtualHost 10.11.12.21:80>
ServerName host-6.mydomain.example.org
<VirtualHost 10.11.12.21:80>
ServerName www.example.com
ServerAlias www.example.com
<VirtualHost 10.11.12.21:80>
ServerName gimbo.customexample.org
<VirtualHost 10.11.12.22:80>
ServerName host-6.mydomain.example.org
<VirtualHost 10.11.12.22:443>
ServerName host-6.mydomain.example.org
<VirtualHost 10.11.12.22:8080>
ServerName host-6.mydomain.example.org
ServerAlias www.example.org www.pollo.biz www.pollone.mondo
<VirtualHost 10.11.12.22:80>
ServerName host-7.mydomain.example.org
<VirtualHost 10.11.12.22:443>
ServerName host-7.mydomain.example.org

第 2 行 --> 使用 sed 通过在该行上设置标签 (

:a;
) 来评估一行,并在下一个标签后附加 ' '(
N;
),找到替换“ ServerAlias " 带有一个简单的空格 (
s/\nServerAlias / / ;
),最后通过跳回到标签 a (
ba
) 来重新启动评估。它会产生:

<VirtualHost 10.11.12.21:80>
ServerName host-6.mydomain.example.org
<VirtualHost 10.11.12.21:80>
ServerName www.example.com www.example.com
<VirtualHost 10.11.12.21:80>
ServerName gimbo.customexample.org
<VirtualHost 10.11.12.22:80>
ServerName host-6.mydomain.example.org
<VirtualHost 10.11.12.22:443>
ServerName host-6.mydomain.example.org
<VirtualHost 10.11.12.22:8080>
ServerName host-6.mydomain.example.org www.example.org www.pollo.biz www.pollone.mondo
<VirtualHost 10.11.12.22:80>
ServerName host-7.mydomain.example.org
<VirtualHost 10.11.12.22:443>
ServerName host-7.mydomain.example.org

第 3 行 --> 删除所有出现的 ServerName 和 VirtualHost (

s/\(<VirtualHost \|ServerName \)//
),将 ':' 替换为 ',',并删除最后的 '>' (
s/:\(.*\)>/,\1/
)。它产生:

10.11.12.21,80
host-6.mydomain.example.org
10.11.12.21,80
www.example.com www.example.com
10.11.12.21,80
gimbo.customexample.org
10.11.12.22,80
host-6.mydomain.example.org
10.11.12.22,443
host-6.mydomain.example.org
10.11.12.22,8080
host-6.mydomain.example.org www.example.org www.pollo.biz www.pollone.mondo
10.11.12.22,80
host-7.mydomain.example.org
10.11.12.22,443
host-7.mydomain.example.org

第 4 行 --> 使用 sed 命令将每个空格替换为新行(

s/ /\n/g
),以便在不同行上获取不同的服务器名称/别名。它产生:

10.11.12.21,80
host-6.mydomain.example.org
10.11.12.21,80
www.example.com
www.example.com
10.11.12.21,80
gimbo.customexample.org
10.11.12.22,80
host-6.mydomain.example.org
10.11.12.22,443
host-6.mydomain.example.org
10.11.12.22,8080
host-6.mydomain.example.org
www.example.org
www.pollo.biz
www.pollone.mondo
10.11.12.22,80
host-7.mydomain.example.org
10.11.12.22,443
host-7.mydomain.example.org

第 5 行 --> 使用 while-do 循环迭代每一行(

while read line; do ...done
),当将一行与 ip 和 port 匹配时临时存储(唯一包含逗号的行:
if [[ "$line" =~ .+,.+ ]]; then address=$line;
)而不打印它,否则通过连接存储的 ip 和端口来打印每隔一行 (
else echo "$line,$address";
)。最终产生:

host-6.mydomain.example.org,10.11.12.21,80
www.example.com,10.11.12.21,80
www.example.com,10.11.12.21,80
gimbo.customexample.org,10.11.12.21,80
host-6.mydomain.example.org,10.11.12.22,80
host-6.mydomain.example.org,10.11.12.22,443
host-6.mydomain.example.org,10.11.12.22,8080
www.example.org,10.11.12.22,8080
www.pollo.biz,10.11.12.22,8080
www.pollone.mondo,10.11.12.22,8080
host-7.mydomain.example.org,10.11.12.22,80
host-7.mydomain.example.org,10.11.12.22,443
© www.soinside.com 2019 - 2024. All rights reserved.