skip to Main Content

I need to manage domain names (fqdn), printing all of them somewhere, possibly in a file csv. All infos are in apache conf files, I need to associate all the domain name with ip and port.
This is the sample file

<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>

These are the domains (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

I need this output:

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

What I tried:

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}'

Now I can print all the fqdn.
How can I add the correct ip address an the port?

3

Answers


  1. Here’s a suggestion:

    (file cmd.awk)

    BEGIN { 
      FS = "[ <>:]"
      OFS = ","
      }
    
    /^<VirtualHost /    { IP = $3; Port = $4 }
    /^ServerName /      { Names = $2 }
    /^ServerAlias /     { sub(/ServerAlias /, "", $0); Names = Names " " $0 }
    /^</VirtualHost>$/ { $0 = Names; for(i = 1; i <= NF; ++ i) { print $i, IP, Port } }
    

    awk -f cmd.awk sample.input should produce the desired output:

    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
    

    Hope that helps.

    Login or Signup to reply.
  2. Provided that @Grobu’s answer is far more elegant (and probably more efficient either), also the following should to the trick:

    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
    

    …where:
    1st line –> use grep to extract only VirtualHost, ServerName and ServerAlias lines. It produces:

    <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
    

    2nd line –> use sed to evaluate a line by setting a label (:a;) on the line, appending the next one with a ‘n’ (N;), found replace "nServerAlias " with a simple space (s/nServerAlias / / ;), and finally restart the evaluation by jumping back to the label a (ba). It produces:

    <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
    

    3rd line –> Delete every ServerName and VirtualHost occurrence (s/(<VirtualHost |ServerName )//), replace ‘:’ with ‘,’ and delete the final ‘>’ (s/:(.*)>/,1/). It produces:

    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
    

    4th line –> use sed command to replace every space with a new line (s/ /n/g), in order to obtain different server name/alias on different lines. It produces:

    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
    

    5th line –> use a while-do loop to iterate every line (while read line; do ...done), temporary storing when matching a line with ip and port (the only lines that contain a comma: if [[ "$line" =~ .+,.+ ]]; then address=$line;) without printing it, and otherwise printing every other line by concatenating the stored ip and port (else echo "$line,$address";). It finally produces:

    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
    
    Login or Signup to reply.
  3. Using any 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
    

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search