Назад | Перейти на главную страницу

Есть ли способ поделиться или повторно использовать конфигурации Apache

У меня следующая структура каталогов на моем сервере Apache

/var/www/domain.com/
    index.html
    site-1/
    site-2/
    .
    .
    .
    site-N/

Каждый сайт использует следующий файл конфигурации, в котором переменные «порт», «сайт» и «концентратор» являются единственными значениями, которые изменяются.

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        # DOMAIN CONFIGURATION
        Define domain domain.dev

        ServerName ${domain}
        ServerAlias www.${domain}
        DocumentRoot /var/www/${domain}

        <Directory "/var/www/${domain}">
            AuthType Basic
            AuthName "${domain} Authentication"
            AuthUserFile /etc/apache2/.htpasswd
            Require valid-user
            <Files "manifest.json">
                Require all granted
            </Files>
        </Directory>

        SSLEngine on
        RewriteEngine on
        SSLProxyEngine on
        SSLProxyVerify none
        SSLProxyCheckPeerCN off
        SSLProxyCheckPeerName off
        SSLProxyCheckPeerExpire off

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        SSLCertificateFile /etc/letsencrypt/live/${domain}/cert.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/${domain}/privkey.pem
        SSLCertificateChainFile /etc/letsencrypt/live/${domain}/fullchain.pem

        <FilesMatch "\.(cgi|shtml|phtml|php)$">
            SSLOptions +StdEnvVars
        </FilesMatch>

        <Directory /usr/lib/cgi-bin>
            SSLOptions +StdEnvVars
        </Directory>

        # SITE CONFIGURATION
        Define site site-1
        Define port 5001
        Define protocol https
        Define hub site-1-hub

        ProxyPassMatch "^/${site}/api/(.+)" "${protocol}://localhost:${port}/api/$1"
        ProxyPassReverse "/" "${protocol}://localhost:${port}/"

        ProxyPassMatch "^/${site}/${hub}/(.+)" "${protocol}://localhost:${port}/${hub}/$1"
        ProxyPassReverse "/" "${protocol}://localhost:${port}/${hub}"

        RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
        RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
        RewriteRule "^/${site}/(.+)" "wss://localhost:${port}/$1" [P]
    </VirtualHost>

Есть ли способ совместного использования, повторного использования или централизации разделов «Конфигурация домена» и «Конфигурация сайта», чтобы мне не приходилось дублировать конфигурации на нескольких сайтах в одном домене? Если да, то я смогу внести изменения в одну общую конфигурацию, которая будет применяться к любому домену или сайту, использующему ее.

apache2ctl -S вывод

        VirtualHost configuration:
    *:80                   localhost (/etc/apache2/sites-enabled/000-default.conf:1)
    ServerRoot: "/etc/apache2"
    Main DocumentRoot: "/var/www/html"
    Main ErrorLog: "/var/log/apache2/error.log"
    Mutex ssl-stapling: using_defaults
    Mutex proxy: using_defaults
    Mutex ssl-cache: using_defaults
    Mutex default: dir="/var/run/apache2/" mechanism=default 
    Mutex watchdog-callback: using_defaults
    Mutex rewrite-map: using_defaults
    Mutex ssl-stapling-refresh: using_defaults
    PidFile: "/var/run/apache2/apache2.pid"
    Define: DUMP_VHOSTS
    Define: DUMP_RUN_CFG
    User: name="www-data" id=33
    Group: name="www-data" id=33

Вот рабочая реализация решения, предоставленного Эса Йокинен (Обратите внимание mod_macro модуль необходимо включить, запустив sudo a2enmod macro в командной строке)

/etc/apache2/sites-available/domain.dev.conf содержимое:

<Macro Domain $domain>
    ServerName $domain
    ServerAlias www.$domain
    DocumentRoot /var/www/$domain

    # Basic authentication
    <Directory "/var/www/$domain">
        AuthType Basic
        AuthName "$domain Authentication"
        AuthUserFile /etc/apache2/.htpasswd
        Require valid-user
        <Files "manifest.json">
            Require all granted
        </Files>
    </Directory>

    RewriteEngine on
    
    SSLEngine on
    SSLProxyEngine on
    SSLProxyVerify none
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerName off
    SSLProxyCheckPeerExpire off

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    SSLCertificateFile /etc/letsencrypt/live/$domain/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/$domain/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/$domain/fullchain.pem

    <FilesMatch "\.(cgi|shtml|phtml|php)$">
        SSLOptions +StdEnvVars
    </FilesMatch>

    <Directory /usr/lib/cgi-bin>
        SSLOptions +StdEnvVars
    </Directory>
</Macro>

<Macro Site $site $port $protocol $hub>
    ProxyPassMatch "^/$site/api/(.+)" "$protocol://localhost:$port/api/$1"
    ProxyPassReverse "/" "$protocol://localhost:$port/"

    ProxyPassMatch "^/$site/$hub/(.+)" "$protocol://localhost:$port/$hub/$1"
    ProxyPassReverse "/" "$protocol://localhost:$port/$hub"

    RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
    RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
    RewriteRule "^/$site/(.+)" "wss://localhost:$port/$1" [P]
</Macro>

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        Use Domain domain.dev

        Use Site site-1 5003 https site-1-hub
        Use Site site-2 5004 https site-2-hub
        .
        .
        .
        Use Site site-N 500N https site-N-hub
    </VirtualHost>
</IfModule>

Модуль Apache mod_macro может быть именно тем, что вы ищете. Вы можете определить макрос:

<Macro MyProxySites $site $port $protocol $hub>
    ProxyPassMatch "^/$site/api/(.+)" "$protocol://localhost:$port/api/$1"
    ProxyPassReverse "/" "$protocol://localhost:$port/"

    ProxyPassMatch "^/$site/$hub/(.+)" "$protocol://localhost:$port/$hub/$1"
    ProxyPassReverse "/" "$protocol://localhost:$port/$hub"

    RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
    RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
    RewriteRule "^/$site/(.+)" "wss://localhost:$port/$1" [P]
</Macro>

А затем несколько раз используйте его в своей конфигурации, например

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        ServerName example.com
        ServerAlias www.example.com
        DocumentRoot /var/www/example.com

        # . . .
        Use MyProxySites site-1 5001 https site-1-hub
        Use MyProxySites site-2 5002 https site-2-hub
    </VirtualHost>
    <VirtualHost *:443>
        ServerName example.net
        ServerAlias www.example.net
        DocumentRoot /var/www/example.net

        # . . .
        Use MyProxySites site-3 5003 https site-3-hub
        Use MyProxySites site-4 5004 https site-4-hub
    </VirtualHost>
</IfModule>

Из вашего вопроса трудно сказать вашу точную цель, но если домен меняется для каждого сайта, а домен имеет только один прокси-сервер, вы также можете встроить его прямо в макрос:

<Macro MyProxySites $domain $site $port $protocol $hub>
    <VirtualHost *:443>
        ServerName $domain
        ServerAlias www.$domain
        DocumentRoot /var/www/$domain

        ProxyPassMatch "^/$site/api/(.+)" "$protocol://localhost:$port/api/$1"
        ProxyPassReverse "/" "$protocol://localhost:$port/"

        ProxyPassMatch "^/$site/$hub/(.+)" "$protocol://localhost:$port/$hub/$1"
        ProxyPassReverse "/" "$protocol://localhost:$port/$hub"

        RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
        RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
        RewriteRule "^/$site/(.+)" "wss://localhost:$port/$1" [P]
    </VirtualHost>
</Macro>

Use MyProxySites example.com site-1 5001 https site-1-hub
Use MyProxySites example.net site-2 5002 https site-2-hub
Use MyProxySites example.org site-3 5003 https site-3-hub