Skip to main content

apache2 configuration file parser and query tool

Project description

a2conf is utility and python module to work with apache2 config files.

For all examples we will use file example.conf which is available examples/example.conf. Use export PYTHONPATH=. to use module if it's not installed. utility


Just smart grep

$ bin/a2conf examples/example.conf --cmd ServerName ServerAlias

$ bin/a2conf examples/example.conf --cmd SSLCertificateFile
SSLCertificateFile /etc/letsencrypt/live/

Only arguments:

# All arguments (including duplicates)
$ bin/a2conf examples/example.conf --cmd ServerName ServerAlias --args

# Only unique arguments
$ bin/a2conf examples/example.conf --cmd ServerName ServerAlias --uargs


# Only SSL hosts. Note: listed
$ bin/a2conf examples/example.conf --cmd ServerName ServerAlias --uargs --filter sslengine on

# Inverted filtering, hosts without SSLEngine on. Note: not listed
$ bin/a2conf examples/example.conf --cmd ServerName ServerAlias --uargs --filter sslengine on --neg

Per-vhost info:

# show documentroot for virtualhosts
$ bin/a2conf examples/example.conf  --cmd servername serveralias --uargs --vhost '{vhostargs} {servername} {documentroot}'
*:80 /var/www/example
*:443 /var/www/example

# ... only for virtualhosts with SSLEngine On
$ bin/a2conf examples/example.conf  --cmd servername serveralias --uargs --vhost '{vhostargs} {servername} {documentroot}' --filter sslengine on
*:443 /var/www/example

# What certfile we use for ?
$ bin/a2conf examples/example.conf --vhost '{servername} {sslcertificatefile}' --filter ServerName,ServerAlias /etc/letsencrypt/live/

# What certfile we use for (more good-style error-prone approach) ?
$ bin/a2conf examples/example.conf --vhost '{servername} {sslcertificatefile}' --filter ServerName,ServerAlias  --undef _skip /etc/letsencrypt/live/

You can get list of all available tokens for --vhost option in verbose mode (-v option).

Node class

Properties and methods

raw - text line as-is, with all spaces, tabs and with comments

cmd - cmd ('ServerName') without args or None (if section)

section - section (e.g. 'VirtualHost')

args - one text line args to cmd or section. for vhost args could be '*:80', for ServerAlias: ''

name - name of node. cmd if node has cmd, or section name (in brackets) if this is section. e.g. 'ServerName' or '<VirtualHost>'

content - list of child nodes (possible empty). For container sections (VirtualHost) attribute content is list of children. For usual commands (e.g. ServerName) - empty list.


__init__(self, read=filename, raw=None, parent=None, name=None, path=None, line=None, includes=True) - In most cases you should not need to use any parameters here except includes and read. read is apache config filename to read. Use includes=False if you want read_file method to ignore Include* directives.

children(name=None, recursive=None) - Main query method, returns generator for all children nodes (e.g. for VirtualHost node). Generator is empty if no children. If name specified, generator will return only nodes with this name (e.g. 'servername' or '<VirtualHost>'). If recursive is On, generator will return nested nodes too (e.g. what is inside <IfModule> or <Directory> settings). To get just one first element use next(node.children('ServerName')). It will raise StopIteration if node has no such children elements.

first(name, recursive=None) - wrapper for children(). Returns only first element or None. Not raising exceptions.

read_file(filename) - Reads apache config. Called automatically from __init__ if you specified read argument.

dump(fh=sys.stdout, depth=0) - dump loaded config in unified format (indented). if fh not specified, just dumps to stdout()

write_file(filename) - opens file for writing and dump() to this file.


Just dump apache config

examples/ just loads config and dumps its structure (without comments) as JSON:

#!/usr/bin/env python3
import sys
import a2conf
import json

root = a2conf.Node(sys.argv[1])

def section_dump(node):
    data = dict()

    for ch in node.children():
        if ch.section and not ch.section.startswith('/'):
            if ch.args:
                key = ch.section + ' ' + ch.args
                key = ch.section
            data[key] = section_dump(ch)
        elif ch.cmd:
            data[ch.cmd] = ch.args
    return data

data = section_dump(root)
print(json.dumps(data, indent=4))


$ examples/ examples/example.conf
    "VirtualHost *:80": {
        "DocumentRoot": "/var/www/example",
        "ServerName": "",
        "ServerAlias": "",
        "DirectoryIndex": "index.html index.htm default.htm index.php",
        "Options": "-Indexes +FollowSymLinks"
    "VirtualHost *:443": {
        "DocumentRoot": "/var/www/example",
        "ServerName": "",
        "ServerAlias": "",
        "DirectoryIndex": "index.html index.htm default.htm index.php",
        "Options": "-Indexes +FollowSymLinks",
        "SSLEngine": "On",
        "SSLCertificateFile": "/etc/letsencrypt/live/",
        "SSLCertificateKeyFile": "/etc/letsencrypt/live/",
        "SSLCertificateChainFile": "/etc/letsencrypt/live/"

Note - this is short example just for demo, it's not very good for production: if virtualhost has more then one directive (e.g. ServerAlias, RewriteRule, RewriteCond), only last one will be used.


examples/ print all SSL sites from config:

#!/usr/bin/env python3
import sys
import a2conf
root = a2conf.Node(sys.argv[1])

for vhost in root.children('<VirtualHost>'):
    servername = vhost.first('servername').args # One query method, via first(). Not much fail-safe but short.

        ssl_option = next(vhost.children('sslengine')).args # Other query method, via children()
        if ssl_option.lower() == 'on':
            print("{} has SSL enabled".format(servername))
    except StopIteration:
        # No SSL Engine directive in this vhost


$ examples/ examples/example.conf has SSL enabled

Replace and delete

examples/ disables SSLEngine directive:

#!/usr/bin/env python3
import sys
import a2conf
root = a2conf.Node(sys.argv[1])

for vhost in root.children('<VirtualHost>'):
    if vhost.first('sslengine'):
        vhost.delete() # Delete SSL vhost
        # Modify DocumentRoot
        vhost.first('DocumentRoot').args = '/var/www/example2'
        vhost.first('DocumentRoot').suffix = '# New DocumentRoot!'
        # Delete ServerAlias



$ examples/ examples/example.conf
# Example config file for a2conf
<VirtualHost *:80>
    # Non-ssl site
    DocumentRoot /var/www/example2 # New DocumentRoot!
    ServerName # .... OUR TEST SITE ....
    DirectoryIndex index.html index.htm default.htm index.php
    Options -Indexes +FollowSymLinks

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for a2conf, version 0.1.15
Filename, size File type Python version Upload date Hashes
Filename, size a2conf-0.1.15.tar.gz (13.6 kB) File type Source Python version None Upload date Hashes View hashes

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page