Securely Piping String in Local Text File to Remote Command using SSH
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
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.
add a comment |
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
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 ofprintfandcatinstead of justgpg-preset-passphrase ... < seed.txt?
– thrig
19 mins ago
Thanks for reply -seed.txtis on the local machine, and the($cat seed.txt)will be executed locally and the contents ofseed.txtsent to the remote server. I think using< seed.txtmeansseed.txtwould have to exist on the remote machine - which is not the case. A quick test givesseed.txt: No such file or directoryif I make this change.
– Phil
11 mins ago
add a comment |
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
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
linux bash ubuntu ssh gpg-agent
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.
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 ofprintfandcatinstead of justgpg-preset-passphrase ... < seed.txt?
– thrig
19 mins ago
Thanks for reply -seed.txtis on the local machine, and the($cat seed.txt)will be executed locally and the contents ofseed.txtsent to the remote server. I think using< seed.txtmeansseed.txtwould have to exist on the remote machine - which is not the case. A quick test givesseed.txt: No such file or directoryif I make this change.
– Phil
11 mins ago
add a comment |
1
why the complications ofprintfandcatinstead of justgpg-preset-passphrase ... < seed.txt?
– thrig
19 mins ago
Thanks for reply -seed.txtis on the local machine, and the($cat seed.txt)will be executed locally and the contents ofseed.txtsent to the remote server. I think using< seed.txtmeansseed.txtwould have to exist on the remote machine - which is not the case. A quick test givesseed.txt: No such file or directoryif 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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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.
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
1
why the complications of
printfandcatinstead of justgpg-preset-passphrase ... < seed.txt?– thrig
19 mins ago
Thanks for reply -
seed.txtis on the local machine, and the($cat seed.txt)will be executed locally and the contents ofseed.txtsent to the remote server. I think using< seed.txtmeansseed.txtwould have to exist on the remote machine - which is not the case. A quick test givesseed.txt: No such file or directoryif I make this change.– Phil
11 mins ago