This article should be revised in the light of recent developments within the organization, in particular:
The gen-passphrase action of the bash-lib bl-security , which implements a method comparable to those of dice and replaces most diceware programs .
This is a step by step procedure giving the ordered way to get an OnlyKey configured and to use it:
The process detailed below is not the only way to go. Some strategic choice have been done:
As for obvious security reasons it is not possible to export keys from the OnlyKey, I have chosen to only use imported keys and not any keys generated inside the OnlyKey. Because I think it is really important to have an offline and interoperable backup of all my keys in case I am deprived of my OnlyKeyses for any reasons (lost, steeled, failure, obsolete, …).
I choose ED22519 keys over RSA keys because 2048 bits RSA keys are obsolete and 4096 bits RSA keys are really slow and buggy on the OnlyKey.
Has I have never personally used it, I will not talk about the FIDO2 functions of the OnlyKey. I prefer SSH/GPG instead. Because FIDO2 secrets can not be imported. For me it is unpractical. Secured but not safe. You will sooner or later be locked out of some of your accounts. And anyway, their is nothing specific to the OnlyKey about it. It work exactly as any other FIDO2 token in the wild.
I do also not speak about the password manager functions. May be I will do it later. Anyway this is relatively straight forward with the graphical user interface. Just do not forget that as the OnlyKey is write only the GUI will never confirm you that what you do is done.
All instructions in this manual are for command line. This is easier for me. It will be easier and less ambiguous for you. You will be able to put together all individual settings instruction in one script to do everything in one go. And any way the graphical user interface only work on amd64 architecture. This is more general.
That is what I have and all my tests are done on a Mobian Trixie and a Raspberry Pi OS Bookworm. This should work the same on all other Debian like. Some very minor adaptations may be necessary for other Linux distributions. For the Apple and Window$ users I will be of no help.
Copyright: 2024 Henri GEIST <geist.henri@laposte.net>
Licence: CC-BY-SA-4.0+
The last version of this document can always be found on codeberg .
You can find the last prettier PDF, HTML, DocBook and Markdown release at:
https://codeberg.org/Henri_GEIST/OnlyKey_hardware_token_HowTo/releases
And if you find any mistake or something unclear or missing do not hesitate to fill an issue on :
https://codeberg.org/Henri_GEIST/OnlyKey_hardware_token_HowTo/issues
You are going to setup an OnlyKey, an hardware token meant to protect your private keys. And avoid to place them at risk on your desktop, laptop or mobile phone.
It could be wise to not configure it, create, store and decipher your private keys on a computer at risque to store them in your OnlyKey. This will defeat part of the purpose.
Then I recommend you to make all the work to configure your OnlyKey on an air-gap (https://fr.wikipedia.org/wiki/Air_gap).
A good solution for a very low price air-gap could be to use a Raspberry Pi Zero. I mean the very first version without Wifi & Bluetooth. But a lot of other solutions exists.
To do the trick:
First you need to get some real physical standard six faces dices to get the best and cheapest source of entropy. A configured printer to print offline passphrase protected copies of your keys as QR codes. And a configured camera or scanner to test that what you will print can be imported back.
Next for configuring your OnlyKey you first need to install some tools then type:
sudo apt install pipx gawk sed wget libusb-1.0-0-dev libudev-dev npm node-getpass
sudo apt install gnupg openssh-client paperkey ruby-asciidoctor-pdf qrencode zbar-tools
pipx install --system-site-packages onlykey
pipx install --system-site-packages keysec
npm install openpgp
. $HOME/.profile
wget https://codeberg.org/Henri_GEIST/OnlyKey_hardware_token_HowTo/raw/branch/master/extract_gpg_keys.js
chmod u+x extract_gpg_keys.js
mv extract_gpg_keys.js $HOME/.local/bin/extract_gpg_keys.js
Note: Those install instruction are not exactly the same as the ones given in the official OnlyKey documentation. Debian need
pipx
instead ofpip
and some moreapt
,pipx
andnpm
packages are needed to follow this guide.
Then set some udev rules to make the OnlyKey device accessible to normal users.
[ -f /etc/udev/rules.d/49-onlykey.rules ] ||
wget https://raw.githubusercontent.com/trustcrypto/trustcrypto.github.io/pages/49-onlykey.rules &&
sudo mv 49-onlykey.rules /etc/udev/rules.d/
And optionally, if you want it, and only if you are working on an x86 architecture you can install the graphical interface by typing:
wget https://github.com/trustcrypto/OnlyKey-App/releases/download/v5.5.0/OnlyKey_5.5.0_amd64.deb
sudo apt install ./OnlyKey_5.5.0_amd64.deb
You need to choose some damn fucking good passphrases and pin codes:
Really hard to guess for someone knowing about you.
Really hard to brute force by a powerful computer.
Easy for you to remember because:
The OnlyKey need three pin codes:
Just roll ten times the dice to get a ten digit pin code. As you will type it everyday you will have no problem at all to remember it quickly . What ever you get.
As you risque to use it less often, to be sure to remember it, you can roll the dice just one more time and get the same pin code as the first account with just the first or last digit changed.
You do not need the same level of secrecy as this one gives access to nothing. And you may not use it for years. So you better have to choose any seven digit you will easily remember. Just be sure it is really different from the accounts pin code for not typing it by mistake.
A drawing is better than a speech. Look at the https://xkcd.com/936/ to understand why I am advocating to you the diceware process.
And then follow this process described at this address: https://www.eff.org/dice
I recommend you to get at least height words from the long list. This will produce a little more than one hundred bits of entropy.
For non native English speaker, you can just translate the individual words you get in any language without security penalty. Or find some lists in other languages on the net.
Then as one of the purpose of an OnlyKey is to prevent you from needing to type your passphrase so often:
Do not fear to have a long passphrase to type. You will rarely do it.
To not forget it, take the habit to say your passphrase in your head like a mantra each time you type your pin code.
This enable to restart from zero.
Note: This is not needed. You can follow this guide and keeping what you already have on your OnlyKey.
WARNING: Be sure to have a copy of all important data you will loose in this operation.
Connect the OnlyKey:
Enter the auto erasure pin code;
Or enter ten time any invalid pin code.
Note: This will only work on an empty OnlyKey. If you have an already initialized OnlyKey jump to the next section.
Connect an uninitialised OnlyKey, run the command command below and follow the instructions.
onlykey-cli init
Then unplug your OnlyKey.
Half of the OnlyKey configuration below request it to be in config
mode. In this mode you can change some configuration needing some
particular caution. They should not be accessible only because your
OnlyKey is connected and unlocked.
To enter in the config
mode:
6
for more than five seconds.6
.The config
mode will exit when the OnlyKey is unplugged.
If you want to be able to extract a backup of your OnlyKey you need to setup a passphrase for it. But it may not be a good idea.
You will need the FIDO2 functionnality and/or some keys generated inside your OnlyKey and you need to duplicate them in an other OnlyKey. But it is better to avoid beeing trap in this situation as you will be bind to your OnlyKey without possibility to escape.
Having an security token from witch noting can be extract in any way.
If you really want to do so, the current version of onlykey-cli
,
(v1.2.10 while I am writing this line) miss what is needed to do so.
Then you first need to add after the line 403 of the file
$HOME/.local/pipx/venvs/onlykey/lib/python3.11/site-packages/onlykey/cli.py
those two lines:
elif sys.argv[2] == 'BACKUP':
slot_id = 131
Just after the lines:
elif sys.argv[2] == 'HMAC2':
slot_id = 129
WARNING: In Python the correct number of
spaces
at begin of lines must be respected.
Note: Depending of your installed version of python the path to the file may be a little different.
Then save the modified file and type:
read -s -p "Enter Passphrase:" PASSPHRASE1
echo
read -s -p "Retype passphrase:" PASSPHRASE2
echo
if [ "$PASSPHRASE1" != "$PASSPHRASE2" ]
then
echo "Error passphrases mismatch" > /dev/stderr
else
onlykey-cli setkey BACKUP x b $(printf "%s" "$PASSPHRASE1" | sha256sum | grep -o '[0-9a-fA-F]*')
fi
PASSPHRASE1=""
PASSPHRASE2=""
WARNING: You can not change your mind after this. This operation is definitive until complete OnlyKey erasure.
If you want to prevent anyone which can have access to your unlocked OnlyKey to dump and use for himself a backup of it. You should lock the backup password editing functionality.
If you haven’t already set a passphrase no backup will ever be possible. If you have already set a passphrase then your adversary can not change the passphrase and if he does not know it, he can still do a backup but not use it.
onlykey-cli backupkeymode 1
Each time the OnlyKey has to type something, when you use the backup function or the passoword manager function for example, the OnlyKey work as it is a keyboard and an agent in the OnlyKey is typing on it. For this to work this internal keyboard layout must match your computer keyboard layout (QWERTY, AZERTY, DVORAK, BEPO, …). And the internal agent must type at a speed your computer can handle.
And select the KEYBOARD_LAYOUT
matching your system configuration in
KEYBOARD_LAYOUT | Description |
---|---|
1 | USA_ENGLISH |
2 | CANADIAN_FRENCH |
3 | CANADIAN_MULTILINGUAL |
4 | DANISH |
5 | FINNISH |
6 | FRENCH |
7 | FRENCH_BELGIAN |
8 | FRENCH_SWISS |
9 | GERMAN |
10 | GERMAN_MAC |
11 | GERMAN_SWISS |
12 | ICELANDIC |
13 | IRISH |
14 | ITALIAN |
15 | NORWEGIAN |
16 | PORTUGUESE |
17 | PORTUGUESE_BRAZILIAN |
18 | SPANISH |
19 | SPANISH_LATIN_AMERICA |
20 | SWEDISH |
21 | TURKISH |
22 | UNITED_KINGDOM |
23 | US_INTERNATIONAL |
24 | CZECH |
25 | SERBIAN_LATIN_ONLY |
26 | HUNGARIAN |
27 | DANISH MAC |
28 | US_DVORAK |
Then type:
onlykey-cli keylayout $KEYBOARD_LAYOUT
Note: If like me, your keyboard layout is not in the list and/or you use a non standard layout in your environment and you still want to to also use your OnlyKey on other computers nearby you. Then you will have to follow the instruction at chapter Adapt to keyboard layout .
Then select a KEYBOARD_SPEED
value between 1
and 10
:
KEYBOARD_SPEED | Comment |
---|---|
1 | Only to connect to extremely slow 8 bits microcontroller board. |
4 | Default value. (but damn slow) |
7 | Maximum speed supported by my Raspberry PI Zero board |
9 | Maximum speed supported by my Intel I5 laptop. |
Find your sweet spot and type:
onlykey-cli keytypespeed $KEYBOARD_SPEED
To use a unique button to valid a GPG or SSH challenge instead of three random button select at each challenge, type:
onlykey-cli storedkeymode 1
onlykey-cli derivedkeymode 1
Note: This is required if you want to use the SSH or GPG agent as daemons. As in this case the random challenge will not be displayed to you. But in this case you can not be absolutely certain on what request trigger the challenge.
If you still prefer to type the three random key challenge, type:
onlykey-cli storedkeymode 0
onlykey-cli derivedkeymode 0
First you need to have some GPG keys to import. Maybe you already have some and can get the list of them with the command:
gpg --list-secret-keys
If you do not have any, you can create some new ones with the command:
gpg --expert --full-generate-key --pinentry-mode loopback
Then answer the questions:
Subject | Answer |
---|---|
Kind of key | (9) ECC and ECC |
Elliptic curve | (1) Curve 25519 |
Key expiration | As long as you want or even never |
Name | First Names LAST NAMES |
your.email@address.com | |
Comment | Usually nothing but what ever you want |
If you already have some but they are not of ed25519
type it may be
time to:
Choose the keyring you want to import in your private keyring list and get its 40 characters hexadecimal fingerprint then type.
GPG_FINGERPRINT="the fingerprint you have just selected"
gpg --export $GPG_FINGERPRINT > $GPG_FINGERPRINT.pub
gpg --export-secret-keys --pinentry-mode loopback $GPG_FINGERPRINT > $GPG_FINGERPRINT.priv
Note: The second command will ask your passphrase but its result is still passphrase protected.
If you are doing all this on an air-gap (see chapter Use an air-gap ) and you will never connect it directly or indirectly to the net again an store it safe, this air-gap count as an offline copy.
But anyway it is always better to have also some copies on paper. Printed paper is a surprisingly time resisting medium compared to disks and memory cards. It rarely misbehave. Then to get a printable PDF version, type:
GPG_FINGERPRINT="The same finger print as in the previous section"
qrencode -l M --8bit --output $GPG_FINGERPRINT.pub.png < $GPG_FINGERPRINT.pub
paperkey --output-type=raw < $GPG_FINGERPRINT.priv | qrencode -l H --8bit --output $GPG_FINGERPRINT.priv.png
asciidoctor-pdf -o $GPG_FINGERPRINT.pdf - << EOF
== Human readable private part
GPG version: $(gpg --version | head -n 1) +
gpg --export-secret-keys $GPG_FINGERPRINT | paperkey
++++
$(paperkey < $GPG_FINGERPRINT.priv)
++++
<<<
== Computer readable public and private keys
image::$GPG_FINGERPRINT.pub.png[title=gpg --export $GPG_FINGERPRINT by: $(gpg --version | head -n 1)]
image::$GPG_FINGERPRINT.priv.png[title=gpg --export-secret-keys $GPG_FINGERPRINT | paperkey --output-type=raw]
EOF
Then print the result two-sided to have every thing on one paper sheet. And keep it in a safe place. And for more safety, make some other copies, and ask some relatives you trust to keep them safe for you. This will ensure you do not lost everything in case of fire or robbery at your home.
Note: Even the paper version is protected by your passphrase and need it to be used. Then your relatives can not use it for themselves.
Unchecked backups will always betray you at the worst possible time. When you desperately need them.
First scan or take photos of your private and public keys QR codes. And
save them as private_GPG_QR_code.jpg
and public_GPG_QR_code.jpg
.
Then check that you can reconstruct the private key you have exported at the section export your keys by typing:
zbarimg --raw -Sbinary public_GPG_QR_code.jpg > public.gpg
zbarimg --raw -Sbinary private_GPG_QR_code.jpg | paperkey --pubring public.gpg > private.gpg
diff private.gpg $GPG_FINGERPRINT.priv
Keep the $GPG_FINGERPRINT
and choose some empty $GPG_SIGN_SLOT
and
GPG_DECIPHER_SLOT
of the _OnlyKey in the range ECC1
.. ECC16
to
flash the keys in and some $GPG_SIGN_LABEL
and $GPG_DECIPHER_LABEL
mnemonic to recall what is in each slot afterward.
Note: Every label can contain a maximum of 16 ASCII characters.
Then type:
GPG_FINGERPRINT="The same fingerprint you use since the begin of this chapter"
GPG_SIGN_SLOT="Some thing in range ECC1 .. ECC16"
GPG_DECIPHER_SLOT="Some other thing in the same range"
GPG_SIGN_LABEL="GPG Singing"
GPG_DECIPHER_LABEL="GPG decipher"
extract_gpg_keys.js < $GPG_FINGERPRINT.priv |
awk -F ':' "/sign/ { system (\"onlykey-cli setkey $GPG_SIGN_SLOT x s\"\$2) };
/decipher/ { system (\"onlykey-cli setkey $GPG_DECIPHER_SLOT x d\"\$2) }"
onlykey-cli setkey $GPG_SIGN_SLOT label "$GPG_SIGN_LABEL"
onlykey-cli setkey $GPG_DECIPHER_SLOT label "$GPG_DECIPHER_LABEL"
Note: If you have already imported a GPG signing key in previous section you can choose to use it also as an SSH key and jump directly to the next section Lock your screen and with a button . If you want to import a dedicated key for SSH read this section.
First you need to have some SSH private keys to import. If you already
have some, it is usually stored in your $HOME/.ssh/
directory. And
probably named id_ed25519
.
If you do not have anyone, it is the right time to create one by typing:
ssh-keygen -t ed25519
Then follow the instructions. If you chose the default values this will
create two key files $HOME/.ssh/id_ed25519
for the private key and
$HOME/.ssh/id_ed25519.pub
for the public part.
The choose the SSH private key file to import in your OnlyKey with
will be referred as SSH_KEY_FILE
for the next scripts snippets.
For the same reason as in the Save your keys offline chapter, make some offline paper version of your SSH keys. To do so type:
SSH_KEY_FILE="The SSH private key file path you have just chosen."
qrencode -l H --8bit --output private_SSH_key.png < $SSH_KEY_FILE
asciidoctor-pdf -o private_SSH_key.pdf - << EOF
== Human readable _SSH_ private key
++++
$(cat $SSH_KEY_FILE)
++++
== Computer readable _SSH_ private key
image::private_SSH_key.png[title=$SSH_KEY_FILE]
EOF
Then print the newly created PDF, keep it in a safe place and make some copy to gives to some people you trust to keep them safe for you.
First scan or take a photo of your SSH keys QR code. And save it as
SSH_keys_QR_code.jpg
. Then type:
zbarimg --raw -Sbinary SSH_keys_QR_code.jpg > SSH_keys_from_QR_code.txt
diff SSH_keys_from_QR_code.txt $SSH_KEY_FILE
Chose an $SSH_SLOT
between ECC1
and ECC16
not already used for
something else, an $SSH_KEY_FILE
name to load in this slot and an
$SSH_KEY_LABEL
to name it. Then type:
Note: Every label can contain a maximum of 16 ASCII characters.
SSH_KEY_FILE="the same private key file path as previously"
SSH_SLOT="The slot you have just chosen"
SSH_KEY_LABEL="SSH key"
onlykey-cli setkey $SSH_SLOT x s "$(keysec info < $SSH_KEY_FILE | sed -n '/priv:/{:a;n;/pub:/b;p;ba}' | tr -d ' :\n')"
onlykey-cli setkey $SSH_SLOT label "$SSH_KEY_LABEL"
Chose an OnlyKey button to be a $LOCK_BUTTON
between 1
and 6
or
choose 0
for none and type:
onlykey-cli lockbutton $LOCK_BUTTON
Now each time you will touch this button your OnlyKey and your screen will lock.
Note: The chosen button will not be able to supply a password any more as long as it is the lock button.
Choose a $TIMEOUT
between 1
and 255
minutes or 0
to deactivate
the this function and type:
onlykey-cli idletimeout $TIMEOUT
Now your OnlyKey will reboot itself an lock after this time of inactivity.
Choose a $BRIGHTNESS
between 1
and 10
from dimmer to brighter and
type:
onlykey-cli ledbrightness $BRIGHTNESS
Note: This do not need to be done on the same computer you used to configure Your OnlyKey. And more than this, I do recommend to configure your OnlyKey on an air-gap different from the computer you will use your OnlyKey on dayly. See the chapter Use an air-gap .
First install the OnlyKey SSH and GPG agents, their dependencies and some basic tools.
sudo apt install pipx grep sed at wget libusb-1.0-0-dev libudev-dev openssh-client gnupg zbar-tools
pipx install --system-site-packages onlykey-agent
pipx install --system-site-packages onlykey
. $HOME/.profile
Note: Those install instruction are not exactly the same as the ones given in the official OnlyKey documentation. Debian need
pipx
instead ofpip
, one moresudo
command is needed and some moreapt`
packages are needed to follow this guide.
Then set some udev rules to make the OnlyKey device accessible to normal users.
[ -f /etc/udev/rules.d/49-onlykey.rules ] ||
wget https://raw.githubusercontent.com/trustcrypto/trustcrypto.github.io/pages/49-onlykey.rules &&
sudo mv 49-onlykey.rules /etc/udev/rules.d/
Optionally, if you want it, and only if you are working on an x86 architecture you can install the graphical interface by typing:
wget https://github.com/trustcrypto/OnlyKey-App/releases/download/v5.5.0/OnlyKey_5.5.0_amd64.deb
sudo apt install ./OnlyKey_5.5.0_amd64.deb
If you want to lock your computer screen on each OnlyKey disconnection
you can add to the file /etc/udev/rules.d/49-onlykey.rules
the line:
ACTION=="remove", SUBSYSTEM=="input", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="60fc", RUN+="/bin/su USER_NAME -c '/usr/bin/xdg-screensaver lock'"
Where USER_NAME
must be replaced by the user owning the graphical
session. If you want to configure this for multiple users your can add
one line per user.
Note: If you have initialised the inactivity lockout timer of your OnlyKey, this will also lock your screen each time your OnlyKey lockout itself.
First get back the public part of the GPG key you have setted in your OnlyKey at chapter Find keys to import . You can get it back from any source:
Your current computer if it is already in your keyring.
The backup QR code you have printed when you generated the key.
Anyone or any keyserver you already gives your public key.
If it is already in your keyring just type:
gpg --export $GPG_FINGERPRINT > $GPG_FINGERPRINT.pub
If you have it on QR code scan it or take a picture of it and name it
$GPG_FINGERPRINT.jpg
and type:
zbarimg --raw -Sbinary $GPG_FINGERPRINT.jpg | gpg --enarmor |
sed 's/ARMORED FILE/PUBLIC KEY BLOCK/' > $GPG_FINGERPRINT.pub
Then choose a $GNUPGHOME
directory to store the config. Usually
$HOME/.gnupg/onlykey
. Then recall the $GPG_DECIPHER_SLOT
and
$GPG_SIGN_SLOT
where you put the private keys in your OnlyKey. If
you forget it but put some labels on them you can get back this
information by typing:
onlykey-cli getkeylabels
Then type:
GPG_FINGERPRINT="The finger print of the keys you want to use."
GPG_DECIPHER_SLOT="The slot ECC1 to ECC16 you put the deciphering key in"
GPG_SIGN_SLOT="The slot ECC1 to ECC16 you put the signing key in"
GNUPGHOME="something like $HOME/.gnupg/onlykey"
onlykey-gpg init "$(gpg --show-keys $GPG_FINGERPRINT.pub | grep uid | sed 's/^uid *//1')" \
-e ed25519 \
-dk $GPG_DECIPHER_SLOT \
-sk $GPG_SIGN_SLOT \
-i $GPG_FINGERPRINT.pub \
--homedir $GNUPGHOME
Note: In case of failure if you want to retry you first need to delete the
$GNUPGHOME
you have just created.
WARNING: But BE CAREFUL DOUBLE CHECK WHAT YOU WILL DELETE. If by mistake you delete your
$HOME/.gnupg
depending on what it already contain it can be a great loss.
If now you want GPG to look in your new $GNUPGHOME
directory instead
of the default $HOME/.gnupg
and then use the OnlyKey instead of the
on disk keyring you need to export the $GNUPGHOME
variable as you have
just set it.
export GNUPGHOME=The_path_you_have_just_chosen
From there the OnlyKey will be required and used for all your GPG signing and deciphering activities. In the current terminal and its children. The OnlyKey will blink purple or turquoise when a signing or deciphering is request and wait on you to touch it.
If you want this configuration to be permanent for all context after logout and new login just place this export line:
export GNUPGHOME=The_path_you_have_just_chosen
At the end of your $HOME/.profile
and restart your session.
First for the rest of this chapter, recall the $SSH_SLOT
it could be
the slot where you put a dedicated SSH key at chapter Flash the key
in the
, or the slot where you put
your signing GPG key at chapter [???](#Flash GPG keys in the OnlyKey)
if you chose to use your GPG singing key also for SSH.
If you have forgotten you can for a reminder type:
onlykey-cli getkeylabels
To get the public key to send to all servers you want to connect to, just type:
SSH_SLOT="The ECCx slot containing the key to use for SSH"
onlykey-agent -sk $SSH_SLOT some.user@some.domaine
Note: You can use what ever you want as
some.user@some.domaine
. It as no impact. It is just like a comment when the-sk $SSH_SLOT
is asserted.
For SSH to use your OnlyKey in the current shell and all its children, type the command:
SSH_SLOT="The ECCx slot containing the key to use for SSH"
onlykey-agent -sk $SSH_SLOT -s foo
Where $SSH_SLOT
is the OnlyKey key slot you have imported the
private key you want to use for SSH authentification probably ECC3
or maybe ECC2
if you have chosen to use the same private key for SSH
and GPG.
Note: The
foo
argument has no purpose with imported keys, it is only use as a place holder required by theonlykey-agent
executable.
Note: I have planed to add some explanations for non Systemd users like Devuan users as soon as I find a solution.
If you want to make it permanent and session wide you need to configure
Systemd to run the OnlyKey SSH agent instead of the standard SSH
agent first create a new user onlykey-ssh-agent
Systemd service:
$HOME/.config/systemd/user/onlykey-ssh-agent.service
:
[Unit]
Description = onlykey-agent SSH agent
Requires = onlykey-ssh-agent.socket
[Service]
Type = simple
Restart = always
Environment = "PATH=/bin:/usr/bin:/usr/local/bin:%h/.local/bin"
ExecStart = %h/.local/bin/onlykey-agent --sock-path %t/onlykey-agent/S.ssh -f -sk $SSH_SLOT foo
WARNING: You need to replace
$SSH_SLOT
at the end of the last line by the realECC1
toECC16
slot containing the key you want to use for SSH. This will not be substitute automatically.
Note: You may need to first create the directory
$HOME/.config/systemd/user
if id does not already exist.
Then create a new user onlykey-ssh-agent
Systemd socket for this
service:
$HOME/.config/systemd/user/onlykey-ssh-agent.socket
:
[Unit]
Description = onlykey-agent SSH agent socket
[Socket]
ListenStream = %t/onlykey-agent/S.ssh
FileDescriptorName = ssh
Service = onlykey-ssh-agent.service
SocketMode = 0600
DirectoryMode = 0700
[Install]
WantedBy = sockets.target
Next start them and make them restart after each reboot by typing:
systemctl --user start onlykey-ssh-agent.service onlykey-ssh-agent.socket
systemctl --user enable onlykey-ssh-agent.service onlykey-ssh-agent.socket
And now add to your $HOME/.profile
some code to set and export the
$SSH_AUTH_SOCK
variable if not already done on each login. It should
not overwrite any existing value to enable agent forwarding.
grep -q '^[^#]*SSH_AUTH_SOCK=.*/onlykey-agent/S.ssh' $HOME/.profile || cat << 'EOF' >> $HOME/.profile
if [ -z "$SSH_AUTH_SOCK" ]
then
SSH_AUTH_SOCK=$(systemctl show --user --property=Listen onlykey-ssh-agent.socket | grep -o "/.*/onlykey-agent/S.ssh")
export SSH_AUTH_SOCK
fi
EOF
Finally, if the gnome_keyring is installed on your system, deactivate it for SSH:
[ -f $HOME/.config/autostart/gnome-keyring-ssh.desktop ] ||
mkdir -p $HOME/.config/autostart/ &&
cp /etc/xdg/autostart/gnome-keyring-ssh.desktop $HOME/.config/autostart/ &&
grep -q '^Hidden\s*=\s*true\(\s\+\|$\)' $HOME/.config/autostart/gnome-keyring-ssh.desktop ||
echo 'Hidden=true' >> $HOME/.config/autostart/gnome-keyring-ssh.desktop
Now everything is in place and will be running on your next session login.
First find the $GPG_FINGERPRINT
of the GPG key you want to use for
this. To do so, connect and unlock your OnlyKey and type:
gpg --list-secret-keys
Then import the public part of the key on the server you want to forward GPG agent to by typing:
GPG_FINGERPRINT="The finger print of the key you have just chosen"
SSH_LOGIN="your ssh login something like 'user@server'"
gpg --armor --export $GPG_FINGERPRINT | ssh $SSH_LOGIN "bash --login -c 'gpg --import'"
Note: You need to already have a working SSH account on the server.
Then you need to find the local GPG agent socket for your user with the command:
gpgconf --list-dir agent-socket
Note: On the classic gpg-agent we should look for the
agent-extra-socket
to prevent private key leaks. But with OnlyKey the normal socket is already like the extra socket and there is no extra socket.
Next, the remote server normal GPG agent socket for your user with the command:
GPG_FINGERPRINT="The finger print of the key you have just chosen"
SSH_LOGIN="your ssh login something like 'user@server'"
gpg --armor --export $GPG_FINGERPRINT | ssh $USER_AT_SERVER "bash --login -c 'gpgconf --list-dir agent-socket'"
Then, add to your $HOME/.ssh/config
a forwarding rule for the remote
server, replacing THE_REMOTE_HOSTNAME
by the remote hostname you want
to connect to, THE_REMOTE_HOST_GPG_AGENT_NORMAL_SOCKET
and
THE_LOCAL_GPG_AGENT_SOCKET
by the socket path you have just found
above:
\$HOME/.ssh/config
:
HOST THE_REMOTE_HOSTNAME
StreamLocalBindUnlink yes
RemoteForward THE_REMOTE_HOST_GPG_AGENT_NORMAL_SOCKET THE_LOCAL_GPG_AGENT_SOCKET
Finally, if you have access to the root privileges on the remote server
add the line StreamLocalBindUnlink yes
to its /etc/ssh/sshd_config
and run on this remote server:
sudo sshd -t && sudo systemctl restart sshd
If you do not have the required privileges ask the administrator to do so. And if you can not. Then you will have to connect two time to your ssh account each time you want to use GPG agent forwarding. The first time just to run the command:
rm $(gpgconf --list-dir agent-socket)
Then disconnect and reconnect a second time to use your SSH session as you wish.
Now you can use GPG on the remote server while keeping your OnlyKey at hand connected on your local machine.
Note: If the keyboard layout configured in your OnlyKey match the keyboard layout configured on your computer you can just jump to the next section.
On Xwindows it is possible to set individually different keyboard for each keyboard. Then even if you use keyboard layout different from the one configured in your OnlyKey or one not in the list of the OnlyKey suported ones you can configure your X session to adapt to the situation.
To find the X id of your OnlyKey emulated keyboard. First connect your OnlyKey and type:
xinput
Then assign it the keyboard layout matching what is configured in your OnlyKey:
By typing:
ONLYKEY_ID="The ID you just find with the command xinput"
ONLYKEY_KEYBOARD_LAYOUT="The layout configured in your _OnlyKey"
setxkbmap -device $ONLYKEY_ID -layout $ONLYKEY_KEYBOARD_LAYOUT
First create the script below to be called each time your OnlyKey is
plugged. Call it .$HOME/.local/bin/onlykey_set_layout.sh
and adapt the
ONLYKEY_KEYBOARD_LAYOUT
and ONLYKEY_USER
to your need.
\$HOME/.local/bin/onlykey_set_layout.sh
:
#!/bin/sh
# This script assign all your connected OnlyKeys the keyboard layout of your
# choice. Without changing the layout of your others keyboards.
#
# Just set the ONLYKEY_KEYBOARD_LAYOUT just below to the same layout that is
# configured in your keys.
# And the ONLYKEY_USER which will use it.
ONLYKEY_KEYBOARD_LAYOUT='us' # or 'fr' or whatever is configured in your OnlyKey
ONLYKEY_USER='Your UNIX login name'
# This look for the first local X display available on the host.
# Work in most usual case but can be improved for rare tricky situations.
DISPLAY=$(ls /tmp/.X11-unix | grep '^X[0-9][0-9]*$' | tr 'X' ':' | head -n 1)
# As this script may be trigger by the USB connection event,
# wait a little bit for initialisation to be done.
sleep 1
# Needed for those vars to be available in the 'heredoc' below.
export DISPLAY ONLYKEY_KEYBOARD_LAYOUT
# Needed to get access rights to the DISPLAY
/bin/su $ONLYKEY_USER << 'EOF'
EXTRACT_XINPUT_DEVICE_ID='s/.*\sid=\([1-9][0-9]*\)\s.*/\1/1'
ONLYKEY_ID_LIST=$(xinput | grep "ONLYKEY" | sed $EXTRACT_XINPUT_DEVICE_ID)
for ONLYKEY_ID in $ONLYKEY_ID_LIST
do
setxkbmap -device $ONLYKEY_ID -layout $ONLYKEY_KEYBOARD_LAYOUT
done
EOF
Then make it executable by typing:
chmod u+x $HOME/.local/bin/onlykey_set_layout.sh
Finally, add the line below to your /etc/udev/rules.d/49-onlykey.rules
file to execute the script each time you plug your OnlyKey.
/etc/udev/rules.d/49-onlykey.rules
:
ACTION=="add", SUBSYSTEM=="input", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="60fc", RUN+="/usr/bin/at -M -f '/home/USER/.local/bin/onlykey_set_layout.sh' now"
And change the USER
string by your UNIX user name. You can have
multiple lines like this for multiple users.
If you plane to use the TOTP second factor authentication
functionality of your OnlyKey you need to set its internal clock each
time you plug it in your USB port. To do so add those to lines below
to the /etc/udev/rules.d/49-onlykey.rules
file.
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="60fc", RUN+="/usr/local/bin/onlykey-cli settime"
KERNEL=="ttyACM*", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="60fc", RUN+="/usr/local/bin/onlykey-cli settime"