Área de transferência compartilhada entre vários servidores X11 (Xephyr, Xpra etc.)

Área de transferência compartilhada entre vários servidores X11 (Xephyr, Xpra etc.)

Pretendo executar aplicativos potencialmente perigosos(navegador, etc.)em um servidor X separado, mas como cada servidor possui sua própria área de transferência, é impossível copiar o link/texto de uma janela para outra.

A maioria dos artigos sugere fazer isso usando scripts usando xclip e outros utilitários semelhantes.

Mas comoCORRETAMENTEcriar uma área de transferência comum para não criar acidentalmente uma nova vulnerabilidade?

Responder1

NOTA: Atualizando a resposta para refletir a mudança de estratégia - em vez de executar o Xephyr em um servidor/contêiner, estou executando-o no ambiente host/de uso principal. A razão para isso é que executar o Xephyr no servidor/contêiner é como colocar uma fechadura em uma porta interna em vez de na porta da frente - os malfeitores contornariam a porta interna e acessariam a área de transferência diretamente através do soquete remoto do tubo X.

Enfrentando o mesmo problema de vulnerabilidade da área de transferência, abordei-o executando um Xephyr no host (meu espaço de trabalho pessoal) e encaminhando o X do(s) servidor(es) em contêiner(es) para o Xephyr local.

O Xephyr está sendo executado na tela ':2' enquanto as janelas e o navegador da minha área de trabalho pessoal estão sendo executados na tela padrão ':0'. Esses dois monitores não compartilham uma área de transferência - cada um possui sua própria área de transferência. Essa é a única maneira de evitar a espionagem da área de transferência do meu espaço de trabalho pessoal na exibição ':0'. Então eu configurei teclas de atalho (por exemplo, teclas de função), uma para transferir o conteúdo da área de transferência de ':0' para ':2' e outra para ':2' para ':0', permitindo assim o controle completo.

No shell script, o código poderia ser parecido com

xsel --display :0 --clipboard -o |  xsel --display :2 --clipboard -i

embora eu esteja usando javascript conforme mostrado no final deste post.

O script Shell para iniciar o encaminhamento do X pode ser parecido com isto

Xephyr <args> :2
DISPLAY=:2 ssh -X -R 44713:localhost:4713 user@container <<EOF
DISPLAY=:10 PULSE_SERVER=tcp:localhost:44713 openbox --startup firefox
EOF

embora eu esteja usando um programa javascript para fazer isso.

Aqui está o código javascript para copiar entre ':0' e ":2" que é mapeado por teclas de atalho. Você pode ver que aparece uma caixa de mensagem temporária para confirmar que funcionou.

#!/usr/bin/env node
`strict`;
const child_process = require('child_process');

// TODO: write unviewable error messasges to system log

function notifySend(title, msg){
  title = title.replace(/"/g, '\\"');
  msg = msg.replace(/"/g, '\\"');
  //msg = msg.replace(/'/g, '\\'')
  try {
    child_process.execSync(`notify-send "${title}" "${msg}"`);
  } catch(e) {
    console.log(`system call "notify-send" failed with ${e.message}`);
  }
}

async function clipXfer(fromDispNum,toDispNum){
  var clipValue;
  let cmd1 = `xsel --display :${fromDispNum} --clipboard --output`;
  let cmd2 = `xsel --display :${toDispNum} --clipboard --input`;
  try {
    clipValue = child_process.execSync(cmd1, { encoding: 'utf-8' });
  } catch(e) {
    throw Error(`Display ${fromDispNum} clipboard is empty`);
  }
  await new Promise((resolve, reject)=>{        
    // eslint-disable-next-line no-unused-vars
    var proc = child_process.exec(cmd2, (error, stdout, stderr) => {
      //if (stdout) console.log(stdout);
      //if (stderr) console.log(stderr);
      if (error) {
        reject(Error(`${error.message}`));
      }
      resolve();
    });
    if (!proc.stdin.write(clipValue))
      reject(Error('clipToCont(), pipe write failed'));
    proc.stdin.end();
  });                    
}


async function main()
{
  let argOff=2;
  if (process.argv.length-argOff<2)
    throw Error('clip-xfer requires two arguments: fromDispNum, toDispNum');
  let fromDispNum = process.argv[argOff];
  let toDispNum = process.argv[argOff+1];
  argOff+=2;
  let f = (outcome)=>{
    notifySend("clipXfer",  `${fromDispNum} => ${toDispNum} ${outcome}`);
  }; 
  await clipXfer(fromDispNum,toDispNum)
    .then(f('SUCCESS'))
    .catch((e)=>{f(`FAILURE, ${e.message}`); throw e;});
}

//console.log(process.argv);
//console.log(process.env);
main()
  .then(()=>{process.exitCode=0;})
  .catch((e)=>{
    console.log(e);
    process.exitCode=1;
  });

Responder2

eu usoxclipsync. Funciona em 98%. Em 2% estou fazendo isso:

Em exibição: 0 executarcopiarq. Em exibição: 1 execuçãoparcelalite. Para sincronizar a área de transferência eu uso

copyq add $(parcellite)

ou para trás

copyq read | parcellite -c

Funciona 100%! :-)

informação relacionada