Script em modo root

Eu entendi a colocação, e não sei se entendi errado mas no caso de acesso dos usuários, eles só fazem logim pra acessar a internet, o usuário do sistema sempre é o mesmo que foi implementado desde o início. Ou seja, o usuário do sistema sempre permanece inalterado não importando quem use o sistema.
E essa atualização automática que o Ubuntu oferece, não são apenas as atualizações de segurança do sistema? Ou elas englobam outros aplicativos instalados pelo usuário? Porque tem alguns aplicativos que foram instalados depois tipo o WPS Office, o Epoptes-client e alguns outros pois foi uma instalação básica do Ubuntu.

Eu consegui resolver agora. O problema estava na máquina virtual que eu estava usando. Eu salvei uma appliance da máquina e apaguei a que estava usando e importei novamente a appliance e agora funcionou nessa nova.
Eu fiz o seguinte no arquivo sudoers:

root ALL = NOPASSWD: /opt/ers/ers.py

E quanto ao arquivo ers.py ficou assim:

def update( ):
	c = 0
	up = False
	conn = 'Not connected'
	while conn == 'Not connected':
		c += 1
		try:
			socket.create_connection(("www.google.com", 80))
			conn = 'Connected'
		except OSError:
			conn = 'Not connected'
			
		if conn == 'Connected':
			try:
				cmd = [['sudo -S rm /var/cache/apt/archives/lock'], ['sudo -S rm /var/lib/dpkg/lock-frontend'], ['sudo -S rm -rf /var/lib/apt/lists/*'], ['sudo -S apt update'], ['sudo -S apt full-upgrade -y'], ['sudo -S apt dist-upgrade -y'], ['sudo -S apt install -f'], ['sudo -S apt autoremove -y'], ['sudo -S apt autoclean -y']]
				for x in cmd:
					p = Popen(x, stderr = PIPE, universal_newlines = True, shell = True)
					stdout, stderr = p.communicate( )
			except Exception as e:
				pass
			up = True
		sleep(1)
		if (c > 3) or (conn == 'Connected'):
			break
	return up

E agora está funcionando como deveria. Bom, ao menos na máquina virtual, funcionou. Ainda vou fazer um teste com um dos computadores da instituição. O pior que pode acontecer, é dar bug no sistema e eu ter que reinstalar tudo. Mas, é a vida…
Valeu pela ajuda pessoal.

1 curtida

Eu venho aqui me juntar ao restante dos post no sentido de reforçar que a melhor escolha provavelmente é o systemd, outro ponto além dos já indicados aqui é você poder usar NetworkManager-wait-online.service para tornar uma conexão válida com a rede um requisito para execução do serviço, evitando esse loop.

4 curtidas

E como eu faria isso? Poderia me dar um exemplo básico?

Pelo que eu entendi, você já tem um .service que você criou e chama o seu script não?

Verifique se você tem esse serviço que eu mencionei e está ativado:

systemctl list-unit-files | ag NetworkManager-wait-online.service

Depois é só ajustar o seu serviço no systemd para que ele exija o target network-online.target e inicia após o mesmo:

[Unit]
Requires=network-online.target
After=network-online.target
...

Uma boa ideia é tornar o serviço instalável e desejado pelo target network-online.target:

...
[Install]
WantedBy=network-online.target

Neste caso você vai ter de ativar o serviço:

systemctl enable seu-servico.service
1 curtida

Sim, eu criei um arquivo desse tipo.

Eu acho que já entendi como funciona. A questão agora é como eu faço pra que a função update( ) reconheça que está conectado? Porque nesse caso o arquivo do Python tem mais uma função que monitora dois horários durante o expediente pra apagar tudo o que é deixado nas máquinas pelos usuários. O primeiro horário é pela manhã, assim que começa o expediente e o outro horário é no final.
Digo isso porque se o arquivo .service que eu criei vai depender de uma conexão com a internet pra chamar o programa (bom, ao menos, foi o que eu entendi nesse trecho Requires=network-online.target), não vai influenciar na função que apaga o conteúdo dos diretórios no /home? Ou eu vou ter que criar dois arquivos .service e dois arquivos em Python?

Me desculpa se as perguntas parecem idiotas, mas é que ultimamente eu tenho me esforçado pra aprender mais sobre Linux e só agora eu estou descobrindo algumas coisas interessantes que dá pra fazer no sistema.

Eu rodei esse comando e vi que essa funcionalidade está ativa no sistema.

Honestamente eu acho essa questão de ficar testando a conexão de dentro do seu script algo não muito elegante, outras possíveis abordagens que acho melhor:

  1. Sem internet seu script vai fatalmente falhar, uma ideia melhor seria pensar em fazer o script falhar graciosamente.

  2. Você pode tentar garantir a existência da rede reiniciando network.service antes de rodar o serviço na segunda vez, ou criando outro serviço para conectar em uma rede garantida, ou algo similar.

Você pode integrar estas questões no systemd repensando a abordagem para tornar o serviço engatilhável via um timer systemd ou então usar os targets shutdown.target, reboot.target, suspend.target , etc ao seu favor.

No fim só sabendo realmente o que você planeja e limites aceitáveis, como pode falhar, etc.

2 curtidas

Tenho, mais ou menos, uma ideia como isso funciona. A questão é que esse loop que eu fiz pra procurar a conexão com a internet é devido ao fato de que os computadores não ficam conectados na internet durante o expediente e, sim, quando umusuário que precise do computador, ative a internet quando ele faz login no provedor de internet da instituição, ou seja, se o usuário quiser acessar o computador sem conectar com a internet, ele pode. Eu preciso aproveitar esse momento em que o usuário se conecta a internet pra atualizar o PC. Deu pra entender?
Eu conheço algumas coisas sobre o Linux, mas ainda não é o suficiente pra chegar nesse nível e isso que me atrapalha pra fazer a lógica no Python.

Já considerou não instalar a atualização enquanto o computador está operante, mas sim apenas baixar os pacotes no cache?

Desse modo, seria possível explorar o pacote unattended-upgrades (já citado) para fazer a instalação durante o desligamento. Também não seria necessário remover arquivos de trava.

2 curtidas

Eu precisaria olhar isso com calma eentender como funciona pra implementar isso. Eu não estou descartando as sugestões, o problema é que, pelo fato de eu querer logo um resultado, eu poderia usar esse que eu consegui agora e depois, quando eu entender como se lida com as sugestões que me foram dadas, eu vou implementando até tornar a tarefa mais performática e prática. Não é o caso de ser teimoso e, sim, o fato de não saber mais além do que eu tenho no momento. rsrsrsrsrsrsrsrs.

Os usuários se conectam via usuário e senha na rede para liberar? Estou curioso porque não entendi bem porque a rede fica bloqueada no restante do tempo. Enfim neste caso seria realmente um loop verificando algum output, como o de ifconfig, mas sem detalhes da rede vai ser difícil definir a melhor abordagem, se é meramente uma questão de detectar um ifupdown ou testar mesmo a rede.

Ainda acho que a abordagem de falhar graciosamente evitaria isso, rodar o comando com ou sem rede, e se der certo, ok, senão, tratar a exceção.

1 curtida

É isso aí. Parece estranho, mas faz um certo sentido, porque, como o acesso é gratuito na instituição (só precisa de um cadastro), qualquer um pode ir lá e usar os computadores. Assim, se alguém usar um PC pra fazer besteira, fica mais fácil de saber quem foi. Há um tempo atrás tinha uns figuras trocando material sobre pedofilia e só foi possível rastrear e dar flagrante por causa desse esquema do cadastro. Ou seja, foi mais fácil de achar os culpados.

Entendo, uma salvaguarda plausível, pois a instituição fica responsável pelo que acontece na rede…

Enfim como eu disse anteriormente, mesmo assim eu não acho que você precise testar a rede, simplesmente suponha que a rede vai existir e se preocupe apenas com a falha, os packagers lidam de forma “graciosa” com a ausência da rede.

Não acho que você precisaria ter um serviço rodando como daemon, um systemd timer configurado para segundos/minutos/etc daria conta de rodar seu script.

Outra abordagem mais elegante, para o futuro, é centralizar essa tarefa em um servidor, alguns packagers tem a capacidade de fazer update via rede local, por exemplo no caso do dnf:

https://dnf-plugins-core.readthedocs.io/en/latest/local.html

Assim um servidor, sempre com rede garantiria essa questão e melhoraria o uso da rede.

1 curtida

Sim, com certeza. Eu achei interessante o que o @Capezotte sugeriu, mas o que falta pra mim, por enquanto, e saber como funciona pra poder implementar. Tendo isso, o resto é tranquilo. Eu só preciso ter uma ideia básica de como funciona e o resto eu faço.
De qualquer forma, agradeço muito a ajuda de vocês.

Na verdade a abordagem do @Capezotte é meio obrigatória, você não vai querer ter de lidar com os estragos de forçar a retirada do locker do database do seu packager enquanto ele está aplicando atualizações e rodar outra instância ao mesmo tempo. Ou um update estar rolando de fundo, durante um reboot, shutdown, ou algo assim, é sistema quebrado na certa.

1 curtida

Ah! Esse comando, eu peguei ele de um script que, se eu não estiver enganado, o Dio usou pra mostrar como ele automatizava a pós instalação do Linux Mint. Eu adaptei ele pra mim e ficou até hoje. Mas o que, precisamente, esse comando faz? Eu sei que ele desbloqueia algo, mas o que é esse algo e o que ele faz?

o packager usa estes lockfiles para proteger o banco de dados de ser modificado por mais de um processo dele mesmo, simplesmente porque a coisa foi implementada para ter 1 database sendo acessado por apenas 1 processo do packager por vez.

Eu aconselharia a fazer como o @Capezotte indicou, só baixar os updates, e não mexer no lock do apt.

Você pode usar systemd timer e dar uma ajustada no serviço, para garantir que o script não rode múltiplas instâncias ao mesmo tempo, e dai aplicar como ele apontou explorando o unattended-upgrades. Assim você vai ter mais garantia que ninguém desligue a máquina enquanto um upgrade está rolando silenciosamente em background e se depare na manhã seguinte com um sistema que não inicia.

De resto aquele comando ali de cima que você colocou no script é uma boa ideia só depois da instalação, ficar rodando aquilo em background vai dar problema.

1 curtida

Ah! Entendi agora. Eu já tirei o comando do script.

Acho que agora que entendi o problema.

A real é que o modo de controle de acesso dos usuários à internet está bem macarrônica. Geralmente o que se faz é usar um controle de navegação via proxy, onde se pode colocar a autenticação. A interface de rede deveria ficar ativa o tempo todo, e então por regras de firewall/iptables bloquear todo o tráfego que não seja para sites estritamente necessários para as tarefas administrativas como atualização de sistema, acesso remoto, etc…

O controle de acesso e logs de usuários fica sendo gerenciado pelo servidor proxy, com possibIlidade de várias regras de bloqueio de sites, com a vantagem de barrar acessos a outros protocolos de rede.

4 curtidas

Acredito até que seria um trabalho para nosso querido pfSense.

1 curtida