Administração de sistemas UnixProfessor Adjunto do Departamento de Engenharia Informática do ISEP IntroduçãoOs sistemas Unix sempre representaram uma opção importante quando se pretende fiabilidade e eficiência, embora existam muitas implementações especificas de determinados fabricantes (HP UX, IBM AIX, Digital ULTRIX, Digital UNIX, Novell UnixWare, SCO Unix, ...) todas elas mantêm um elevado grau de compatibilidade baseada no compilador de linguagem C, um conjunto de bibliotecas compativeis e um núcleo de sistema operativo (kernel) com conceitos que caracterizam os sistemas operativos tipo Unix. Embora não exista compatibilidade binária entre os diversos sistemas tipo Unix, existe compatibilidade de código fonte, isto significa que o "software" desenvolvido em linguagem C para uma dada plataforma Unix pode ser "compilado" em qualquer outra plataforma Unix. Mais recentemente o projecto aberto Linux tem-se assumido como uma alternativa de enorme importância, com um núcleo desenvolvido de forma aberta ("open source"), encontra-se disponível de forma mais ou menos gratuita, através de diversas distribuíções. Estas distribuíções Linux, além do núcleo, incluem todo o "software" adicional e ficheiros necessários para o funcionamento do sistema, a maioria deste "software" adicional é também desenvolvido em "open source". Sem tomar qualquer partido, algumas das distribuições mais tradicionais são: Slackware, Redhat e Suse. Administração de sistemas LinuxDada a sua importancia actual, a maioria da informação constante neste documento baseia-se em Linux, contudo a administração de outros sistemas Unix não difere quase nada da administração de sistema Linux. Com o seu carácter "open source", o sistema operativo Linux recebe as mais diversas contribuições e é actualmente a implementação Unix mais versátil, suportando as mais diversas possibilidades de configuração e integração. Administrar sistemas Linux pode ser um desafio significativo, normalmente os projectos "open source" produzem dois tipos de produto, "versão estável" e "versão em desenvolvimento/instavel", se o administrador se restringir à utilização das versões estáveis, tem certas garantias de uma existência pacífica, se pelo contrário tentar utilizar versões em desnvolvimento, corre riscos de instabilidade no respectivo sistema e possívelmente acabará a colaborar no desenvolvimento desses projectos. Por uma questão de metodologia, a administração de um sistema operatvo pode ser dividida em várias áreas distintas:
Na realidade todas estas áreas estão intimamente relacionadas entre sí
Qualquer sistema multi-utilizador tem de manter uma base de dados de utilizadores, nesta base de dados, geralmente de tipo relacional, existe um registo para cada utilizador. Cada utilizador tem diversas propriedades associadas a sí, para gerir os utilizadores e todo o sistema em geral existe um "super-utilizador" ou administrador, nos sistemas Unix existe um único administrador que tem o nome "root". Nos sistemas tipo Unix os utilizadores estão definidos no ficheiro /etc/passwd, neste ficheiro de texto, cada linha corresponde a um utilizador, constando uma sequencia de campos, separados por dois pontos, todos os campos são obrigatórios, mas alguns podem estar vazios. O exemplo seguinte ilustra um extracto de 8 linhas (8 utilizadores) de um ficheiro /etc/passwd: root:BeDyr8qulmhZ2:0:0:root:/root:/bin/bash daemon:*:2:2:daemon:/sbin:/bin/bash bin:*:1:1:bin:/bin:/bin/bash postgres:*:26:2:Postgres Database Admin:/var/lib/pgsql:/bin/bash wwwrun:*:30:65534:Daemon user for apache:/tmp:/bin/bash empress:*:35:2:Empress Database Admin:/usr/empress:/bin/bash guest:a28HqK3Yamh7t:1001:102:Utilizador nosso convidado:/home/guest:/bin/csh user:uHr5fg6RtEw23:1002:102:Utilizador local:/home/user:/bin/bash + Os campos são, ordenadamente, os seguintes:
Grupos de utilizadores A definição de grupos de utilizadores é muito vantajosa sob o ponto de vista de administração porque quando se pretende atribuir a muitos utilizadores um dado direito (permissão) é possível atribuir esse direito ao grupo, tendo como efeito que todos os utilizadores que são membros do grupo passam também a usufruir desse direito. Nos sistemas Unix os grupos estão definidos no ficheiro /etc/group, este ficheiro tem uma estrutura semalhante à do /etc/passwd, os campos são os seguintes:
A seguir apresenta-se um extracto de um ficheiro /etc/group: root:x:0:root bin:x:1:root,bin,daemon daemon:x:2: users:x:102: nogroup:x:65534:root Pode observar-se que apesar do grupo "users" não ter membros definidos, na realidade, por cruzamento com o exemplo /etc/passwd anterior, os utilizadores "guest" e "user" são membros. Outro aspecto a destacar é a existência de um grupo chamado "root", se forem colocados utilizadores neste grupo, eles passarão a ter muitos dos direitos que o administrador possui sobre objectos do sistema, já que este é o grupo primário do administrador. Shadow passwd Um dos problemas suscitados pelo ficheiro /etc/passwd é o facto de ter de ser legivel para todos os utilizadores. Uma vez que o HASH da password consta no ficheiro, torna-se possível tentar "adivinhar" uma "password" que gera esse HASH, possivelmente não será a mesma "password" que o utilizador usa, mas servirá como autenticação. Quebrar desta forma o mecanismo de autenticação é extremamente difícil e moroso, a abordagem que é usada na prática consiste em usar um programa gerador de "passwords", baseado por exemplo num dicionário e tentar essas "passwords". Seja como for o acesso aos "hash" das "passwords" dos utilizadores é claramente um ponto fraco, o processo de tentativa de autenticação que deveria ser controlado pelo sistema (controlando o número máximo de tentativas e o atraso entre tentativas) pode ser simulado em outro sistema, basta para isso que o "hash" que consta no /etc/passwd seja copiado. Para resolver este problema de segurança, existe a possibilidade de utilizar um ficheiro sombra para armazenar os hash das "passwords", este ficheiro é /etc/shadow, mas ao contrário do ficheiro /etc/passwd apenas é legivel pelo utilizador "root". A designação "shadow" (sombra) deve-se ao facto de conter exactamente os mesmos registos do /etc/passwd. O ficheiro /etc/shadow tem uma estrutura semelhante ao /etc/passwd, mas os campos são os previstos para o campo da password no ficheiro /etc/passwd. Os campos, ordenadamente, são os seguintes:
Gestão das bases de dados de utilizadores Unix Existem diversos programas que podem ser usados para gerir os utilizadores, aqui vou apenas referir os programas básicos, que devem estar disponíveis em todos os tipos de sistema Unix, existem depois muitos outros programas que usam os primeiros e que são especificos de cada sistema em particular, muitos deles com interface gráfica. Na realidade para administrar utilizadores em Unix basta um editor de texto, de preferência o "vi", o único campo que não pode ser editado directamente é o "hash" da password, para isso é necessário recorrer ao programa "passwd". Em sistemas onde se usa "shadow passwords", depois de modificar manualmente o /etc/passwd é necessário ainda invocar o programa "pwconv". O "pwconv" cria no directório corrente um ficheiro "npasswd" e um "nshadow" que correspondem às novas versões dos ficheiros /etc/passwd e /etc/shadow depois de realizada a junção da informação. Os utilizadores podem alterar alguns aspectos da sua conta, o administrador pode alterar qualquer conta, para o efeito os programas seguintes verificam se quem os está a executar é o administrador ou não:
Geralmente todos os sistemas dispõem de programas mais sofisticados para manipular utlizadores, a utilização destes programas está geralmente reservada ao administrador:
A utilização de programas especificos é mais razoável do que a edição manual, estes programas especificos garante a exclusão mútua para escrita, isto é garantem que nunca existem dois programas a alterar simultaneamente as bases de dados dos utilizadores, com os resultados imprevisiveis que daí podem resultar, por outro lado a edição manual pode, por erro do administrador levar a que os ficheiros não respeitem a formatação ou não sejam coerentes. Tratando-se da base de dados dos utilizadores estes erros podem ser muito graves. Bases de dados de utilizadores centralizadas - NIS Com a rápida evoluçãao das redes de computadores, em grande parte impulsionadas pelos sistemas operativos Unix, tornou-se absolutamente necessário criar sistemas centralizados para estas bases de dados que evitassem uma gestão independente para cada máquina de uma rede, o mais tradicional em ambiente Unix é o sistema conhecido por "Yellow Pages" (yp) ou NIS ("Network Information Service"). Este sistema é composto por um servidor "ypserv", instalado numa máquina central por clientes "ypbind" instalados nas outras máquinas. Os vários clientes (ypbind) contactam o servidor para obterem mapas, que não são mais do que equivalentes dos conteúdos habituais dos ficheiros /etc/passwd, /etc/group e outros, como por exemplo o /etc/hosts ou o /etc/services. O servidor (ypserv) não usa directamente os ficheiros locais para responder aos clientes, existem programas (geralmente invocados através do comando "make" no directório /var/yp) que convertem a informação residente nos ficheiros locais (aqui vistos como ficheiros fonte) para um formato adequado ao servidor. Os ficheiros fonte podem ou não ser as versões em uso local no servidor (localizadas no directório /etc), se forem usadas como fonte as versões locais existe a grande vantagem de poderem ser usados os programas de gestão de utilizadores atrás referidos, apenas é necessário não esquecer de, após as alterações, invocar o comando "make" no directório /var/yp para actualizar a base de dados NIS. A desvantagem desta opção é que os utilizadores de sistema, tais como root, daemon, field, ... também vão ser colocados na base de dados. A opção por ficheiros separados como fonte NIS (noutro directório que não /etc) implica a necessidade de se usar programas especificos para gestão de utilizadores que permitam a manipulação dos ficheiros noutros directórios, estes programas não abundam. Os clientes NIS utilizam o programa ypbind direccionado para o servidor NIS, para que na autenticação dos utilizadores o servidor NIS seja consultado é necessário que a última linha dos ficheiros locais (/etc/passwd, /etc/group e /etc/shadow) contenha o sinal "+", que significa adicionar toda a informação do servidor NIS (também é possivel adicionar utilizadores NIS individuais, usando linhas contendo "+username". Nos clientes NIS é ainda possível usar vários comandos tais como o "ypcat" para consultar os vários mapas disponibilizados pelo servidor NIS, ou o "ypmatch" para pesquisar os mapas. O servidor NIS (ypserv) é apenas de leitura, para que os utilizadores possam alterar os seus dados "password/shell/nome-completo" recorre-se a um serviço separado, assim conjuntamente como o "ypserv" instala-se um outro servidor, o "yppasswdd" no lado do cliente NIS utiliza-se agora os comandos yppasswd, ypchsh e ypchfn que contactam o yppasswdd no servidor NIS. Suporte a multiplas origens de dados - nsswitch Com a introdução do NIS passaram a existir nos clientes duas origens para as definições de utilizadores, as bases de dados locais (no directório /etc) e as bases de dados NIS. A forma como se sinaliza tal facto é através da colocação de sinais "+" nas versões locais, tal significa que naquele ponto da pesquisa local deve ser realizada uma pesquisa no servidor NIS. Para o caso da resolução de nomes de máquinas podemos ter mesmo 3 origens diferentes para os dados: local (/etc/hosts), NIS ou DNS, os sistemas que são usados e em que ordem estão especificados no ficheiro /etc/host.conf. Os sistema Linux mais recentes expandem significativamente esta ideia, generalizando o suporte a multiplas origens para a informação de sistema, nomeadamente quanto a utilizadores. O sistema NSS ("Name Service Switch"), usa a informação constante no ficheiro /etc/nsswitch.conf para definir para cada tipo de informação, quais as origens a pesquisar e em que ordem. O NSS permite distinguir os seguintes tipos de informação de sistema: aliases, ethers, group, hosts, netgroup, network, passwd, protocols, publickey, rpc, services e shadow. Para cada um dos tipos de informação podem ser definidas as origens a pesquisar e a ordem que são pesquisadas. As origens possíveis para a pesquisa são definidas de forma modular, para cada tipo de origem deve ser instalada a biblioteca apropriada, geralmente com designação do tipo libnss_SERVICE.so, onde SERVICE é substituido pela designação do tipo de base da dados que pode posteriormente ser usada no /etc/nsswitch.conf. Alguns exemplos são:
O NSS permite um acesso transparente a diversas fontes de informação de sistema, contudo quando se trata de informaçãao referente a autenticação tudo se complica, no caso do NIS, as passwords são armazenadas exactamente da mesma forma que nas versões locais, mas se queremos generalizar para outros tipos de bases de dados de sistema, certamente que vai ser necessário suportar outros formatos. Recorde-se que mesmo para o NIS foi necessário criar um serviço separado (yppasswdd) para permitir a alteração de passwords. Para resolver o problema da autenticação com diversos tipos de bases de dados foi criado o conceito de "Pluggable Authentication Module" (PAM), trata-se de um sistema modular que por adição das bibliotecas apropriadas, geralmente residentes no directório /lib/security, permite aos programas usar os diversos sistemas de autenticação. Os ficheiros de configuração residentes no directório /etc/pam.d/ permitem definir para cada aplicação quais os modulos de autenticação a usar, tais como pam_ldap, pam_winbind, etc.
O sistema operativo Unix utiliza uma árvore de directórios única, isto é, no acesso aos ficheiros não existe o conceito de dispositivo de armazenamento (ex.: letras de drive), todos os dispositivos de armazenamemnto são integrados numa única árvore de directórios. Apesar disso são suportados um grande número de diferentes tipos de sistemas de ficheiros residentes nos mais diversos tipos de dispositivo de armazenamento ou servidores de ficheiros, que são depois integrados numa mesma árvore de directórios. A operação de integração de sistemas de ficheiros residentes em dispositivos distintos é conseguida à custa do conceito de "montagem". O sistema de ficheiros integrado começa a ser constituido através da montagem do directório RAIZ, simbolizado por "/", este é sempre o primeiro passo, geralmente o dispositivo que é usado para este efeito é um disco local, mas para máquinas "diskless" também pode ser um directório residente num servidor de ficheiros, ou um disco de RAM. Uma vez montada a raiz (/) podem ser acrescentados é estrutura outros sistemas de ficheiros residentes em outros dispositivos ou servidores de rede, para o efeito basta que na estrutura que já está montada exista um directório vazio, a montagem consiste na associação do directorio vazio ao dispositivo em questão. Depois de realizada a montagem o ponto inicial do sistema de ficheiros residente no dispositivo/servidor passa a coincidir com o que antes era o directório vazio, isto é o directório deixa de estár vazio e passa a conter a informação que se encontra no dispositivo/servidor. As montagens são permanentes até que sejam "desfeitas" (desmontagem), ficando disponíveis para todos os utilizadores e aplicações do sistema, estas operações apenas podem ser realizadas pelo administrador (root). O comando "mount" permite, montar um sistema de ficheiros, a sua sintaxe básica é a seguinte: mount dispositivo ponto-de-montagem A especificação do dispositivo varia de acordo com o seu tipo, os dispositivos locais estão definidos no directório /dev, por exemplo numa máquina equipada com dois controladores IDE, os discos serão:
A maioria das formatações para os discos exige a definição de partições, mesmo que seja uma única que ocupa todo o disco, as partições sõo identificadas por números inteiros que se acrescentam é identificação do disco, a primeira partição é a 1, a segunda a 2 e assim sucessivamente, deste modo, por exemplo a terceira partição do disco MASTER do controlador secundário é identificada por /dev/hdc3. Para o caso de controladores de discos SCSI, que ao contrários dos controladores IDE não estão limitados a dois discos, as identificações dos discos são /dev/sda, /dev/sdb, /dev/sdc, ... . Novamente, caso existam partições nos discos, estas serão númeradas e identificadas da mesma forma que foi descrita para os discos IDE. Os drives de disquete são identificados por /dev/fd(n), onde (n) é substituido por um número, o equivalente ao drive A: é /dev/fd0, o drive B: será /dev/fd1. O comando mount sem argumentos devolve uma listagem das montagens correntes, esta informação é mantida no ficheiro /etc/mtab, o exemplo seguinte mostra um resultado da invocação do comando mount, sem argumentos. /dev/hda3 on / type ext2 (rw) proc on /proc type proc (rw) /dev/hda1 on /boot type ext2 (rw) /dev/hdb on /cdrom1 type iso9660 (ro) /dev/hdc1 on /usr/local2 type ext2 (rw) /dev/fd0 on /disquete type msdos (ro) //winbox/c on /mnt/doshdd type smbfs (0) linuxbox:/usr on /usr2 type nfs (rw,addr=192.168.0.2) A informação apresentada consiste na identificação do dispositivo, ponto de montagem, tipo de sistema de ficheiros e opções de montagem, por exemplo rw=leitura/escrita e ro=leitura-apenas. Podemos verificar que a raiz do sistema de ficheiros é a terceira partição do disco MASTER do controlador IDE primário, enquanto a primeira partição do mesmo disco se encontra acessivel no directório /boot. O nome "proc" não corresponde a nenhum dispositivo, é usado pelo núcleo do sistema operativo para guardar diversa informação sobre o seu estado e deve estár sempre montado no directório /proc. De destacar ainda o /dev/hdb montado no directório /cdrom1, não se trata de um disco, mas sim de um leitor de CD-ROM, o facto de os CD's não terem partições justifica o facto de não existir qualquer numeração na identificação do dispositivo, o tipo de sistema de ficheiros mais comum para os CD-ROM's é o ISO9660, note-se ainda que esta montagem é apenas de leitura (ro). Pode também observar-se que a disquete correspondente ao drive A: está montada no directório /disquete. As duas últimas linhas apresentadas correspondem a directórios de servidores de rede, nestes casos a forma de definir o dispositivo depende do tipo de servidor, no caso, //winbox/c corresponde a uma partilha com o nome "C", por um PC Windows/98, chamado "WINBOX", o protocolo usado é o SMB (tipo de sistema de ficheiros é "smbfs"), este sistema de ficheiros remoto fica acessível no directório /mnt/doshdd. A última linha corresponde à montagem do directório /usr, exportado por uma máquina chamada "LINUXBOX", usando o protocolo NFS, este sistema de ficheiros remoto fica acessível em /usr2. O sistema operativo Unix usa intensivamente "caching" nos acessos aos sistemas de ficheiros que estão montados, para termos a certeza de que todas as alterações sobre um sistema de ficheiros são colocadas no dispositivo, este tem de ser desmontado. Para desmontar um sistema de ficheiros usa-se o comando "umount" que recebe como argumento o nome do directório onde o dispositivo está montado. Isto é valido por exemplo para dispositivos amoviveis, especialmente se montados no modo "leitura-escrita", por exemplo para usar uma disquete temos de realizar as operações na seguinte ordem: COLOCAR DISQUETE - MONTAR DISPOSITIVO - UTILIZAR - DESMONTAR DISPOSITIVO - RETIRAR DISQUETE. Em fases iniciais de desenvolvimento do suporte de alguns tipos de dispositivo, em especial para dispositivos correspondentes a servidores de ficheiros, pode ser necessário recorrer a programas separados para realizar as operações de montagem, posteriormente esse suporte é integrado no sistema e pode ser usado o comando mount. O ficheiro /proc/filesystems contém a lista de tipos de sistemas de ficheiros suportados pelo núcleo do sistema operativo e que por isso podem ser montados com o comando "mount". Embora os sistemas mais recentes já possuam o suporte de "smbfs" (acesso a servidores MicroSoft) integrado, podendo ser usado o comando mount, em sistemas Linux mais antigos, ou em que o suporte de "smbfs" não foi incluido ao compilar o núcleo do sistema operativo, pode ser necessário usar o comando smbmount. Embora não exemplificado acima, outro tipo de servidor suportado são os servidores Novell Netware, sendo nesse caso o tipo de sistema de ficheiros ncpfs, também neste caso, em versões mais antigas do Linux pode ser necessário recorrer ao programa "ncpmount". Embora existam também equivalentes smbumount e ncpumount, o comando umount permite desmontar qualquer tipo de sistemas de ficheiros. Quando se realiza uma montagem, com recurso ao comando mount, podemos especificar o tipo de sistema de ficheiros, usando a sintaxe Alguns tipos vulgarmente suportados em Linix são:
Durante o arranque ("boot") de um sistema Unix existe um conjunto de dispositivos que deve ser "montado" no sistema de ficheiros automaticamente. O ficheiro /etc/fstab contém a lista de todos os dispositivos que devem ser montados no arranque da máquina (e devem ser desmontados no encerramento da mesma). Eis um exemplo: /dev/hda3 / ext2 defaults 1 1 /dev/hda2 swap swap defaults 0 0 /dev/hda1 /boot ext2 defaults 1 2 /dev/hdb /cdrom1 iso9660 ro 0 0 /dev/hdc1 /usr/local2 ext2 defaults 1 1 none /proc proc defaults 0 0 A partição /dev/hda2 é usada para SWAP (memória virtual), sendo formatada de forma apropriada para esse efeito. Embora para as partições de SWAP não exista o conceito de montagem porque essas partições não são directamente acessiveis, nem fazem parte do sistema de ficheiros, devem ser activadas durante o arranque e para isso são registadas no ficheiro /etc/fstab. Os sistemas de ficheiros em Unix, para serem completamente funcionais, necessitam de um conjunto de caracteristicas importantes em termos de caracterização de cada entrada existente (ficheiro, directório, ... ). Estas caracteristicas (atributos) que devem estár associadas a cada entrada (i-node), algumas das mais importantes e visíveis são:
Nem todos os sistemas de ficheiros suportados pelo Linux obdecem a estas caracteriscas, sendo nessas situaçãoes realizadas adaptações de modo a que as diferenças que transpareçam sejam minimas, por exemplo se o sistema de ficheiros não suporta permissões ou outras propriedades, estes atributos serão definidos de um modo fixo no acto de montagem e o sistema montado aparenta ter esses atributos. Cada entrada num sistema de ficheiros Unix possui associada a sí uma identificação de utilizador (UID) e uma identificação de grupo (GID). Quando um utilizador cria uma nova entrada (ex.: ficheiro) o UID desse utilizador fica associado ao ficheiro, bem como o GID do grupo primário desse utilizador. O UID associado a uma entrada indica quem é o proprietário do ficheiro. Cada entrada num sistema de ficheiros Unix deve suportar o atributo MODO com capacidade para 16 bits, do bit mais significativo para o menos significativo, eles são usados da seguinte forma:
Como foi referido os 4 bits mais significativos são reservados para o sistema e nunca são manuseados directamente, os 3 bits seguintes definem permissões especiais que se abordará mais tarde, seguem-se 3 grupos de 3 bits que definem as permissões para 3 entidades, respectivamente o proprietário da entrada (UID), o grupo associado à entrada (GID) e todos os utilizadores. Como se pode observar existem 3 direitos básicos (permissões) LEITURA, ESCRITA e EXECUÇÃO. O significado que estas permissões assumem dependem do tipo de entrada, para os dois tipos mais comuns de entrada no sistema de ficheiros, o significado é o seguinte:
Para manter a segurança eficaz existem ainda as seguintes restrições:
As permissões básicas READ/WRITE/EXECUTE são habitualmente representadas através de um digito que correspondem à representação decimal dos 3 bits, deste modo EXECUTE corresponde ao valor 1 (1º bit), WRITE corresponde ao valor 2 (2º bit) e READ corresponde ao valor 4 (3º bit). Exemplos: 7 representa todos os bits com valor 1, ou seja todas as permissõ:es; 4 representa permissão de leitura apenas; 5 representa permissão de execução e de leitura. Representando na forma decimal os 3 grupos de permissões, para proprietário, grupo e outros forma-se uma sequencia de 3 digitos. Exemplos:
Este tipo de representação é vulgarmente usado no comando "chmod" que permite alterar as permissões sobre uma entrada do sistema de ficheiros. A permissões podem facilmente ser visualizadas através do comando "ls" com output longo (ls -l), eis um exemplo de uma listagem deste tipo de um directório /etc: total 1318 -rw-r--r-- 1 root root 9 Dec 10 1999 HOSTNAME drwxr-xr-x 2 root root 1024 Mar 10 2001 SuSEconfig -rw-r--r-- 1 root root 40458 Oct 9 18:50 TextConfig lrwxrwxrwx 1 root root 23 Oct 14 01:23 X -> /usr/local/deix/SVGA_16 -r--r--r-- 1 root root 12758 Jan 28 2000 apsfilterrc -rw------- 1 root root 608 Nov 14 09:41 crontab drwxr-xr-x 2 root root 1024 Oct 9 1999 default -rwxr-xr-x 1 root root 106 Sep 22 2000 hostOff -rw-r--r-- 1 root root 3139 Sep 22 2000 hostOff.log -rw-r--r-- 1 root root 10137 Nov 16 15:52 hosts -rw------- 1 root root 457 Jul 27 00:04 lilo.conf lrwxrwxrwx 1 root root 28 Mar 14 2001 lmhosts.rpmorig -> /usr/local/samba/lib/lmhosts -rw-rw-r-- 1 root root 32768 Oct 9 1999 psdevtab -rw-r----- 1 root shadow 879 Oct 19 11:31 shadow- -rw------- 1 root root 340 Oct 20 12:07 ypgroup -rw-r--r-- 1 root root 107 Oct 8 1998 ytalkrc lrwxrwxrwx 1 root root 7 Oct 9 1999 zshrc -> profile Na coluna da esquerda são representas as permissões/modo, primeira letra indica o tipo de entrada:
As 9 letras seguintes representam as permissões para proprietário, grupo e outros (3 letras para cada). Quando um utilizador cria um ficheiro ou directório, as permissões com que este é criado são definidas através da FILE CREATION MASK, esta máscara está definida no formato décimal acima descrito, nesta máscara devem estar activos os bits que se pretende forçar a zero nos novos ficheiros e directórios. Os utilizadores podem alterar a sua mascara de criação de ficheiros, geralmente o valor inicial (definido pelo sistema) é 022, que significa não dar permissão de escrita para o grupo nem para os outros. O valor desta máscara pode ser alterado usando o comando "umask". Alguns sistema Unix podem guardar mascaras individuais para cada utilizador (usando o campo de comentários do /etc/passwd), a maioria dos sistema Linux não o faz e por isso as alterações da mascara têm efeito apenas durante a sessão. Quando um utilizador possui direitos de execução sobre um ficheiro, tal significa que se trata de um programa que pode ser transformado num processo em execução. Quando um utilizador transforma um destes ficheiros num processo (invoca o executável) o processo possui sobre o sistema as mesmas permissões do utilizador que o invocou, isso acontece porque os processos ficam com um UID/GID associado correspondentes ao utilizador que os cria. Em muitas situações torna-se conveniente dar aos utilizadores permissões especiais, mas apenas para executar determinadas tarefas bem definidas que não comprometam a segurança. Para o conseguir, em Unix, é possível associar a um ficheiro executável o modo SETUID ou SETGID, se o ficheiro executável possúi um destes modos, o processo fica autorizado a alterar respectivamente o seu UID ou GID para os correspondentes aos do ficheiro. Observe-se os exemplos seguintes: -rwsr-xr-x 1 root shadow 34936 Sep 12 1998 /usr/bin/passwd -r-sr-sr-x 1 root root 20704 Sep 12 1998 /usr/bin/lpr Podemos observar que o programa /usr/bin/passwd tem activo o modo "s" nas permissões de proprietário, logo tem a possibilidade de adquirir o UID de root, e as suas permissões, diz-se que é um programa SETUID ROOT. Na segunda linha está listado o programa /usr/bin/lpr que é SETUID ROOT e SETGID ROOT. Os programas SETUID devem ser vistos sempre com desconfiança pois permitem a um utilizador qualquer adquirir as permissões do proprietário. Estas permissões especiais apenas devem ser associadas a programas de inteira confiança e muito bem testados, se eventualmente um utilizador conseguir alterar o comportamento normal de um destes programas as consequencias podem ser extremamente graves. Como medida de segurança adicional, em alguns sistemas, os bits SETUID e SETGID podem ser automaticamente desactivados sempre que se realiza uma operação de escrita sobre o ficheiro. Finalmente falta referir a utilização do bit STICKY (representado pela letra "t"), este bit pode ter diferentes significados em diferentes sistemas Unix, por exemplo para directórios o significado mais habitual é impedir a remoção de entradas a outros utilizadores além do proprietário dessas entradas, neste contexto é habitual estár associado aos directórios temporários partilhados, nos quais se pretende que todos os utilizadores possam criar novas entradas, mas não se pretende que uns possam remover/alterar as entradas dos outros: drwxrwxrwt 5 root root 5120 Nov 19 00:01 tmp Recorde-se que o direito de remover/mover entradas num sistema de ficheiros Unix, não é ditado pelas permissões sobre essas entradas, mas sim pelas permissões sobre o directório onde as entradas se encontram. Uma outra utilização comum do STICKY bit é em ficheiros executáveis, para evitar que fiquem bloqueados quando existem processos respectivos em execução, se o STICKY bit está activo, o ficheiro binário é colocado no dispositivo de SWAP para ser usado de forma privada pelo processo em execução. Em alguns sistema apenas o administrador pode activar o STICKY bit. Ligações Simbólicas De entre os vários tipos de entrada num sistema de ficheiros Unix vulgarmente manuseados directamente pelos utilizadores, além dos ficheiros e directórios, destacam-se ainda as ligações simbólicas. As ligações simbólicas são um conceito simples, mas com enorme utilizade para os utilizadores em geral e muito em especial para o administrador. Trata-se de entradas no sistema de ficheiros que apontam para outra entrada noutro ponto do sistema de ficheiros. Na listagem exemplo do directório /etc anteriormente apresentada podem observar-se 3 ligações simbólicas. Para todos os efeitos as propriedadas de uma ligação simbólica são as propriedades do "apontado", tipo de entrada (ficheiro, directório, etc), modo (permissões, etc), UID/GID. A única diferença entre o apontador (ligação simbólica) e o apontado está no nome, que pode ou não ser igual, e na localização. Para criar uma ligação simbólica pode ser usado o comando: As utilizações são as mais diversas. De um modo geral as ligações simbólicas são úteis sempre que pretendemos que algo aparente existir onde não existe ou/e que algo aparente ter um nome que não tem.
A instalação de "software" num sistema Unix pode ser realizada por diversas vias, uma das caracteristicas importantes deste tipo de sistema é a possibilidade de as actividades da administraçõo seram realizadas a diversos níveis de acordo com as necessidades particulares e nível de conhecimento do administrador sobre os detalhes de funcionamento considerados de baixo nível. Gestores de aplicações instaladas Com o progressivo desenvolvimento do sistema operativo Linux começam a ser cada vez mais comum "software" de gestão de aplicações instaladas. Estes programas de gestão do "software" instalado mantêm uma base de dados onde são registados todos os programas que estão instalados no sistema, os ficheiros pelos quais cada um dos programas é composto e ainda as relações de dependendecia entre o diverso "software". A sua utilização é extremamente vantajosa e simplifica de forma muito significativa o trabalho do administrador. Remover, actualizar e instalar "software" torna-se muito mais simples. A instalação de um dado "software" com estes sistemas exige desde logo a obtenção de um ficheiro de instalação do "software" apropriado ao gestor em uso. Estes ficheiros de instalação (normalmente designados por "packages"), além dos ficheiros pelos quais é constituida a aplicação, contêm diversa informação quanto a pré-requesitos a serem verificados, tais como o tipo de plataforma exigido e as dependencias que definem que outros "packages" devem estár previamente instalados no sistema. As dependências são também importantes no que se refere à remoção ou actualização de "software" já que este tipo de operação pode ter consequencias sobre outro "software" instalado que é dependente do primeiro. O sucesso deste tipo de gestores depende em larga medida da sua aceitação geral. Um dos mais conhecidos é o RPM ("Red Hat Package Manager"), incluido em muitas distribuições Linux tais como "Red Hat" ,"Suse", "Mandrake", ... . Infelizmente, nem sempre se encontram disponíveis os "packages" que pretendemos, para a nossa plataforma, para facilitar esta tarefa, o RPM pode usar "packages" em formato "source", ou seja "software" sob a forma de código fonte, sem compilar, o RPM pode depois ser usado para proceder à compilação do código fonte, produzindo um "package" binário pronto a instalar. Os "packages" em formato de código fonte, no caso do RPM são habitualmente conhecidos por SRC-RPM e a sua grande vantagem é poderem ser usados em qualquer plataforma, constituindo-se como alternativa quando não existe uma versão RPM (pré-compilada) disponível para uma dada plataforma, o seu inconveniente é que para efectuar a compilação (BUILD) é geralmente necessário instalar "software" adicional que não é necessário para usar as versões pré-compiladas. Software Comercial A maioria do software comercial, por razões obvias, é fornecido sob a forma pré-compilada e geralmente não utilizam os gestores de "software" existentes, em seu lugar disponibilizam um programa de instalação que se encarrega de verificar se a plataforma obdece aos requesitos pré-estabelecidos, estas verificações tentam determinar, por observação do sistema de ficheiros e realização de diversos testes se os pré-requesitos são atingidos. Algum deste "software" pré-compilado, de menor qualidade, pode mesmo não realizar verificações, deixando estas a cargo do administrador. Em certos casos, a instalação pode mesmo ser manual, obrigando o administrador a copiar os ficheiros da aplicação para os locais indicados. A utilização destes programas de instalação tem o inconveniente, na maioria dos casos, de não actualizar a base de dados do gestor de "software", logo para o gestor esse "software" não existe no sistema, como consequencia a remoção ou actualização de programas do qual este "software" comercial depende vai ser permitida. Software em código fonte A maioria do "software" "open-source" encontra-se disponível sob a forma de código fonte simples, geralmente sob a forma de um arquivo em formato TAR, este arquivo contém um directório base dentro do qual se encontra uma árvore de directórios contendo as várias partes do código fonte. O "software" distribuído desta forma, pode em principio, ser instalado em qualquer tipo de sistema Unix, contudo trata-se de um processo um pouco mais moroso que envolve a compilação do código fonte. Depois de extraidos os ficheiros do arquivo (para arquivos simples, com extensão [.tar] pode ser usado o comando tar xf, para arquivos comprimidos usando o gzip, geralmente com extensaão [.tgz] ou [.tag.gz], é necessária a opção z) obtem-se um directório de base no qual deve existir um programa de configuração, geralmente com o nome "configure". O programa de configuração destina-se a verificar requesitos do sistema e adaptar o código fonte às particularidades do sistema, uma vez executado com sucesso, o "software" encontra-se pronto a ser compilado. O processo de compilação inicia-se com o comando "make" e pode ser algo moroso. Uma vez concluida a compilação com sucesso, geralmente é suportada o comando "make install" que vai copiar os ficheiros binários e outros para os locais apropriados e desta forma instalar a aplicação. Embora o processo descrito acima seja quase "standard", nunca deve ser iniciado sem antes ler a documentação que acompanha o código fonte (geralmente ficheiros README ou INSTALL no interior do directório de base). Instalação manual de "software" Embora a instalação manual de "software" não seja actualmente muito conveniente, o conhecimento dos procedimentos envolvidos é muito importante porque permite ao administrador resolver problemas resultantes de instalações deficientes. Em Unix para a instalação de aplicações é usado um conjunto de nomes de directório "standard" que é obrigatório conhecer, cada um destes directórios tem uma finalidade a respeitar:
Este conjunto de directórios (ou parte deles) pode existir em vários pontos do sistema de ficheiros, esses pontos são o directório de base de instalação da aplicação, a instalação consiste basicamente na cópia de ficheiros para os subdirectórios apropriados do directório base:
Muitas aplicações também criam ficheiros de configuração/dados nos directórios dos utilizadores, quando estes usam as aplicações pela primeira vez, isto permite uma personalização da configuração individual para cada utilizador. A aplicação, uma vez instalada num dado directório base vai usar esse directório como base para encontrar os ficheiros de que necessita, nomeadamente de dados e de configuração. Se a aplicação sabe desde logo onde procurar os seus ficheiros, o mesmo não se pode dizer do sistema operativo. Neste aspecto existem 3 situações onde a interacção entre a aplicação e o sistema operativo pode ser afectada:
Administração de ServiçosOs serviços de um sistema são um conjunto de meios que permitem um acesso organizado aos recursos, a maioria dos serviços destinam-se a acesso externo (via rede) o acesso interno (apartir da "shell") é muito mais directo e simples (acesso ao sistema de ficheiros, execução de comandos, ...) pelo que normalmente não é necessário recorrer a este conceito. Um serviço de rede, que pretende facultar acesso a determinados recursos partindo do exterior do sistema tem de se preocupar com várias questões, tais como tipo de protocolo de comunicação usado, autenticação de utilizadores e filtragem de origens dos pedidos. Os serviços de rede usam protocolos de rede para transporte de dados, em Unix os protocolos de eleição são o TCP e o UDP que por sua vez usam o IP ("Internet Protocol"), mas especialmente quando se fala de Linux existe um grande número de protocolos suportados, tais como o IPX ou o Appletalk. Os serviços locais utilizam mecanismos internos de comunicação (IPC) tais como "Sockets Unix", "Filas de Mensagens", "Pipes" (FIFOs) e memória partilhada. Embora o Unix, e em particular o Linux, suportem outros protocolos de rede/transporte, existe uma clara ligação entre o Unix e a pilha TCP/IP, tal deve-se ao facto de o Unix ter sido a plataforma usada para o desenvolvimento do TPC/IP. Por sua vez o TCP/IP foi sempre a pilha mais usada pelo Unix, muitas implementações Unix apenas suportam TCP/IP e praticamente todos os sistemas operativos Unix suportam TCP/IP. Os serviços são quase todos implementados segundo o modelo "Cliente-Servidor", neste modelo o servidor é uma aplicação passiva que aguarda o contacto de um cliente, quando tal acontece "acorda" e presta o serviço pedido. O suporte de multiplas comunicações independentes com processos no interior de uma dada máquina é assegurado através da multiplexagem da interface-de-rede/endereço-de-máquina através dos números de porto ou porta ("port number"). Consultar o documento Redes, endereços, nomes e serviços - introdução. Na pilha TCP/IP existem dois protocolos disponíveis para a implementação de serviços, o UDP e o TCP:
Uma das caracteristicas que um serviço deve ter é estar permanentemente disponível, independentemente do número de clientes que estãao a ser atendidos. A implementação das aplicações servidoras tem de atender a este aspecto e às caracteristicas do protocolo usado:
Podemos então considerar dois tipos de servidor básico, os servidores UPD asseguram serviços simples sem ligação, são constituidos por um único processo que atende todos os pedidos de todos os clientes, quando existe um grande número de clientes, o tempo de resposta é afectado segundo o modelo das filas de espera M/D/1. Os servidores TCP proporcionam serviços fiáveis, com ligação, o servidor TCP é constituido por um processo que recebe os pedidos de ligação dos clientes, quando recebe um pedido cria um novo processo que trabalha em exclusivo para o novo cliente, os tempos de resposta sob pressão de um grande número clientes não são significativos porque existem processos servidores dedicados a cada cliente. Para serviços simples, os servidores UDP são mais eficientes em tempo de resposta porque não necessitam de criar um novo processo. Os sistemas tipo Unix são adequados a muitas finalidade, mas a sua eficiência e fiabilidade tornaram-nos a primeira escolha como plataforma para a implementação de serviços. Os serviços devem estár disponíveis imediatamente depois do arranque do sistema, os processos servidores são criados apartir dos "scripts" de boot de sistema, de acordo como o que está definido no ficheiro /etc/inittab, geralmente estes "scripts" encontram-se dentro do directório /sbin/init.d/, o exemplo seguinte mostra parte do ficheiro /sbin/init.d/apache : case "$1" in start) if test -x /usr/sbin/httpd ; then echo "Starting WWW-Server apache." /usr/sbin/httpd -f /etc/httpd/httpd.conf fi ;; stop) if [ -f /var/run/httpd.pid ] ; then echo -n "Shutting down Apache HTTP server" kill `cat /var/run/httpd.pid` rm -f /var/run/httpd.pid else echo -n "Apache not running?" fi echo ;; restart) if [ -f /var/run/httpd.pid ] ; then echo -n "Reload Apache configuration" kill -1 `cat /var/run/httpd.pid` else echo -n "Apache not running?" fi echo ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 esac Este script é automaticamente executado durante o arranque do sistema, com o argumento "start", pode observar-se que o processo servidor é criado por invocação do binário /usr/sbin/httpd que trata de criar o processo servidor. O "Internet Super-Server" (inetd) É comum um sistema Unix prestar dezenas ou centenas de serviços distintos, em principio seria necessário ter em execução outros tantos processos servidores. Embora um processo servidor não apresente grande consumo de capacidade de processamento quando não está a atender clientes, usa alguma memória central, e mesmo que tal não seja muito significativo pode considerar-se um despedicio de recursos porque são processos que até existir algum cliente "não fazem nada". O "Internet Super-Server" (inetd) resolve esta situação, a ideia é ter um único processo que assegure o atendimento de todos os diversos tipos de serviço necessários no sistema. É claro que o "inetd" não possui as funcionalidades dos diversos tipos de serviço, para isso recorre a programas externos. O "inetd" limita-se a escutar as várias portas de serviço, quando chega um pedido "passa a batata quente" a um programa externo específico para esse serviço. O programa "inetd" consulta o ficheiro de configuração /etc/inetd.conf, neste ficheiro encontram-se definidos os serviços que devem ser assegurados pelo "inetd", um serviço por linha, cada linha contém os seguintes campos separados por espaços:
O exemplo seguinte apresenta um extracto de um ficheiro /etc/inetd.conf: echo dgram udp wait root internal daytime dgram udp wait root internal time stream tcp nowait root internal ftp stream tcp nowait root /usr/sbin/tcpd in.ftpd telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd smtp stream tcp nowait root /usr/sbin/sendmail sendmail -bs shell stream tcp nowait root /usr/sbin/tcpd in.rshd -L pop3 stream tcp nowait root /usr/sbin/popper popper -s tftp dgram udp wait.400 root /usr/sbin/tcpd in.tftpd /tftpboot bootps dgram udp wait root /usr/sbin/bootpd bootpd -d4 -c /usr/local2/tftpboot finger stream tcp nowait nobody /usr/local/libexec/in.xfingerd in.xfingerd -b dc=pt systat stream tcp nowait nobody /bin/ps ps -auwwx netstat stream tcp nowait root /bin/netstat netstat -a netbios-ssn stream tcp nowait root /usr/sbin/smbd smbd -s /etc/smb.conf netbios-ns dgram udp wait root /usr/sbin/nmbd nmbd # End. O "inetd" assegura alguns serviços básicos sem recurso a programas externos, nesses casos (3 primeiras linhas do exemplo) usa-se a palavra "internal" em lugar do nome do executável externo. O programa "tcpd" é um auxiliar que realiza algumas validações da proveniencia dos pedidos e será abordado adiante. O funcionamento do "inetd" pode ser descrito do seguinte modo:
Os serviços com ligação (stream/tcp) podem ser sempre do tipo "nowait" porque para cada cliente é criado um "socket" independente ("system-call" "accept"), assim o "inetd" pode atender imediatamente novos pedidos para esse serviço. Pelo contrário, para os serviços sem ligação deverá ser sempre usado o modo "wait" porque só existe um "socket" e consequentemente não podem existir dois processo a usa-lo, apenas quando o novo processo termina é possível o "inetd" voltar a receber pedidos desse serviço. Por esta razão os servidores UDP devem ter tempos de execução o mais curtos possíveis, além disso se um destes servidores "encrava", o serviço fica bloqueado. Imediatamente a seguir ao modo wait/nowait pode ser colocado um número, separado por um ponto que indica o número máximo de processos que podem ser criados por minuto para atender o serviço, se nada for indicado o valor usado pelo "inetd" é normalmente de 40. Os servidores executáveis, invocados pelo "inetd" para prestar os serviços utilizam a entrada "standard" para receber dados do cliente (STDIN/Descritor 0) e a saída "standard" para enviar dados ao cliente (STDOUT/Descritor 1). Isto significa que os servidores invocados pelo "inetd" não necessitam de ser aplicações especificamente desenvolvidas para trabalhar em rede, no exemplo acima pode observar-se que as linhas correspondentes aos serviços "systat" e "netstat" utilizam comandos habitualmente usados na "shell", por exemplo, quando o comando "ps" é invocado escreve o seu resultado no descritor 1, como o "inetd" duplicou o descritor do "sochet" de rede para o descritor 1, o resultado é enviado ao cliente, no caso através de um "datagrama" UDP. O "xinetd" é uma versão melhorada do "inetd", utiliza o ficheiro de configuração /etc/xinetd.conf, mas pode ser realizada a inclusão de outros ficheiros de configuração, geralmente usa-se um directório /etc/xinetd.d/ para esse efeito, o "xinetd" é semelhante ao "inetd", o formato dos ficheiros de configuração é diferente, mas o conteúdo essencialmente o mesmo, ao contrário do "inetd", o "xinetd" permite filtrar os endereços de origem dos pedidos, para se conseguir isso com o "inetd" é necessário recorrer a um programa auxiliar, o "tcpd". Os sistemas Linux possuem uma biblioteca para implementação de filtragem de pedidos, essa biblioteca "libwrap.a" ("Access Control Library) define funções para realizar diversos tipos de validação, a validação (para cada serviço) pode basear-se em "nome do cliente", "endereço do cliente", "nome do utilizador", "nome do processo servidor", "nome do servidor", "endereço do servidor" e utiliza dois ficheiros de configuração: /etc/hosts.allow e /etc/hosts.deny. Estes ficheiros usam mascaras para identificar os clientes. Primeiro é verificado se o cliente se ajusta a alguma definição no /etc/hosts.allow, se isso acontecer o acesso é imediatamente autorizado. Se não, então será verificado se o cliente está abrangido pelo /etc/hosts.deny, se isso acontece o acesso é negado, caso contrário é autorizado. O programa "tcpd" ("TCP/IP Daemon Wrapper Program") destina-se a servir de intermediário entre o "inetd" e servidores que não suportam esta biblioteca de controlo de acesso. O "inetd" invoca o "tcpd" em lugar do servidor, o "tcpd" determina o número de porto/serviço a que estão associados os descritores (0/1) ("system-call" "getsockname") e valida o acesso usando a "libwrap", se o acesso é válido utiliza uma função "exec" para se substituir pelo verdadeiro servidor. Como se pode observar no exemplo anterior, o "tcpd" não necessita de uma especificação do executável servidor ao estilo função "exec", basta o nome do executável e os respectivos argumentos, o "tcpd" permite que o nome do executável seja especificado sem caminho, nesse caso o executável será procurado num directório pré-definido, normalmente /usr/bin/. Em termos de validação de acessos, a utilização do "xinetd" é vantajosa porque apesar de não ter tantas possibilidades de configuração como a "libwrap" usada pelo "tcpd" garante uma negação de acesso mais directa. A combinação "inetd/tcpd" obriga a criar um novo processo mesmo que depois o cliente não seja autorizado. Isso pode facilitar ataques de negação de serviço (saturação de pedidos). Confiança entre sistemas Unix A relação de confiança entre certos servidores é um conceito actualmente suportado por quase todos os sistemas operativos com pretenções a servirem de plataforma a servidores. Estas relações de confiança, geralmente definidas entre sistemas com administração comum visam aumentar a cooperação entre servidores, permitindo uma melhor distribuíção dos serviços e facilitando a administração. No limite o conjunto de servidores cooperantes pode funcionar como um todo e apresentar neste ponto de vista capacidade impossíveis de atingir com um único sistema. A cooperação entre sistemas envolve a existência de comunicações entre eles, na maioria dos casos sob a forma de prestação de serviços, o problema é que grande parte destes serviços são sensiveis sob o ponto de vista de segurança e por isso é necessário utilizar mecanismos de autenticação que tornam as operações mais pesadas. Os sistemas Unix utilizam um mecanismo muito simples que dispensa a utilização de processos pesados de autenticação, este mecanismo baseia-se apenas nos protocolos de comunicação e aproveita o facto de apenas o administrador poder usar portos UDP/TCP com valores inferiores a 1024, conhecidos normalmente por "portos reservados". No sistema que presta o serviço (servidor) definem-se estaticamente, os endereços de rede (IP) dos clientes de confiança, quando o servidor recebe um pedido consulta esta informação e compara o endereço de origem para saber se o cliente é de confiança. Em sistemas multi-utilizador esta verificação é insuficiente, é necessário saber se foi o utilizador "root" que emitiu o pedido, para isso o cliente tem de usar um porto inferior a 1024, assim o servidor além de verificar se o endereço de origem corresponde a uma máquina de confiança tem também de verificar se o porto de origem é inferior a 1024, nessas condiçõo o servidor sabe que o pedido provém do utilizador "root" na "máquina de confiança". Por ser extremamente simples este mecanismo é muito eficiênte, mas baseia toda a validação no endereço de origem o que pode não ser totalmente seguro. Este mecanismo é usado por vários serviços tais como "Remote Shell/Remote Copy" (rcp/rsh/rshd), "Remote Login" (rlogin/rlogind) e "Line Printer" (lpr/.../lpd), todos estes servidores usam o ficheiro de configuração /etc/hosts.equiv onde se encontram definidos os nomes/endereços dos "clientes de confiança". Muitos destes comandos destinam-se a ser invocados directamente pelo utilizidor, para conseguirem abrir um porto reservado (<1024) são SETUID "root". Uma outra aplicação importante do conceito de "sistema de confiança" é no NFS ("Network File System"), este sistema de servidores de ficheiros foi desenvolvido especificamente no contexto Unix e é radicalmente diferente dos outros servidores de ficheiros mais comuns. Enquanto os servidores de ficheiros mais conhecidos como Windows (SMB) e NetWare (NCP) baseiam este tipo de serviço no estabelecimento prévio de uma sessão de utilizador (geralmente autenticada por "username/password"), os servidores NFS disponibilizam ficheiros a máquinas clientes e não a utilizadores em particular. A configuração de um servidor NFS (mountd/nfsd) baseia-se no ficheiro /etc/exports, neste ficheiro são definidos os directórios a exportar (sub-directórios automaticamente incluidos) e uma lista de clientes (máquinas/endereços) que podem usar cada um dos directórios, para este efeito os clientes referênciados aqui são considerados de confiança. Para cada cliente é possível ainda especificar diversas opções relativas ao modo como o directório é exportado, o extracto seguinte apresenta um ficheiro /etc/exports: # This file contains a list of all directories exported to other computers. # It is used by rpc.nfsd and rpc.mountd. /tftpboot/192.168.0.1 linuxbox(rw,no_root_squash) /usr/local *(ro) newhost(rw) /cdrom1 *(ro) Neste exemplo pode observar-se que os directórios /usr/local e /cdrom1 são exportados para todos os clientes (*), em modo de leitura apenas (ro), sendo um acesso apenas de leitura e não sendo a informação confidencial, permite-se deste modo um acesso público a estes directíorios. O cliente "newhost" tem no entanto acesso de escrita (rw) ao directório /usr/local. O directório /tftpboot/192.168.0.1 é exportado em modo "read-write" para o cliente "linuxbox", é usada ainda a opcão "no_root_squash". Os pedidos envidos ao servidor NFS transportam sempre o UID/GID do utilizador que os desencadeou no cliente, no servidor esse UID/GID é usado no acesso ao directório local, por esta razão é conveniente que os UID/GID sejam os mesmos no cliente e no servidor, para isso basta centralizar a base de dados de utilizadores, por exemplo recorrendo a um servidor NIS. A utilização no servidor NFS do UID na máquina cliente tem uma excepção, por razões de segurança quando o servidor NFS recebe um pedido do UID=0 (root) não usa esse UID no servidor, em seu lugar usa o utilizador "nobody", esta medida de segurança pode ser desactivada usando a opção "no_root_squash", tal como se pode observar no exemplo acima. O operação se alteração de UID entre cliente e servidor é conhecida por "squashing" e sendo automática para o UID=0 pode ser forçada para outros UIDs. O servidor NFS apenas aceita pedidos provenientes de portas reservadas (<1024), o cliente NFS está integrado no núclo do sistema operativo da máquina cliente, o acesso ao servidor estabelecido pelo administrador usando o comando "mount", geralmente é colocada uma entrada no /etc/fstab para que seja realizado durante o arranque do sistema. Na máquina cliente, a forma como os utilizadores acedem ao sistema de ficheiros é de total responsabilidade da administração local, uma vez montado, o directório remoto torna-se acessível localmente como qualquer outro sistema de ficheiros. Uma das grandes vantagens dos servidores NFS é que não têm estado ("stateless"), apenas facultam operações deleitura e escrita, não disponibilizando as operações de abertura e encerramento do ficheiro, por esta razaão se um servidor NFS é reinicializado, os clientes não perdem informação, apenas existe uma indisponibilidade temporária. Segurança da confiança baseada em endereços O mecanismo de confiança entre máquinas baseado nos endereços de origem dos pedidos tem a grande vantagem de ser muito ligeiro e logo muito eficiênte sob o ponto de vista de performance, contudo a sua aplicação deve ter em consideração que se um intruso conseguir forjar o endereço de uma máquina de confiança, tudo está perdido. Desde logo este mecanismo só deve ser usado sob endereços de rede que são geridos pelo mesmo administrador dos sistemas, geralmente todos pertencentes a uma mesma rede. Embora se trate de forjar o endereço de origem do pedido, o intruso tem também de se assegurar que recebe os dados de resposta, isto complica bastante a tarefa, considerando que as máquinas de confiança se encontram todas numa mesma rede local, a menos que o servidor verdadeiro esteja inactivo, é impossível realizar o ataque porque ao existirem duas máquinas com o mesmo endereço torna-se imprevisivel a qual das máquinas vão ser entregues os dados que de qualquer forma não serã legiveis porque são apenas fragmentos. Uma abordagem possível seria desencadear um ataque duplo, por um lado bloquear o servidor verdadeiro com um ataque de negação de serviço (inundação de pedidos) e simultaneamente usar outra máquina para simular o endereço do servidor verdadeiro. O ataque descrito é possível se os servidores usarem ARP dinâmico (situação usual). Para fazer os dados chegar ao destino dentro de uma rede local, o endereço IP não é suficiente porque a infra-estrutura de comunicação usada (ex: ethernet) usa outro formato de endereços conhecidos por endereços físicos ou endereços MAC. Assim cada sistema Unix mantém uma tabela de equivalencias entre endereços IP locais e endereços MAC locais que lhe permite fazer chegar os dados ao destino correcto dentro de uma rede local. Para evitar a definição estática das tabelas MAC é usado um protocolo auxiliar, o ARP ("Address Resolution Protocol") que permite determinar quando necessário, qual o endereço MAC correspondente a um dado endereço IP. Para evitar o recurso sistemático a este protocolo, as equivalencias IP/MAC são guardadas numa tabela interna (tabela ARP), quando determinadas via protocolo ARP, as entradas nesta tabala são temporárias e são eliminadas depois de estarem algum tempo sem serem usadas. O problema do protocolo ARP é que não tem qualquer segurança, explicado de forma simples funciona do seguinte modo: é enviado a todos os nós da rede ("broadcast") um pedido para que o detentor do endereço IP do qual se pretende o MAC responda, ao obter a resposta fica-se a conhecer o endereço MAC. Como é obvio qualquer nó da rede que diga ser o detentor desse endereço IP vai ser aceite. A alternativa é utilizar uma tabela ARP estática, isso obriga o administrador a inserir com a ajuda do comando "arp" entradas na tabela, inseridas deste modo estas entradas são permanentes e o protocolo ARP nunca será usado para elas. As tabelas ARP estáticas aumentam um pouco a segurança, e inviabilizam a maioria dos ataques, embora afectem o funcionamento do sistema verdadeiro, não será possível ao intruso realizar operações sobre os sistemas aproveitando o estatuto de confiança. Com ARP estático o intruso é obrigado é obrigado a simular não apenas o endereço IP, mas também o endereço MAC, a maioria das interfaces de rede e respectivos "device drivers" actuais permitem que o endereço MAC seja alterado. Os efeitos da existência de dois nós com o mesmo endereço MAC numa mesma rede inviabilizam na maioria dos casos a comunicação, os efeitos exactos dependem da infra-estrutura de comunicação, por exemplo se se trata de um meio de "broadcast" simples ou de uma rede com comutação. Na eventualidade de o sistema verdadeiro estar inactivo (sem comunicações), a tarefa do intruso fica muito facilitada, se for usado ARP dinâmico, basta usar na máquina intrusa o mesmo IP do sistema verdadeiro, se for usado ARP estático terá também de ser simulado o enderço MAC. Para resolver o problema só existe uma via segura: evitar o acesso físico à rede onde se encontram os servidores. Esta configuração corresponde aliás ao modelo mais aconselhado para implementação de "intranets" com ligação á "internet". Aconselha-se vivamente que a rede onde se encontram os sistemas servidores esteja isolada e não seja a mesma rede onde os utilizadores trabalham, este tipo de rede isolada, exclusiva para servidores corresponde ao que se designa vulgarmente por rede desmilitarizada (DMZ - "DeMilitarized Zone"). A ligação desta rede à "internet" e à "intranet" é assegurada por um ou mais "routers"/"firewalls". |