Securely Piping String in Local Text File to Remote Command using SSH












0















The following takes place on Ubuntu 18.



I need to automate the remote seeding of a gpg-agent with a passphrase stored in a file on my local machine using SSH.



The passphrase needs to be handled in such a way so that it cannot be easily viewed by other nosey users - principally on the remote server, but also it should be secure on the local box too.



The problem is a general one, rather than being GPG specific - how do I pass a string securely into a programming running on a remote server using ssh?



I know that putting the password on the command line means is visible using ps -ef on both local (ssh) and remote machines (bash -c). So I must avoid this.



I also know that storing the password in environment variables means a process' initial env can be see as cat /proc/<pid>/environ and gdb can be used to look at current state. So details can be seen on the local machine or the remote machine if local environment variables are forwarded. So this is not ideal, especially as I can't control tightly other people's access to the SSH user account on the remote machine.



After a bit of reading and experimentation I've come-up with the below - it certainly works! You can assume seed.txt is chmod 400 so short of someone having root access it is safe (or at least as safe as my SSH keys).



Note - seed.txt does not exist on the remote server, only on the local server, so it's contents must be sent to the remote server.



SSH connection is using keys so no password is need for that.



#!/bin/bash
ssh -T my-server <<EOSSH > /dev/null
printf '%sn' "$(cat seed.txt)" | /usr/lib/gnupg2/gpg-preset-passphrase -c 123456789
EOSSH


Using ps -ef on the local machine will only yield ssh -T my-server as the actual commands to be remotely executed are piped into stdin, rather than using the ssh command line.



Likewise the cat command line displays only the filename. printf, I believe, is a built-in command so will not show-up in ps. I believe the printf is being executed on the remote machine?



On the remote server ps will only show /usr/lib/gnupg2/gpg-preset-passphrase -c 123456789 as the passphrase is piped in again using stdin.



I'm making no direct use of environment variables so there shouldn't be any issue here. I'm a little anxious that something will be exposed from the SSH environment variables?



My question is - is my method sensible/simple/safe (assuming root access is not compromised), are there any obvious issues, and if yes, what are the suggested workarounds?



The only other options I've managed to get working is to use expect but given both ssh and gpg-preset-passphrase seem to be happy to accept input as stdin rather than interactively, it seems overkill to use expect?










share|improve this question









New contributor




Phil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1





    why the complications of printf and cat instead of just gpg-preset-passphrase ... < seed.txt ?

    – thrig
    19 mins ago











  • Thanks for reply - seed.txt is on the local machine, and the ($cat seed.txt) will be executed locally and the contents of seed.txt sent to the remote server. I think using < seed.txt means seed.txt would have to exist on the remote machine - which is not the case. A quick test gives seed.txt: No such file or directory if I make this change.

    – Phil
    11 mins ago


















0















The following takes place on Ubuntu 18.



I need to automate the remote seeding of a gpg-agent with a passphrase stored in a file on my local machine using SSH.



The passphrase needs to be handled in such a way so that it cannot be easily viewed by other nosey users - principally on the remote server, but also it should be secure on the local box too.



The problem is a general one, rather than being GPG specific - how do I pass a string securely into a programming running on a remote server using ssh?



I know that putting the password on the command line means is visible using ps -ef on both local (ssh) and remote machines (bash -c). So I must avoid this.



I also know that storing the password in environment variables means a process' initial env can be see as cat /proc/<pid>/environ and gdb can be used to look at current state. So details can be seen on the local machine or the remote machine if local environment variables are forwarded. So this is not ideal, especially as I can't control tightly other people's access to the SSH user account on the remote machine.



After a bit of reading and experimentation I've come-up with the below - it certainly works! You can assume seed.txt is chmod 400 so short of someone having root access it is safe (or at least as safe as my SSH keys).



Note - seed.txt does not exist on the remote server, only on the local server, so it's contents must be sent to the remote server.



SSH connection is using keys so no password is need for that.



#!/bin/bash
ssh -T my-server <<EOSSH > /dev/null
printf '%sn' "$(cat seed.txt)" | /usr/lib/gnupg2/gpg-preset-passphrase -c 123456789
EOSSH


Using ps -ef on the local machine will only yield ssh -T my-server as the actual commands to be remotely executed are piped into stdin, rather than using the ssh command line.



Likewise the cat command line displays only the filename. printf, I believe, is a built-in command so will not show-up in ps. I believe the printf is being executed on the remote machine?



On the remote server ps will only show /usr/lib/gnupg2/gpg-preset-passphrase -c 123456789 as the passphrase is piped in again using stdin.



I'm making no direct use of environment variables so there shouldn't be any issue here. I'm a little anxious that something will be exposed from the SSH environment variables?



My question is - is my method sensible/simple/safe (assuming root access is not compromised), are there any obvious issues, and if yes, what are the suggested workarounds?



The only other options I've managed to get working is to use expect but given both ssh and gpg-preset-passphrase seem to be happy to accept input as stdin rather than interactively, it seems overkill to use expect?










share|improve this question









New contributor




Phil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1





    why the complications of printf and cat instead of just gpg-preset-passphrase ... < seed.txt ?

    – thrig
    19 mins ago











  • Thanks for reply - seed.txt is on the local machine, and the ($cat seed.txt) will be executed locally and the contents of seed.txt sent to the remote server. I think using < seed.txt means seed.txt would have to exist on the remote machine - which is not the case. A quick test gives seed.txt: No such file or directory if I make this change.

    – Phil
    11 mins ago
















0












0








0


1






The following takes place on Ubuntu 18.



I need to automate the remote seeding of a gpg-agent with a passphrase stored in a file on my local machine using SSH.



The passphrase needs to be handled in such a way so that it cannot be easily viewed by other nosey users - principally on the remote server, but also it should be secure on the local box too.



The problem is a general one, rather than being GPG specific - how do I pass a string securely into a programming running on a remote server using ssh?



I know that putting the password on the command line means is visible using ps -ef on both local (ssh) and remote machines (bash -c). So I must avoid this.



I also know that storing the password in environment variables means a process' initial env can be see as cat /proc/<pid>/environ and gdb can be used to look at current state. So details can be seen on the local machine or the remote machine if local environment variables are forwarded. So this is not ideal, especially as I can't control tightly other people's access to the SSH user account on the remote machine.



After a bit of reading and experimentation I've come-up with the below - it certainly works! You can assume seed.txt is chmod 400 so short of someone having root access it is safe (or at least as safe as my SSH keys).



Note - seed.txt does not exist on the remote server, only on the local server, so it's contents must be sent to the remote server.



SSH connection is using keys so no password is need for that.



#!/bin/bash
ssh -T my-server <<EOSSH > /dev/null
printf '%sn' "$(cat seed.txt)" | /usr/lib/gnupg2/gpg-preset-passphrase -c 123456789
EOSSH


Using ps -ef on the local machine will only yield ssh -T my-server as the actual commands to be remotely executed are piped into stdin, rather than using the ssh command line.



Likewise the cat command line displays only the filename. printf, I believe, is a built-in command so will not show-up in ps. I believe the printf is being executed on the remote machine?



On the remote server ps will only show /usr/lib/gnupg2/gpg-preset-passphrase -c 123456789 as the passphrase is piped in again using stdin.



I'm making no direct use of environment variables so there shouldn't be any issue here. I'm a little anxious that something will be exposed from the SSH environment variables?



My question is - is my method sensible/simple/safe (assuming root access is not compromised), are there any obvious issues, and if yes, what are the suggested workarounds?



The only other options I've managed to get working is to use expect but given both ssh and gpg-preset-passphrase seem to be happy to accept input as stdin rather than interactively, it seems overkill to use expect?










share|improve this question









New contributor




Phil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












The following takes place on Ubuntu 18.



I need to automate the remote seeding of a gpg-agent with a passphrase stored in a file on my local machine using SSH.



The passphrase needs to be handled in such a way so that it cannot be easily viewed by other nosey users - principally on the remote server, but also it should be secure on the local box too.



The problem is a general one, rather than being GPG specific - how do I pass a string securely into a programming running on a remote server using ssh?



I know that putting the password on the command line means is visible using ps -ef on both local (ssh) and remote machines (bash -c). So I must avoid this.



I also know that storing the password in environment variables means a process' initial env can be see as cat /proc/<pid>/environ and gdb can be used to look at current state. So details can be seen on the local machine or the remote machine if local environment variables are forwarded. So this is not ideal, especially as I can't control tightly other people's access to the SSH user account on the remote machine.



After a bit of reading and experimentation I've come-up with the below - it certainly works! You can assume seed.txt is chmod 400 so short of someone having root access it is safe (or at least as safe as my SSH keys).



Note - seed.txt does not exist on the remote server, only on the local server, so it's contents must be sent to the remote server.



SSH connection is using keys so no password is need for that.



#!/bin/bash
ssh -T my-server <<EOSSH > /dev/null
printf '%sn' "$(cat seed.txt)" | /usr/lib/gnupg2/gpg-preset-passphrase -c 123456789
EOSSH


Using ps -ef on the local machine will only yield ssh -T my-server as the actual commands to be remotely executed are piped into stdin, rather than using the ssh command line.



Likewise the cat command line displays only the filename. printf, I believe, is a built-in command so will not show-up in ps. I believe the printf is being executed on the remote machine?



On the remote server ps will only show /usr/lib/gnupg2/gpg-preset-passphrase -c 123456789 as the passphrase is piped in again using stdin.



I'm making no direct use of environment variables so there shouldn't be any issue here. I'm a little anxious that something will be exposed from the SSH environment variables?



My question is - is my method sensible/simple/safe (assuming root access is not compromised), are there any obvious issues, and if yes, what are the suggested workarounds?



The only other options I've managed to get working is to use expect but given both ssh and gpg-preset-passphrase seem to be happy to accept input as stdin rather than interactively, it seems overkill to use expect?







linux bash ubuntu ssh gpg-agent






share|improve this question









New contributor




Phil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Phil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 1 min ago







Phil













New contributor




Phil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 28 mins ago









PhilPhil

12




12




New contributor




Phil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Phil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Phil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








  • 1





    why the complications of printf and cat instead of just gpg-preset-passphrase ... < seed.txt ?

    – thrig
    19 mins ago











  • Thanks for reply - seed.txt is on the local machine, and the ($cat seed.txt) will be executed locally and the contents of seed.txt sent to the remote server. I think using < seed.txt means seed.txt would have to exist on the remote machine - which is not the case. A quick test gives seed.txt: No such file or directory if I make this change.

    – Phil
    11 mins ago
















  • 1





    why the complications of printf and cat instead of just gpg-preset-passphrase ... < seed.txt ?

    – thrig
    19 mins ago











  • Thanks for reply - seed.txt is on the local machine, and the ($cat seed.txt) will be executed locally and the contents of seed.txt sent to the remote server. I think using < seed.txt means seed.txt would have to exist on the remote machine - which is not the case. A quick test gives seed.txt: No such file or directory if I make this change.

    – Phil
    11 mins ago










1




1





why the complications of printf and cat instead of just gpg-preset-passphrase ... < seed.txt ?

– thrig
19 mins ago





why the complications of printf and cat instead of just gpg-preset-passphrase ... < seed.txt ?

– thrig
19 mins ago













Thanks for reply - seed.txt is on the local machine, and the ($cat seed.txt) will be executed locally and the contents of seed.txt sent to the remote server. I think using < seed.txt means seed.txt would have to exist on the remote machine - which is not the case. A quick test gives seed.txt: No such file or directory if I make this change.

– Phil
11 mins ago







Thanks for reply - seed.txt is on the local machine, and the ($cat seed.txt) will be executed locally and the contents of seed.txt sent to the remote server. I think using < seed.txt means seed.txt would have to exist on the remote machine - which is not the case. A quick test gives seed.txt: No such file or directory if I make this change.

– Phil
11 mins ago












0






active

oldest

votes











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});






Phil is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f496799%2fsecurely-piping-string-in-local-text-file-to-remote-command-using-ssh%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes








Phil is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















Phil is a new contributor. Be nice, and check out our Code of Conduct.













Phil is a new contributor. Be nice, and check out our Code of Conduct.












Phil is a new contributor. Be nice, and check out our Code of Conduct.
















Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f496799%2fsecurely-piping-string-in-local-text-file-to-remote-command-using-ssh%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

CARDNET

Boot-repair Failure: Unable to locate package grub-common:i386

濃尾地震