Introdução:
O Servidor HTTP Apache (do inglês Apache HTTP Server) ou Servidor Apache ou HTTP Daemon Apache ou somente Apache, é o servidor web livre criado em 1995 por Rob McCool. É a principal tecnologia da Apache Software Foundation, responsável por mais de uma dezena de projetos envolvendo tecnologias de transmissão via web, processamento de dados e execução de aplicativos distribuídos.
É um servidor do tipo HTTPD, compatível com o protocolo HTTP versão 1.1 do inglês(HTTPd stands for Hypertext Transfer Protocol daemon). Suas funcionalidades são mantidas através de uma estrutura de módulos, permitindo inclusive que o usuário escreva seus próprios módulos — utilizando a API do software.
É disponibilizado em versões para os sistemas operacionais Windows, Novell, OS/2 e outros do padrão POSIX IEEE 1003 (Unix, Linux, FreeBSD, etc.).
Em maio de 2010, o Apache deu suporte a aproximadamente 54,68% de todos os sites e, 66% dos sites mais acessados mundialmente. O uso nos servidores ativos representa cerca de 47.20%.
Nós veremos nesse post como instalar o apache2 em um servidor debian 9.4, iremos dar uma olhada na estrutura dos arquivos de configuração, configurar Vhosts, implementar TLS/SSL utilizando certificados self-signed e por ultimo iremos dar uma olhada em técnicas de hardenin do daemon.
O apache possui dois modos de operação MPM Worker e PreFork, o segundo módulo trabalha utilizando a estrutura clássica de processos Unix, mantendo a compatibilidade com o Apache versão 1.X. Nesse modo, quando recebe a solicitação de uma conexão, ele cria um processo de controle para que outros processos tratem isoladamente cada conexão. O que garante um bom desempenho até alcançar o valor máximo definido em MaxClients., isso melhora a segurança, tendo em vista que se um processo crashar, ele está isolado, porém consome muito mais recursos já que processos diferentes não compartilham recursos e funções do sistema.
Já no modo MPM(Multi Processing Modules) Worker, o apache trabalhará com uma implementação de processos e threads, onde um processo controlador, que passa requisições para threads, que por sua vez criarão novos threads e compartilharam os recursos do sistema., comparado com a configuração PreFork, nesse modo, o apache mantém um processo controlando uma série de threads o que optimiza o desempenho para aplicações que suportam threads. Porém pode se tornar instável caso o processo controlador for comprometido.
Instalação:
A maioria dos sistemas atuais baseados tanto em debian como em redhat já contam com o apache2 em seus repositórios, então para a instalação do apache2 iremos instalar os gerenciadores de pacote.
Para instalar o apache2 em um sistema baseado em Debian:
sudo apt-get install apache2
Arquivos de Configuração
Todos os arquivos de configuração se encontram no diretório /etc/apache2:
root@srv-web-apache:/etc/apache2# ls -l /etc/apache2/
total 80
-rw-r--r-- 1 root root 7226 mai 5 21:24 apache2.conf
drwxr-xr-x 2 root root 4096 mai 5 17:26 conf-available
drwxr-xr-x 2 root root 4096 mai 5 17:26 conf-enabled
-rw-r--r-- 1 root root 1782 mar 30 15:07 envvars
-rw-r--r-- 1 root root 31063 mar 30 15:07 magic
drwxr-xr-x 2 root root 12288 jun 13 12:09 mods-available
drwxr-xr-x 2 root root 4096 jun 13 13:01 mods-enabled
-rw-r--r-- 1 root root 320 mar 30 15:07 ports.conf
drwxr-xr-x 2 root root 4096 jun 13 13:23 sites-available
drwxr-xr-x 2 root root 4096 jun 13 11:49 sites-enabled
O arquivo principal do apache2 é o /etc/apache2/apache2.conf, nele é possível alguns includes:
# Include module configuration:
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf
# Include list of ports to listen on
Include ports.conf
# Include generic snippets of statements
IncludeOptional conf-enabled/*.conf
# Include the virtual host configurations:
IncludeOptional sites-enabled/*.conf
As diretivas Include e IncludeOptional são diretivas que fazem o daemon carregar arquivos de configuração externos ao apache2.conf. A diferença entre as duas diretivas é que a primeira crasha o serviço caso o arquivo não exista, já a segunda, ela não crasha se o arquivo não existir.
O carregamento dos módulos feito através dos includes, é realizado através do DSO(Dynamic Shared Objects). Os módulos disponíveis porém não necessariamente carregados podem ser visualizados no diretório /etc/apache2/mods-available. Já os módulos habilitados, que estão no diretório /etc/apache2/mods-enabled nada mais são do que links para o diretório onde os módulos estão disponíveis.
Segue exemplo do arquivo de configuração principal:
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
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
Algumas diretivas do /etc/apache2/apache2.conf
- ServerRoot -> Caminho padrão dos arquivos de configuração do prório apache
- PidFile -> Arquivo de controle do PID do apache.
- Timeout -> Tempo max de segundos que o apache aguarda por resposta do cliente.
- User -> Usuário utilizado para executar o servidor.
- Group -> Grupo utilizado para executar o servidor.
- AccessFileName -> Informa ao Apache qual arquivo contém configurações sobre as diretivas de acesso.
- hostnamelookups -> Esta configuração faz com que o Apache faça resolução de nomes por origem, espeficiando o nome do cliente atráves da resolução DNS. Obviamente o tempo de resposta aumentará muito e possívelmente causará problemas de desempenho
- KeepAlive -> Uso de conexões persistentes, permite que várias requisições utilizem a mesma conexão
- MaxKeepAliveRequests -> Número máximo de requisições que um usuário poderá fazer utilizando a mesma conexão. Se utilizado ‘0’ corresponde à ilimitado
- KeepAliveTimeout -> Valor máximo em segundos que o servidor aguardará uma nova requisição do usuário antes de terminar a conexão.
- MaxClients -> Quantidade máxima de conexões simultâneas
- MaxSpareThreads -> Worker: Esta diretiva especifica o número máximo de threads ociosas aguardando requisições. Valor default é 75
- MinSpareThreads -> Worker: Esta diretiva especifica o número mínimo de threads ociosas aguardando requisições. Valor default é 25
- MaxRequestWorkers -> Worker: Número máximo de conexões que vão ser processadas simultaneamente..
- MaxConnectionsPerChild Work: Limit on the number of connections that an individual child server will handle during its life.
- MaxSpareServers -> Essa diretiva informa a quantidade máxima de processos ociosos executando no servidor, caso ultrapasse esse valor, os processos serão ifnalizados até alcançar o valor definido.
- MaxRequestsPerChild -> Prefork: Informa a quantidade de requisições que um processo filho poderá servir antes que ele seja finalizado, o valor 0 define ilimitado.
- MaxKeepAliveRequests -> The maximum number of requests to allow during a persistent connection. Set to 0 to allow an unlimited amount.
- StartServers -> Prefork: A quantidade de processos filhos inicializados juntamente com o processo inicial.
- MinSpareServers -> Prefork: Essa diretiva informa o número mínimo de processos filhos ociosos no servidor aguardando conexão. Caso a quantidade atual seja menor que a configurada, o servidor inicializará os processos a uma taxa de um segundo até alcançar o mínimo.
Apache Log
O access_log contém uma visão genérica das requisições de páginas do servidor web. O formado dos log é altamente configurável. O formato é especificado usando o formato de string que é muito semelhante ao print C-style. Uma configuração típica pode ser vista abaixo:
LogFormat "%h %l %u %t "%r" %>s %b" common
CustomLog logs/access_log common
CLF -> Common Log Format
1. IP address of the client (%h)
2. RFC 1413 identity determined by identd (%l)
3. userid of person requesting (%u)
4. time server finished serving request (%t)
5. request line of user (%r)
6. status code servers sent to client (%s)
7. size of object returned (%b).
Manipulação do Serviço:
apache2ctl start
apache2ctl stop
apache2ctl restart -> Reinicia o daemon do apache. Se ele não estiver sendo executando então inicia-o. Ele também checa a integridade dos arquivos do apache antes de inicializar-lo.
apache2ctl graceful -> Reinicia o servidor. Se estiver parado inicia, mas de qualquer forma aguarda as conexões ativas terminarem.
apache2ctl configtest -> Verifica o arquivo de configuração do apache a procura de erros.
systemctl start apache2
systemctl stop apache2
systemctl restart apache2
systemctl reload apache2
Exibindo os Virtuais hosts configurados:
root@srv-web-apache:/var/www/html# apachectl -t -D DUMP_VHOSTS
VirtualHost configuration:
*:80 is a NameVirtualHost
default server srv-web-apache.novalocal (/etc/apache2/sites-enabled/000-default.conf:1)
port 80 namevhost srv-web-apache.novalocal (/etc/apache2/sites-enabled/000-default.conf:1)
port 80 namevhost gride (/etc/apache2/sites-enabled/default.conf:1)
Exibir todos os websites rodando:
root@srv-web-apache:/var/www/html# apachectl -S
VirtualHost configuration:
*:80 is a NameVirtualHost
default server srv-web-apache.novalocal (/etc/apache2/sites-enabled/000-default.conf:1)
port 80 namevhost srv-web-apache.novalocal (/etc/apache2/sites-enabled/000-default.conf:1)
port 80 namevhost gride (/etc/apache2/sites-enabled/default.conf:1)
ServerRoot: "/etc/apache2"
Main DocumentRoot: "/var/www/html"
Main ErrorLog: "/var/log/apache2/error.log"
Mutex rewrite-map: using_defaults
Mutex default: dir="/var/run/apache2/" mechanism=default
Mutex mpm-accept: using_defaults
Mutex watchdog-callback: 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
Exibindo os módulos carregados:
root@srv-web-apache:/etc/apache2# apache2ctl -M
Loaded Modules:
core_module (static)
so_module (static)
watchdog_module (static)
http_module (static)
log_config_module (static)
logio_module (static)
version_module (static)
unixd_module (static)
access_compat_module (shared)
alias_module (shared)
auth_basic_module (shared)
authn_core_module (shared)
authn_file_module (shared)
authz_core_module (shared)
authz_host_module (shared)
authz_user_module (shared)
autoindex_module (shared)
deflate_module (shared)
dir_module (shared)
env_module (shared)
filter_module (shared)
mime_module (shared)
mpm_prefork_module (shared)
negotiation_module (shared)
php7_module (shared)
reqtimeout_module (shared)
rewrite_module (shared)
setenvif_module (shared)
socache_shmcb_module (shared)
ssl_module (shared)
status_module (shared)
O help do comando apache2ctl:
root@srv-web-apache:/etc/apache2# apache2ctl -h
Usage: /usr/sbin/apache2 [-D name] [-d directory] [-f file]
[-C "directive"] [-c "directive"]
[-k start|restart|graceful|graceful-stop|stop]
[-v] [-V] [-h] [-l] [-L] [-t] [-T] [-S] [-X]
Options:
-D name : define a name for use in directives
-d directory : specify an alternate initial ServerRoot
-f file : specify an alternate ServerConfigFile
-C "directive" : process directive before reading config files
-c "directive" : process directive after reading config files
-e level : show startup errors of level (see LogLevel)
-E file : log startup errors to file
-v : show version number
-V : show compile settings
-h : list available command line options (this page)
-l : list compiled in modules
-L : list available configuration directives
-t -D DUMP_VHOSTS : show parsed vhost settings
-t -D DUMP_RUN_CFG : show parsed run settings
-S : a synonym for -t -D DUMP_VHOSTS -D DUMP_RUN_CFG
-t -D DUMP_MODULES : show all loaded modules
-M : a synonym for -t -D DUMP_MODULES
-t -D DUMP_INCLUDES: show all included configuration files
-t : run syntax check for config files
-T : start without DocumentRoot(s) check
-X : debug mode (only one worker, do not detach)
Configurando Vhosts:
Vhost no apache2 está para Hosts Virtuais, que é basicamente algo como colocar vários websites no mesmo servidor. Existem duas formas de se fazer isso, a primeira que nós não vamos utilizar é a baseada em endereço IP, ela se baseia no endereço IP do servidor, por exemplo você configura várias interfaces virtuais sendo cada uma com um endereço IP, atribuindo então ao seu sistema vários endereços IP, então você coloca um website em cada endereço IP. A outra forma é a baseada em dominio, onde o apache2 identifica através da requisição o endereço do dominio que o cliente está tentando acessar e então redireciona para o site respectivo. Caso o site respectivo não exista, o apache2 exibe o primeiro da lista, o que é uma boa ideia então alterar o arquivo de configuração do primeiro host da lista e adicionar informações sobre Notfound etc. O primeiro host da lista por exemplo é o 000-dafault., mas não é um padrão, é porquê o 000-default é o primeiro que vem configurado, caso você remova ele e adicione algum outro nome, tem que analisar qual é o primeiro da lista, porém eu indico de qualquer forma criar o default no próprio vhost 000-default.conf.
Para realizar a configuração dos hosts virtuais, você precisa configurar eles no diretório /etc/apache2/sites-available. Eu recomendo fortemente que você copie e renomeie o arquivo 000-default.conf para o nome do website que você irá configurar o vhost.
root@srv-web-apache:/etc/apache2# cp sites-available/000-default.conf sites-available/resistance.conf
root@srv-web-apache:/etc/apache2# cp sites-available/000-default.conf sites-available/machine.conf
Agora configurando o arquivo /etc/apache2/sites-available/resistance.conf, deixe-o da seguinte forma:
< VirtualHost *:80>
ServerAdmin webkiller@resistance.hope
DocumentRoot /var/www/resistance/public_html
Servername resistance.hope
ServerAlias resistance *.hope
< Directory /var/www/resistance/public_html>
Options -Indexes -FollowSymLinks
AllowOverride All
< /Directory>
CustomLog /var/www/resistance/logs/access.log combined
ErrorLog /var/www/resistance/logs/error.log
< /VirtualHost>
Agora configurando o arquivo /etc/apache2/sites-available/machine.conf, deixe-o da seguinte forma:
< VirtualHost *:80>
ServerAdmin webpwn@machine.kill
DocumentRoot /var/www/machine/public_html
Servername machine.kill
ServerAlias machine *.kill
< Directory /var/www/machine/public_html>
Options -Indexes -FollowSymLinks
AllowOverride All
< /Directory>
ErrorLog /var/www/machine/logs/error.log
CustomLog /var/www/machine/logs/access.log combined
< /VirtualHost>
Agora vamos criar os diretórios dentro de /var/www/, criar uma página html boba e definir o owner.
root@srv-web-apache:/etc/apache2/sites-available# mkdir -p /var/www/machine/logs /var/www/resistance/logs
root@srv-web-apache:/etc/apache2/sites-available# mkdir /var/www/machine/public_html /var/www/resistance/public_html
root@srv-web-apache:/etc/apache2/sites-available# echo 'hello machine' > /var/www/machine/public_html/index.html
root@srv-web-apache:/etc/apache2/sites-available# echo 'hello resistance' >/var/www/resistance/public_html/index.html
root@srv-web-apache:/etc/apache2/sites-available# chown www-data.www-data /var/www/* -R
Observação: As boas práticas dizem que é melhor você criar um usuário para cada host, logo, não faça o que eu fiz, defina um owner para cada diretório de website.
Vamos habilitar os sites:
root@srv-web-apache:/etc/apache2/sites-available# a2ensite resistance.conf
Enabling site resistance.
To activate the new configuration, you need to run:
systemctl reload apache2
root@srv-web-apache:/etc/apache2/sites-available# a2ensite machine.conf
Enabling site machine.
To activate the new configuration, you need to run:
systemctl reload apache2
Antes de reiniciar o daemon, vamos verificar se as configurações estão OK:
root@srv-web-apache:/etc/apache2/sites-available# apache2ctl configtest
Syntax OK
Ok, agora é hora de reinicializar o daemon:
root@srv-web-apache:/etc/apache2/sites-available# apache2ctl restart
Para acessar os hosts virtuais configurados, será necessário alterar no cliente, no caso seu pc, o arquivo /etc/hosts e inserir os registros dos hosts virtuais pois vamos precisar acessar pelo nome do “dominio”:
172.24.4.11 machine machine.kill
172.24.4.11 resistance resistance.hope
Bom, se tudo correu bem, até aqui temos 2 virtualhosts configurados e rodando.
Autenticação e Autorização:
A diferença de Autenticação e Autorização é bem interessante, autenticação é referente à você provar quem é vocẽ, já sobre autorização é sobre o que você pode fazer.
Os módulos do apache que servem para o propóstito de autheNtication seguem uma convenção de mod_authn_*. Os módulos que servem para o próprosito de authoriZation seguem uma convenção de mod_authz_*. Uma exceção à essa regra é o módulo authnz_ldap, que como você pode imaginar, devido à natureza do LDAP, esse módulo opera com os dois tipos.
Em geral, os módulos vão usar uma forma de database para armazenar e ler as informaçoes de credenciais. O Módulo mod_authn_file por instância utiliza arquivos de texto e mod_auth_dbm implementa uma database DBM Unix.
Alguns módulos de autenticação e autorização:
- mod_auth_file (DAC): Essa é a base para maioria dos módulos do apache, utiliza arquivos de texto como databases de autenticação.
- mod_access (MAC) This used to be the only module in the standard Apache distribution which applies what Apache defines as mandatory controls. It used to allow you to list hosts, domains, and/or IP addresses or networks that were permitted or denied access to documents. As of Apache 2.4, this module is no longer used. Apache 2.4 and newer use an updated> authentication and authorization model. This new model also comes with new modules, new directives and new syntax.
- mod_authn_anon (DAC) This module mimics the behaviour of anonymous FTP. Rather than having a database of valid cre-
dentials, it recognizes a list of valid usernames (i.e., the way an FTP server recognizes “ftp” and “anonymous”) and grants
access to any of those with virtually any password. This module is more useful for logging access to resources and keeping
robots out than it is for actual access control. - mod_authn_dbm (DAC) Like mod_auth_db, except that credentials are stored in a Unix DBM file.
- mod_auth_digest (DAC) This module implements HTTP Digest Authentication (RFC2617), which used to provide a more secure alternative to the mod_auth_basic functionality. The explanation that follows is nice to know but outdated. The whole point of digest authentication was to prevent user credentials to travel via unencrypted HTTP over the wire. The hashing algorithms used by the digest module are however seriously outdated. Using digest authentication instead of basic HTTP authentication does not offer as many advantages in terms of security as the use of HTTPS would.
- mod_authz_host -> The mod_authz_host module may be used to Require a certain source of request towards Apache. The mod_authz_host module is quite flexible about the arguments provided. Due to the name of the module, it may seem logical to provide a hostname. While this certainly works, it may not be the preferred choice. Not only does this module need to perform a forward DNS lookup on the provided hostname to resolve it to a numerical IP, the module is also configured to perform a reverse DNS lookup on the resolved numerical IP after the forward lookup is performed. Providing a hostname thus leads to at least two DNS lookups for every affected webserver request. And if the reverse DNS result differs from the provided hostname, the request will be denied despite what the configuration may allow. To circumvent this requirement regarding forward and reverse DNS records matching, the forward-dns option may be used when providing a hostname. Luckily, mod_authz_host not only accepts hostnames as an argument. It can also handle (partial) IP addresses, both IPv4 and IPv6, and CIDR style notations. There is also an argument available called local. This will translate to the 127.0.0.0/8 or ::1 loopback addresses as well as the configured IP addresses of the server. This setting may come in handy when restricting connections in regards to the local host. Because of the liberal way that IP addresses are interpreted, it is recommended to be as explicit as possible when using this module.
- mod_access_compat -> The directives provided by mod_access_compat are used in , , and sections as well as .htaccess files to control access to particular parts of the server. Access can be controlled based on the client hostname, IP address, or other characteristics of the client request, as captured in environment variables. The Allow and Deny directives are used to specify which clients are or are not allowed access to the server, while the Order directive sets the default access state, and configures how the Allow and Deny directives interact with each other.
- mod_auth_basic -> This module allows the use of HTTP Basic Authentication to restrict access by looking up users in the given providers. HTTP Digest Authentication is provided by mod_auth_digest. This module should usually be combined with at least one authentication module such as mod_authn_file and one authorization module such as mod_authz_user.
Configurando Autenticação
Se você passou o olho nós módulos anteriores viu que é possível definir acesso à endereços IP, redes locais etc. O que nós vamos configurar aqui vai ser referente à usuário atráves do htpasswd, vamos também abordar a configuração de grupos com o htgroup.
A primeira configuração deve ser realizada dentro do arquivo de configuração do website, podendo ser externa também porém iremos fazer interno. As configurações devem ser realizadas dentro do campo Directory. Para que, por exemplo, você configure um arquivo htaccess que é um arquivo que define algumas politicas de segurança do diretório, esse arquivo geralmente se encontra dentro do diretório onde você quer implantar as diretivas, você precisará alterar a diretiva AllowOverride para all.
Segue exemplo:
Configuração do website machine
< VirtualHost *:80>
ServerAdmin webpwn@machine.kill
DocumentRoot /var/www/machine/public_html
Servername machine.kill
ServerAlias machine *.kill
< Directory /var/www/machine/public_html>
Options -Indexes -FollowSymLinks
AllowOverride All
Authtype Basic
AuthName "Admin Area, backoff"
AuthUserFile /var/www/machine/.htpasswd
Require valid-user
< /Directory>
ErrorLog /var/www/machine/logs/error.log
CustomLog /var/www/machine/logs/access.log combined
< /VirtualHost>
Um adendo à AllowOverride, essa diretiva é mais relacionada à segurança e autenticação. Se irá haver ou não. Esta diretiva deve informar opções a respeito disto. Normalmente relacionado ao arquivo .htaccess. Algumas das opções que ela aceita:
- None -> O arquivo .htaccess não será lido. É o default
- Authconfig -> Habilita o uso de diretivas de autorização através do arquivo .htaccess. Diretivas como Authtype, AuthUserFile, AuthGroupFile e entre outros
- FileInfo -> Habilita o uso de diretivas de controle de tipo de documentos. E altera ou seta opções como linguagem, mime-type, entre outras. Diretivas utilizadas como AddType, Addlanguage, DefaultType e etc.
- Indexes -> Habilita o uso de diretivas para controlar a indexação de diretórios. Por exemplo, especificar que serão abertos por padrão(index.html,index.php,default.html)
- Limit -> Relacionado à permissões de acesso como Order allow,deny e etc
Uma explicação das diretivas anteriores:
- Authtype -> Define o tipo de autenticação, no caso, basic.
- AuthName -> Mensagem que irá aparecer no popup de autenticação.
- Require -> Informa que é necessário uma autenticação válida. Podendo ser: group(deve ser especificado o grupo)/user(deve ser especificado o usuário)/valid-user(usuário valido).
Bom, agora é necessário configurar o arquivo .htpasswd. As boas práticas de segurança dizem que é melhor deixar esse arquivo em um diretório separado do documentroot.
O Algoritmo crypt usado pelo htpasswd por default é considerado inseguro, eis aqui o motivo:
Crypt will limit the provided password to the first eight characters. Every part of the password string from the ninth character on will be neglected. Crypt password strings are subject to fast brute force cracking and therefore pose a considerable security risk. The use of the crypt algorithm should be avoided whenever possible. Instead, the bcrypt algorithm should be considered when available
Então de acordo com a quote anterior, é necessário utilizar o bcrypt
Abaixo segue as opções do htpasswd
Usage:
htpasswd [-cimBdpsDv] [-C cost] passwordfile username
htpasswd -b[cmBdpsDv] [-C cost] passwordfile username password
htpasswd -n[imBdps] [-C cost] username
htpasswd -nb[mBdps] [-C cost] username password
-c Create a new file.
-n Don't update file; display results on stdout.
-b Use the password from the command line rather than prompting for it.
-i Read password from stdin without verification (for script usage).
-m Force MD5 encryption of the password (default).
-B Force bcrypt encryption of the password (very secure).
-C Set the computing time used for the bcrypt algorithm
(higher is more secure but slower, default: 5, valid: 4 to 31).
-d Force CRYPT encryption of the password (8 chars max, insecure).
-s Force SHA encryption of the password (insecure).
-p Do not encrypt the password (plaintext, insecure).
-D Delete the specified user.
-v Verify password for the specified user.
On other systems than Windows and NetWare the '-p' flag will probably not work.
The SHA algorithm does not use a salt and is less secure than the MD5 algorithm.
Com base nessas opções, vamos precisar então rodar o htpasswd e criar o arquivo htpasswd no diretório apropriado, já definindo um usuário, segue:
root@srv-web-apache:/var/www/machine# htpasswd -cB /var/www/machine/.htpasswd bob
New password: *********
Re-type new password: **********
Adding password for user bob
Agora para adicionar um novo usuário à lista, é só omitir a opção -c:
root@srv-web-apache:/var/www/machine# htpasswd -B /var/www/machine/.htpasswd alice
New password:
Re-type new password:
Adding password for user alice
Para alterar a senha de um usuário, basta definir ele novamente:
root@srv-web-apache:/var/www/machine# htpasswd -B /var/www/machine/.htpasswd alice
New password:
Re-type new password:
Updating password for user alice
Reinicie o daemon e faça um teste.
Também é possível adotar grupos de usuários, vamos então criar um grupo chamado staff e adicionar alice e bob:
Arquivo /var/www/machine/.htgroup:
staff: bob alice
Para utilizar o grupo, precisamos utilizar a diretiva AuthGroupFile dentro do campo Directory
< VirtualHost *:80>
ServerAdmin webpwn@machine.kill
DocumentRoot /var/www/machine/public_html
Servername machine.kill
ServerAlias machine *.kill
< Directory /var/www/machine/public_html>
Options -Indexes -FollowSymLinks
AllowOverride All
Authtype Basic
AuthName "Admin Area, backoff"
AuthUserFile /var/www/machine/.htpasswd
AuthGroupFile /var/www/machine/.htgroup
Require group staff
< /Directory>
ErrorLog /var/www/machine/logs/error.log
CustomLog /var/www/machine/logs/access.log combined
< VirtualHost>
Repare que utilizamos a diretiva Require group staff e removemos a valid-user, isso significa que vamos aceitar qualquer usuário com autenticação válida do grupo staff.
Habilite o módulo authz_groupfile:
a2enmod authz_groupfile
Faça o teste, as senhas já estão definidas, não esqueça de antes reiniciar o daemon.
Htaccess
Como já informado anteriormente, o htaccess tem como função sobreescrever as configurações para o diretório qual o arquivo se encontra. Ou seja, eu crio um htaccess no diretório /var/www/resistance/public_html e ele vai sobreescrever as configurações que se encontram no arquivo de configuração do website. Porém só funciona se a diretiva AllowOverride estiver como All
Então vamos seguir com um exemplo, quero criar uma autenticação básica no diretório citado anteriormente usando o htaccess. Basta criar o arquivo .htaccess e popular com as novas configurações, segue exemplo:
AuthType basic
AuthUserFile /var/www/resistance/public_html/.htpasswd
AuthName "You Should not pass"
Require valid-user
Com as configurações anteriores, eu estou habilitando uma autenticação básica para o diretório atual.
Configuração de Apache para HTTPS:
A ideia aqui é implementar certificados self-signed, vamos configurar os websites machine e resistance para utilizar tal funcionalidade.
SSL/TLS utiliza Public Key Cryptography(PKC), conhecido também como criptografia assimétrica.
Para utilizar tais funcionalidades, é preciso do mod_ssl, então é necessário instalar o módulo:
Instalando em Redhat based:
$ sudo yum install httpd mod_ssl
Instalando em Debian based:
$ sudo apt-get install apache2 openssl
Habilitando o módulo:
$ sudo a2enmod ssl
Criando e instalando certificados self-signed no apache:
Por padrão, existem diretórios no linux próprios para armazenar as chaves, nós iremos então utilizar o diretório /etc/ssl e dentro dele vamos criar um diretório para cada website.
~# cd /etc/ssl ; mkdir machine resistance
Agora vamos gerar as chaves
~# openssl req -new -x509 -days 365 -nodes -out /etc/ssl/machine/apache.pem -keyout /etc/ssl/machine/apache.key
--- saida omitida ---
~# openssl req -new -x509 -days 365 -nodes -out /etc/ssl/resistance/apache.pem -keyout /etc/ssl/resistance/apache.key
--- saida omitida ---
Configurando os arquivos dos websites:
Website Machine:
< VirtualHost *:443>
ServerAdmin webpwn@machine.kill
DocumentRoot /var/www/machine/public_html
Servername machine.kill
ServerAlias machine *.kill
< Directory /var/www/machine/public_html>
Options -Indexes -FollowSymLinks
AllowOverride All
Authtype Basic
AuthName "Admin Area, backoff"
AuthUserFile /var/www/machine/.htpasswd
AuthGroupFile /var/www/machine/.htgroup
Require group staff
< /Directory>
ErrorLog /var/www/machine/logs/error.log
CustomLog /var/www/machine/logs/access.log combined
SSLEngine ON
SSLCertificateFile /etc/ssl/machine/apache.pem
SSLCertificateKeyFile /etc/ssl/machine/apache.key
< /VirtualHost>
Website Resistance:
< VirtualHost *:443>
ServerAdmin webkiller@resistance.hope
DocumentRoot /var/www/resistance/public_html
Servername resistance.hope
ServerAlias resistance *.hope
< Directory /var/www/resistance/public_html>
Options +Indexes -FollowSymLinks
AllowOverride All
< /Directory>
ErrorLog /var/www/resistance/logs/error.log
CustomLog /var/www/resistance/logs/access.log combined
SSLEngine On
SSLCertificateFile /etc/ssl/resistance/apache.pem
SSLCertificatekeyFile /etc/ssl/resistance/apache.key
< /VirtualHost>
Explicação de configurações:
- SSLEngine -> This directive toggles the usage of the SSL/TLS Protocol Engine. This should be used inside a < VirtualHost> section to enable SSL/TLS for a that virtual host. By default the SSL/TLS Protocol Engine is disabled for both the main server and all configured virtual hosts.
- SSLCertificateKeyFile -> This directive points to the PEM-encoded private key file for the server. If the contained privatekey is encrypted, the pass phrase dialog is forced at startup time. This directive can be used up to three times (referencing different filenames) when an RSA, a DSA, and an ECC based private key is used in parallel. For each SSLCertificateKey- File directive, there must be a matching SSLCertificateFile directive.
- SSLCertificateFile -> This directive points to a file with certificate data in PEM format. At a minimum, the file must include an end-entity (leaf) certificate. This directive can be used up to three times (referencing different filenames) when an RSA, a DSA, and an ECC based server certificate is used in parallel.
Verificando as configurações:
root@srv-web-apache:/etc/apache2/sites-available# apache2ctl configtest
Syntax OK
Reiniciando o daeamon
root@srv-web-apache:/etc/apache2/sites-available# apache2ctl restart
Outras opções:
- SSLCACertificateFile -> This directive sets the all-in-one file where you can assemble the certificates of Certification Au-thorities (CA) whose clients you deal with. These are used for Client Authentication. Such a file is simply the concatenation of the various PEM-encoded certificate files, in order of preference.
- SSLCACertificatePath -> Sets the directory where you keep the certificates of Certification Authorities (CAs) whose clients you deal with. These are used to verify the client certificate on Client Authentication.
- SSLCipherSuite -> This complex directive uses a colon-separated cipher-spec string consisting of OpenSSL cipher specifications to configure the Cipher Suite the client is permitted to negotiate in the SSL handshake phase. Notice that this directive can be used both in per-server and per-directory context. In per-server context it applies to the standard SSL handshake when a connection is established. In per-directory context it forces a SSL renegotiation with the reconfigured Cipher Suite after the HTTP request was read but before the HTTP response is sent.
- SSLProtocol -> This directive can be used to control the SSL protocol flavors mod_ssl should use when establishing its server environment. Clients then can only connect with one of the provided protocols.
- ServerSignature -> The ServerSignature directive allows the configuration of a trailing footer line under server-generated documents (error messages, mod_proxy ftp directory listings, mod_info output, …). The reason why you would want to enable such a footer line is that in a chain of proxies, the user often has no possibility to tell which of the chained servers actually produced a returned error message.
- ServerTokens-> This directive controls whether the Server response header field which is sent back to clients includes minimal information, everything worth mentioning or somewhere in between. By default, the ServerTokens directive is set to Full. By declaring this (global) directive and setting it to Prod, the supplied information will be reduced to the bare minimum. During the first chapter of this subject the necessity for compiling Apache from source is mentioned. Modifying the Apache Server response header field values could be a scenario that requires modification of source code. This could very well be part of a server hardening process. As a result, the Apache server could provide different values as response header fields.
- TraceEnable -> This directive overrides the behavior of TRACE for both the core server and mod_proxy. The default TraceEnable on permits TRACE requests per RFC 2616, which disallows any request body to accompany the request. TraceEnable off causes the core server and mod_proxy to return a 405 (method not allowed) error to the client. There is also the non-compliant setting extended which will allow message bodies to accompany the trace requests. This setting should only be used for debugging purposes. Despite what a security scan may say, the TRACE method is part of the HTTP/1.1 RFC 2616 specification and should therefore not be disabled without a specific reason.
Uma boa forma de melhorar a segurança em servidores web apache instalados em debian é editar o arquivo /etc/apache2/conf-enabled/security.conf:
ServerSignature Off
ServeTokens Prod
TraceEnable Off
Header set X-Frame-Options: "sameorigin"
Header set X-Content-Type-Options: "nosniff"
# HTTP ONLY
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure
# Enforce HSTS
Header always set Strict-Transport-Security "max-age=31536000;includeSubDomains"
Para limitar os métodos disponíveis, você pode inserir dentro das tags [b]Directory[/b] o seguinte bloco:
Require all granted
Require all denied
Todo método que não for tratado vai estar habilitado por default. Você pode realizar a configuração direto no módulo [b]/etc/apache2/mods-available/userdir.conf[/b]. Não esqueça de habilitar ele posteriormente.Outra dica de segurança é desabilitar a função exec do php, como todo mano dos terminal sabe, é muito massa usar o php pra injetar comandos no servidor web por algum bug ridiculo que algum dev do youtube escreveu, então uma forma do sysadmin manter a casa limpa é assim:
root@srv-web-apache:/etc/apache2# vim /etc/php/7.0/apache2/php.ini +/disable_functions
E adicione exec.
Algumas outras opções que podem ser desabilitadas:
- show_source
- system
- shell_exec
- passthru
- popen
- symlink
expose_php = Off -> Essa opção está relacionada mais com privacidade do que com a segurança propriamente dita. Com expose_php habilitada, será possível determinar se o PHP está instalado no servidor. Isso pode ser feito com uma consulta ao servidor web.
register_globals = Off -> Essa opção não representa um problema de segurança no PHP, porém pode proporcionar potenciais riscos à segurança do sistema por induzir o desenvolvedor ao erro. Não existe uma boa razão para habilitar essa diretriz e, de modo geral, register_globals deve permanecer sempre com o valor Off.
Essas opções abaixo permitem abrir ou processar uma pagina ou arquivo externo dentro do script php. Vários servidores de hospedagem desativam essa opção. Desabilitar também dentro do php.ini
allow_url_fopen = Off
allow_url_include = Off
Desabilitando protocolos inseguros:
By setting the SSLHonorCipherOrder directive to a value of on, the server will honor the order of ciphers as specified by the SSLCipherSuite directive. Otherwise, the client will have the upper hand when deciding which ciphers will be used. This secure channel then is used to transmit the encryption keys that will be used to secure the communication from here on forward. Those encryption keys must also be in a cipher format that both the server and client can handle. Neither is Arcfour (or RC4 in short) a recommended cipher to be used. As far as protocols go, SSL v2 and SSL v3 are known to be vulnerable to a plethora of attack vectors. TLS v1.0 and v1.1 also have their weaknesses. TLS v1.2 is currently the recommended protocol to use if security is a concern. With TLS v1.3 being almost visible on the horizon. Apache allows for configuration of the ciphers being offered to clients. By using the following directives, the list of ciphers that Apache offers to client software can be limited:
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:!RC4
SSLProtocol -All +TLSv1.2
SSLHonorCipherOrder On
SSLCompression Off
Rewrite
É possível criar redirecionamentos no servidor para por exemplo vamos supor que você precise redirecionar as requisições da porta 80 para a 443, você pode utilizar o .htaccess dentro do diretório do website, claro com o AllowRewrite definido no options do arquivo de configuração.
Exemplo do .htaccess:
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.seunome.com.br/$1 [R,L]
Posteriormente é necessário ativar o mod_rewrite:
a2enmod rewrite
Alguns Módulos Interessantes
- mod_cband -> Limitação de Banda, definição de quota de tráfego
- mod_security -> Basicamente um WAF
- mod_evasive -> Basicamente um IPS que foca em mitigação de ataques DDoS/DoS
Fontes:
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Reference_Guide/s3-apache-minmaxsparethreads.html
https://httpd.apache.org/docs/trunk/mod/mpm_common.html
https://httpd.apache.org/docs/2.4/mod/mod_access_compat.html
https://httpd.apache.org/docs/2.4/mod/mod_authz_host.html
https://httpd.apache.org/docs/2.4/mod/mod_auth_basic.html
https://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI
