Usando o Pi-Hole, um filtro de DNS

Algo bem legal de usar o raspberry pi é usar ele como servidor de DNS, para bloquear algumas propagandas. E existe uma solução perfeita para isso chamada pi hole.

Primeiro temos que saber o que é DNS.

DNS é o Domain Name System, um sistema que responde qual o ip de um determinado nome. Basicamente ele traduz nomes em endereços de ip. Antes de existir o DNS, não existiam páginas como google.com, tudo era um endereço de ip, e você tinha que ter uma listinha de ips que te interessavam, até que alguém fez o dns para tirar essa listinha da sua mão e deixar num servidor, porque é mais prático, e mais simples lembrar de google.com do que um endereço de ip.

Pra entender melhor, no terminal no linux, a gente tem o programa chamado host que diz em qual ip um endereço responde, então por exemplo o google.com

augusto@augusto-xps:~$ host google.com google.com has address 216.58.202.174 google.com has IPv6 address 2800:3f0:4001:815::200e google.com mail is handled by 30 alt2.aspmx.l.google.com. google.com mail is handled by 40 alt3.aspmx.l.google.com. google.com mail is handled by 20 alt1.aspmx.l.google.com. google.com mail is handled by 50 alt4.aspmx.l.google.com. google.com mail is handled by 10 aspmx.l.google.com.

Ele na verdade está no ip 216.58.202.174, o programa host fez uma pergunta para o DNS, e esse respondeu. Agora, veja que o google.com.br está em outro endereço.

augusto@augusto-xps:~$ host google.com.br google.com.br has address 216.58.202.3 google.com.br has IPv6 address 2800:3f0:4001:807::2003 google.com.br mail is handled by 40 alt3.aspmx.l.google.com. google.com.br mail is handled by 10 aspmx.l.google.com. google.com.br mail is handled by 20 alt1.aspmx.l.google.com. google.com.br mail is handled by 50 alt4.aspmx.l.google.com. google.com.br mail is handled by 30 alt2.aspmx.l.google.com.

No caso 216.58.202.3, provavelmente porque deve estar mais perto da gente, para evitar ter que percorrer uma grande distância física, mas isso não vem ao caso agora.

Então o DNS é uma lista que fala qual ip está associado a qual nome. Normalmente a gente usa o dns do nosso provedor, ou o do google, mas ter controle sobre o dns pode ser interessante, para bloquear endereços indesejados de propagandas por exemplo, que é o que o pi hole faz.

Para instalar ele no raspberry é bem fácil, começamos fazendo um update e upgrade.

sudo apt-get update
sudo apt-get upgrade

E para instalar

sudo curl -sSL https://install.pi-hole.net | sudo bash

Veja que eu coloco o sudo, porque precisamos ser root, e eu achei mais fácil assim. E pronto, acabou, eu escolhi todas as opções default na instalação e já era. Meu Raspberry é um servidor de DNS bloqueando links indesejados.

Agora quando todo mundo conecta no meu roteador, eu tenho que avisar a todos dispositivo que é para usar o raspberry como DNS, então precisamos agora alterar no roteador isso, que no meu roteador dlink fica logo na tela inicial que se configura a conexão.

Bem simples, agora meu raspberry, que está no endereço de rede interno 192.168.0.3 fixo funciona como DNS server, todo mundo pergunta para ele qual o IP das páginas, claro que não está tudo nele, num grande arquivo, existe uma hierarquia de procura, mas depois vemos isso, o que interessa é que ele da a resposta final, você fala um nome e ele da o ip.

Como tudo não são flores, eu tive um problema que o pi hole começou a bloquear meus javascript, temos que consertar alguns problemas que tive. Lembra que deixo o raspberry em kiosk mode? Então, meu kiosk mode pifou sem javascript, na página, o javascript vinha assim:

x = "Pi-hole: A black hole for Internet advertisements."

Mas com algumas buscas eu vi que ele altera alguns arquivos, nesse caso esse arquivo /etc/lighttpd/lighttpd.conf, então precisamos fazer uma pequena modificação nele.

sudo emacs /etc/lighttpd/lighttpd.conf

O arquivo é grande, mas o problema são essas duas linhas, que basta comentar, e inserir um comentário acima para lembrar que fomos nos que comentamos.

# Impede o uso de javascript # Rewite js requests, must be out of $HTTP block due to bug #2526 # url.rewrite = ( "^(?!/admin/).*\.js$" => "pihole/index.js" )

Feito isso tudo volta a funcionar. Agora para entender o que está sendo feito, como o pi hole está funcionando, veja como uma página como o pirate bay fica sem bloquear o DNS de propaganda.

Agora bloquando, a gente ve o seguinte.

Não abre as propagandas, ou seja, quando o navegador pergunta, ei DNS, qual o ip dessa propaganda para que eu possa baixar as imagens, o DNS fala que não achou e pimba, a gente não baixa a imagem, e fica desse jeito a página. Ai você pode dizer, a, mas eu uso algum bloqueador já, mas de qualquer forma você baixou a imagem e depois bloqueou, dessa forma você nem baixa propaganda, o que pode diminuir até o seu tráfego. Além de que, você pode bloquear páginas maliciosas também de quebra.

O pi hole tem um menu para administração.

Ele traz uma série de informações, e ao fim da instalação, ele te da uma senha gerada automática para acessar esse menu de administração.

Nele podemos ligar e desligar, mexer em várias opções, podemos curiosar inclusive sobre o tráfego, o que está mais sendo bloqueado.

So de olhar os endereços bloqueados, a gente ve o tanto de informação que deve estar mandando para caras como o google, sobre nossa atividade na internet, além das propagandas.

Veja que quem está fazendo mais requisições de DNS, lembrando que 192.168.0.1 é o meu roteador, ou seja meu notebook pergunta o DNS pro roteador, que pergunta pro raspberry, que resolve, e devolve pro roteador que devolve pro notebook, por isso as requisições vem todas do 192.168.0.1.

E podemos resolver nossos próprios endereços também. No arquivo /etc/dnsmasq.d/01-pihole.conf temos algumas configurações interessantes.

pi@rasp_levins:~ $ cat /etc/dnsmasq.d/01-pihole.conf # Pi-hole: A black hole for Internet advertisements # (c) 2015, 2016 by Jacob Salmela # Network-wide ad blocking via your Raspberry Pi # http://pi-hole.net # dnsmasq config for Pi-hole # # Pi-hole is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. ############################################################################### # FILE AUTOMATICALLY POPULATED BY PI-HOLE INSTALL/UPDATE PROCEDURE. # # ANY CHANGES MADE TO THIS FILE AFTER INSTALL WILL BE LOST ON THE NEXT UPDATE # # # # IF YOU WISH TO CHANGE THE UPSTREAM SERVERS, CHANGE THEM IN: # # /etc/pihole/setupVars.conf # # # # ANY OTHER CHANGES SHOULD BE MADE IN A SEPERATE CONFIG FILE # # OR IN /etc/dnsmasq.conf # ############################################################################### addn-hosts=/etc/pihole/gravity.list addn-hosts=/etc/pihole/local.list addn-hosts=/etc/pihole/black.list domain-needed localise-queries bogus-priv no-resolv server=8.8.8.8 server=8.8.4.4 interface=eth0 cache-size=10000 log-queries log-facility=/var/log/pihole.log local-ttl=300 log-async

Veja que no começo, ele chama 3 arquivos, que são listas de nomes com ips para resolver, no caso a lista local.list, da nossa rede interna aqui em casa tem.

pi@rasp_levins:~ $ cat /etc/pihole/local.list 192.168.0.3 rasp_levins 192.168.0.3 pi.hole

Agora quando eu digito http://pi.hole eu sou mandando para o ip 192.168.0.3, ou seja para acessar o pi.hole, eu posso usar http://pi.hole ao invés de http://192.168.0.3. Lembra do comando host la que usamos la em cima, veja so

Agora por exemplo podemos fazer um atalho, ou simplificar para usar o ssh, que também usa o DNS, podemos adicionar rasp_levins.local naquele aquivo com o ip 192.168.0.3, assim:

192.168.0.3 rasp_levins 192.168.0.3 pi.hole 192.168.0.3 rasp_levins.local

E agora basta usar ssh pi@rasp_levins.local ao inves de ssh pi@192.168.0.3.

Bem é isso ai, algo que não mexemos aqui é na interface que o pi hole tem, mas eu vou colocar alguns gráficos no kiosk mode ainda, e se eu escrevi alguma bobeira, algo errado, deixe um comentário corrigindo ou mande um e-mail.

Criando um gráfico com bandeiras dos países.

Esses tempos, um colega me pediu para fazer alguns gráficos tipo os que tem no google analytics, mais especificamente nesse estilo aqui.

É de uma versão mais antiga dessa figura, mas a ideia é essa, basicamente um gráfico de barras na vertical. A única parte difícil, foi as bandeiras, primeiro foi achar essas bandeiras, depois inserir na figura.

Para achar as figuras, a primeira coisa foi procurar algum pacote que tivesse isso pronto, achei que encontraria, mas não achei nenhum, então ao procurar pelas bandeiras, uma fonte seria baixar diretamente do wikipedia, que tem bandeiras para todos os paises, mas eu achei esse conjunto aqui, que inclusive está em um repositorio do github que podemos clonar, o que facilita bastante o trabalho, ali temos as bandeiras em formato png em vários tamanhos, eu preferi usar o de maior resolução.

então clonado o repositório com as bandeiras, eu fiz a figura com o seguinte código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
library(png)
paises<-list.files("64")
 
##Figura country.png
 
country<-c("Brazil","United States","Portugal","Mozambique","Mexico","Germany","Peru","Australia","Cape Verde","Angola")
country_br<-c("Brasil","Estados Unidos","Portugal","Mozambique","México","Alemanha","Perú","Austrália","Cabo Verde","Angola")
sessions<-c(2113,259,85,63,54,49,38,37,36,36)
sessions_percentage<-c(60.39,7.4,2.43,1.8,1.54,1.4,1.09,1.06,1.03,1.03)
 
ampliacao <- 2
jpeg("country.jpg",width = ampliacao*480,height = ampliacao*480,pointsize = ampliacao*12)
escala<-barplot(rev(sessions_percentage),horiz=T,xlim=c(-150,100),xaxt="n",col="#76A7FA")
text(rep(0,10),escala,rev(sessions),pos=2)
text(rev(sessions_percentage)+14,escala,paste(rev(format(round(sessions_percentage, 2), nsmall = 2)),"%",sep=""))
text(rep(-130,10),escala,10:1,pos=2)
text(rep(-120,10),escala,rev(country_br),pos=4)
mtext(c("País","Sessões","% Sessões"),3,0,at=c(-125,-15,35))
 
list.files()
 
for(i in 1:10){
    country[i]
    posicao<-agrep(country[i],paises)
    paises[posicao]
    bandeira<-readPNG(paste("64/",paises[posicao],sep=""))
    rasterImage(bandeira,-133,rev(escala)[i]-0.5,-117,rev(escala)[i]+0.5)
}
dev.off()

Que gera a seguinte figura.

Bem legal eu achei, agora vou fazer alguns comentários do meu código.

Primeiro:

1
2
country<-c("Brazil","United States","Portugal","Mozambique","Mexico","Germany","Peru","Australia","Cape Verde","Angola")
country_br<-c("Brasil","Estados Unidos","Portugal","Mozambique","México","Alemanha","Perú","Austrália","Cabo Verde","Angola")

Bem como são poucos dados, eu digitei o nomes do países em inglês e em português, isso porque o nome em inglês eu uso para achar o nome do arquivo da bandeira, que é o nome do pais, e em português para usar na figura em si.

Depois disso para facilitar a mudança do tamanho, eu costumo guardar uma variável para o tamanho, que multiplica a largura, a altura e o tamanho do ponto, assim só altero ela para mudar o tamanho da figura, a sua resolução.

1
2
3
4
5
6
ampliacao <- 2
jpeg("country.jpg",width = ampliacao*480,height = ampliacao*480,pointsize = ampliacao*12)
 
##Figura
 
dev.off()

A figura em si é um barplot na vertical, a única coisa é que mudo bastante as margens, o tamanho do eixos de forma a caber as outras informações e bandeiras, que são colocadas com a função text para dentro da figura e mtext para a parte de fora. Depois disso, talvez essa parte ainda tenha algo de interesse.

1
2
3
4
5
6
7
for(i in 1:10){
    country[i]
    posicao<-agrep(country[i],paises)
    paises[posicao]
    bandeira<-readPNG(paste("64/",paises[posicao],sep=""))
    rasterImage(bandeira,-133,rev(escala)[i]-0.5,-117,rev(escala)[i]+0.5)
}

Então eu pego o nome do pais em inglês, e uso agrep na lista de nomes de arquivos, agrep, porque é um grep, ou seja acha a palavra na lista, mas permite alguns erros de caracteres, que da para regular com argumentos, mas então com o agrep a gente vai achar o nome do arquivo, com ele a gente le a figura png com o readPNG, que le o raster da figura, então com rasterImage a gente adiciona ela a figura, aqui a gente tem que colocar os quatro pontos da imagem para adicionar ela, veja se da até para colocar a imagem espelhada, feito isso ta pronto. Para economizar, eu fiz um loop para todas as bandeiras.

Bem é isso ai, o script vai estar la no repositório recologia, e se eu escrevi alguma bobeira, algo errado, deixe um comentário corrigindo ou mande um e-mail. Um post bem simples, mas é o tipo de código que é legal guardar, pois pode ser útil copiar e colar um dia.

Iniciando uma pequena Aplicação para controlar atividades no Raspberry

Depois de concluir a faculdade, uma área que eu achei bem legal foi o desenvolvimento web, e resolvi tentar fazer um projeto pessoal na área.

Normalmente eu controlo coisas como áudio e vídeo no raspberry acessando ele remotamente via ssh, mas eu gostaria de controlar do celular ou de qualquer outro dispositivo, e uma forma de fazer isso é com uma aplicaçãozinha web. Eu ja fiz algumas coisas simples como ligar e desligar a música, videos, e apesar de só ser acessível dentro da rede interna aqui que o roteador de casa faz, eu gostaria de fazer algo mais organizado, usando senha.

O que eu quero é fazer algo assim:

Um banner superior com um menu lateral, e algumas informações acima do banner, no centro da tela então eu uma tela com os controles, de som por exemplo.

Então mais especificamente, eu quero fazer algo assim:

Se você entrar na página deslogado, eu peço uma senha, e uma vez que você tenha se autenticado:

A gente começa a aplicação, e deixa algumas informações de login, como quem está logado.

Bem, como eu não conheço muitas tecnologias, o que está mais a mão no raspberry é o php, então eu resolvi usar o php no lado do servidor e html, css e javascript para fazer algumas páginas e formulários. Além disso, vou tentar organizar tudo usando o MVC, model, view e controller.

Eu instalei o apache e o php no raspberry segundo os tutoriais da própria página do raspberry, então dentro da pasta /var/www/html eu criei uma pasta chamada rasp_apps para colocar meu código. O conteúdo dessa pasta está no repositório de mesmo nome aqui, de forma que código fica público, e é fácil administrar mudanças, backup, etc. Acho que não estou adicionando muita coisa aqui, essas são mais notas mentais do que uma explicação do que estou fazendo de verdade.

Mas tudo bem, vamos ao código em si.

Dentro da pasta inicial da minha aplicação, temos um index.php, e nele temos:

1
2
3
4
5
6
7
<?php
require_once 'Controller/controller.php';
ob_start();
session_start(['cookie_lifetime' => 86400,]);
$controller = new Controller();
$controller->init();
?>

Bem, aqui a gente inicia um cookie, que é a forma de manter alguém conectado, de outra forma, não teríamos como manter as variáveis, depois vou tentar escrever sobre a comunicação web, mas depois disso a gente cria um objeto da classe controller que criamos e iniciamos ele, com a função init.

Eu não fiz uma pasta model ainda, pois ainda não comecei a usar banco de dados, até aqui eu só fiz um formulário para entrar com usuário e senha e validar. E como eu faço isso? Para isso server o controller, ele controla tudo, e chama as visualizações.

Quando a gente roda

1
$controller = new Controller();

nos construímos o objeto, que nesse caso, tudo que a gente faz é

1
2
3
4
public function __construct() {
        ini_set('error_reporting', E_ALL);
        ini_set('display_errors', 1);
    }

Habilitar a apresentação dos erros do php, que ajudam a entender porque tudo não funciona, e depois nos rodamos o init

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
 public function init() {       
 
        if (isset($_SESSION['valid'])){
 
            if (isset($_GET['op'])) {
                $op = $_GET['op'];
            } else {
                $op = "";
            }
 
            switch ($op) {
            case 'cfg':
                $this->cfg();
                break;
            case 'logout':
                $this->logout();
                break;
            default:
                $this->index();
                break;
            }
 
        }else{
            $this->login();
        }
 
    }

Esse método, é basicamente um ifelse para saber se a pessoa está autenticada,

1
2
3
4
5
6
7
8
9
10
 
if (isset($_SESSION['valid'])){
 
 
             ###Código
            
 
        }else{
            $this->login();
        }

Senão nos vamos logar, e quanto estivermos logados, vamos cair num switch, que vai administrar as possibilidades da aplicação. Mas então para logar, chamamos o método login.

1
2
3
4
5
6
7
8
9
10
public function login() {
        if (isset($_POST['login']) && !empty($_POST['usuario']) && !empty($_POST['senha'])) {
                $this->valida_login();
        } else{
            if(isset($_SESSION['mensagem'])==false){
                $_SESSION['mensagem']='';
            }            
            require 'View/login.php';
        }
    }

O login, vai olhar se foi enviado algo pelo método post, se o usuário enviou algum dado, como é a primeira entrada no método, nenhuma dessas variáveis existem, então vamos ao else, que olhar se tem alguma mensagem, para apaga-la, e como não tem nada, ele só chama a tela de login.

O que de fato interessa na tela de login é o seguinte:

1
2
3
4
5
6
7
8
9
<?php echo $_SESSION['mensagem']?>
 
	<form action="?op=''" method="post" ?>
 
	    <input type = "text"  name = "usuario" placeholder = "Usuário = teste" required autofocus></br>
	    <input type = "password"  name = "senha" placeholder = "Senha = 1234" required>
	    <button type = "submit" name = "login">Login</button>
 
	</form>

Aquela mensagem, ela vai ser exibida, se tiver algo nela, e temos um formulário, que preenche exatamente aquelas informações de usuário e senha e tem um botão que envia essas informações ao controller, veja que a gente preenche duas coisas, o usuário e a senha, enviando via post.

Agora, vamos denovo passar pelo init, não estamos autenticados ainda, o que nos leva para o método login, mas agora temos um usuário e senha então vamos para o método valida_login

1
2
3
4
5
6
7
8
9
10
11
public function valida_login() {
            if ($_POST['usuario'] == 'teste' && $_POST['senha'] == '1234') {
                $_SESSION['valid'] = true;
                $_SESSION['timeout'] = time();
                $_SESSION['usuario'] = 'Rasp_levins';
            }else {
                unset($_POST);
                $_SESSION['mensagem'] = 'Usuário ou senha incorreto!';
            }
            $this->init();
    }

Agora a gente pode finalmente testar se o usuário e senha conferem, e nesse caso, validar a sessão, ou se o usuário digitou o conjunto usuário e senha errados, nós geramos uma mensagem de erro, e não validamos a sessão.

A princípio, é tudo bem simples, e temos somente um usuário e senha no método de avaliação. Agora o próximo passo é criar uma base de dados com usuário e senha para fazer essa consulta, de forma a não ficar os usuários e senhas ali no meio do código, bem existem muitas coisas a serem feitas ainda, mas fazer a conexão com um banco de dados já possibilita várias outras coisas.

Bem é isso ai, o script vai estar la no repositório rasp_aaps, e se eu escrevi alguma bobeira, algo errado, deixe um comentário corrigindo ou mande um e-mail.

Variância e a desigualdade de Chebyshev

Como falamos antes de média aqui, vamos falar de Variância agora.

Variância é definida como:

Var(X)=E[(X-\mu)^2]

Sendo que esse E é o valor esperado, que é

 E[X]= \sum\limits_{i=1}^\infty x_i \cdot p(x_i)

e o \mu é o centro da distribuição, a média, como vimos aqui

E essa é a forma geral de calcular a variância, que é o espalhamento dos dados em torno da média.

Uma forma mais fácil de calcular é

Var(X)=E[X^2]-E[X]^2

A raiz quadrada da variância é o famoso desvio padrão, que como não está em unidades quadradas, vai estar na mesma unidade de medida dos dados originais. Veja que se a gente tem uma constante multiplicando X

Var(aX)= a^2 \cdot Var(X)

Ela sai da variância ao quadrado.

Para entender melhor vamos calcular a variância de uma jogada de dados, o dado comum de 6 faces.

Sabemos que a valor esperado é:

E[X]=3.5

e

E[X^2]=1^2\cdot\frac{1}{6}+2^2\cdot\frac{1}{6}+3^2\cdot\frac{1}{6}+4^2\cdot\frac{1}{6}+5^2\cdot\frac{1}{6}+6^2\cdot\frac{1}{6}=15.17

Então para a variância temos:

Var(X)=E[X^2]-E[X]^2 = 15.17-3.5^2=2.92

Veja que se a gente usar:

Var(X)=E[(X-\mu)^2]= (1-3.5)^2\cdot\frac{1}{6}+(2-3.5)^2\cdot\frac{1}{6}+(3-3.5)^2\cdot\frac{1}{6}+(4-3.5)^2\cdot\frac{1}{6}+(5-3.5)^2\cdot\frac{1}{6}+(6-3.5)^2\cdot\frac{1}{6}

Como a média está em todas as multiplicações, podemos fatorar ela, que é da onde vem a fórmula anterior, lembrando que a média está dentro de um quadrado, então não da para ir tirando ela diretamente.

Agora qual a variância de uma jogada de moeda com uma chance p para cara.

E[X]=0 \cdot (1-p) + 1 \cdot p = p


E[X^2]= E[X] = p


Var(X)=E[X^2]-E[X]^2=p-p^2=p(1-p)

E essa fórmula é bem conhecida, mesmo sem saber da onde ela vinha, e veja que ela é maximizada no p=0.5

Ou seja, a maior entropia, menos previsibilidade, está numa moeda honesta.

Então suponha que uma variável aleatória X em que O \leq X \leq 1 e E[X]=p

Veja que X^2 \leq X pode ser igual quando pensamos em 1 por exemplo, já que um ao quadrado da 1, mas fora isso, sempre X^2 vai ser maior, então E[X^2]\leq E[X]=p

Assim, Var(X) = E[X^2]-E[X]^2 \leq E[X]-E[X]^2 = p(1-p)

Dessa forma, a variância de Bernoulli é a maior possível para uma variável aleatória entre 0 e 1. O que nos leva a inequação de Chebyshev, que é útil para interpretar de forma geral variâncias.

A inequação mostra que

P( X-\mu \leq k\sigma) \leq \frac{1}{k^2}

Por exemplo, a probabilidade que uma variável aleatória esteja além de k desvios padrões é menos de \frac{1}{k^2}

 2 \sigma = 25\%


 3 \sigma = 11\%


 4 \sigma = 6\%

Mas veja que esse é apenas um limite geral, a probabilidade pode ser bem menor, mas esse é um limite superior independente da distribuição, e essa generalização que torna essa inequação importante, principalmente para afirmações de forma geral.

Bem é isso ai, o script vai estar la no repositório recologia, e se eu escrevi alguma bobeira, algo errado, deixe um comentário corrigindo ou mande um e-mail e esses post está a uns dias parados, então resolvi finalizar logo. Além disso tem uma prova para essa inequação, mas achei a prova muito difícil.

Referência:
Coursera, curso Mathematical Biostatistics Boot Camp 1 do Brian Caffo

Usando o raspberry para administrar os arquivos de torrents.

Um uso que eu acho muito bom no raspberry é para baixar torrents, primeiro porque você deixa de ter que se preocupar com torrents no seu computador, e como ele fica ligado direto e gasta bem menos energia que um notebook por exemplo, é bem interessante.

O meu raspberry usa o Raspbian como sistema operacional, e para administrar os torrents eu uso o Transmission.

Primeiro temos que instalar o Transmission, que é fácil com o apt.

1
2
3
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install transmission-daemon

Aqui, no meu rasp_levins (que é o nome do meu raspberry aqui) tem um hd externo ligado nele, para ele sempre ser montado já na inicialização, eu alterei o arquivo fstab, que monta os drives na inicialização do linux.

proc /proc proc defaults 0 0 PARTUUID=0ce2607c-01 /boot vfat defaults 0 2 PARTUUID=0ce2607c-02 / ext4 defaults,noatime 0 1 # a swapfile is not a swap partition, no line here # use dphys-swapfile swap[on|off] for that # Montagen do hd_externo UUID=38F25F26F25EE7A0 /media/hd_externo ntfs-3g uid=1000,gid=1000,umask=007 0 0

Então como ele é sempre montado no /media/hd_externo, eu criei duas pastas la. Detalhe que ele é formatado como ntfs, para compatibilidade com windows, se precisar, mas eu uso o pacote ntfs-3g para funcionar o sistema de permissões do linux.

1
2
mkdir -p /media/hd_externo/Torrent_completo
mkdir -p /media/hd_externo/Torrent_emprogresso

Outra coisa a se fazer é permitir que o transmission escreva nesses locais, ele roda como o usuario “debian-transmission”, como o hd_externo é do usuario pi e do grupo pi, com permissão 770

drwxrwx--- 1 pi pi 8192 Aug 20 18:21 hd_externo

A gente adiciona o “debian-transmission para conseguir usar o hd_externo

1
sudo usermod -a -G pi debian-transmission

Feito isso, a gente so precisa configurar o Transmission, alterado o arquivo json que fica todas as configurações dele

1
sudo emacs /etc/transmission-daemon/settings.json

O meu ficou assim:

{ "alt-speed-down": 50, "alt-speed-enabled": false, "alt-speed-time-begin": 540, "alt-speed-time-day": 127, "alt-speed-time-enabled": false, "alt-speed-time-end": 1020, "alt-speed-up": 50, "bind-address-ipv4": "0.0.0.0", "bind-address-ipv6": "::", "blocklist-enabled": true, "blocklist-url": "http://list.iblocklist.com/?list=ydxerpxkpcfqjaybcssw&fileformat=p2p&archiveformat=gz", "cache-size-mb": 4, "dht-enabled": true, "download-dir": "/media/hd_externo/Torrent_completo", "download-limit": 100, "download-limit-enabled": 0, "download-queue-enabled": true, "download-queue-size": 5, "encryption": 1, "idle-seeding-limit": 30, "idle-seeding-limit-enabled": false, "incomplete-dir": "/media/hd_externo/Torrent_completo", "incomplete-dir-enabled": true, "lpd-enabled": false, "max-peers-global": 200, "message-level": 1, "peer-congestion-algorithm": "", "peer-id-ttl-hours": 6, "peer-limit-global": 200, "peer-limit-per-torrent": 50, "peer-port": 51413, "peer-port-random-high": 65535, "peer-port-random-low": 49152, "peer-port-random-on-start": false, "peer-socket-tos": "default", "pex-enabled": true, "port-forwarding-enabled": false, "preallocation": 1, "prefetch-enabled": 1, "queue-stalled-enabled": true, "queue-stalled-minutes": 30, "ratio-limit": 2, "ratio-limit-enabled": false, "rename-partial-files": true, "rpc-authentication-required": true, "rpc-bind-address": "0.0.0.0", "rpc-enabled": true, "rpc-password": "{2d15be92741a1b2cd87ef7af39931c1b088499b0A8PoYK7r", "rpc-port": 9091, "rpc-url": "/transmission/", "rpc-username": "rasp_levins", "rpc-whitelist": "127.0.0.1", "rpc-whitelist-enabled": false, "scrape-paused-torrents-enabled": true, "script-torrent-done-enabled": false, "script-torrent-done-filename": "", "seed-queue-enabled": false, "seed-queue-size": 10, "speed-limit-down": 100, "speed-limit-down-enabled": false, "speed-limit-up": 100, "speed-limit-up-enabled": false, "start-added-torrents": true, "trash-original-torrent-files": false, "umask": 18, "upload-limit": 100, "upload-limit-enabled": 0, "upload-slots-per-torrent": 14, "utp-enabled": true }

Eu alterei o “download-dir”, alterei o “incomplete-dir” e habilitei seu uso com “incomplete-dir-enabled”: true, por padrão ele joga todos os arquivos na mesma pasta, habilitei autenticação em “rpc-enabled”, troquei o “rpc-username” e “rpc-password”, e ao salvar o arquivo e reiniciar o transmission, ele usa um hash na senha, para ninguém ler sua senha nesse arquivo.

Para reiniciar o transmission no terminal eu uso

1
sudo service transmission-daemon reload

E depois disso é so acessar ele pelo ip do seu raspberry na porta 9091, se você não alterou a porta no arquivo acima, aqui em casa eu acesso com o link http://192.168.0.3:9091, ja que eu fixei o ip do rasp_levins.

Espero que ninguém me julgue pelo que estou baixando até o momento desse post heheh, agora outra coisa que eu fiz, é que como já tenho o raspberry rodando um kiosk mode, como visto no tópico passado, eu quis deixar rodando la um pequeno quadradinho para indicar se o torrent está ligado, se tem algo sendo baixado, para saber que estou consumindo banda e algumas estatísticas simples de uso. Isso foi relativamente fácil porque o Transmission tem uma interface php, disponível na página deles, nesse repositório do github, dai podemos usar essa classe para tirar algumas informações e deixar elas aparecendo, no meu caso ficou assim:

Todo o código dessa página do kiosk-mode está no repositório que eu fiz no github, e depois vou explicar melhor o código no README.md do repositório.

Bem é isso ai, estou tomando coragem para voltar a estudar mais seriamente, ainda tenho projeto para terminar de escrever mas o desanimo anda forte, mas vamos levando a vida. Até a Próxima.