domingo, 14 de dezembro de 2014

Daemon rTorrent com Screen

Usar o rTorrent como cliente de torrents numa máquina remota ou headless.

Como o rTorrent é um programa baseado em terminal, para poder correr precisa de um terminal, ou em alternativa de um screen ou dtach.
Vou usar o screen e também a interface web RTGui.

aptitude install rtorrent screen rtgui

Adiciona-se um utilizador que será usado apenas para executar o rTorrent:

adduser rtorrent

Cria-se o ficheiro /etc/init.d/rtorrent com o seguinte conteúdo:

#! /bin/sh
# rTorrent init script
#

case "$1" in
  start)
echo "Starting rtorrent..."
    su rtorrent -c 'screen -dmS rtorrent rtorrent'
    ;;
  stop)
echo "Stopping rtorrent..."
killall -s 2 rtorrent
    ;;
  *)
    echo "Usage: $0 {start|stop}"
    exit 1
    ;;
esac

exit 0

Definem-se as permissões e as opções necessárias:

chmod 755 /etc/init.d/rtorrent
update-rc.d rtorrent defaults
mkdir /etc/rtorrent
cd /etc/rtorrent
usermod -d /etc/rtorrent rtorrent
wget http://rtgui.googlecode.com/files/.rtorrent.rc

O ficheiro está em formato DOS, é preciso converter para formato linux para o rTorrent o conseguir ler.
Edita-se o ficheiro .rtorrent.rc, para conter os caminhos certos das diretorias, por exemplo:

directory=/media/disk1

Para configurar a interface web edita-se o ficheiro /etc/apache2/sites-enabled/000-default e adicionam-se estas linhas antes do último "</VirtualHost >"

LoadModule scgi_module /usr/lib/apache2/modules/mod_scgi.so
SCGIMount /RPC2 127.0.0.1:5000

Após esta alteração é preciso reniciar o Apache.

Servidor de impressão para Windows e Linux com CUPS

Servidor linux, no meu caso, Debian 6.0 Squeeze, a servir para a rede a impressora HP 1050 com o CUPS 1.4.4.

Entrar no servidor como root e instalar:

aptitude install cups hplip

O script de instalação inicia o cups, mas o daemon tem de estar desligado para as alterações nos ficheiros de configuração funcionarem, por isso fazemos:

/etc/init.d/cups stop

Editamos o ficheiro nano /etc/cups/cupsd.conf:

#
#
#   Sample configuration file for the Common UNIX Printing System (CUPS)
#   scheduler.  See "man cupsd.conf" for a complete description of this
#   file.
#

# Log general information in error_log - change "info" to "debug" for
# troubleshooting...
LogLevel warn

# Only listen for connections from the local machine.
Listen 0.0.0.0:631
Listen /var/run/cups/cups.sock

# Show shared printers on the local network.
Browsing On
BrowseOrder allow,deny
BrowseAllow all
BrowseAddress @LOCAL

# Default authentication type, when authentication is required...
DefaultAuthType Basic

JobRetryInterval 60
JobRetryLimit 10

# Restrict access to the server...

<Location />
  Order allow,deny
  Allow localhost
  Allow @LOCAL

</Location>

# Restrict access to the admin pages...
<Location /admin>
  Encryption Required
  Order allow,deny
  Allow @LOCAL
</Location>

# Restrict access to configuration files...
<Location /admin/conf>
  AuthType Basic
  Require user @SYSTEM
  Order allow,deny
  Allow @LOCAL
</Location>
(...)


Editamos o ficheiro /etc/cups/cups-files.conf:

# Administrator user group...
SystemGroup lpadmin

Inicia-se o daemon cups e adicionam-se as impressoras. O painel de configuração está em https://<endereço_ip>:631, onmde <endereço_ip> é o endereço ip da máquina onde o CUPS está instalado.
Depois volta a desativar-se o cups e edita-se o ficheiro /etc/cups/printers.conf, para mudar a política em caso de erro:

(...)
ErrorPolicy retry-job
(...)

Podemos ainda dizer qo SAMBA para usar o cups para fazer impressões. Editar /etc/samba/smb.conf

[printers]
   comment = All Printers
   browseable = no
   path = /tmp
   printable = yes
   public = yes
   writable = no
   create mode = 0700
   printcap name = /etc/printcap
   print command = /usr/bin/lpr -P%p -r %s
   printing = cups

domingo, 6 de outubro de 2013

Desativar serviços no Windows 7

O Windows 7 ( e todos os outros Windows depois e antes) tem uma grande quantidade de serviços a correr em background cuja única finalidade parece ser consumir recursos sem fornecer grande serviço...
Infelizmente, desligar serviços à toa pode ter consequências desagradáveis, pois estão interligados por uma rede de dependências e nem sempre é claro qual a consequência de desativar determinado serviço.
Ainda assim, compilei uma lista de serviços que são mais ou menos seguros de desativar, em determinadas situações.
A partir da linha de comandos os serviços podem ser desligados com sc stop "nome_do_serviço" e ligados com sc start "nome_do_serviço". Para desativar realmente o serviço também pode ser usado a linha de comandos, mas não vou aqui fazer isso. Apenas voi criar dois batch files para parar e reiniciar os respetivos serviços. Os comentários das batch files são auto-explicativos.

Desligar seviços


@echo off
rem Sem Homegroup estes seviços são desnecessários
sc stop "upnphost"
sc stop "Mcx2Svc"
sc stop "SSDPSRV"
sc stop "HomeGroupProvider"

rem Desligar o aero, temas, animações, etc do ecrã
sc stop "UxSms"
sc stop "Themes"

rem Desligar a impressora, scanner, fax
sc stop "Spooler"
sc stop "StiSvc"
sc stop "TapiSrv"
sc stop "Fax"

rem Desligar o diagnóstico e relato de erros
sc stop "DPS"

rem Desligar o ambiente de trabalho remoto
rem (tanto cliente como servidor)
sc stop "UmRdpService"
sc stop "SessionEnv"
echo Esperar 2 segundos...
choice /c sn /n /t 2 /d s
sc stop "TermService"

rem Desligar as atualizações e pesquisa do Windows
sc stop "wuauserv"
sc stop "WSearch"
sc stop "WPDBusEnum"
sc stop "BITS"
sc stop "lmhosts"

rem Desligar outras atualizações (adobe e google)
sc stop "AdobeARMService"
sc stop "gupdate"
sc stop "gupdatem"

Ligar os serviços


@echo off
rem Para usar o Homegroup
sc start "upnphost"
rem sc start "Mcx2Svc"
sc start "SSDPSRV"
sc start "HomeGroupProvider"

rem Ativar aero e animações de ecrã, etc
sc start "UxSms"
sc start "Themes"

rem Ativar a impressora e scanner
sc start "Spooler"
sc start "StiSvc"
sc start "TapiSrv"

rem Ativar o diagnósticos e relato de erros
sc start "DPS"

rem Ativar o ambiente de trabalho remoto
rem (cliente e servidor)
sc start "SessionEnv"
sc start "TermService"
sc start "UmRdpService"

rem Ativar atualizações e pesquisa do Windows
sc start "wuauserv"
sc start "WSearch"
sc start "WPDBusEnum"
sc start "BITS"
sc start "lmhosts"

rem Ativar outras atualizações (adobe, google)
sc start "AdobeARMService"
sc start "gupdate"

Parando todos os serviços é possível libertar várias centenas de MiB de memória RAM e muitos ciclos de processador.


Referências


sexta-feira, 4 de outubro de 2013

Restaurar WIM no Linux

Os ficheiros WIM (Windows IMage) são ficheiros comprimidos que contêm uma estrutura de diretórios ou um sistema de ficheiros inteiro do Windows e mais alguns metadados necessários para restaurar os ficheiros.
Os ficheiros WIM são normalmente usados para guardar e restaurar a partição de sistema do Windows, sendo portanto usados nas partições e discos de recuperação.
Um ficheiro WIM pode conter vários "volumes" internamente. A reposição do sistema normalmente implica a reposição de todos os volumes do ficheiro.
O ficheiro de reposição tem geralmente o nome boot.wim, mas pode ter outros nomes (como install.wim, final.wim, etc).
Os portáteis costumam trazer um programa específico para ler estes ficheiros e executar a recuperação do sistema.
Também é possível fazer a recuperação "à mão" usando o utilitário imagex.exe da Microsoft.O imagex é um executável de menos de 1 MiB que está incluído no WAIK (Windows Automated Installation Kit), que é um download de quase 2 GiB.
A recuperação pela linha de comandos não é propriamente simples, pois é preciso ter outro Windows onde executar os comandos, uma vez que vamos apagar completamente o Windows "original" do disco.
Existe, no entanto, um pacote wimtools para linux que permite manipular os ficheiros WIM de forma muito semelhante ao Windows.
As wimtools estão disponíveis em várias distribuições, mas o mais simples é usar Ubuntu, pois há um PPA para várias versões de Ubuntu:

sudo add-apt-repository ppa:nilarimogard/webupd8
sudo apt-get update
sudo apt-get install wimtools

Admitindo que o ficheiro WIM está em /media/pen/boot.wim e que a partição de destino é /dev/sda2, é preciso:

  1. Formatar a partição /dev/sda2 para ntfs
  2. Recuperar o ficheiro WIM:
    wimlib-imagex apply /media/pen/boot.wim 1 /dev/sda2
    1. Repetir o comando anterior para todos os volumes dentro de boot.wim (o número identifica o volume)
  3. Atualizar o gestor de arranque (por exemplo o Grub) para reconhecer os novos ficheiros na partição /dev/sda2
  4. Reiniciar e esperar
Depois fazer uma imagem com o partimage e salvar o setor de arranque e tabela de partições com o dd, porque os ficheiros WIM são muito chatos de usar.

quinta-feira, 29 de agosto de 2013

Raspberry Pi



A Universidade de Cambridge é uma das mais conceituadas universidades do mundo, mas desde há alguns anos se tem vindo a debater com um problema nos cursos de informática. A cada ano que passa os candidatos a estes cursos parecem vir cada vez pior preparados! O que significa que tem de ser investido mais tempo a ensinar a estes alunos conceitos que já deveriam ter adquirido. Sobra portanto menos tempo para aprender tópicos mais avançados, que fazem a diferença quando as empresas de informática pretendem contratar novos colaboradores. É claro que isto acaba por ter um efeito direto muito mais importante em nós os utilizadores finais: os jogos perdem qualidade, porque não há bons programadores para os fazer!


A Universidade procurou descobrir a razão desta tendência e chegou à conclusão de que se deve ao facto de as crianças terem menos necessidade de "experimentar" os computadores. Quando Bill Gates e Steve Jobs iniciaram as suas fortunas, os computadores eram apenas para "entusiastas" da eletrónica. Os computadores eram vendidos em kits (ou era preciso comprar as peças) e montá-los e programá-los manualmente para funcionarem. Atualmente os computadores são comprados já prontos para ser usados, com uma interface colorida, simples, bonita e cara, que desincentiva os utilizadores a desmontar a máquina e a experimentar.


Iniciou-se assim um projeto para trazer de volta os "bons velhos tempos" em que os utilizadores eram incentivados a experimentar com as suas máquinas. Nasceu o projeto Raspberry Pi.


Raspberry Pi Modelo A


Um Raspberry Pi é um dispositivo do tamanho de um cartão de crédito, capaz de realizar as mesmas tarefas de um computador de secretária de entrada de gama, mas produzido de forma a ser de baixo custo.


O modelo A (mais limitado) tem 128 MB de RAM, uma porta USB. O modelo B tem 256 MB de RAM, duas portas USB e uma porta ethernet. Ambos os modelos têm uma porta HDMI e saída vídeo RCA e audio stereo. No lugar de disco rígido possuiu uma ligação a um cartão SD interno. O processador é um ARM 11 a 700 MHz incluído num SoC (System on Chip - todo o sistema está incluído num único chip) que contém também um processador gráfico Videocore 4, capaz de descodificar vídeo em alta resolução.


Todos os componentes foram escolhidos de forma a serem baratos, mas capazes de desempenho aproximadamente equivalente a um PC de secretária e capazes de correr com uma fonte limitada de energia. A alimentação elétrica é fornecida através de uma ligação micro-USB padrão com 5 V, pelo que pode ser alimentada por 4 pilhas AA.


O Raspberry não inclui na embalagem disco, teclado, rato nem monitor. O disco é substituído por um cartão SD que pode ser facilmente trocado (evitando portanto que o sistema fique "bricado", pois se encravar basta substituir o cartão SD). O monitor é o componente mais caro de um PC, por isso o Raspberry possui uma saída HDMI que lhe permite ser ligado a uma televisão ou monitor recentes e uma saída RCA para ligar a televisões mais antigas.


O dispositivo é compatível com uma série de distribuições linux, existindo na internet muitos recursos, tanto oficiais como de entusiastas, sobre como colocar uma determinada distribuição (versão) de linux no Raspberry Pi. Agora perguntam-se "Linux?! Então e Windows?". O objetivo do Raspberry é que os utilizadores experimentem e compreendam o funcionamento do sistema, o que não é possível usando um sistema fechado, como o Windows.


Há utilizadores que transformram o Raspberry em PCs de secretária, servidores, estações multimédia para a sala, colocaram-nos em balões e aviões telecomandados, usaram-nos como partes de um sistema de domótica, etc. O limite é a imaginação :)


terça-feira, 27 de agosto de 2013

domingo, 23 de junho de 2013

PXE Boot Server

Criar um servidor de imagens PXE com Debian Wheezy

Iniciando com uma máquina Debian já instalada é preciso:

  1. Instalar o TFTP e DHCP
  2. Configurar o TFTP e DHCP
  3. Criar uma imagem PXE
O servidor DHCP escolhido é o isc-dhcp-server e o servidor TFTP é o tftpd-hpa.
A interface onde vai funcionar o servidor DHCP tem de estar já configurada e ter um IP estático (não pode haver dois servidores DHCP no mesmo segmento de rede).

1. Instalar o TFTP e DHCP


Como de costume com Debian, a instalação é muito simples, a configuração é que é complicada.

aptitude install isc-dhcp-server tftpd-hpa

2. Configurar o TFTP e o DHCP


nano /etc/default/tftpd-hpa


TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure"

nano /etc/default/isc-dhcp-server

INTERFACES="eth1"

nano /etc/dhcp/dhcpd.conf

allow booting;
allow bootp;
authoritative;
subnet 10.0.0.0 netmask 255.255.255.0 {
        range dynamic-bootp 10.0.0.20 10.0.0.100;
        option routers 10.0.0.254;
        option broadcast-address 10.0.0.255;
        option domain-name-servers 208.67.222.222;
        allow unknown-clients;
        next-server 10.0.0.254;
        filename "pxelinux.0";
}

Reiniciar os serviços:

service tftpd-hpa restart
service isc-dhcp-server restart

3. Criar uma imagem PXE

aptitude install debootstrap nfs-kernel-server
mkdir /srv/tftp/pxeroot
debootstrap wheezy /srv/tftp/pxeroot
cd /srv/tftp/pxeroot
nano etc/network/interfaces
auto loiface lo inet loopbackauto eth0iface eth0 inet dhcp
nano etc/fstab
/dev/ram0  /       ext2   defaults    0   0proc       /proc      proc   defaults    0   1tmpfs      /tmp       tmpfs  defaults    0   1
chroot /srv/tftp/pxeroot

aptitude install linux-image-486
aptitude install partimage
aptitude install locales
dpkg-reconfigure locales
adduser root
adduser user
aptitude install xorg icewm slim
exit

cd /srv/tftp
wget http://ftp.debian.org/debian/dists/wheezy/main/installer-i386/current/images/netboot/pxelinux.0
cp pxeroot/vmlinuz ./
cp pxeroot/initrd.img ./
mkdir pxelinux.cfg
nano pxelinux.cfg/default

default menu.c32prompt 0timeout 300ONTIMEOUT local
MENU TITLE Welcome to PXE
LABEL Debian Wheezy x86 MENU LABEL Debian Wheezy x86 KERNEL images/deb-installer/linux APPEND initrd=images/deb-installer/initrd.gz
LABEL linux    kernel pxeroot/vmlinuz    append vga=normal initrd=pxeroot/boot/initrd.img-3.2.0-4-486 ramdisk_size=14332 root=/dev/nfs nfsroot=10.0.0.254:/srv/tftp/pxeroot rw --
nano /etc/exports
/srv/tftp/pxeroot    10.0.0.0/255.255.255.0(rw,sync,no_root_squash,no_subtree_check)
service nfs-kernel-server restart

domingo, 10 de março de 2013

Checklist de segurança Joomla!

Algumas dicas de segurança mais ou menos avulsas para Joomla.

A. Geral

  1. Aplicam-se as regras de segurança genéricas para o Apache, PHP e MySQL.

B. Instalação

  1. Não usar o prefixo de tabela MySQL "jos_".
  2. Definir as permissões do configuration.php para 444 (ou pelo menos 644).
  3. Em geral, os ficheiro PHP precisam de permissões 644 (preferencialmente 444) e as diretorias 755 (ou preferencialmente 555).
  4. De forma geral é boa ideia mover as diretorias /tmp, /log e todas as diretorias que precisem permissão de escrita (caches, imagens, uploads, etc) para FORA da diretoria pública (public_html), retirando-lhes portanto a possibilidade de acesso através de HTTP. No entanto isto pode causar problemas com a diretiva open_basedir do PHP e com algumas extensões.
  5. Não permitir o upload de scripts
  6. Renomear o ficheiro htaccess.txt para .htaccess e ligar o RewriteEngine.
  7. A adição destas linhas ao .htaccess bloqueia alguns exploits mais comuns:

########## Begin - Rewrite rules to block out some common exploits
#
# Block out any script trying to set a mosConfig value through the URL
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|%3D) [OR]
# Block out any script trying to base64_encode crap to send via URL
RewriteCond %{QUERY_STRING} base64_encode.*(.*) [OR]
# Block out any script that includes a < script> tag in URL
RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
# Block out any script trying to set a PHP GLOBALS variable via URL
RewriteCond %{QUERY_STRING} GLOBALS(=|[|%[0-9A-Z]{0,2}) [OR]
# Block out any script trying to modify a _REQUEST variable via URL
RewriteCond %{QUERY_STRING} _REQUEST(=|[|%[0-9A-Z]{0,2}) [OR]
# Block out any script that tries to set CONFIG_EXT (com_extcal2 issue)
RewriteCond %{QUERY_STRING} CONFIG_EXT([|%20|%5B).*= [NC,OR]
# Block out any script that tries to set sbp or sb_authorname via URL (simpleboard)
RewriteCond %{QUERY_STRING} sbp(=|%20|%3D) [OR]
RewriteCond %{QUERY_STRING} sb_authorname(=|%20|%3D)
# Send all blocked request to homepage with 403 Forbidden error!
RewriteRule ^(.*)$ index.php [F,L]
#
########## End - Rewrite rules to block out some common exploits

C. Utilizadores e passwords

  1. Usar passwords não triviais.
  2. Criar uma conta de administrador com um username não trivial (ou seja, diferente de admin, administrator, root, etc). Promover esse utilizador a super-user e apagar a conta de admin. Além de ser um username conhecido, a conta de admin tem sempre o id 42 (homenagem ao Hitchhicker's Guide to The Galaxy), por isso é uma vulnerabilidade potencial (para Joomla anterior a 2.5.5).

D. Extensões

  1. Não instalar extensões desnecessárias.
  2. A extensão sh404SEF adiciona mais um nível de segurança e capacidades SEF (Search Engine Friendly). Esta extensão é vulnerável nas versões < 3.7.0.
  3. A extensão Admin Tools Core permite aplicar num único local várias das proteções aqui referidas.
  4. A extensão Akeeba Backup Core permite fazer backups completos de forma simples.
  5. Há outras extensões que melhoram a segurança (mas ver regra D.1).

E. Não fornecer informação gratuita

  1. Não publicitar o nome e versão do Joomla. Remover a meta tag "Generator".
  2. Não publicitar o nome e versão das extensões.

F. Ações periódicas

  1. Fazer backups regulares (por exemplo com o Akeeba Backup)
  2. Fazer regularmente uma "inspeção visual" e eliminar ficheiros suspeitos/desnecessários.
  3. Fazer testes de vulnerabilidades (com o nikto, joomscan, etc) e corrigir as vulnerabilidades detetadas.
  4. Manter-se atualizado sobre as novas vulnerabilidades descobertas consultando sites especializados (http://secunia.com/search/?search=joomla, http://www.frsirt.com/english, http://www.milw0rm.com/, por exemplo)

G. Atualizar

  1. Manter o Apache, PHP e MySQL atualizados.
  2. Manter o Joomla atualizado. A partir da versão 1.6 há a opção de o Joomla se autoatualizar (mas é necessário verificar a disponibilidade das extensões). Não usar Joomla 1.5 ou anterior.
  3. Manter as extensões atualizadas. Mesmo as extensões mais conhecidas e populares têm problemas de segurança.

Referências


Cliente GoogleDrive em Debian

O Google Drive já anda por aí há uns bons meses e a Google ainda não libertou o cliente para linux.
Há já varias alternativas não oficiais, algumas open source outras não.
A insync disponibiliza um cliente de sincronização para Google Drive em linux (muitas distribuições suportadas) que é gratuito em versão beta, mas que se vai tornar pago quando sair de beta. Enquanto está em beta e a Google não acaba o seu próprio cliente esta é a maneira de instala o insync.
Em Debian (ou Ubuntu ou Mint) basta importar a chave do repositório com:

wget -qO - https://d2t3ff60b2tol4.cloudfront.net/services@insynchq.com.gpg.key | sudo apt-key add -

Acrescentar um ficheiro /etc/apt/sources.list.s/insync.list, com a linha:

deb http://apt.insynchq.com/[DISTRIBUTION] [CODENAME] non-free

Em que [DISTRIBUTION] é o nome da distribuição e [CODENAME] é o nome da versão. Por exemplo, para Debian 6 (squeeze) fica:

deb http://apt.insynchq.com/debian squeeze non-free

Atualizar os repositórios:

apt-get update

Há pacotes diferentes para cada interface gráfico. Instalar com

apt-get install insync-beta-[INTERFACE]

Para debian com Gnome fica:

apt-get install insync-beta-gnome

[INTERFACE] pode ser: ubuntu, cinnamon, gnome, kde, mate, xfce
O pacote kde suporta KDE 4.
O pacote gnome, aparentemente, só suporta Gnome 3, porque não consegui instalar em Squeeze.


Referência:
https://www.insynchq.com/linux

domingo, 3 de fevereiro de 2013

Proteger o acesso a uma página web do Apache com .htaccess

O ficheiro .htaccess permite modificar o comportamento do servidor web Apache de várias formas. Uma dessas formas é a definição de uma password que tem de ser digitada para poder aceder à página.
Este método envolve a criação de dois ficheiros: .htpasswd (que vai conter a password) e .htaccess (que contém as instruções para o Apache pedir a password). É necessário também ter acesso à linha de comandos do servidor (acesso físico ou por SSH).

.htpasswd

Criamos o ficheiro .htpasswd com o seguinte conteúdo:
myuser:X4r!23dF
Em que "myuser" é o nome de utilizador e o "X4r!23dF" é a password. O ":" é o separador entre o username e a password.
O .htpassword, por uma questão de segurança, deve ser criado numa pasta não acessível a partir da web.
O ficheiro .htpasswd tem de ser encriptado para poder ser utilizado. A encriptação é feita usando o utilitário htpasswd. Portanto executamos:
htpasswd -c .htpasswd myuser
O parâmetro -c indica que queremos criar um novo ficheiro encriptado. O "myuser" é o username que queremos usar. É nos pedida a password (duas vezes).
Se tentarmos ver o conteúdo do .htpasswd com:
cat .htpasswd
Verificamos que o nome de utilizador continua visível, mas a password está encriptada.

.htaccess

Vamos agora criar o ficheiro .htaccess. Ao contrário do .htpasswd, este deve ser criado na pasta web que pretendemos proteger.
O .htaccess deve ficar com este conteúdo:

AuthUserFile /caminho/completo/.htpasswdAuthType BasicAuthName "Documento protegido"Require valid-user

Erro comum

Se as diretivas no ficheiro .htacces aparentam não estar a funcionar, a causa mais provável é a existência da diretiva
AllowOverride none
na configuração da pasta no Apache. Com esta opção o ficheiro .htaccess é completamente ignorado pelo Apache. Apenas é necessário editar a linha para
AllowOverride all
para permitir todas as diretivas no .htaccess, ou então
AllowOverride AuthConfig
para autorizar apenas as oções relativas à autrnticação.
Depois de alterar a configuração do Apache é necessário reiniciá-lo com
/etc/init.d/apache2 restart
ou com um comando equivalente.

Referências


http://www.elated.com/articles/password-protecting-your-pages-with-htaccess/
http://httpd.apache.org/docs/2.0/mod/core.html#allowoverride

sexta-feira, 19 de outubro de 2012

Repositórios Debian

Alguns repositórios Debian

Aqui fica uma lista de alguns repositórios Debian bem jeitosos. O sources.list fica apenas com os repositórios oficiais Debian. Os outros repositórios ficam cada um no seu ficheiro .list na diretoria sources.list.d, para ser mais fácil gerir.

 

sources.list


deb http://ftp.pt.debian.org/debian/ squeeze main contrib non-free

deb-src http://ftp.pt.debian.org/debian/ squeeze main contrib non-free

deb http://security.debian.org/ squeeze/updates main contrib non-free
deb-src http://security.debian.org/ squeeze/updates main contrib non-free

# squeeze-updates, previously known as 'volatile'
deb http://ftp.pt.debian.org/debian/ squeeze-updates main contrib non-free
deb-src http://ftp.pt.debian.org/debian/ squeeze-updates main contrib non-free

sources.list.d/dropbox.list


# dropbox
# apt-key adv --keyserver pgp.mit.edu --recv-keys 5044912E
deb http://linux.dropbox.com/debian squeeze main

sources.list.d/google.list


##########################
# Google APT Repositories #
##########################
# wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
# Google Chrome repo http://www.google.com/linuxrepositories/
deb http://dl.google.com/linux/chrome/deb/ stable main
# Google Talk browser plugin http://www.google.com/chat/video
# deb http://dl.google.com/linux/talkplugin/deb/ stable main
# Google Earth
# deb http://dl.google.com/linux/earth/deb/ stable main
# Google's Music Manager
# http://www.google.com/support/music/bin/answer.py?answer=1229970
# deb http://dl.google.com/linux/musicmanager/deb/ stable main

sources.list.d/mozilla.list


# mozilla
# http://mozilla.debian.net
# iceweasel, icedove, iceape
# apt-get install pkg-mozilla-archive-keyring
# deb http://mozilla.debian.net/ squeeze main
# firefox, thunderbird
# apt-key adv --recv-keys --keyserver keyserver.ubuntu.com C1289A29
deb http://downloads.sourceforge.net/project/ubuntuzilla/mozilla/apt all main
# os pacotes são firefox-mozilla-build, thunderbird-mozilla-build, seamonkey-mozilla-build

sources.list.d/multimedia.list


# deb multimedia
# http://deb-multimedia.org
# apt-get update
# apt-get install deb-multimedia-keyring
deb http://deb-multimedia.org squeeze main non-free
# deb http://deb-multimedia.org squeeze-backports main

sources.list.d/playonlinux.list


# play-on-linux
# wget -q "http://deb.playonlinux.com/public.gpg" -O- | apt-key add -
deb http://deb.playonlinux.com/ squeeze main

sources.list.d/virtualbox.list


# virtualbox
# wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -
deb http://download.virtualbox.org/virtualbox/debian squeeze contrib non-free

sources.list.d/scribus.list


# scribus
# apt-key adv --recv-keys --keyserver subkeys.pgp.net EEF818CF
deb http://debian.scribus.net/debian stable main
deb-src http://debian.scribus.net/debian stable main

Referências

https://sites.google.com/site/mydebiansourceslist/

quinta-feira, 23 de agosto de 2012

logwatch, fail2ban, molly-guard

Mais umas excelentes ferramentas para sistemas linux

logwatch


Instala-se com o habitual

apt-get install logwatch

E já está.
A instalação cria um script em /etc/cron.daily que se encarrega de correr o logwatch e enviar um email para o root.

Para modificar as opções pré-definidas é preciso copiar o ficheiro de configuração de exemplo para /etc/logwatch/conf:


cp /usr/share/logwatch/default.conf/logwatch.conf /etc/logwatch/conf/

E editar o ficheiro. No Debian a opção TmpDir estava mal configurada, deve ser mudada para /tmp.
Todas as opções podem ser sobrepostas através de parâmetros na linha de comandos.

O logwatch apenas cria o relatório com os eventos mais significativos do sistema, é responsabilidade do administrador ler o relatório e agir em conformidade.

fail2ban

apt-get install fail2ban

E já está.
A configuração básica está em /etc/fail2ban/fail2ban.conf e a configuração mais específica em /etc/fail2ban/jail.conf.

Apenas a proteção das ligações SSH está pré-definida, para outros protocolos/aplicações é preciso editar o /etc/fail2ban/jail.conf.

molly-guard

apt-get install molly-guard

E já está.
O molly-guard pede o nome da máquina quando tentamos desligar uma máquina através de SSH.

Algumas coisas básicas a fazer numa máquina nova

Um pequeno conjunto de aplicações e configurações a executar em máquinas novas (linux claro, Debian de preferência)

Rede


Primeiro que tudo é sempre preciso configurar corretamente a rede.
Se a interface de rede é configurada por DHCP não há muito a fazer, mas se queremos um IP estático é preciso editar o /etc/network/interfaces e substituir o dhcp por static na interface pretendida e indicar, pelo menos o endereço, netmask e gateway, qualquer coisa assim:


auto eth0
iface eth0 inet static
        address 192.168.1.31
        netmask 255.255.255.0
        gateway 192.168.1.254

Mas nem só de IP vive a rede. Também é importante definir os servidores de DNS, o hostname e o domain name. Mais uma vez o DHCP trata disto, mas se quisermos um IP estático temos de editar /etc/resolv.conf, /etc/hostname e /etc/hosts.

É preciso escolher um hostname, que identifica a máquina e um nome de domínio, que identifica a rede local. Vamos usar server001 e lan, respetivamente.

Em /etc/resolv.conf colocamos o nome de domínio e os servidores de DNS. DNS é um serviço crítico, por isso normalmente são definidos pelo menos dois. O ficheiro pode ficar com este conteúdo:

domain lan
search lan
nameserver 208.67.220.220
nameserver 208.67.222.222

Neste caso o domínio chama-se lan (é o pré-definido) e dizemos que queremos pesquisar o domínio lan. As duas entradas nameserver são os dois servidores DNS a usar. Os IPs indicados são do serviço OpenDNS e podem ser usados livremente. Por vezes há uma única entrada nameserver que corresponde ao gateway da rede, é usual em sistemas configurados por DHCP.

Em /etc/hostname colocamos o hostname (basicamente o nome da máquina), assim:

server001

No ficheiro hosts convém colocar uma entrada para o hostname definido antes, qualquer coisa como:

127.0.0.1 localhost
127.0.0.1 server001 server001.lan

Para que tudo funcione é preciso reiniciar os serviços respetivos:

/etc/init.d/networking restart
/etc/init.d/hostname start

Tempo


Parecendo que não, é bastante importante que o relógio e o fuso horário do sistema estejam certos, principalmente se vamos usar coisas como servidores de mail, serviços de autenticação  e até para os logs do sistema.
Para configurar o fuso horário:

dpkg-reconfigure tzdata

Para acertar a hora o melhor é deixar que o sistema se atualize automaticamente, é para isso que existe o serviço NTP. Basta fazer:

apt-get install ntp

E esperar um pouco enquanto o sistema sincroniza.
Podemos ver o estado do NTP com:

ntpq -p

Para ver a data e hora atual fazer:

date

Quando a hora estiver certa convém atualizar o relógio de hardware, para poder manter a hora certa (pelo menos com pequenas variações) mesmo enquanto o sistema está desligado. Para atualizar o relógio de hardware fazemos:

hwclock --systohc

Locale

Chama-se locale ao conjunto de definições que informam o sistema a língua a utilizar e os formatos para apresentação de datas, horas, valores monetários, etc.
É importante definir corretamente o locale que pretendemos usar, pois se não o fizermos arriscamo-nos a receber mensagens numa língua que não entendemos.
Para escolher os locales a gerar fazemos:

dpkg-reconfigure locales

Os locales selecionados serão criados. Pode demorar alguns segundos (ou minutos) a gerar cada locale.
O comando locale mostra as variáveis definidas.
Se alguma estiver em branco pode ser necessário defini-la manualmente com, por exemplo:

export LC_TIME=en_US.UTF-8

Ainda não consegui descobrir porque é que o dpkg-reconfigure locales nem sempre define todas as variáveis LC_* e LANG*.

Um script útil em servidores (principalmente os que têm pouco espaço em disco) é o localepurge. É só instalar com:

apt-get install localepurge

É preciso selecionar os locales a MANTER, todos os outros serão apagados.
Da próxima vez que se fizer uma instalação com o apt-get, ou se correr manualmente o localepurge, serão apagados os locales que não foram selecionados. Este script não é 'oficial' e pode causar alguns erros (inofensivos). Usar com precaução e RTFM.

rkhunter

Um caçador de rootkits para linux e BSD

Para instalar o rkhunter pode fazer-se o download a partir do site oficial e correr o script de instalação, mas como de costume prefiro os repositórios Debian:

apt-get install rkhunter

Ou para quem prefere otimizar o código (e tiver o apt-build instalado):

apt-build install rkhunter

Para correr manualmente, convém fazer uma atualização e só depois fazer a verificação:

rkhunter --update
rkhunter --check

Também podemos correr o comando:

rkhunter --propupd

Que cria uma base de dados com as propriedades dos ficheiros executáveis presentes no sistema. Das próximas vezes que o rkhunter for executado (SEM a opção --propupd) compara os ficheiros com a informação guardada e avisa se ocorreu alguma alteração. É claro que:

  1. É da responsabilidade do utilizador assegurar que todos os executáveis são legítimos quando se executa o --propupd;
  2. O rkhunter apenas avisa se ocorrer alguma alteração dos ficheiros, não tem forma de saber se essa alteração é fidedigna ou não (por exemplo, um apt-get upgrade altera as propriedades dos ficheiros).

O rkhunter costuma gerar alguns avisos 'falsos positivos', mas devem ser investigados, porque às vezes um verdadeiro positivo está escondido atrás de um falso.

A instalação do rkhunter cria os scripts /etc/cron.daily/rkhunter e /etc/cron.weekly/rkhunter que se encarregam de correr o rkhunter diariamente e de o atualizar semanalmente.
Os ficheiros /etc/default/rkhunter e /etc/rkhunter.conf têm as configurações a usar, mas as que estão pré-definidas são normalmente suficientes.

Referências

http://rkhunter.sourceforge.net/


segunda-feira, 30 de julho de 2012

Wake on lan e auto shutdown

Wake on lan e auto shutdown

Auto shutdown

O autoshutdown é simples, basta colocar o comando no crontab, mas esqueço-me sempre que os comandos no crontab precisam do caminho completo, porque a PATH é mais limitada.
Basta editar (como root) o crontab com:

crontab -e

E acrescentar uma linha do tipo:

00 03 * * * /sbin/shutdown -h +5

Isto vai fazer com que o computador se desligue às 3:05 da manhã, dando um aviso com 5 minutos de antecedência.

Wake on LAN

O Wake on LAN não é uma opção muito segura. Apesar de haver extensões ao protocolo original que acrescentam autenticação, o WOL original é muito inseguro. Mesmo assim pode dar jeito em casa :)
O computador deve ser configurado na BIOS para suportar o Wake on LAN. Nem todas as BIOS o suportam, nem todas as interfaces de rede o suportam e a forma como aparece na BIOS pode ser muito variada. Pode aparacer mesmo como "Wake on LAN" ou "Wake on PCI event" ou "Wake on PCI-E event" ou qualquer coisa parecida.
Mesmo assim pode ainda não ser suficiente para que o WOL funcione. O sistema operatvo também tem de colaborar. No Windows isso faz-se nas propriedades avançadas da interface de rede. No linux faz-se com o ethtool.
Para verificar se a interface de rede suporta Wak on LAN basta executar (como root):

ethtool eth0|grep Wake

Se não aparecer nada significa que a interface não suporta WOL.
Para assegurar que o linux habilita o WOL criei um script em /etc/network/if-ip.d/wolenable, com o seguinte conteúdo:

#!/bin/sh
ethtool -s eth0 wol g

Não esquecer de tornar o script executável com:

chmod +x /etc/network/if-up.d/wolenable

Para que o script seja executado é preciso adicionar uma linha à configuração da interface de rede em /etc/network/interfaces:

auto eth0
iface eth0 inet dhcp
    post-up /etc/network/if-up.d/wolenable

Isto vai executar o script cada vez que a interface eth0 seja iniciada (a linha nova está a negrito).
Depois é só uma questão de a partir de outra máquina (no mesmo domínio de broadcast) executar:

wakeonlan 01:23:45:67:89:ab

Substituindo o 01:23:45:67:89:ab pelo MAC address da máquina, claro.

sexta-feira, 27 de julho de 2012

Instalar o Debian por PXE

Instalar o Debian por PXE

A documentação do Debian, mas por vezes está um pouco desatualizada, como é o caso, por isso aqui fica um guião para instalar o Debian 6 por PXE.
Para instalar por PXE é preciso:


  1. Que o cliente esteja definido para arrancar por rede
  2. Um servidor de PXE com:
    1. Servidor DHCP corretamente configurado
    2. Servidor TFTP corretamente configurado
    3. Os ficheiro de arranque do Debian colocados no sítio certo.


1. Definir o arranque por rede

É preciso aceder à configuração da BIOS e definir o arranque por rede (ou PXE, ou LAN, ou ...). às vezes é mais complicado que que parece. Em algumas motherboards é preciso ativar a placa de rede e ou o arranque por PXE e depois reiniciar e voltar a entrar nas configurações da BIOS e só então aparece o arranque por LAN como opção de arranque. Caso o equipamento não suporte mesmo  arranque por LAN, ainda assim é possível criar uma disquete com o http://rom-o-matic.net/ (o guião fica para outro dia).


2. Servidor PXE

Para fazer o arranque por PXE é necessário configurar os serviços de DHCP e TFTP (há outras opções, usando BOOTP ou RARP, mas DHCP+TFTP é o mais simples e eficaz). Não é necessário que os dois serviços estejam na mesma máquina, nem que sejam linux, mas é mais fácil se estiverem. Aqui vou usar o próprio Debian 6 para fazer um servidor de PXE.

2.1. Instalar e configurar o DHCP

O pacote recomendado é o isc-dhcp-server:
apt-get install isc-dhcp-server
A configuração é feita no ficheiro /etc/dhcp/dhcpd.conf.
Coloquei o seguinte conteúdo:

ddns-update-style none;


option domain-name "lan";
option domain-name-servers 208.67.222.222, 208.67.220.220;
option subnet-mask 255.255.255.0;
default-lease-time 600;
max-lease-time 7200;
server-name "pxeserver";
allow booting;
allow bootp;
authoritative;



subnet 192.168.13.0 netmask 255.255.255.0 {
  range 192.168.13.20 192.168.13.100;
  option routers 192.168.13.254;
  option broadcast-address 192.168.13.255;
  option domain-name-servers 208.67.222.222;
}

subnet 192.168.1.0 netmask 255.255.255.0 {
}

group {
  host tftpclient {
    hardware ethernet 08:00:27:FA:3B:A2;
    filename "/pxelinux.0";
  }
}

2.2. Servidor TFTP corretamente configurado

O servidor de TFTP é o tftpd-hpa, embora haja outros.
apt-get install tftpd-hpa
E em princípio não é preciso mais nada. O TFTP deve ficar instalado e a funcionar. A diretoria que vai usar é a /srv/tftp. Portanto os ficheiros deve ser aí colocados.

2.3. Colocar os ficheiro de arranque do Debian

O CD de arranque do Debian contém um ficheiro netboot/netboot.tar.gz. Apenas é preciso descompactar este ficheiro na diretoria do TFTP (/srv/tftp).
Referências
http://www.debian.org/releases/stable/i386/ch04s05.html.pt
http://wiki.debian.org/DHCP_Server
http://http.us.debian.org/debian/dists/squeeze/main/installer-i386/current/images/netboot/

Partilhar ligação de internet

Partilhar a ligação de internet

Colocar uma máquina linux a partilhar a ligação de internet (desde que tenha pelo menos duas placas de rede, claro), é relativamente simples.
Aqui ficam as instruções para referência futura. Assume-se que wlan0 liga à internet e que eth0 liga à intranet.

Ligar o sistema de NAT (masquerade) na interface de ligação ao exterior:
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE

Aceitar pedido de encaminhamento proveniente da interface "interior":
iptables -A FORWARD -i eth0 -j ACCEPT

Habilitar o forwarding para IPv4:
sysctl -w net.ipv4.ip_forward=1

Atribuir um endereço à interface externa. Este passo não é necessário de a interface já tiver um endereço.
ifconfig eth0 10.0.0.254/24

Reiniciar o serviço de rede:
/etc/init.d/networking restart

segunda-feira, 23 de julho de 2012

Desligar (spindown) os discos automaticamente

Desligar (spindown) os discos automaticamente

Esta dica funciona melhor em sistemas com mais de um disco rígido (por exemplo, um homeserver, como é o meu caso) ou num portátil.
A ideia é arranjar maneira de desligar o motor dos discos rígidos quando estes não estão a ser usados. Poupa-se energia, pois o disco consome menos com o motor desligado obviamente e pode prolongar-se o tempo de vida do disco. Para prolongar o tempo de vida do disco é preciso definir um tempo espera generoso antes de fazer o spindown, pois demasiados ciclos de desligar e reiniciar o motor vão ter o efeito contrário, isto é, diminuir o tempo de vida do disco.
Assim, vou usar 30 minutos como tempo recomendado.
Há um projeto aqui http://code.google.com/p/spindown/ de um daemon que faz exatamente o que se pretende, mas eu quero uma solução mais "caseira", que assente mais em bash e que não seja preciso andar a compilar código.
Vou usar Debian para este projeto, pois ando desanimado com o Ubuntu. Está cada vez mais parecido ao Windows.
É preciso executar todos os comandos como root.

1. Instalar o sg3-utils

apt-get install sg3-utils
O pacote sg3-utils tem o comando sg_start que podemos usar para parar o motor do disco.
Aparentemente também se pode fazer com o sdparm e com o hdparm, mas ainda não experimentei.

2. Criar um script

Criei um script em /root/bin/spindown.sh com o seguinte conteúdo:

# !/bin/sh
if [ "$(id -u)" != "0" ]; then
        echo "This script must be run as root" 1>&2
        exit 1
fi
if [ -z $1 ]; then
        echo Usage: $0 sdX
        exit 1
fi
# isto estava a causar alguns problemas, por enquanto fica desligado
#if ! [ -e /dev/$1 ]; then
#        echo /dev/$1 not found
#        exit 1
#fi
NEWFILE=/tmp/NewState.$1
OLDFILE=/tmp/OldState.$1
date +"%F %T"
# Get new state from diskstats
NEWstate=$(cat /proc/diskstats | grep $1)
echo $NEWstate > $NEWFILE

if [ -z $(diff OLDstate.txt NEWstate.txt) ]; then
        echo Stopping $1...
        # sdparm --flexible --command=stop /dev/$1 &>/dev/null
        sg_start --stop /dev/$1
else
        echo $1 active
fi



# Write current state to file
echo $NEWstate > $OLDFILE

Não esquecer de ligar o bit executável no ficheiro:
chmod +x spindown.sh

3. Adicionar ao crontab

Adicionar ao crontab a linha:
*/30 * * * * /root/bin/spindown.sh sdc
Deve ser adicionada uma linha por cada disco que se pretende controlar, mudando o 'sdc' de acordo com o disco, claro.

Como o script faz algumas verificações antes de ser executado, deve ser seguro de executar na linha de comandos para testes (sem garantias...),
Não é uma solução muito elegante, mas é relativamente simples.

Referências


quarta-feira, 25 de abril de 2012

Programar para Android - 08


Botões que lançam outras atividades

Começamos por criar um novo projeto Try06 e retirar a string hello world, para ficar com um projeto vazio, mas já com a atividade já criada.

Desta vez vamos fazer algo um pouco mais longo e vamos ter o primeiro contacto com intents, permissões, obter dados do GPS e do Wifi e editar o AndroidManifest.xml.

Vamos criar uma atividade com 6 botões que lançam atividades ou realizam outras ações, algumas mais simples outras mais complexas.

Começamos por criar seis strings no strings.xml com nomes app1 a app6 e com o conteúdo: Google, Calculadora, Notificação, Vibrar, GPS, Wifi. Os botões irão:

  • lançar o endereço http://www.google.pt;
  • lançar a calculadora;
  • mostrar uma notificação no écrã;
  • vibrar o telemóvel;
  • obter informação sobre o GPS;
  • obter informação sobre a ligação Wifi.

No main.xml vamos criar o layout. Adicionamos três LinearLayout horizontais dentro do LinearLayout vertical. Dentro de cada LinearLayout horizontal criamos dois botões, ficando assim com seis botões. Usando o botão "Distribute Weights Evenly", podemos fazer que os botões ocupem todo o écrã de forma equilibrada. O aspeto fica assim:
O xml do layout fica assim:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >

        <Button
            android:id="@+id/button1"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:onClick="runApp1"
            android:text="@string/app1" />

        <Button
            android:id="@+id/button2"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:onClick="runApp2"
            android:text="@string/app2" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >

        <Button
            android:id="@+id/button3"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:onClick="runApp3"
            android:text="@string/app3" />

        <Button
            android:id="@+id/button4"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:onClick="runApp4"
            android:text="@string/app4" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >

        <Button
            android:id="@+id/button5"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:onClick="runApp5"
            android:text="@string/app5" />

        <Button
            android:id="@+id/button6"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:onClick="runApp6"
            android:text="@string/app6" />
    </LinearLayout>

</LinearLayout>


Já não vamos precisar de mexer mais no strings.xml nem no main.xml.
Vamos agora ver o AndroidManifest.xml. Tal como o strings.xml e o main.xml, o Eclipse mostra uma interface gráfica, mas vamos editar diretamente o XML.
Este ficheiro contém informação sobre a aplicação que é usada, por exemplo, no Android Market (agora Play) para listar e identificar as aplicações.
Muitas das tags são óbvias. Desta vez vamos apenas acrescentar algumas linhas de texto, entre o <uses-sdk ...> e o <application ...>.
As linhas a acrescentar são estas:


    <uses-permission android:name="android.permission.VIBRATE"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    
    <uses-feature android:name="android.hardware.wifi" />
    <uses-feature android:name="android.hardware.location" />
    <uses-feature android:name="android.hardware.location.network" />
    <uses-feature android:name="android.hardware.location.gps" />


Os uses-permission listam as permissões que a aplicação precisa de ter para poder funcionar, neste caso precisa de poder ligar a vibração (VIBRATE), aceder aos dados de localização por GPS e pela rede (ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION) e aceder a informação da ligação sem fios (ACCESS_WIFI_STATE).
Esta informação também é mostrada ao utilizador no momento em que instala a aplicação e o utilizador tem de dar estas permissões à aplicação.
As linhas de uses-feature informam que a aplicação só irá funcionar em dispositivos que tenham o hardware indicado (neste caso wifi e GPS). Esta informação é usada no market para filtrar as aplicações que não são compatíveis com o dispositivo do utilizador.

Finalmente vamos ao código e graças à separação que o Android faz ao colocar o layout e permissões em ficheiros XML, só temos de nos preocupar mesmo com o código.
O método onCreate() que já existe não precisa ser mexido, apenas precisamos criar seis métodos novos, um para cada botão, com os nomes runApp1() a runApp6(). Estes foram os nomes definidos no main.xml.

O primeiro botão lança um browser para aceder ao endereço http://www.google.pt. Isso consegue-se com este código:


public void runApp1(View v) {
Intent i = new Intent(Intent.ACTION_VIEW, 
          Uri.parse("http://www.google.pt/"));
startActivity(i);
}

Um intent é um objeto que, basicamente, contém uma mensagem que é passada ao sistema. Neste caso o intent é criado com a mensagem (ação) ACTION_VIEW e com um parâmetro "http://www.google.pt". Um intent pode ter várias formas, mas este é uma das mais usadas. Contém dois parâmetros, o primeiro é a ação a executar (pode ser VIEW, PICK, EDIT, DELETE, etc) e o segundo parâmetro é um argumento para a ação. Neste caso estamos a dizer ao sistema que queremos ver (VIEW) o URL indicado. O sistema analisa o intent e escolhe a aplicação certa para executar a ação pedida. Pode haver mais que uma aplicação que possa executar essa ação, então o sistema pergunta ao utilizador qual a aplicação que pretende usar. Neste caso se houvesse dois browsers presentes no dispositivo o sistema iria perguntar que browser se pretendia usar.

O segundo botão lança a calculadora, usando também um intent.


 public void runApp2(View v) {
    Intent i = new Intent();
    i.setClassName("com.android.calculator2", "com.android.calculator2.Calculator");
    startActivity(i);
 }

Este intent é diferente. Começamos por criar um intent vazio e adicionamos um nome de classe. Este nome de classe é definido a partir do packagename da atividade. Por isso é importante que cada atividade tenha um nome único, porque esse nome vai ser utilizado para lançar a atividade e tem portanto de ser único.

O terceiro botão apenas mostra uma mensagem de notificação, que no Android é chamado um Toast.

public void runApp3(View v) {
    String msg = "Hello World, again!";
    Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
 
O quarto botão liga a vibração durante 1 segundo (1000 milisegundos). Usa o serviço de sistema VIBRATOR_SERVICE.

public void runApp4(View v) {
    Vibrator vib;
     vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
     vib.vibrate(1000);
}
 
O quinto botão obtém informação de localização do GPS ou da rede. Primeiro tenta obter a informação do GPS (GPS_PROVIDER). Se a informção não estiver disponível (GPS desligado ou sem sinal) pede informação à rede (NETWORK_PROVIDER). A informação obtida é mostrada num Toast.

public void runApp5(View v) {
    LocationManager locator = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    Location l = locator.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    if (l == null) {
        // Fall back to coarse location.
        l = locator.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
    }
    double alt = l.getAltitude();
    double lat = l.getLatitude();
    double lon = l.getLongitude();
    long time = l.getTime();
    float acc = l.getAccuracy();
    float speed = l.getSpeed();
    String prov = l.getProvider();
    String msg =
       "Lat: " + lat + "\n" +
       "Long: " + lon + "\n" +
       "Alt: " + alt + "\n" +
       "Time: " + time + "\n" +
       "Accuracy: " + acc + "\n" +
       "Speed: " + speed + "\n" +
       "Provider: " + prov + "\n";
    Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}

O sexto e último botão obtém e mostra a informação sobre a ligação wifi atual. Usa o serviço de wifi do sistema (WIFI_SERVICE). A informação obtida também é mostrada num Toast.

public void runApp6(View v) {
    String msg;
    WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
  if (wifi.isWifiEnabled()) {
  msg = "Wifi ligado\n";
  WifiInfo winfo = wifi.getConnectionInfo();
 
  int ipadd = winfo.getIpAddress();
  String ip = String.format("%d.%d.%d.%d",
ipadd & 0xff,
ipadd >> 8 & 0xff,
ipadd >> 16 & 0xff,
ipadd >> 24 & 0xff);
  msg +=
"BSSID: " + winfo.getBSSID() + "\n" +
"IP: " + ip + "\n" +
"Speed: " + winfo.getLinkSpeed() + "\n" +
"MAC: " + winfo.getMacAddress() + "\n" +
"RSSI: " + winfo.getRssi() + "\n" +
"SSID: " + winfo.getSSID();
} else
msg = "Wifi desligado";
  Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}


O projeto necessita de uma lista relativamente longa de imports, que devem ser gerados pelo Eclipse, mas para referência aqui ficam:


import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Vibrator;
import android.view.View;
import android.widget.Toast;

Referências:

http://www.krvarma.com/2010/07/getting-ip-address-of-the-device-in-android/
http://www.damonkohler.com/2009/02/android-recipes.html
além do obrigatório: http://developer.android.com/reference/packages.html