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
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
1
why the complications ofprintf
andcat
instead of justgpg-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 ofseed.txt
sent to the remote server. I think using< seed.txt
meansseed.txt
would have to exist on the remote machine - which is not the case. A quick test givesseed.txt: No such file or directory
if 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
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
New contributor
edited 1 min ago
Phil
New contributor
asked 28 mins ago
PhilPhil
12
12
New contributor
New contributor
1
why the complications ofprintf
andcat
instead of justgpg-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 ofseed.txt
sent to the remote server. I think using< seed.txt
meansseed.txt
would have to exist on the remote machine - which is not the case. A quick test givesseed.txt: No such file or directory
if I make this change.
– Phil
11 mins ago
add a comment |
1
why the complications ofprintf
andcat
instead of justgpg-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 ofseed.txt
sent to the remote server. I think using< seed.txt
meansseed.txt
would have to exist on the remote machine - which is not the case. A quick test givesseed.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
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
printf
andcat
instead of justgpg-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 ofseed.txt
sent to the remote server. I think using< seed.txt
meansseed.txt
would have to exist on the remote machine - which is not the case. A quick test givesseed.txt: No such file or directory
if I make this change.– Phil
11 mins ago