{{Title|
title=How-to: Use Monero Offline (Cold Storage) (Air Gap) + Daemon Isolation in {{q_project_name_long}} over Tor
}}
{{Header}}
{{#seo:
|description=Keep Monero private keys offline and isolate the network part (monerod) from the wallet part (Monero Wallet) for better security.
|image=Moneroheader.png
}}
[[File:Monero-symbol-1280.png|thumb|60px|128px|alt=Monero|link=Monero|Monero Logo]]
= Introduction =
'''UNFINISHED!'''
This instructions document how to keep Monero private keys offline as well as how to isolate the network part (monerod
) from the wallet part (Monero Wallet) for better security. monerod
is the Monero daemon, a full blockchain verifying background process which downloads and verifies the whole blockchain.
That advantage of this setup is, should there ever be a vulnerability that allows the exploitation of Monero Wallet CLI's network source code and/or monerod
by malware, then all user funds would remain safe, since these would remain isolated in the Monero Wallet CLI in a different offline VM.
If monerod
was ever compromised, then this setup would have the same issues as descried on the [[Monero]] wiki page in chapter [[Monero#Remote_Node_Security_and_Privacy_Considerations|Remote Node Security and Privacy Considerations]]. This is an issue unspecific to these instructions.
The connection scheme is Monero Offline Wallet
→ Monero Online Wallet
→ monerod
→ Tor
→ Monero network
.
The VM scheme is monero-wallet-vault
→ monero-wallet-ws
→ monerod-ws
→ {{project_name_gateway_vm}}
.
Instructions on this wiki page are compatible with the {{project_name_long}} isolating proxy feature, i.e. after [[Stream_Isolation#Disable_Transparent_Proxying|disabling transparent proxying]].
The following addresses and seed phrases on this wiki page are functional. Do NOT use them. Do NOT send funds there.
[[Root#Inappropriate_Use_of_Root_Rights|Inappropriate Use of Root Rights]] should be avoided. Instructions on this wiki page have been carefully crafted with when to use and when not to use sudo
in mind. The user should not use sudo
unless instructed in documentation.
The systemctl --user
must be run as normal, non-root user without sudo
because these are systemd
user units and not systemd
system units.
{{stub}}
{{Testers-Only}}
Credits: These instructions are based on [https://www.getmonero.org/resources/user-guides/cli_wallet_daemon_isolation_qubes_whonix.html How to use Monero CLI/daemon with Qubes + Whonix] by [https://www.getmonero.org getmonero.org] and from [https://web.archive.org/web/20230329234145/https://monerodocs.org/cold-storage/offline-transaction-signing/ Offline Transaction Signing] on [https://web.archive.org/web/20240222090354/http://monerodocs.org/ monerodocs.org] by [https://github.com/crocket crocket].
= Prerequisite Knowledge =
Since this setup is more complex and for advanced users only, it is highly recommended to acquire essential knowledge about the usage of Monero first without reference to the instructions on this wiki page as per the "normal", simpler instructions on the [[Monero]] wiki page. Only after the essential knowledge has been acquired, the more complex setup documented on this wiki page should be layered on top.
Exercising with small amount of value is recommended but not too small (below the dust level, unable to move funds due to funds being worth less than the required transaction fees). Exercising on Monero testnet first should also be considered. This is [[unspecific]] to {{project_name_short}}.
'''1.''' Optional. How to use Monero Wallet GUI.
If the end-goal is using an offline (airgap) Monero Wallet, learning how to use Monero Wallet GUI would be expendable.
'''2.''' How to use Monero Wallet CLI.
Wallet creation, receiving funds, spending funds.
'''3.''' How to use [[Monero Wallet Isolation]].
= Setup =
== Qubes dom0
Configuration ==
=== Create App Qubes ===
In dom0
.
It is easier to use the exact same names as in the example below in this chapter. Otherwise, adjustments in next chapter "Qubes qrexec Policy Configuration" would be required.
Qubes VM Manager
→ VM
→ Create App Qube
* Create Qubes-{{project_name_workstation_long}} App Qube
** Name: monero-wallet-vault
.
** Color: Choose a color label for the {{project_name_workstation_short}} App Qube. Optional suggestion: black
** Use this template: Choose the {{project_name_workstation_short}} Template. For example: {{project_name_workstation_template}}
.
** Standalone: Leave the Standalone field unchecked.
** Type: Choose the type App Qube
.
** Allow networking: Choose none
.
** Press: OK
.
Qubes VM Manager
→ VM
→ Create App Qube
* Create Qubes-{{project_name_workstation_short}} App Qube
** Name: monero-wallet-ws
.
** Color: Choose a color label for the {{project_name_workstation_short}} App Qube. Optional suggestion: yellow
** Use this template: Choose the {{project_name_workstation_short}} Template. For example: {{project_name_workstation_template}}
.
** Standalone: Leave the Standalone field unchecked.
** Type: Choose the type App Qube
.
** Allow networking: Choose none
.
** Press: OK
.
Qubes VM Manager
→ VM
→ Create App Qube
* Create monerod-ws
App Qube
** Name: monerod-ws
.
** Color: Choose a color label for the {{project_name_workstation_short}} App Qube. Optional suggestion: red
** Use this template: Choose the {{project_name_workstation_short}} Template. For example: {{project_name_workstation_template}}
.
** Standalone: Leave the Standalone field unchecked.
** Type: Choose the type App Qube
.
** Allow networking: Choose the desired {{project_name_gateway_long}} ProxyVM from the list. For example: {{project_name_gateway_vm}}
.
** Press: OK
.
** Make sure this workstation has enough private storage. You can estimate how much space you need by checking the size of the raw blockchain. Keep in mind that the blockchain will take up more space with time.
=== Qubes qrexec Policy Configuration ===
In dom0
.
'''1.''' Create the file /etc/qubes-rpc/policy/user.monerod
:
{{CodeSelect|code=
sudo nano /etc/qubes-rpc/policy/user.monerod
}}
'''2.''' Add the following line:
Note: If the user is using different names for the VMs other than monero-wallet-ws
and monerod-ws
, the next line would have to be modified accordingly. If the user is using the exact names as suggested in previous chapter "Create App Qubes", then no modifications are required.
{{CodeSelect|code=
monero-wallet-ws monerod-ws allow
}}
'''3.''' Save and close file.
'''4.''' Done.
Qubes dom0
setup is complete.
== monerod-ws
VM Configuration ==
'''Note:''' The following instructions should be applied in {{project_name_workstation_short}} ([[Qubes|{{q_project_name_short}}]]: App Qube monerod-ws
).
'''1.''' Create folder ~/.config/systemd/user
.
{{CodeSelect|code=
mkdir -p ~/.config/systemd/user
}}
'''2.''' Create file ~/.config/systemd/user/monerod.service
.
{{Open File|
filename=~/.config/systemd/user/monerod.service
}}
'''3.''' Paste the following contents.
Do not use --detach
- outdated style for daemons. Better error handling without.
{{CodeSelect|code=
[Unit]
Description=Monero Full Node
After=network.target
[Service]
Type=simple
PIDFile=/home/user/.bitmonero/monerod.pid
## https://github.com/monero-project/monero/issues/5098
KillSignal=SIGKILL
Environment=DNS_PUBLIC=tcp
Environment=TORSOCKS_ALLOW_INBOUND=1
ExecStart=torsocks monerod --data-dir=/home/user/.bitmonero \
--no-igd --hide-my-port --pidfile=/home/user/.bitmonero/monerod.pid \
--log-file=/home/user/.bitmonero/bitmonero.log --p2p-bind-ip=127.0.0.1 \
--non-interactive
Restart=always
PrivateTmp=true
[Install]
WantedBy=default.target
}}
'''4.''' Save and close file.
'''5.''' Reload systemd user instance.
{{CodeSelect|code=
systemctl --user daemon-reload
}}
'''6.''' Optional: Enable autostart for the monerod
systemd user instance.
{{CodeSelect|code=
systemctl --user enable monerod
}}
'''7.''' Start monerod
systemd user instance.
{{CodeSelect|code=
systemctl --user restart monerod
}}
'''8.''' Create folder /rw/usrlocal/etc/qubes-rpc
.
{{CodeSelect|code=
sudo mkdir -p /rw/usrlocal/etc/qubes-rpc
}}
'''9.''' {{Open with root rights
|filename=/rw/usrlocal/etc/qubes-rpc/user.monerod
}}
'''10.''' Add this line:
{{CodeSelect|code=
socat STDIO TCP:localhost:18081
}}
'''11.''' Make the /rw/usrlocal/etc/qubes-rpc/user.monerod
script executable.
{{CodeSelect|code=
sudo chmod +x /rw/usrlocal/etc/qubes-rpc/user.monerod
}}
'''12.''' Done
Creation and configuration of monerod
systemd user unit has been completed.
== monero-wallet-vault
VM Setup ==
These instructions explain how to initially create the Monero private keys in the offline Monero vault VM.
'''Note:''' The following instructions should be applied in {{project_name_workstation_short}} ([[Qubes|{{q_project_name_short}}]]: App Qube monero-wallet-vault
).
'''x.''' Generate a new Monero wallet file.
File name wallet1
and file path ~/wallet1
is arbitrary.
{{CodeSelect|code=
monero-wallet-cli --offline --generate-new-wallet ~/wallet1
}}
'''x.''' Monero Wallet CLI will show:
This is the command line monero wallet. It needs to connect to a monero daemon to work correctly. WARNING: Do not reuse your Monero keys on another fork, UNLESS this fork has key reuse mitigations built in. Doing so will harm your privacy. Monero 'Oxygen Orion' (v0.17.2.3-release) Logging to monero-wallet-cli.log Specify wallet file name (e.g., MyWallet). If the wallet doesn't exist, it will be created. Wallet file name (or Ctrl-C to quit):'''x.''' Enter the name of the wallet, for example:
wallet1
'''x.''' Monero Wallet CLI will ask:
No wallet found with that name. Confirm creation of new wallet named: wallet1 (Y/Yes/N/No):'''x.''' Type
Y
and press enter.
'''x.''' Monero Wallet CLI will ask:
Generating new wallet... Enter a new password for the wallet: Confirm password:'''x.''' Enter a password or leave it empty. Arguably how useful it is when using [[Full Disk Encryption]] on the host operating system. Re-enter password to confirm. '''x.''' Monero Wallet CLI will ask:
List of available languages for your wallet's seed: If your display freezes, exit blind with ^C, then run again with --use-english-language-names 0 : Deutsch 1 : English 2 : Español 3 : Français 4 : Italiano 5 : Nederlands 6 : Português 7 : русский язык 8 : 日本語 9 : 简体中文 (中国) 10 : Esperanto 11 : Lojban Enter the number corresponding to the language of your choice:'''x.''' Enter
1
recommended. In the opinion of the author this is the most common language and least likely to suffer from potential restoration issues in a few decades. Optional: choose a language of your choice.
'''x.''' Example printout:
Note: Do not use address, keys or seed phrase from the example below!
Generated new wallet: 496qfvthZzy99adqviEhoDdFivmwcDH3vBZvPRSX8V6VScBTkR2VuMdb8xEgeMjyPqCigRfBK4cfrEXiX6YEdkF55rWD2Rq View key: 89298e00f35bd89928b23d8a199bcfb49c61d63e242ffe0ca6b235cc0ddb8706 ********************************************************************** Your wallet has been generated! To start synchronizing with the daemon, use the "refresh" command. Use the "help" command to see a simplified list of available commands. Use "help all" command to see the list of all available commands. Use "help'''x.''' Press" to see a command's documentation. Always use the "exit" command when closing monero-wallet-cli to save your current session's state. Otherwise, you might need to synchronize your wallet again (your wallet keys are NOT at risk in any case). NOTE: the following 25 words can be used to recover access to your wallet. Write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. launching okay honked putty zoom zoom people grunt ajar cylinder sake gypsy comb dexterity ethics square sincerely fictional glide equip fierce january journal kisses zoom ********************************************************************** The daemon is not set up to background mine. With background mining enabled, the daemon will mine when idle and not on battery. Enabling this supports the network you are using, and makes you eligible for receiving new monero Do you want to do it now? (Y/Yes/N/No): :
n
to disable mining.
'''x.''' Note the standard address
.
Note, in above example print out a line starting with Generated new wallet:
. In above example, the wallet address is 496qfvthZzy99adqviEhoDdFivmwcDH3vBZvPRSX8V6VScBTkR2VuMdb8xEgeMjyPqCigRfBK4cfrEXiX6YEdkF55rWD2Rq
.
This is also called standard address
or primary address
. It is important to know what the standard address
/ primary address
is.
There is no need to memorize it. A note in a text file in an offline vault VM should be made "my standard address is ...". Replace ...
with the actual standard address
.
'''x.''' Note the view key
.
Note, in above example print out a line starting with View key:
. In above example, the wallet address is 89298e00f35bd89928b23d8a199bcfb49c61d63e242ffe0ca6b235cc0ddb8706
. There is no need to memorize it.
The view key
is also sometimes called secret view key
. It is important to memorize that view key
is sometimes called secret view key
.
A note in a text file in an offline vault VM should be made "my secret view key is ...". Replace ...
with the actual view key.
'''x.''' Note the seed phrase.
Note, in above example print out a line starting with NOTE: the following 25 words can be used to recover access to your wallet. Write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control.
. In above example, wallet seed phrase is:
launching okay honked putty zoom zoom people grunt ajar cylinder sake gypsy comb dexterity ethics square sincerely fictional glide equip fierce january journal kisses zoomDo NOT use above seed phrase. A note in a text file in an offline vault VM should be made "my seed phrase is ... Replace
...
with the actual seed phrase. This is the most important thing to backup! Everything else can be lost (computer, view key, standard address). The only thing required for recovery is the seed phrase. It might be a good idea to memorize it.
'''x.''' Note.
[wallet 496qfv (no daemon)]:
represents the Monero Wallet CLI command prompt.
'''x.''' Optional. Disable Monero Wallet CLI timeout.
https://monero.stackexchange.com/questions/11737/how-can-i-slow-down-or-disable-cli-wallets-automatic-locking-due-to-inactivity
Run the following command in the Monero Wallet CLI command prompt.
{{CodeSelect|code=
set inactivity-lock-timeout 0
}}
== monero-wallet-ws
VM Setup ==
=== socat setup ===
'''Note:''' The following instructions should be applied in {{project_name_workstation_short}} ([[Qubes|{{q_project_name_short}}]]: App Qube monero-wallet-ws
).
'''1.''' {{Open with root rights
|filename=/rw/config/rc.local
}}
'''2.''' Append at the bottom.
{{CodeSelect|code=
socat TCP-LISTEN:18081,fork,bind=127.0.0.1 EXEC:"qrexec-client-vm monerod-ws user.monerod"
}}
'''3.''' Save and close file.
'''4.''' Make the /rw/config/rc.local
script executable.
{{CodeSelect|code=
sudo chmod +x /rw/config/rc.local
}}
'''5.''' Restart the monero-wallet-ws
VM.
'''6.''' Done.
Setting up automatically starting the socat
process has been completed.
=== View-Only Wallet Setup ===
'''Note:''' The following instructions should be applied in {{project_name_workstation_short}} ([[Qubes|{{q_project_name_short}}]]: App Qube monero-wallet-ws
).
'''1.''' Generate view-only wallet.
{{CodeSelect|code=
monero-wallet-cli --generate-from-view-key ~/view1
}}
Monero Wallet CLI is more "clever" and automatically detects the already available monerod
.
monero-wallet-cli
detects that monerod
's default port 18081
is open on localhost. The detection mechanism is port based. Not process based.
Therefore as opposed to Monero Wallet GUI, no "remote node" configuration is neccessary.
'''2.''' Monero will show:
This is the command line monero wallet. It needs to connect to a monero daemon to work correctly. WARNING: Do not reuse your Monero keys on another fork, UNLESS this fork has key reuse mitigations built in. Doing so will harm your privacy. Monero 'Oxygen Orion' (v0.17.2.3-release) Logging to monero-wallet-cli.log Standard address:'''3.''' Enter the
standard address
.
'''4.''' Monero will show:
Secret view key:'''5.''' Enter the
secret view key
.
'''6.''' Example printout:
Standard address: 496qfvthZzy99adqviEhoDdFivmwcDH3vBZvPRSX8V6VScBTkR2VuMdb8xEgeMjyPqCigRfBK4cfrEXiX6YEdkF55rWD2Rq Secret view key: 89298e00f35bd89928b23d8a199bcfb49c61d63e242ffe0ca6b235cc0ddb8706 Enter a new password for the wallet: Confirm password: Generated new wallet: 496qfvthZzy99adqviEhoDdFivmwcDH3vBZvPRSX8V6VScBTkR2VuMdb8xEgeMjyPqCigRfBK4cfrEXiX6YEdkF55rWD2Rq Restore from specific blockchain height (optional, default 0): The daemon is not set up to background mine. With background mining enabled, the daemon will mine when idle and not on battery. Enabling this supports the network you are using, and makes you eligible for receiving new monero Do you want to do it now? (Y/Yes/N/No): : n Background mining not enabled. Set setup-background-mining to 1 to change. If you are new to Monero, type "welcome" for a brief overview. Background refresh thread started= Usage = == Introduction == '''Note:''' On the host (Qubes users: in
dom0
).
The involved VMs need to be started using any usual method (using Qubes VM Manger (QVMM), starting a terminal emulator or otherwise).
'''1.''' Start monerod-ws
VM.
'''2.''' Expectations.
Nothing is expected to happen. monerod
is a background service. To monitor it, see chapter [[Monero_Wallet_Isolation#Monitoring|monitoring]].
'''3.''' Start monero-wallet-ws
VM.
'''4.''' Start monero-wallet-vault
VM.
== Receiving ==
'''Note:''' The following instructions should be applied in {{project_name_workstation_short}} ([[Qubes|{{q_project_name_short}}]]: App Qube monero-wallet-vault
).
Copy the standard address
always from the monero-wallet-vault
VM! Never from the monero-wallet-ws
VM. Provide payees with the standard address
or a subaddress
.
{{CodeSelect|code=
monero-wallet-cli --offline --wallet-file ~/wallet1
}}
To show the standard address
/ primary address
the Monero Wallet CLI prompt, run:
{{CodeSelect|code=
address
}}
It is also possible to run any amount of additional subaddress
. See:
{{CodeSelect|code=
help address
}}
== Watching ==
TODO
== Spending ==
TODO
= Monitoring monerod
=
'''Note:''' The following instructions should be applied in {{project_name_workstation_short}} ([[Qubes|{{q_project_name_short}}]]: App Qube monerod-ws
).
Check the status of the monerod
systemd user service.
{{CodeSelect|code=
systemctl --user status monerod
}}
Follow the journal log of the monerod
systemd user service.
{{CodeSelect|code=
journalctl --boot --user -f -u monerod
}}
Follow the log file of the monerod
.
{{CodeSelect|code=
tail -f ~/.bitmonero/bitmonero.log
}}
View the log file of monerod
.
{{Open File|filename=
~/.bitmonero/bitmonero.log
}}
For the initial author of this wiki page it took approximately 7 minutes from monerod
log file starting SYNCHRONIZATION started
until further progress on synchronization having actually started has been reported.
2021-11-02 10:53:55.204 [P2P4] INFO global src/cryptonote_protocol/cryptonote_protocol_handler.inl:413 SYNCHRONIZATION started 2021-11-02 11:00:20.821 [P2P9] INFO global src/cryptonote_protocol/cryptonote_protocol_handler.inl:1680 Synced 201/2484385 (0%, 2484184 left)= See Also = * [[Money]] * [[Monero]] = Donations = After installing the Monero offline wallet, please consider making a donation to Monero and {{project_name_short}} project ([[Donate]]) to help keep it running for many years to come. {{Pay_Monero_Specific}} = Footnotes = {{reflist|close=1}} {{Footer}} [[Category:Documentation]]