Infotech Notes

22/Agosto/2008

LPI

Arquivado em: LPI 101, LPI 102, Linux — Gustavo @ 2:24 pm

Estes são os assuntos das provas LPI 101 e 102

LPI 101:

- Hardware & Architecture

- Linux installation & Package management

- GNI & Linux commands

- Devices, linux filesystems, Filesystem Hierarchy Standard (FHS)

- X

LPI 102:

- Kernel

- Boot, Initialization, Shutdown and Runlevels

- Printing

- Documentation

- Shells, ScriptingProgramming and Compiling

- Administrative Tasks

- Networking Fundamentals

- Networking Services

- Security

Eu sugiro fazer uma prova de cada vez (101 e 102) para facilitar o estudo, pois eu acho mais fácil.

Eu vou ver se coloco aqui algumas provas que eu usei para estudar para estas duas provas.

Remover opção “Ajuda e Suporte” do Windows

Arquivado em: Windows — Gustavo @ 2:19 pm

Para quem já se encheu de clicar errado na opção de “Ajuda e Suporte” do Windows XP, saiba que existe uma maneira de removê-la do menu.

Basta seguir os passos abaixo.

1. Clique no menu iniciar, executar e digite regedit.exe

2. Vá até a chave

HKEY_CURRENT_USER\ Software \Microsoft \Windows \CurrentVersion \Explorer \Advanced

3. Crie uma nova REG_DWORD com nome NoStartMenuHelp

4. Dê um duplo clique na entrada NoStartMenuHelp e altere o valor para 1

5. Feche o regedit.

6. De um reboot.

Veja que a opção desapareceu.

7/Agosto/2008

Link aggregation/Bonding em linux

Arquivado em: ldap — Gustavo @ 9:56 pm

Seguem algumas informações e dois scripts úteis para adição e configuração de interfaces em link agregation/bonding em linux. Eu fiz isso em Debian 3.1, mas vale para qualquer linux.

No exemplo abaixo (/etc/init.d/start_bondig) eu tenho um servidor com 4 interfaces de rede e estou criando 2 link aggregation, para uso em dois switches trabalhando com HSRP (Cisco). Eu vou criar a interface lógica bond0 com as interfaces físicas eth1 e eth2, e a interface lógica bond1 com as interfaces físicas eth3 e eth4.

Vale lembrar que se voce tem 1 servidor e 1 switch operando em modo bonding, a escolha do modo é muito importante para o correto balanceamento.

No caso do servidor, o melhor modo para balanceamento é o mode=0, que envia um pacote para cada interface alternadamente. A escolha do modo vale somente para o envio dos pacotes, uma vez que quando o bondiing ou aggregation está ativado, qualquer que seja o modo de configuração do bonding, o outro equipamento deve ser capaz de recebê-los sem problema. Ou seja, eu posso ter modo de envio 0 (Round-robin mode) do servidor para o switch e modo 1 (Active-backup mode) do switch para o servidor, e eles serão capazes de trocar tráfego sem problema.

#!/bin/sh
# arquivo /etc/init.d/start_bonding
# obtendo os MACs
MAC_ADDR_0=`ifconfig -a | grep eth1 | awk ‘{printf$5″\n”}’`
MAC_ADDR_1=`ifconfig -a | grep eth3 | awk ‘{printf$5″\n”}’`

# carregando os modulos em memoria
# mode=0 ==> Round-robin policy
# mode=1 ==> Active-backup policy
# mode=2 ==> Balance-xor policy
# mode=3 ==> Broadcast policy
# mode=4 ==> 802.3ad policy
# mode=5 ==> Balance-tlb (Adaptive transmit load balancing) policy
# mode=6 ==> Balance-alb (Adaptive load balancing) policy

# tip para carregar o segundo bonding
/sbin/modprobe bonding mode=0                           ## bond0
/sbin/modprobe bonding -o bonding1 mode=0      ## bond1

/sbin/ifconfig bond0 hw ether $MAC_ADDR_0
/sbin/ifconfig bond0 up

/sbin/ifconfig bond1 hw ether $MAC_ADDR_1
/sbin/ifconfig bond1 up

#interfaces para o switch
/sbin/ifenslave bond0 eth1
/sbin/ifenslave bond0 eth2

#interfaces para o brick
/sbin/ifenslave bond1 eth3
/sbin/ifenslave bond1 eth4

/sbin/ifconfig eth1 up
/sbin/ifconfig eth2 up
/sbin/ifconfig eth3 up
/sbin/ifconfig eth4 up

#========eof /etc/init.d/start_bonding

Para desfazer as interfaces, use este script

#!/bin/sh
# arquivo /etc/init.d/stop_bonding

/sbin/ifconfig br0 down
/usr/sbin/brctl delif br0 bond0
/usr/sbin/brctl delif br0 bond1
/usr/sbin/brctl delbr br0

/sbin/ifconfig eth1 down
/sbin/ifconfig eth2 down
/sbin/ifconfig eth3 down
/sbin/ifconfig eth4 down

/sbin/ifenslave -d bond0 eth1
/sbin/ifenslave -d bond0 eth2
/sbin/ifenslave -d bond1 eth3
/sbin/ifenslave -d bond1 eth4

/sbin/ifconfig bond0 down
/sbin/ifconfig bond1 down

#===========eof  /etc/init.d/stop_bonding

29/Julho/2008

LDAP com TLS/SSL

Arquivado em: Linux, ldap — Gustavo @ 6:28 pm

Seguem aqui os passos para adicionar um pouco de segurança ao sistema LDAP. No meu caso, eu utilizo um certificado auto-assinado. Não é a maneira mais segura, mas ajuda muito quando voce tem que autenticar os usuários e quer evitar que a senha seja lida caso algum sniffer esteja ativo.

Lembre-se de manter a parte privativa do certificado o mais seguro possível, pois é isto que garantirá a segurança e a privacidade das informações. O sistema usado como exemplo é um Red Hat AS 4 Update 6 e os comandos devem ser executados pelo usuário root.

Criação da autoridade certificadora e geração do scertificado:

cd /usr/share/ssl
rm -fr demoCA
/usr/share/ssl/misc/CA -newca
openssl req -newkey rsa:1024 -nodes -keyout newreq.pem -out newreq.pem /usr/share/ssl/misc/CA -sign

Com isto, voce já tem os certificados privados e público. Vamos agora colocar os arquivos certos nos lugares certos.

cp demoCA/cacert.pem /etc/openldap/cacerts/cacert.pem
cp newcert.pem /etc/openldap/cacerts/servercrt.pem
cp newreq.pem /etc/openldap/cacerts/serverkey.pem

Corrigindo as permissões e proprietários

chmod 0400 /etc/openldap/cacerts/serverkey.pem
chown -R ldap:ldap /etc/openldap/cacerts /etc/init.d/ldap restart

Copiando os certificados na máquina cliente ldap

scp /etc/openldap/cacerts/cacert.pem root@<ip_client>:/etc/openldap/cacerts/.

Com estes passos feitos, basta acertar as configurações dos arquivos abaixo nas máquinas LDAP Client:

# arquivo: /etc/ldap.conf
host <fqdn_ldap_server>
base ou=Users,dc=com
uri ldaps://<fqdn_ldap_server>/
ldap_version 3
port 636
timelimit 120
bind_timelimit 120
idle_timelimit 3600
pam_password md5
pam_password exop
ssl on
tls_checkpeer yes
tls_cacertfile /etc/openldap/cacerts/cacert.pem
tls_cacertdir /etc/openldap/cacerts
tls_reqcert never
tls_ciphers TLSv1
pam_password md5

# arquivo: /etc/openldap/ldap.conf
URI ldaps://<fqdn_ldap_server>:636
HOST <fqdn_ldap_server>
BASE ou=Users,dc=com
TLS_CACERTDIR /etc/openldap/cacerts
TLS_REQCERT never

24/Julho/2008

Limpar o conteúdo da fila de impressão

Arquivado em: Windows — Gustavo @ 5:44 pm

Para quem às vezes tem algum problema na hora de imprimir algum documento, nada é mais chato do que tentar apagar o(s) documento(s) da fila de impressão.

Para fazer isso de uma forma elegante, crie um arquivo limpa.bat (ou qualquer outro nome que voce ache conveniente) e coloque o texto abaixo dentro dele.

net stop spooler
cd %systemroot%\system32\spool\PRINTERS
del /f /s *.SHD
del /f /s *.SPL
net start spooler

Pronto. Sua fila de impressão estará limpa e voce pode imprimir o que precisar.

20/Julho/2008

Montando um servidor LDAP, parte 3

Arquivado em: Linux, ldap — Gustavo @ 1:34 am

Bom, continuando os posts 1 e 2, seguem agora os arquivos de configuração /usr/local/etc/openldap/slapd.conf e /etc/init.d/ldap

Como eu não consigo formatar este post para representar corretamente os espaços nestes arquivos, eu vou anexá-los em um PDF. Estes arquivos referem-se à configuração do servidor Master LDAP (IP 10.0.0.31) e do servidor Slave (IP 10.0.0.32), contendo também o arquivo /etc/init.d/ldap, para início do serviço nos dois servidores.

Arquivo PDF com a configuração LDAP master e slave

Alguns simples problemas costumam acontecer:
- o diretório /var/lib/ldap não existe
- o script de inicializacao /etc/init.d/ldap não tem permissão de execução
- o diretório dos schemas é diferente do especificado no arquivo slapd.conf

Corrija-os e então inicie o ldap.

Após iniciar, voce pode usar o utilitário LDAP Admin (http://ldapadmin.sourceforge.net/) que roda em MS-Windows, facilitando a gerencia da árvore LDAP.

Não esqueça de adicionar a base (ou o topo) da árvore, que no nosso exemplo é o domínio dc=com. Para isto, basta criar um arquivo texto com as linhas a seguir e emitir o seguinte comando no seu servidor LDAP (nos dois servidores).

dn: dc=com
objectClass: domain
dc: com

Salve com o nome base.ldif (arquivo de texto puro, usando vi/vim ou outro editor) e rode o seguinte comando ldapadd -x -D “cn=Manager,dc=com” -W -f base.ldif

Ele pedirá uma senha. Informe a senha usada no comando slappasswd

Rode o LDAP Admin e veja a base de sua árvore LDAP no ar. A partir deste ponto, voce pode começar a criar a estrutura de sua árvore LDAP.

19/Julho/2008

Montando um servidor LDAP, parte 2

Arquivado em: ldap, sincronismo, vrrp — Gustavo @ 11:48 pm

Bom, depois de algum tempo na frente dos seus servidores compilando o OpenLDAP e o VRRP Daemon, chegou a hora de configurá-los e colocá-los em operação.

Vamos começar pelo VRRP que é mais fácil e mais simples. Para isso eu vou presumir 2 servidores com IPs 10.0.0.31 (LDAP Master) e 10.0.0.32 (LDAP Slave). O IP virtual que será o responsável pelas respostas das duas máquinas será o 10.0.0.30

Servidor Master (ip 10.0.0.31). Crie o arquivo /etc/init.d/vrrpd e coloque este texto nele

Arquivo PFD com a configuração do VRRP Server

Dê permissões de execução e crie o link em /etc/rc3.d/S94vrrpd. Os espaços deste script foram comidos na hora de publicar a mensagem. Mas o script é pequeno e fácil de entender.

Servidor Slave (ip 10.0.0.32). Crie o arquivo /etc/init.d/vrrpd e coloque este texto nele

Arquivo PDF com a configuração do VRRP Slave

Dê permissões de execução e crie o link em /etc/rc3.d/S94vrrpd

Com as configurações deste arquivo, também é possível executar um chkconfig –add vrrpd, sem a necessidade de criar o link manualmente. Eu fiz isto em um RedHat.

Inicie o serviço VRRP e faça os testes. Efetue um ping para o IP Virtual e então veja o arp deste IP. Então pare o serviço no servidor Master, e veja que o ping perde alguns pacotes mas logo volta a responder. Verifique novamente o arp deste IP e veja que o arp está diferente.

As mensagens deste serviço são colocadas no arquivo /var/log/messages e se parecem com estas

May 28 11:11:53 master-server vrrpd: VRRP ID 1 on eth1: we are now a backup router.
May 28 11:11:57 master-server vrrpd: VRRP ID 1 on eth1: we are now the master router.

Sugiro também adicionar em seu servidor DNS uma entrada A e PTR que resolva o nome e o reverso para este novo elemento em sua rede.

16/Maio/2008

Montando um servidor LDAP

Arquivado em: ldap, sincronismo, vrrp — Gustavo @ 1:23 am

Recentemente eu montei um servidor LDAP utilizando dois servidores rodando linux RedHat AS 4, com redundância através de VRRP e sincronismo da dase de dados LDAP.
Este post descreve todos os passos e dicas sobre como colocar este serviço no ar.

Algumas das características utilizadas são:
- Servidores com replicação da base LDAP
- Utilização de um software de virtualização de IPs para redundancia
- Autenticação com utilização de certificados para cifragem dos dados
- Testes com Autenticação de ambientes Windows (Cliente pago)

Servidor Linux:
O servidor utilizado não é um fator tão importante. Eu escolhi utilizar um RedHat AS4, mas pode ser feito também com SUSE, Debian, e mesmo em Unix (Solaris, HP-UX, AIX), pois todo o software utilizado deve ser compilado no servidor, então a distribuição pode ser a escolha de cada um. Penso que vale a pena ter a versão mais atualizada do linux/unix escolhido. Vale a pena lembrar que a versão RHES4 deve ter o update 5 instalado, ou superior. Se for update 4 ou inferior o ldap com password policy não vai funcionar.

VRRP Daemon:
O serviço VRRP é semelhante ao HSRP da Cisco, e permite que duas estações com IPs distintos (ex. 10.0.0.31 = Server1 e 10.0.0.32 = Server2) possam responder por um terceiro IP (10.0.0.30) com redundancia do serviço. Um dos servidores será o master e o outro será o slave. Quando o master ficar fora do ar, o slave assume a resposta pelo IP 10.0.0.30. Quando o server1 voltar ao ar, ele volta a responder pelo IP 10.0.0.30 e o server 2 devolve o IP ao master.
Este serviço é fundamental para garantir a redundancia do servidor, uma vez que na configuração do LDAP será feita a colocação de um master e um slave, com sincronismo da base de ldados LDAP entre os servidores.
O fonte deste recurso pode ser encontrado em https://sourceforge.net/projects/vrrpd/ e deve ser compilado nos dois servidores.

LDAP:
O servidor LDAP utilizado foi a última versão stable, localizada em http://www.openldap.org/software/download/OpenLDAP/openldap-stable/
Depois de baixar a versão, mova o arquivo para o diretório /usr/local e descompacte-o lá.
Rode os seguintes comandos para realizar a configuração e compilação:
# ./configure –enable-crypt –enable-bdb –disable-sql –enable-ppolicy –with-cyrsus-sasl –with-tls –disable-ipv6 –with-slurpd
# make depend && make && make install && echo $?

Se voce encontrar algum problema no configure, é porque deve estar faltando algum pacote necessário à compilação do openldap. Ao executar um rpm -qa | grep -i sasl, eu obtive estes pacotes
- cyrus-sasl-sql-2.1.19-14
- cyrus-sasl-md5-2.1.19-14
- cyrus-sasl-plain-2.1.19-14
- cyrus-sasl-ntlm-2.1.19-14
- cyrus-sasl-2.1.19-14
- cyrus-sasl-gssapi-2.1.19-14
- cyrus-sasl-devel-2.1.19-14

E ao executar um rpm -qa | grep -i ssl eu obtive os seguintes pacotes
- openssl096b-0.9.6b-22.46
- openssl-devel-0.9.7a-43.16
- pyOpenSSL-0.6-1.p23
- xmlsec1-openssl-1.2.6-3
- openssl-0.9.7a-43.16
- mod_ssl-2.0.52-32.3.ent
- perl-Crypt-SSLeay-0.51-5

A versão que eu uso do RedHat é AS4 Update 6

Com as dependências de pacotes resolvidas, o configure deve rodar sem problema, e coom isso os makes podem ser feitos. O echo $? deve retornar um 0 (zero), informando que não houve qualquer problema na compilação e instalação.

Caso voce utilize um servidor ldap master e um slave, execute a instalação do openldap nas duas máquinas, exatamente da mesma maneira.

Nos próximos dias eu continuarei com este post, mostrando como criar um slapd.conf, criar a árvore ldap inicial, criar as entradas na árvore ldap, criar os usuários e definir e aplicar as políticas permittidas pelo Password Policy

13/Setembro/2007

Kernel

Arquivado em: Uncategorized — Gustavo @ 1:33 am

Particularmente o processo de compilação é relativamente simples. O que pega mesmo é o que voce vai compilar (ou melhor, o que será compilado juntamente com a base e o que será compilado como módulo). O comentário é que, se voce usa algum recurso mais de uma vez em uma mesma semana, então compile o suporte a este recurso diretamente no kernel. Caso contrário, compile-o como módulo.

O sistema utilizado nestes passos foi um Debian 3.1 r5, com kernel padrão 2.4.27. O kernel compilado foi o 2.6.13, mas os passos para compilar qualquer outro kernel da série 2.6 é o mesmo.

Para iniciar, vá até o site http://www.kernel.org/pub/linux/kernel/v2.6/ e pegue o arquivo linux-2.6.13.5.tar.bz2.

Salve este arquivo em qualquer lugar no seu sistema. Realize a descompactação e untar do mesmo com o comando tar xvjf linux-2.6.13.5.tar.bz2 -C /usr/src

Vá até o diretório /usr/src e crie um link para linux com o comando ln -s linux-2.6.13.5 linux

Instale alguns aplicativos necessários para começarmos a configurar o seu kernel e depois compilá-lo. Vale lembrar que o compilador C deve estar instalado no seu sistema. Caso não esteja, basta adicionar a parte entre colchetes na linha abaixo.
# aptitude install libncurses5 libncurses5-dev initrd-tools [gcc g++]

Após o término da instalação destes aplicativos, vá para o diretório linux e edite o arquivo Makefile. Na variavel Extraversion, coloque alguma string que identifique que este kernel foi compilado por voce. Salve e saia.

Execute o comando make menuconfig, e escolha as opções para que sua máquina funcione corretamente. Uma dica é utilizar os comandos lsusb e lspci para listar o hardware que sua máquina tem atualmente. Caso voce não encontre estes comandos, basta instalar os pacotes pciutils e usbutils

Este passo de configuração deve serfeito com bastante calma, pois dependendo da sua configuração algumas configurações especiais precisarão existir, e isto depende exclusivamente do hardware que voce possui. Lembre-se de salvar o arquivo de configuração com o nome .config.

Depois de salvar a sua configuração, efetue uma cópia de segurança de seu arquivo de configuração, apenas para manter registro. Caso a sua compilação não funcione, ou a máquina não consiga bootar com o novo kernel, voce deve voltar à prancheta novamente e verificar a sua configuração.

Bom, pensando que a sua configuração está OK, vamos executar a compilação propiamente dita. Para isso, basta digitar make.

Após uns 20 a 30 minutos de trabalho de seu micro, o seu novo kernel já está compilado. Como na série 2.6 a compilação dos módulos já acontece juntamente com a compilação do kernel, basta copiarmos estes módulos compilados para seu local padrão, que deve ser /lib/modules/2.6.13.5_sua-string. Isto é feito com o comando make módules_install

Copie o arquivo bzImage para o diretório /boot. Minha sugestão é que voce renomeie este arquivo para algo mais esclarecedor, como por exemplo kernel-2.6.13.5_sua-string. Use o comando cp /usr/src/linux/arch/i386/boot/bzImage /boot/kernel-2.6.13.5_sua-string

Vamos criar o arquivo de inicialização. Para fazer isso, use o comando mkinitrd -o /boot/initrd.img-2.6.13.5_sua-string /lib/modules/2.6.13.5_sua-string.

Agora o último passo é configurar o boot loader, ou o GRUB como é mais conhecido. Edite o arquivo /boot/grub/menu.lst e vá até o final do arquivo. Lá voce deve encontrar linhas semelhantes a estas abaixo.

title                                                      Debian GNU/Linux, kernel 2.4.27
root                                                      (hd0,0)
kernel                                                   /vmlinuz-2.4.27 root=/dev/sda3 ro
initrd                                                    /initrd.img-2.4.27
savedefault

Faça uma cópia destas linhas e coloque no final do arquivo. De acordo com as informações acima, suas linhas devem se parecer com estas

title                                                       Debian GNU/Linux, kernel 2.6.13.5_sua-string
root                                                       (hd0,0)
kernel                                                    /vmlinuz-2.6.13.5_sua-string root=/dev/sda3 ro
initrd                                                     /initrd.img-2.6.13.5_sua-string
savedefault

Prontinho. Agora basta ajoelhar e torcer para que sua máquina suba com o novo kernel compilado por voce.

Módulos

Eu mencionei a compilação automática dos módulos quando o kernel foi compilado. Mas como é a utilização e/ou gerenciamento destes módulos compilados ?

A princípio, quando o kernel necessita de uma funcionalidade que é suprida pelo módulo, o próprio kernel se encarrega de carregá-lo, mas voce pode carregá-lo usando o comando modprobe.

Pense no iptables. Mesmo quando voce compila todo o iptables no kernel, algumas características são fornecidas somente através de módulos, como o Connection Track ou o Stablished/Related. Quando voce chama o iptables com estas características, dois módulos são carregados para que estas características estejam disponíveis: ipt_state e ip_conntrack.

Então, depois que estes módulos foram carregados, execute um lsmod para ver se eles estão realmente lá. É possível também ver quais módulos estão carregados como comando cat proc/modules

Para verificar quais módulos estão disponíveis (compilados) para serem usados, basta executar um modprobe -l. Todos os arquivos que terminam em .ko são os módulos compilados e estão à sua disposição.

O comando modinfo mostra diversas informações sobre o módulo, inclusive se ele depende de algum outro módulo. Existe um arquivo chamado modules.dep que relaciona todos os módulos e suas dependencias. Caso haja algum problema com a carga de algum módulo por causa de suas dependencias, isto pode ser por algum erro neste arquivo. A melhor coisa a fazer é remover este arquivo e refaze-lo. O arquivo encontra-se em /lib/modules/$(uname -r)/modules.dep e para reconstruí-lo, use o comando depmod.

Para remover um módulo da memória, utilize o comando rmmod ou modprobe -r

12/Setembro/2007

Segurança

Arquivado em: Linux — Gustavo @ 1:03 am

O acesso remoto é um ponto extremamente problemático em termos de segurança. De que adianta ter um sistema bem fechado, se todo o acesso é realizado através de telnet e ftp ? Nestes protocolos, a senha trafega em texto puro, e qualquer sniffer é capaz de ler o usuário e senha utilizado.

Levando isto em consideração, muitos administradores hoje sequer ativam os serviços de telnet em seus servidores, e se o ftp é usado, é feito completamente sem senha, para evitar problemas.

O substituto destes dois protocolos chama-se ssh (de Secure SHell).

A instalação do ssh é extremamente simples. Em um sistema debian, basta executar um apt-get install ssh.

A parte legal disto é que através de um software chamado WinSCP, voce consegue copiar de e para o servidor Linux/Unix qualquer arquivo, como se fosse uma janela do windows explorer. Arrastar e soltar. Já para realizar o acesso remoto, use o PuTTy.

Entre estações linux/unix, o comando para acesso remoto é ssh usuario@ip-remoto. Para copiar arquivos, use o scp – scp arq-local usuario@ip-remoto:arq-remoto ou scp usuario@ip-remoto:arq-remoto arq-local

Mas em ssh existe uma facilidade na autenticação, que é a utilização de chaves. As chaves permitem segurança na autenticação, uma vez que ela é composta de 2 partes – pública e privada. Depois que a chave é criada, a parte pública pode e deve ser divulgada entre os servidores que receberão a conexão. E a parte privada da chave deve ficar bem guardada e bem protegida. Quando a conexão ssh se realiza, a verificação entre estas duas chaves, se OK, garante o acesso sem a necessidade de utilização de senha.

O processo de geração das chaves é muito simples. Basta usar o comando ssh-keygen (definindo qual é o tipo de chave escolhida) e seguir as orientações. Feito isto, proteja a chave privada e divulgue a chave pública.

TCP Wrappers

A utilização desta facilidade demanda várias conversas acaloradas. Existem os que abominam o uso e os que não vivem sem. Eu ainda vou assistir duas pessoas destes grupos defendendo as suas posições. Vai ser divertido…

Basicamente a coisa funciona assim. Existem 2 arquivos. /etc/hosts.sllow e /etc/hosts.deny. O primeiro permite as conexões e o segundo nega as conexões.

Para exemplificar, vou criar um bloqueio para que ninguém acesse meu seridor através de ssh, exceto minha máquina. A sintaxe fica assim (/etc/hosts.deny)

sshd : ALL EXCEPT 192.168.0.15

Ou assim (/etc/hosts.allow)

sshd : 192.168.0.15

Há os que dizem que a segunda maneira é melhor que a primeira. Particularmente eu não gosto de usar, porque há maneiras mais elegantes de impedir este tipo de acesso. Mas há quem goste, então ele ainda existe e creio que deve ficar no ar mais um bom tempo…

« Posts mais novosPosts mais antigos »

Blog no WordPress.com.