Sou cliente do DreamHost já faz um tempo e acho o serviço deles sensacional.
Uma feature que eu ainda não tinha usado é a API que eles disponibilizam para todos os clientes. Bem bacana e flexível.
Como em casa eu tenho IP dinâmico e vez por outra ele muda justamente quando preciso acessar de volta resolvi aproveitar e fiz um shell script quick’n dirty pra usar esse recurso bacana.
Sei que existem diversos serviços de DNS dinâmico por ai, mas preferi essa alternativa que pode ser útil pra mais alguém com uma necessidade parecida.
Se você já precisou acessar um servidor Linux atrás de um NAT sobre qual você não tem controle sabe como seria bom poder iniciar a conexão do lado do servidor conectando de volta em você.
Isso é possível com um túnel SSH reverso. A idéia é que o servidor que você deseja acessar inicia a conexão do lado dele, conecta-se na sua máquina e disponibiliza, via túnel SSH uma porta de volta pra ele.
Eu uso isso como um acesso rápido de casa para a empresa naqueles casos onde preciso só acessar rapidamente alguma coisa vinha linha de comando. Tenho acesso VPN se precisar de email, Terminal Services, etc. Seria possível fazer tudo via túnel, mas ai o desempenho não fica grandes coisas e nem é tão conveniente.
O comando (a ser executado do servidor atrás do NAT) é:
ssh -nNT -R 2222:localhost:22 username@suamaquina
Uma vez estabelecido o túnel você pode conectar de volta à partir da sua máquina utilizando:
ssh -p 2222 username@localhost
Como é possível que a conexão caia, o processo trave ou sei lá o que mais, recomendo os seguintes truques:
UPDATE: Acho que arrumei a formatação. Deve estar legível agora. !!!ATENÇÃO – A visualização de algumas sessões pode estar truncando conteúdo! Pelo jeito a tag <pre> tá quebrada. Preciso olhar isso, mas preguiça, né? Dá pra ler direitinho usando o RSS !!!!
Mesmo com a a infra-estrutura toda virtualizada e clusterizada nos ESXi fazer um cluster de MySQL ainda é uma boa idéia.
Não só você pode colocar as duas máquinas em storages diferentes e eliminar mais um ponto de falha mas também você pode dedicar uma (ou mais) VM(s) para read-only.
Isso quer dizer que seus usuários rodando reports e chamando estatísticas/gráficos no meio do dia não vão afetar o desempenho de quem está entrando operações em produção.
Isso dito entra em cena o MySQL Multi Master Replication Manager (MMM): Um conjunto de scripts Perl que facilita a replicação e gerenciamento do seu cluster MySQL.
Abaixo os passos que utilizei para criar um cluster de 2 máquinas CentOS 5.5. Vou assumir que você já tem as máquinas em pé com MySQL devidamente instalado.
Além das máquinas rodando o MySQL você vai precisar de uma terceira, que é o monitor. É esse cara que vai manter os olhos no cluster, decidir quando uma máquina morreu e gerenciar os papéis de cada uma.
Nem idéia ainda dos requisitos mínimos desse servidor, visto que apenas fiz um teste pequeno aqui. Mas tá rodando sem reclamar em 1 processador e 512 de RAM.
Cenário:
IP Leitura/Gravação MySQL -> 10.0.0.1
IP Somente Leitura MySQL -> 10.0.0.100
IP Servidor MySQL 1 (hostname master) -> 10.0.0.2
IP Servidor MySQL 2 (hostname master2) -> 10.0.0.3
IP Monitor (hostname mon) -> 10.0.0.10
Editando a configuração do MySQL:
Em cada um dos servidores adicione as seguintes linhas embaixo da sessão [mysqld] do /etc/my.cnf:
#MMM
read-only
replicate-ignore-db = mysql
binlog-ignore-db = mysql
log-bin=master-binary
relay-log=master-relay
server-id=2
Atenção!! master (ali no log-bin e relay-bin) é o HOSTNAME da máquina em questão. Então no meu caso no outro servidor o arquivo receberá as linhas:
#MMM
read-only
replicate-ignore-db = mysql
binlog-ignore-db = mysql
log-bin=master2-binary
relay-log=master2-relay
server-id=2
Isso vai evitar que mudanças sejam feitas no banco de dados mysql e também define um nome único para os logs que vamos usar mais tarde.
Não esqueça do restart no serviço.
Instalando o MMM:
Não sei vocês, mas já passei da idade de compilar pacote na mão. Eu instalo a EPEL e já era.
Dentro de cada servidor precisamos criar 3 usuários: replication, agent e monitor. Abra seu console do MySQL e mande:
GRANT REPLICATION CLIENT ON *.* TO 'mmm_monitor'@'10.0.0.%' IDENTIFIED BY 'monitor_password';
GRANT SUPER, REPLICATION CLIENT, PROCESS ON *.* TO 'mmm_agent'@'10.0.0.%' IDENTIFIED BY 'agent_password';
GRANT REPLICATION SLAVE ON *.* TO 'replication'@'10.0.0.%' IDENTIFIED BY 'replication_password';
FLUSH PRIVILEGES;
FLUSH TABLES WITH READ LOCK;
Abra duas sessões (uma em cada MySQL) e não as feche depois de rodar os comandos acima. Com eles executados faça a seguir:
Você vai usar essa informação nos comandos abaixo. Note que você deve utilizar o output da execução em uma máquina no input da outra, de forma que crie uma cross-reference entre elas:
change master to master_host = '10.0.0.3', master_user='replication', master_password='replication_password', master_log_file='master2-binary.000001', master_log_pos=98;
A seguir vamos editar o /etc/mysql-mmm/mmm_common.conf:
Copiamos nele também o /etc/mysql-mmm/mmm_common.conf.
E depois editamos o /etc/mysql-mmm/mmm_mon.conf:
<monitor>
ip 127.0.0.1
pid_path /var/run/mysql-mmm/mmm_mond.pid
bin_path /usr/libexec/mysql-mmm
status_path /var/lib/mysql-mmm/mmm_mond.status
ping_ips 10.0.0.1,10.0.0.2,10.0.0.3,10.0.0.100
auto_set_online 60
# The kill_host_bin does not exist by default, though the monitor will
# throw a warning about it missing. See the section 5.10 "Kill Host
# Functionality" in the PDF documentation.
#
# kill_host_bin /usr/libexec/mysql-mmm/monitor/kill_host
#
</monitor>
<host default>
monitor_user mmm_monitor
monitor_password monitor_password
</host>
debug 0
Iniciando os serviços:
Nos servidores MySQL:
service mysql-mmm-agent start
chkconfig mysql-mmm-agent on
No servidor de monitoração:
service mysql-mmm-monitor start
chkconfig mysql-mmm-monitor on
Se tudo correu bem em alguns segundos você vai ter os serviços rodando e pode ver o status deles à partir do servidor de monitoração com o seguinte comando:
Como sysadmins vez por outra a gente precisa dar acesso a clientes, parceiros ou outro tipo de usuário temporário/untrusted aos servidores. Apesar de criar um jail root completo ser a melhor solução muitas vezes é mais trabalho do que o necessário e começa a entrar naquele cenário em que a segurança atrapalha a usabilidade e os negócios.
Uma forma simples de conseguir uma segurança bacana é utilizar o modo restrito do bash. Com isso habilitado o shell irá desabilitar as seguintes funções:
Mudar o diretório (cd)
Mudar o valor das variáveis SHELL, PATH, ENV, or BASH_ENV
Comandos que incluem /
Especificar um arquivo que contenha / como fonte para o comando “.”
Usar redirecionamento de output (>, >>, |)
etc (man bash para todas as features)
Colocando para rodar:
Crie um link do bash para o rbash e adicione o mesmo em /etc/shells:
Depois é só mudar o shell do usuário a ser restringido para usar o rbash:
usermod -s /bin/rbash username
Combinando isso com traps (do CTRL+C, por exemplo) você consegue criar um ambiente seguro o suficiente para fornecer serviços e acessos aos seus servidores e ainda assim dormir à noite.
Recentemente coloquei no ar o FollowUpTime, que como já disse em outros posts é um sistema de monitoração para redes e servidores.
Como podem imaginar, um bocado de linhas de código está envolvida num sistema assim e a conta só do engine principal passa das 90 mil linhas. Isso sem incluir templates, javascripts, etc.
O sistema é composto de duas partes: Uma que roda num servidor principal gerenciando a maior parte das tarefas e as “probes”. As probes são pequenos scripts que recebem instruções sobre hosts a serem testados e respondem para o servidor principal com o tempo de resposta, um OK ou um FAIL. Simples assim.
São essas probes que temos espalhados por vários cantos do planeta.
Porém quando recebi a probe dos desenvolvedores me vi com um pequeno, mas incoveniente problema. Os desenvolvedores realmente optaram pelo princípio KISS. Eles me entregaram uma excelente probe que fazia o que era necessário. E nada mais. Eu tinha nas mãos um daemon que rodava em foreground e jogava mensagens para stdout e stderr e nada mais.
Eu não me demorei e ataquei o problema da forma errada, pensando como um programador e não como um administrador Unix. E acabei reinventado a roda.
Introdução – O problema
Quando percebi o que eu tinha nas mãos logo pensei nos problemas que eu precisava resolver:
Preciso iniciar o daemon sempre que der boot na máquina
Preciso ser capaz de rodar em daemon em background, ou vai me zoar a seqüencia de boot
Posso precisar parar/reiniciar/iniciar manualmente este daemon
Se o processo morrer eu tenho que ser notificado e que, de preferência, ele seja reiniciado automaticamente
E sim, esse processo não deve rodar como root
Já velhaco de Linux logo pensei num script para ser colocado em /etc/init.d/ que ia resolver boa parte dos meus problemas. Com uma combinação bonita de bash scripting, várias ferramentas e comandos Linux que só se conhece depois de muito tempo de casa (como nohup, pidof, &) e gambiarras na crontab eu consegui. Consegui reinventar a roda. Não vou entrar em detalhes da solução que fiz, pois apesar de 100% funcional não era nem de perto tão bonita quanto:
A solução – Daemontools
Nosso caro amigo D.J.B, autor do famoso Qmail também já passou por um problema parecido com o meu, mas ao invés de criar um solução simples para resolver um problema pontual ele foi mais longe. Ele criou uma solução global que atende o problema dele, o meu e provavelmente também o seu.
Na página oficial do daemontools tem uma tabela, que traduzo abaixo, comparando a ferramenta dele com outras abordagens (incluindo a minha, que utilizava init.d):
Funcionalidade
inittab
ttys
init.d
rc.local
/service
Fácil instalação e remoção de serviços
Não
Não
Sim
Não
Sim
Simples startup inicial
Não
Não
Não
Não
Sim
Reinicializações confiáveis
Sim
Sim
Não
Não
Sim
Sinalização simples e confiável
Não
Não
Não
Não
Sim
Estado de processo limpo
Sim
Sim
Não
Não
Sim
Portabilidade
Não
Não
Não
Não
Sim
Dá para perceber que o cara pensou em tudo e não tem porquê reinventar a roda. Vamos utilizar o daemontools!
Não sei ao certo como é o nome em português. Variáveis aninhadas?
Me deparei com um problema assim hoje: Eu tinha uma função num script shell que recebia um parâmetro de sucesso ou erro. Eu executava algumas coisas e depois tinha que jogar uns dados no arquivo respectivo.
Então inicialmente tinha setado uma variável com os paths dos caminhos:
Esses dias me deparei com a seguinte situação: Precisava implementar um serviço baseado em web. Esse serviço vai acumular bastante informações sobre a infra-estrutura da empresa e por isso precisa de autenticação para garantir que apenas as pessoas corretas tenham acesso a essas informações.
Mas por motivos que nem vale a pena citar, afinal não quero uma gastrite, o bagulho não aceita autenticação.
A forma que eu arranjei para resolver isso foi simples: A porta do serviço original é bloqueada via iptables e instalei o lighttpd para servir como proxy, já me aproveitando das features de autenticação dele.
Caso precise fazer algo parecido com isso um dia, segue abaixo como fiz:
Como já devem saber eu sou da turminha do vi. Nada contra o Emacs, lógico, mas vi é vi.
O relacionamento com ele nunca começa bem. Lembro-me que a primeira vez que abri o vi, num SCO Unix, o único jeito que consegui sair do editor foi rebootando a máquina. Eu não tinha nem idéia de que bastava um ESC:q! para cumprir a tarefa. Mas passados 11 anos ou mais deste início traumático, posso dizer que me dou bem com o editor hoje em dia, utilizando-o inclusive para escrever posts no meu blog, como neste momento o faço.
Às vezes o que sentia falta era de alguma coisa para facilitar minha vida quando estava fazendo meus scripts. Alguns pedaços de código você usa de novo, de novo e de novo. E é um saco ficar redigitando.
Importar para dentro do arquivo atual (ESC:r /path/arquivo) ajuda, mas não resolve.
A solução
Pesquisando achei o sensacional BASH-IDE para vim. Resolveu todos os meus problemas, exceto a falta de competência como programador.
Utilizando o BASH-IDE podemos configurar um template para novos arquivos, de forma que sempre que abro um novo arquivo .sh no vim ele já adiciona o cabeçalho com informação sobre o autor, data, tag $id$ pro cvs e algumas variáveis e funções que eu coloco em todos os meus script.
O autor do BASH-IDE foi cuidadoso para facilitar a documentação de forma que vários atalhos já são auto-documentados.
Uma nova função criada utilizando o BASH-IDE automaticamente terá o seguinte aspecto:
function teste ()
{
} # ---------- end of function teste ----------
E ao chamar o atalho para documentação de função você recebe este template:
Como tudo é baseado em arquivos texto, as customizações só dependem da sua boa vontade. E ainda vem com um uma cheat sheet em pdf pronta para imprimir e pendurar na sua baia!