Skip to content

Instantly share code, notes, and snippets.

@tdcosta100
Last active July 17, 2023 17:24
Show Gist options
  • Star 25 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save tdcosta100/c5c206f8958e82e638fa0ea226351081 to your computer and use it in GitHub Desktop.
Save tdcosta100/c5c206f8958e82e638fa0ea226351081 to your computer and use it in GitHub Desktop.
Tutorial para utilizar interface gráfica no WSL2, substituindo XServer pelo Xvnc, permitindo ao WSL trabalhar como se fosse Linux nativo, incluindo tela de login

WSL2 com interface gráfica utilizando Xvnc

Nesse tutorial, iremos configurar a interface gráfica no WSL2 e acessá-la utilizando VNC. Nenhum software adicional fora do WSL é necessário (como o VcXsrv), exceto, claro, um VNC Viewer (RealVNC, TightVNC, TigerVNC, UVNC, etc, todos devem funcionar sem problemas).

Os componentes-chave que precisamos instalar são: tigervnc-standalone-server e systemd-genie.

Para essa configuração, irei utilizar o Ubuntu 20.04 LTS (Focal Fossa) e irei instalar o GNOME Desktop. Uma vez que os componentes-chave não são diretamente relacionados ou dependentes do Ubuntu ou do GNOME, você pode utilizar sua distribuição favorita e interface gráfica. Dê uma olhada na seção Telas de exempo para exemplos.

Então vamos lá. Primeiro precisamos ter o WSL2 instalado e funcionando.

Antes de colocar a mão na massa, temos que garantir que tudo esteja atualizado.

sudo apt update
sudo apt upgrade

Se você está utilizando Debian, você também precisa do comando abaixo:

sudo apt install curl wget

Agora sim, estamos prontos para começar.

Instalando os componentes

Instalando a interface gráfica

  1. O Ubuntu tem um excelente instalador chamado tasksel, porém ele não vem instalado por padrão. Então vamos instalá-lo.

    sudo apt install tasksel
    
  2. Agora que instalamos, vamos executá-lo.

    sudo tasksel
    
  3. Na lista de pacotes, selecione sua interface gráfica favorita. Use a barra de espaço para selecionar o pacote desejado, e Tab para confirmar a sua escolha. Eu selecionei Ubuntu Desktop. A instalação vai demorar um pouco, então seja paciente.

Instalando o VNC Server

Muito simples, um comando e pronto.

sudo apt install tigervnc-standalone-server

Instalando o dotnet-runtime

O systemd-genie é dependente do dotnet-runtime, ele só pode ser instalado manualmente. Siga as instruções de instalação. Os comandos para instalar o dotnet-runtime-5.0 no Ubuntu 20.04 LTS (Focal Fossa) são:

wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt update
sudo apt install dotnet-runtime-5.0

Instalando o systemd-genie

Agora podemos instalar o systemd-genie, que é o responsável por transformar o WSL minimalista em uma instância de Linux bem mais completa, com systemd e outras coisas. Isso é necessário para executar o GDM (GNOME Display Manager) e o LightDM adequadamente, e permitindo ao usuário ter uma experiência gráfica completa, com login e tudo mais. Aqui estão as instruções de instalação. Em meados de 06/04/2021, os passos necessários para instalá-lo são (e só posso garantir que irão funcionar no Ubuntu. Para outras distribuições, você deve seguir as instruções de instalação para obter o pacote apropriado para o seu sistema):

sudo apt install apt-transport-https
sudo wget -O /etc/apt/trusted.gpg.d/wsl-transdebian.gpg https://arkane-systems.github.io/wsl-transdebian/apt/wsl-transdebian.gpg
sudo chmod a+r /etc/apt/trusted.gpg.d/wsl-transdebian.gpg
source /etc/os-release
cat << EOF | sudo tee /etc/apt/sources.list.d/wsl-transdebian.list
deb https://arkane-systems.github.io/wsl-transdebian/apt/ $VERSION_CODENAME main
deb-src https://arkane-systems.github.io/wsl-transdebian/apt/ $VERSION_CODENAME main
EOF
sudo apt update
sudo apt install systemd-genie

O processo de instalação finalmente está completo.

Configurando o ambiente

Criando as senhas do VNC

  1. Nessa configuração, cada usuário tem uma senha de VNC diferente. Então, precisamos configurar pelo menos três senhas: uma para o usuário atual, uma para o usuário root, e uma para o usuário gdm, que é o que irá apresentar a tela de login. Se as senhas não forem configuradas, não será possível acessar a tela de login, ou a área de trabalho do usuário. Então vamos configurar a senha de VNC para o usuário atual:

    vncpasswd
    
  2. Agora, vamos configurar a senha de VNC para o usuário root (necessária para o caso de você utilizar o LightDM no lugar do GDM):

    sudo -H vncpasswd
    
  3. Por fim, vamos configurar a senha de VNC para o usuário do GDM:

    sudo -H -u gdm vncpasswd
    

    Dica: no Debian, o usuário é do GDM é Debian-gdm.

    Você pode repetir esse passo para outros usuários existentes.

Substituindo o XServer pelo Xvnc

Por padrão, o display manager cria múltiplas instâncias do XServer, uma para cada sessão de usuário, incluindo a tela de login, que é a sessão do usuário gdm. Portanto, vamos substituir o script Xorg por uma nova versão que chama o Xvnc ao invés do XServer. Esta É a "mágica" que estamos tentando fazer de fato.

  1. Primeiro, faremos um backup do script Xorg original.

    sudo mv /usr/bin/Xorg /usr/bin/Xorg_old
    
  2. Agora, criamos um novo script Xorg.

    sudo nano /usr/bin/Xorg_new
    
  3. Cole o código abaixo no editor (lembre-se, o shell do WSL utiliza CTRL + SHIFT + V para colar, ao invés do tradicional CTRL + V):

    #!/bin/bash
    for arg do
      shift
      case $arg in
        # O Xvnc nao suporta o argumento vtxx. Entao vamos converte-lo para ttyxx
        vt*)
          set -- "$@" "${arg//vt/tty}"
          ;;
        # -keeptty nao e suportado pelo Xvnc
        -keeptty)
          ;;
        # -novtswitch nao e suportado pelo Xvnc
        -novtswitch)
          ;;
        # outros argumentos ficam intocados
        *)
          set -- "$@" "$arg"
          ;;
      esac
    done
    
    # Aqui voce pode adicionar ou alterar as opcoes conforme for necessario
    command=("/usr/bin/Xvnc" "-geometry" "1024x768" "-PasswordFile" "${HOME:-/root}/.vnc/passwd" "$@") 
    
    systemd-cat -t /usr/bin/Xorg echo "Starting Xvnc:" "${command[@]}"
    
    exec "${command[@]}"
    

    Note a resolução da tela virtual. Você pode alterá-la para o que julgar adequado (1366x768, 1920x1080, etc). Você também pode alterar a opção -PasswordFile para um caminho fixo ao invés da home do usuário atual, tornando desnecessário ter uma senha de VNC para cada usuário.

  4. Finalmente, ajustamos as permissões do script.

    sudo chmod 0755 /usr/bin/Xorg_new
    sudo ln -sf Xorg_new /usr/bin/Xorg
    

    Atenção: quando ocorrem atualizações do sistema, o script Xorg pode acabar sendo substituído pela sua versão original. Caso isso ocorra, basta repetir os comandos acima.

Executando o systemd-genie

Finalmente chegou a hora de fazer tudo funcionar.

genie -s

Fazer isso é como dar boot no Linux novamente, dessa vez com o systemd. Por causa do systemd, o serviço gdm será iniciado automaticamente, e irá criar uma instância do XServer para mostrar a interface de login. Nós mudamos isso para fazê-lo criar instâncias de Xvnc, portanto podemos acessá-las. A primeira instância vai estar disponível na porta 5900, a segunda estará disponível na porta 5901, e assim por diante.

Atenção: caso queira evitar os erros que aparecem durante a inicialização do genie, ou para fazê-lo iniciar mais rápido, dê uma olhada nesta página.

Acessando a tela de VNC

Depois de um tempo (geralmente, cerca de 30 segundos, mas se você não tiver um SSD pode demorar 1 a 2 minutos), podemos testar se está tudo funcionando corretamente. Use seu VNC Viewer favorito para conectar-se ao seu localhost na porta 5900 (localhost:5900). Use a senha de VNC definida para o usuário gdm. A tela de login deve aparecer.

Depois de fazer login, a tela ficará em branco. Isso acontece porque uma nova instância do Xvnc foi criada para para a área de trabalho do usuário, acessível pela porta 5901. Conecte-se a esta tela agora. A área de trabalho do usuário logado deve aparecer. Quando você se deslogar, a tela da porta 5900 deverá mostrar a interface de login novamente. Porém isso se aplica ao GDM (que é o que é instalado junto com o Ubuntu Desktop). Você pode alterar esse comportamento através dos passos abaixo:

  1. sudo nano /etc/gdm3/custom.conf

  2. Descomente e edite as seguintes linhas:

     AutomaticLoginEnable=true
     AutomaticLogin=[seu username sem os colchetes]
    

Se você instalou o LightDM, a tela de área de trabalho vai aparecer também na tela da porta 5900, portanto não há necessidade de se conectar à porta 5901.

Finalizando corretamente

Uma coisa muito importante é: uma vez que você iniciou os serviços do systemd, você não pode simplesmente parar sua instância de Linux abruptamente. Você deve fazer um desligamento normal de Linux. Você pode utilizar uma das alternativas abaixo:

  • Opção Desligar no menu da interface gráfica
  • sudo init 0, caso esteja dentro da instância do genie
  • genie -u, caso esteja fora da instância do genie

Depois disso, você pode parar a sua instância de WSL com segurança, através do comando wsl --terminate ou wsl --shutdown. Não realizar o processo de desligamento poderá corromper sua instância de WSL, portanto seja cuidadoso.

Dicas e truques

  • O VNC é um protocolo bastante adaptativo, e por padrão utiliza a maior taxa de compressão possível, para otimizar a utilização da rede. Mas no nosso caso, isso apenas desperdiça processamento, uma vez que você está se conectando ao próprio computador (largura de banda "infinita" e ping praticamente zero). Para não utilizar nenhum algoritmo de compressão e assim reduzir o delay, o ideal é forçar seu VNC Viewer a conectar-se utilizando a codificação RAW. O ganho de performance é perceptível, especialmente ao reproduzir vídeos (apesar de a performance não ser grande coisa nesse caso específico).

  • Se você está utilizando Debian, vai precisar executar o seguinte comando para alguns aplicativos funcionarem:

    echo "LANG=en_US.UTF-8" | sudo tee -a /etc/default/locale
    

Solução de problemas

  1. Se não funcionar logo de cara, tente ver os logs do journalctl:

    journalctl -b -t /usr/lib/gdm3/gdm-x-session -t /usr/bin/Xorg --no-pager
    

    Na saída gerada, você deve conseguir encontrar qual linha de comando foi gerada para o Xvnc, e quais mensagens de erro aparecem. E claro, mesmo que tudo funcione corretamente, ainda assim você pode checar os logs para ver o que está acontecendo, ou para fazer debug.

  2. Se você estiver utilizando o LightDM, também precisa checar os logs do diretório /var/log/lightdm (para conseguir usar o comando cat nos arquivos desse diretório, utilize sudo). A saída de log do Xvnc deve ser encontrada no arquivo /var/log/lightdm/x-0.log.

  3. Se você consegue se conectar nas portas 59XX, mas recebe uma mensagem de erro do tipo Authentication failure: No password configured for VNC Auth, está faltando o arquivo $HOME/.vnc/passwd para o usuário da tela correspondente (na tela da porta 5900, o usuário é o gdm). Tente repetir os passos da seção Criando as senhas do VNC e tente se conectar novamente.

  4. Se ainda não funciona, tente reiniciar o WSL. Abra um prompt de comando do Windows PowerShell, e execute o seguinte comando (mas antes, não se esqueça de salvar tudo o que estiver aberto no WSL, porque ele será finalizado completamente sem aviso prévio):

    PS > wsl --terminate <nome da sua distribuição>
    

    Depois disso, abra o shell da sua distribuição e repita os passos da seção Executando o systemd-genie.

Telas de exemplo

GDM

GDM

LightDM

LightDM

GNOME

GNOME

KDE

KDE

Xfce

Xfce

Budgie Desktop

Budgie Desktop

Pessoas que contribuíram

Meu muito obrigado às pessoas abaixo, cujo feedback fez esse tutorial atingir o nível atual de qualidade e completitude (e ficará cada vez mais completo conforme mais feedback for sendo dado).

@swapansanjay
Copy link

Hello tdcosta100,
I was unsuccessful in installing "systemd-genie" following your tutorial.
It keeps giving the the error E: systemd-genie not found.
Also trying your workaround given in the link - /etc/apt/sources.list.d/wsl-transdebian.list I keep getting errors - E: Malformed entry 1 in list file /etc/apt/sources.list.d/wsl-transdebian.list (Component)
E: The list of sources could not be read.
I dont know what to do.
Also you have not explained the flow of process of WSL2 to the XVNC terminal how is the interconnections of various softwares working because of which unable to figure out where the problem is.

regards,
Swapan

@tdcosta100
Copy link
Author

Hello tdcosta100,
I was unsuccessful in installing "systemd-genie" following your tutorial.
It keeps giving the the error E: systemd-genie not found.
Also trying your workaround given in the link - /etc/apt/sources.list.d/wsl-transdebian.list I keep getting errors - E: Malformed entry 1 in list file /etc/apt/sources.list.d/wsl-transdebian.list (Component)
E: The list of sources could not be read.
I dont know what to do.
Also you have not explained the flow of process of WSL2 to the XVNC terminal how is the interconnections of various softwares working because of which unable to figure out where the problem is.

regards,
Swapan

Hi, @swapansanjay. Your problem is to correctly setup systemd-genie repositories. Could you please copy and paste your comment in the english version tutorial? Thank you!

@tdcosta100
Copy link
Author

tdcosta100 commented May 28, 2021

Hi tdcosta,

I'm having trouble with the following line:

sudo wget -O /etc/apt/trusted.gpg.d/wsl-transdebian.gpg https://arkane-systems.github.io/wsl-transdebian/apt/wsl-transdebian.gpg

I'm getting a 404 Error and I'm wondering if this is something you notice too. Has the site changed in the last month?

Best,
Avik

Hi, Avik. This tutorial is outdated. Please follow the instructions of the english version. Tell me (in the english version comments) if you have any trouble.

@an3dree
Copy link

an3dree commented Jun 8, 2021

Olá @tdcosta100 . Parabéns pelo trabalho, muito bom!

Consegui seguir o passo a passo e consegui logar na GUI com o LightDM, utilizando a porta 5900

Agora só preciso melhorar os graficos aqui :D

Muito obrigado !

@tdcosta100
Copy link
Author

Olá, @Aan3dree! Muito obrigado! Fico muito feliz que você conseguiu usar esse tutorial, visto que está um bocado desatualizado em relação ao tutorial em inglês (preciso de um tempo pra atualizar a versão em português). Então deu tudo certo? Qualquer dúvida é só perguntar que se estiver ao meu alcance, eu vejo aqui.

Abraços,
Tiago

@an3dree
Copy link

an3dree commented Jun 10, 2021

Olá, @Aan3dree! Muito obrigado! Fico muito feliz que você conseguiu usar esse tutorial, visto que está um bocado desatualizado em relação ao tutorial em inglês (preciso de um tempo pra atualizar a versão em português). Então deu tudo certo? Qualquer dúvida é só perguntar que se estiver ao meu alcance, eu vejo aqui.

Abraços,
Tiago

Precisei acompanhar os dois pra dar certo e da primeira vez não consegui. Fica bem bacana, mas percebi que ele perde algumas integrações ne? tipo qd vou dar 'code .' em um projeto ele nao abre o mais o VScode remoto com wsl e tbm não tem som kkkkk, acho que eu tinha escolhido o desktop Budgie por ser bem bacana pra multimidia. No geral ficou muito bom!

Mas agradeço muito, top seu tutorial. Ta de parabéns!
Depois vou te procurar nas redes e compartilhar com os devidos créditos.

Se cuide,
André

@tdcosta100
Copy link
Author

tdcosta100 commented Jun 10, 2021

Olá, @Aan3dree! Muito obrigado! Fico muito feliz que você conseguiu usar esse tutorial, visto que está um bocado desatualizado em relação ao tutorial em inglês (preciso de um tempo pra atualizar a versão em português). Então deu tudo certo? Qualquer dúvida é só perguntar que se estiver ao meu alcance, eu vejo aqui.
Abraços,
Tiago

Precisei acompanhar os dois pra dar certo e da primeira vez não consegui. Fica bem bacana, mas percebi que ele perde algumas integrações ne? tipo qd vou dar 'code .' em um projeto ele nao abre o mais o VScode remoto com wsl e tbm não tem som kkkkk, acho que eu tinha escolhido o desktop Budgie por ser bem bacana pra multimidia. No geral ficou muito bom!

Mas agradeço muito, top seu tutorial. Ta de parabéns!
Depois vou te procurar nas redes e compartilhar com os devidos créditos.

Se cuide,
André

Valeu mesmo pelo reconhecimento! Quanto ao VSCode especificamente, dê uma olhada aqui!

Abraços,
Tiago

@an3dree
Copy link

an3dree commented Jun 11, 2021

Olá, @Aan3dree! Muito obrigado! Fico muito feliz que você conseguiu usar esse tutorial, visto que está um bocado desatualizado em relação ao tutorial em inglês (preciso de um tempo pra atualizar a versão em português). Então deu tudo certo? Qualquer dúvida é só perguntar que se estiver ao meu alcance, eu vejo aqui.
Abraços,
Tiago

Precisei acompanhar os dois pra dar certo e da primeira vez não consegui. Fica bem bacana, mas percebi que ele perde algumas integrações ne? tipo qd vou dar 'code .' em um projeto ele nao abre o mais o VScode remoto com wsl e tbm não tem som kkkkk, acho que eu tinha escolhido o desktop Budgie por ser bem bacana pra multimidia. No geral ficou muito bom!
Mas agradeço muito, top seu tutorial. Ta de parabéns!
Depois vou te procurar nas redes e compartilhar com os devidos créditos.
Se cuide,
André

Valeu mesmo pelo reconhecimento! Quanto ao VSCode especificamente, dê uma olhada aqui!

Abraços,
Tiago

Poxa cara, valeu mesmo! Deu certo aqui =D

Se cuide,
André

@tdcosta100
Copy link
Author

Poxa cara, valeu mesmo! Deu certo aqui =D

Se cuide,
André

Opa, que ótimo! Qualquer coisa, fale aí que corro atrás.

Abraços,
Tiago

@mlknservices
Copy link

Primeiro gostaria de agradecer o compartilhamento deste tutorial, segui todos os passos e funcionou tudo pra mim exceto o som, não consigo fazer que saia o som de jeito nenhum, já pesquisei e não consigo encontrar como corrigir, se alguém passou pelo mesmo problema e conseguiu resolver, se puder compartilhar agradeço.

Abraço a todo.

@tdcosta100
Copy link
Author

Valeu, @mlknservices! O som precisa de uma solução própria. Tem vários tutoriais e todos que conheço passam por um servidor de áudio rodando no Windows e daí você redireciona pra ele via TCP (mais ou menos a mesma coisa que o pessoal que usa X Server rodando no Windows faz). Um exemplo:

microsoft/WSL#4205

Espero que consiga fazer funcionar.

Abraços,
Tiago

@thiagozucarini
Copy link

Tiago, logo após colocar a senha do VNC, aparece a mensagem:

Would you like to enter a view-only password (y/n)?

Qual opção coloco?

@tdcosta100
Copy link
Author

Olá, @thiagozucarini. Essa é a mensagem para você criar uma segunda senha para o VNC, e quem utilizá-la conseguirá apenas ver a tela, não conseguirá mexer em nada. A segunda senha é opcional, você pode escolher tê-la ou não. No contexto do WSL, creio que não faz sentido você ter essa segunda senha. No meu setup, eu escolho N.

@davilos
Copy link

davilos commented Aug 18, 2022

Opa tdcosta100, parabéns pelo trabalho, tá sensacional. Só estou com uma dúvida, como faço pra desinstalar a interface Xubuntu e instala a do Ubuntu? Instalei a do Xubuntu porque pensei que talvez ficasse travando muito, mas tá rodando liso aqui.

@tdcosta100
Copy link
Author

Olá, @davilos. Perdão pela demora, estava de férias e fiquei meio off. Você instalou o Xubuntu pelo tasksel? Se sim, é só desmarcar as opções marcadas lá, e depois de tudo desinstalado, instalar o Ubuntu Desktop. Mas pra instalar a interface do Ubuntu eu acho que você não precisa desinstalar nada do Xubuntu, ele só vai perguntar pra você qual display manager você quer usar (e aí você escolhe o GDM), e na hora de fazer login, qual desktop você quer usar (e aí você escolhe o Ubuntu). Testa aí e me fala se funcionou :).

@1993nxv
Copy link

1993nxv commented Mar 9, 2023

Boa tarde! Segui os passos, estou com este erro. Pode da um help?

genie: WARNING: systemd default target is default.target; targets other than multi-user.target may not work
genie: WARNING: if you wish to use a different target, this warning can be disabled in the config file
genie: WARNING: if you experience problems, please change the target to multi-user.target
umount: /proc/sys/fs/binfmt_misc: not mounted.
genie: failed to unmount binfmt_misc filesystem; attempting to continue
Waiting for systemd....!
genie: systemd did not enter running state (degraded) after 240 seconds
genie: this may be due to a problem with your systemd configuration
genie: information on problematic units is available at https://github.com/arkane-systems/genie/wiki/Systemd-units-known-to-be-problematic-under-WSL
genie: a list of failed units follows:

UNIT LOAD ACTIVE SUB DESCRIPTION
● atd.service loaded failed failed Deferred execution scheduler
● ssh.service loaded failed failed OpenBSD Secure Shell server
● systemd-remount-fs.service loaded failed failed Remount Root and Kernel File Systems
● multipathd.socket loaded failed failed multipathd control socket

LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.

4 loaded units listed.
genie: WARNING: systemd is in degraded state, issues may occur!

@tdcosta100
Copy link
Author

Olá, @1993nxv. Muita coisa mudou desde que esse tutorial foi escrito. Agora existe suporte nativo ao systemd, e com isso as coisas ficaram um pouco diferentes. Eu vou reescrever o tutorial para abraçar essas mudanças. Enquanto isso, me conte qual é a distro que você está usando? Pergunto porque o Ubuntu 22.04 infelizmente tem coisas que não funcionam, aí a opção será usar o Ubuntu 20.04 mesmo. Me avise que aí consigo continuar te ajudando.

@cjannuzzi
Copy link

@tdcosta100 gostei da ideia de reescrever o tutorial atualizado. Já que o 22.04 ta bugado pode ser o 20.04 caso esteja rodando liso. De qualquer forma, agradeço desde já o empenho.

@tdcosta100
Copy link
Author

Olá, @cjannuzzi. Ainda não atualizei a versão em português, mas você já pode conferir a versão atualizada em inglês aqui.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment