Анатомия безопасного конфигурационного файла apache2

Некоторые предложения

Итак, сначала я хочу предложить вам разбить ваши файлы конфигурации, а затем включить каждый сайт (и другие основные типы конфигурации) в конфигурацию основного сервера. Ваш файл конфигурации с общими настройками сервера будет называться apache2.confили иногда httpd.conf и обычно располагается в
/etc/apache2/ каталог. В этом основном каталоге конфигурации apache2 вы, вероятно, также увидите некоторые другие каталоги, которые позже будут включены из вашего основного файла конфигурации. Три, которые мы будем использовать сегодня, будут mods-available / mods-enabled, sites-available /sites-enabledа также conf-available / conf-enabled. Теперь вы действительно можете организовать все это так, как хотите, если вы все правильно включаете. Но я предлагаю использовать схему по умолчанию, так как большинство людей, а также документация придерживаются этой настройки.

Основной файл конфигурации

Теперь, когда это не так, мы собираемся взглянуть на текущую конфигурацию, если вы только что установили apache2 из своего менеджера пакетов, она будет выглядеть очень обобщенно, как это (за исключением большого количества документации закомментировано, я опущу):

Намекать: Вы можете задокументировать свою собственную конфигурацию, как вам нравится, добавив хэш «#” перед тем, что вы хотите напомнить себе или кому-то другому!

ServerRoot "/etc/apache2"
Mutex file:${APACHE_LOCK_DIR} default
PidFile ${APACHE_PID_FILE}
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
HostnameLookups Off
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf
Include ports.conf
<Directory />
  Options FollowSymLinks
  AllowOverride None
  Require all denied
</Directory>
<Directory /usr/share>
  AllowOverride None
  Require all granted
</Directory>
<Directory /var/www/>
  Options Indexes FollowSymLinks
  AllowOverride None
  Require all granted
</Directory>
AccessFileName .htaccess
<FilesMatch "^\.ht">
  Require all denied
</FilesMatch>
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
IncludeOptional conf-enabled/*.conf
IncludeOptional sites-enabled/*.conf

Большинство из этих вещей должны быть оставлены и могут быть без изменений.

Итак, первая строка ServerRoot "/etc/apache2" просто говорит нам, в каком каталоге будут размещены все наши настройки. Он никогда не должен иметь завершающую косую черту.

Наша первая функция типа безопасности — это User а также Group declerations, которые сообщают двоичному файлу apache2, какие привилегии запускать. Это важно, потому что если сервер делает получить pwnt, тогда злоумышленник не получит более высокие привилегии, чем те, которые перечислены здесь.

Предупреждение: НИКОГДА не устанавливайте ни один из них для пользователя root или пользователя своей личной учетной записи.

Следующие две важные директивы типа безопасности — это ErrorLog и LogLevel. Я бы порекомендовал оставить их без изменений, за исключением того, что если у вас возникли проблемы, вы можете изменить уровень журнала на любой от trace1 до trace8, а также отладку, информацию, уведомление, предупреждение, ошибку, крит, предупреждение, появление. Это даст вам некоторые результаты отладки. Будьте осторожны, чтобы не оставлять вывод отладки включенным в рабочей среде, это может привести к проблемам с производительностью под нагрузкой.

Ваши следующие три важные вещи — это ваш сингл Include файлы и ваши IncludeOptional каталоги, каждый с файлами для включения в свой первый уровень. Они будут важны позже.

Теперь единственный Directory директива, которую я оставляю на своих серверах prod:

<Directory />
  Options FollowSymLinks
  AllowOverride None
  Require all denied
</Directory>

Так что ни в коем случае нельзя получить доступ к корневому каталогу нашего сервера. Сначала мы говорим ему следовать каждой симлинке, а затем явно запрещаем чтение этого каталога любой клиентской стороной и не допускаем возможности переопределения .htaccess.

Затем мы также полностью запрещаем загрузку на стороне клиента любого файла, начинающегося с .ht. Это ссылка на .htaccess а также .htpasswdв случае, если они находятся где-либо, которые в настоящее время обслуживаются, и в случае .htaccessэто будет.

У вас также будут директивы LogFormat, которые сообщают серверу, как генерировать ваши error.log а также access.log. Если не указано иное, они появятся в /var/log/apache2/.

Теперь некоторые дополнения, ориентированные на безопасность

Я поделюсь несколько отредактированной версией одного из моих собственных apache2.conf файлы. Некоторые из этих вещей могут нуждаться в настройке для вашего предполагаемого варианта использования, пожалуйста, не просто копируйте/вставляйте их.

DefaultRuntimeDir ${APACHE_RUN_DIR}
PidFile ${APACHE_PID_FILE}
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
HostnameLookups Off
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf
IncludeOptional conf-enabled/*.conf
IncludeOptional sites-enabled/*.conf
Include ports.conf
SetEnv SERVER_ADMIN youremail@yoursite.com
SetEnv TZ America/New_York
DefaultLanguage en-US
LoadModule headers_module modules/mod_headers.so
Header always set X-XSS-Protection "1; mode=block"
Header always append X-Frame-Options deny
Header always set X-Content-Type-Options "nosniff"
Header always set Content-Security-Policy "default-src 'self' data: blob: cdn.jsdelivr.net;"
Header always set Content-Security-Policy "style-src 'self' *.google.com googleapis.com;"
Header always set Content-Security-Policy "script-src 'self' nonce-76dbe9426bd20a5ffbe536edc407958201af3a03 *.google.com;"
Header always set Content-Security-Policy "frame-src: 'self' feed.mikle.com;"
Header always set Permissions-Policy "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()"
Header always set Referrer-Policy "no-referrer-when-downgrade"
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure;SameSite=None
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
ServerSignature Off
ServerTokens Prod
AccessFileName .htaccess
TraceEnable Off
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" detailed
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
<Directory />
  Options +FollowSymLinks
  AllowOverride None
  Require all denied
</Directory>

<FilesMatch "^\.ht">
  Require all denied
</FilesMatch>

Примечание: Вы можете добавить следующие несколько вещей, о которых я говорю, к /etc/apache2/conf-enabled/security.confили держите их все в одном месте, если хотите!

Так что многое из этого то же самое с некоторыми незначительными изменениями, но я пройдусь по вещам, которые вы должны добавить.

Во-первых, в случае непредвиденных ошибок вы должны указать свой адрес электронной почты в конфигурации сервера, чтобы пользователь мог связаться с вами в случае сбоя службы. Мы делаем это с помощью SetEnv SERVER_ADMIN переменная среды сервера.

Мы также должны включить добавление и модификацию встроенных заголовков для следующих нескольких строк, мы сделаем это с помощьюLoadModule headers_module modules/mod_headers.so. В результате теперь мы можем установить такие вещи, как XSS-защита на стороне сервера, с помощью:Header always set X-XSS-Protection "1; mode=block" и его сопутствующие параметры: Header always append X-Frame-Options deny а такжеHeader always set X-Content-Type-Options "nosniff". Мы делаем это с помощью заголовков, потому что некоторые из них должны указывать нашим клиентам, веб-браузерам, как взаимодействовать с некоторыми данными, которыми мы делимся с ними.

Еще одна вещь, которую мы можем выполнить с добавлением заголовка, — это использование нашей CSP или политики безопасности контента, в основном направляющей через сервер то, что клиентский браузер может извлекать и использовать на странице из внешнего источника, и откуда конкретно он может это извлекать. Мы делаем это сHeader always set Content-Security-Policy. Если бы я сказал, что хотел бы иметь возможность запускать javascript, размещенный на внешнем сервере, с js.google.com или script.google.com, мы могли бы установить его следующим образом: Header always set Content-Security-Policy "script-src 'self' *.google.com;". Как видите, существуют разные типы для javascript, iframes, css и т. д.

Мы также можем установить наш заголовок Referrer-Policy, который важен в случае, если другие небезопасные веб-сайты выбирают, на какой странице наши клиенты были последними. Для моего использования я установил свой на no-referrer-when-downgrade, но вы также можете установить ряд других, в том числе: «без реферера», «без реферера при переходе на более раннюю версию», «того же происхождения», «происхождение», «строгое происхождение», «происхождение при- перекрестное происхождение», «строгое происхождение при перекрестном происхождении» и «небезопасный URL». У каждого свой темп, и вы можете прочитать больше о каждой политике конкретно здесь.

Наш Permissions-Policy header также должен быть установлен на большинстве современных веб-серверов. Это диктует, какие права наш сервер имеет для доступа к компьютеру клиентского браузера, например, к камере или их точному местоположению. Ваш сайт и то, для чего вы используете браузер, подскажут вам, какие разрешения вам нужны, поэтому здесь я отложу до хорошего разговора. Генератор политики разрешений Я нашел полезным, что может автоматически генерировать эту строку для вас без ошибок. Я предлагаю запрашивать только то, что вам действительно нужно, так как запрос слишком большого количества «неиспользуемых» разрешений — отличный способ отвернуть пользователя.

Одна классная вещь, которую мы можем сделать с Header edit директива делает такие вещи, как редактирование встроенного файла cookie перед его отправкой пользователю, так что, скажем, мы хотим настроить все файлы cookie на Httponly;Secure; мы бы использовали регулярное выражение: Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure; как улов.

Обычно я также удаляю доступ к небезопасным протоколам SSL при подключении к моему серверу. Нет ничего хуже, чем думать, что ваше соединение защищено, когда это не так. Вы можете сделать это, используя директиву SSLProtocol и настроив ее по своему усмотрению. Я поставил свой:SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 на всякий случай.

Важно убедиться, что наш теперь защищенный сервер не пропускает внутреннюю информацию о сервере, когда злоумышленник взламывает его, генерируя коды ошибок. Итак, теперь, когда наш сервер подтянут, мы должны установить TraceEnable Off, ServerSignature Off и наконец ServerTokens Prod. Теперь наши ошибки должны быть доступны для чтения и восприниматься конечным пользователем как ошибки, но при этом не будет утечки важной серверной информации, такой как IP-адреса и версии сервера. Для справки в будущем трассировку всегда следует отключать на рабочем сервере, подключенном к Интернету, поскольку это небезопасный метод HTTP.

Сайт

Теперь мы можем отправиться в /etc/apache2/sites-available и создайте свой сайт. Я предполагаю, что вы уже настроили SSL/HTTPS и работаете с вашим сайтом, будь то с LetsEncrypt или чем-то еще. Я также предполагаю, что у вас есть работающий сайт, по крайней мере, с главной страницей и подкаталогом с чем-то в нем.

Я покажу вам простую конфигурацию одного из моих сайтов с удаленными некоторыми более чувствительными вещами.

Итак, в /etc/apache2/sites-available У меня есть следующий файл с именем site.com-ssl.conf. Также должна быть символическая ссылка, связывающая этот файл с/etc/apache2/sites-enabled так что данные анализируются, а затем обслуживаются apache2.

<IfModule mod_ssl.c>
<VirtualHost *:443>
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
  ServerAdmin marshall@site.com
  DocumentRoot /var/www/site.com
  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined
  ServerName site.com
  ServerAlias site.com
  Include /etc/letsencrypt/options-ssl-apache.conf
  SSLCertificateFile /etc/letsencrypt/live/site.com/fullchain.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/site.com/privkey.pem
</VirtualHost>
</IfModule>
<Directory "/var/www/site.com/">
  Options -Indexes +FollowSymLinks -ExecCGI
  AllowOverride all
  Require all granted
  Header always set Access-Control-Allow-Origin "*"
  RewriteEngine on
  ErrorDocument 403 
  ErrorDocument 404 
  RewriteCond %{REQUEST_METHOD} !^(GET|HEAD|POST|OPTIONS)$ [NC]
  RewriteRule .? - [F,NS,L]
  RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ .+\ HTTP/(0\.9|1\.0|1\.1) [NC]
  RewriteRule .? - [F,NS,L]
</Directory>
<Location "/code/">
  AddType text/plain .txt .cpp .c .pl .sh .py
  Options +Indexes +FollowSymLinks -ExecCGI
  require all granted
  AllowOverride None
</Location>

Итак, как вы можете видеть, довольно общая установка apache2 с парой дополнений.

Вам понадобится DocumentRoot как минимум, указывая на самый нижний каталог, который вы хотели бы использовать для этого сайта.

Теги нашего каталога указывают на место на файловая система к которому мы хотели бы добавить прилагаемые директивы. Теги Location заключают в себе местоположение, которое_обслуживается_ веб-сервером, к которому мы хотели бы добавить директивы. Это важное различие.

Если мы не используем CGI (например, Perl или PHP) в этом каталоге, обязательно добавьте -ExecCGI к директиве Options. Вы также можете добавить или опустить Indexes, с плюсом или минусом, чтобы указать, хотим ли мы, чтобы список каталогов был в дочерних каталогах, или нет. Я оставляю это здесь.

Предполагая, что у нас есть модификации заголовков, мы можем иметь Header always set Access-Control-Allow-Origin "*" для управления доступом, если вы не тянете ни с чего другого, вы можете установить это на свой сайт, только немного подкрутить.

Мы хотим, чтобы наш механизм перезаписи URL-адресов был включен, чтобы мы могли указать ему ТОЛЬКО разрешать безопасные методы HTTP с помощьюRewriteCond %{REQUEST_METHOD} !^(GET|HEAD|POST|OPTIONS)$ [NC] а потом RewriteRule .? - [F,NS,L]и мы хотели бы получать только действительные HTTP-запросы, поэтому следующая директива RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ .+\ HTTP/(0\.9|1\.0|1\.1) [NC] а также RewriteRule .? - [F,NS,L].

Чтобы подвести итог, мы можем дополнительно запустить HTTP-сервер, а также наш HTTPS-сервер, и просто использовать HTTP для переключения на HTTPS с перезаписью, поэтому, если вы хотите сделать это, создайте файл с именем site.com.conf это выглядит примерно так:

<VirtualHost *:80>
  ServerAdmin marshall@site.org
  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined
  RewriteEngine on
  RewriteCond %{SERVER_NAME} =site.com
  RewriteRule ^  [END,NE,R=permanent]
</VirtualHost>

Вывод

Теперь вам просто нужно бежать systemctl restart apache2 чтобы перезапустить сервер с новыми настройками. Теперь, когда мы все исправили, у вас может быть немного больше спокойствия против хакеров. Тем не менее, всегда проверяйте журналы на наличие подозрительного кода.

Не стесняйтесь, пишите мне с комментариями и предложениями!

Удачной службы!

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *