GNUnet is a framework for secure and anonymous peer-to-peer networking that does not use any centralized or otherwise trusted services. Currently, the framework offers censorship-resistant file-sharing, messaging, VPN, GNS (a decentralized version of DNS), and much more.
GNUnet can be installed with the AUR package. The most recent experimental version is available as AUR.
The default GNUnet configuration is a multi-user configuration. This means that the system services are run by the
gnunet system user, while users that belong to the
gnunet group are allowed to interface with the daemon – to search and download a file for example.
Before using GNUnet you must therefore make sure to add your user to the
gnunet group to gain the necessary permissions.
The default configuration should work out of the box in most cases. For changing the system configuration please refer to
/etc/gnunet.conf, while for changing the current user configuration please refer to
See Configuration Handbook in the manual for further insight. See also #Launching the daemon as current user in a multi-user setup.
Entering the GNUnet network
Checking the network
You can check the current state of the network by launching the
gnunet-peerinfo command as normal user.
To know your peer identity launch:
$ gnunet-peerinfo -s
Searching for a file
gnunet-search to search for a file using keywords (these are not necessarily related to the file's name). For example, to search for files that have been indexed under the “commons” keyword, launch:
$ gnunet-search 'commons'
The output of
gnunet-search is a list of
gnunet-download commands that you can directly copy and launch as normal user.
For example, using the output generated by
$ gnunet-search 'commons'
#1: gnunet-download -o "Liotard (2017)_ Fablab - a new space for commons based peer production.pdf" gnunet://fs/chk/C6369DRQ3S8RYK1FD5VDE666W2HVEJ5G5GJRX29BH6ZM08CBRWS7FY9326RBJ4G0N8V1RJ2N802KBYZT7RJT2EDK1J9JR2DXK5MTVM0.4SXJCK9NT5XGCZ0YAJ0ETXJJGY3P2SMNZ0Q94N775YEX9SXS2RW5FWRFK4GMBTP668Z3R8QZZ4WSHW1KG1AVQ5VFC1VF5T3WF57GT58.336423 #2: gnunet-download -o "Rose, Carol (1986)_ The Comedy of the Commons_ Commerce, Custom, and inherently Public Property.pdf" gnunet://fs/chk/TQK3A2C279EJQ50B1TQWFNTPMGQZJJ4JXYTF2D88D03H038TB7SVVSRBT74FMYPNZ47YZSV096PVVZH0TQ3B8KBVBV2H8GN9VAASTJR.CQ7M7843MGPZCV8M26NKH6EB5MBGZAXRWCF39YS668WM6F22D214GSXNTJ4RYGE7XF68VPZM4C19XR48TT4J8WH8S2E00C96Q8K6790.1593230 #3: gnunet-download -o "Hardin, Garett (1968)_ Tragedy of the Commons.pdf" gnunet://fs/chk/Y1FD7D123CEGWDW544YDEP15YA5E7ZD2XRSJBNP0847A5JXMMZEZ0XACGRG42BBBTGKZ0ZCBW0A9T6196Z5N26HA6SP1T8GDAT5H5SG.RN38G25DMYG3TBQJEGWDZT2B84N1JYYJZ8VRJ8HG2G1A4EFD4GH5TZXB0RXV7QEMZBSKWCCEF736FXNH6C5BYKG9DSTV99ETFGC93R0.1520328 ...
you can launch,
$ gnunet-download -o "Hardin, Garett (1968)_ Tragedy of the Commons.pdf" gnunet://fs/chk/Y1FD7D123CEGWDW544YDEP15YA5E7ZD2XRSJBNP0847A5JXMMZEZ0XACGRG42BBBTGKZ0ZCBW0A9T6196Z5N26HA6SP1T8GDAT5H5SG.RN38G25DMYG3TBQJEGWDZT2B84N1JYYJZ8VRJ8HG2G1A4EFD4GH5TZXB0RXV7QEMZBSKWCCEF736FXNH6C5BYKG9DSTV99ETFGC93R0.1520328
which will download
Hardin, Garett (1968)_ Tragedy of the Commons.pdf in the current directory.
Mounting a remote GNUnet directory without downloading it
A module, named
gnunet-fuse, directories that have been published on the GNUnet network can be mounted as read-only file systems and accessed using normal file operations. In contrast to downloading the directory recursively via
gnunet-download, this has the advantage that files are downloaded on-demand. Only those files (or directories) that you access will be downloaded. For more information please install the module and type
Publishing a file on the GNUnet file-sharing network involves choosing keywords that can be later used by other people to search for the file.
Keywords are not strictly required, but they are recommended. This is because GNUnet does not allow searching by filename, but by keywords. Thelibrary, which is a dependency of GNUnet, can automatically extract keywords from a file, but you may wish to enter keywords of your own.
In the following example, we use the keywords "commons" and "state" to publish a file named
$ gnunet-publish -k 'commons' -k 'state' ostrom.pdf
Publishing `/srv/filesharing/gnunet/ostrom.pdf' done. URI is `gnunet://fs/chk/M57S...
GNUnet users can now find the file by using the
$ gnunet-search 'commons'
#1: gnunet-download -o "ostrom.pdf" gnunet://fs/chk/M57S...
To list all the files that are currently published launch
gnunet-fs -i. If later you want to stop sharing a file you can use
gnunet-unindex filename (in our example,
Once a file is published it is not possible to retrieve the keywords whereby the file was indexed (i.e., reverse search). It is always possible however to add further keywords to it.
Please note that it might take some time (up to some hours) till your peers can see your freshly uploaded files.
gnunet-publishmust be considered an irreversible action.
gnunet-publish command offers an option –
-n or equivalently
--noindex – to publish a file without indexing it. When used, GNUnet will perform a full insertion and store the entire file in encrypted form in the GNUnet database.
This option has been created with the purpose of avoiding that who takes physical access to a computer running GNUnet finds out which files are currently being published, in case of censored files in countries with strong censorship.
Modifying and removing indexed files
- When you modify a file, the URI of the file changes. Therefore, GNUnet considers this to be a completely different file and the indexed file will be considered missing. Therefore, make sure that the original file is unindexed first (using the
gnunet-unindexcommand), modify the file, and then index the new file to make it accessible through the network.
- If you want to remove a file from your filesystem, then you should unindex it first.
- If you know in advance that a published file will likely need to be updated more or less frequently, see #Publishing updatable files
Downloading + sharing
GNUnet file-sharing network is a DHT (see Wikipedia:Distributed hash table). As peers in the DHT, users store chunks of various files on their disk, even from files they do not download or have downloaded. Which files are stored depends on the DHT distance metric / algorithm.
Technically unless a file has been completely downloaded only parts of it are stored. These are stored in a cache (typically under
/var/lib/gnunet/.local/share/gnunet). If a DHT query finds its way to a peer for one of the cached parts, the peer will provide it. The database used to store the file-sharing blocks is kept finite (below a configurable quota), and all the cached parts can expire to make space for newer files.
If someone shares a file in the GNUnet network the distributed chunks of that file will remain in the network's cache for a while, and the file will remain available even if who shared it goes offline. But if the original publisher goes missing and nobody else shared the file explicitly (with
gnunet-publish), the file will eventually become unavailable as the peer caches expire or the peers go offline.
The only way to ensure that a file persists in the GNUnet network is then to re-publish it explicitly after downloading it (with
gnunet-publish) and let the machine that publishes the file visit the network regularly.
Publishing a file after downloading will always generate the same URI whereby the file was downloaded (
gnunet://fs/chk/Y1FD... in the example below), independently of the keywords chosen for re-publishing it:
$ gnunet-download -o 'Hardin, Garett (1968)_ Tragedy of the Commons.pdf' gnunet://fs/chk/Y1FD...
100% [============================================================] Downloading `Hardin, Garett (1968)_ Tragedy of the Commons.pdf' done (160 b/s).
$ gnunet-publish -k 'tragedy' 'Hardin, Garett (1968)_ Tragedy of the Commons.pdf'
Publishing `/srv/filesharing/gnunet/Hardin, Garett (1968)_ Tragedy of the Commons.pdf' done. URI is `gnunet://fs/chk/Y1FD...
Chatting with other GNUnet users
To chat with GNUnet users the
gnunet-messenger utility is available. For instance, to enter the “miscellanea” room using “alice” as nickname, launch
$ gnunet-messenger -e alice -r miscellanea
* Welcome to the messenger, 'alice'! * You try to open a room... * You joined the room. [EHDA8T] * 'anonymous' opened the room on: 2ABN944E16FTWFMOKTMQ5JMPQ233YSPBKC47XR2DHSPQCQ8GYK80 [EHDA8T] * 'anonymous' gets renamed to 'alice' █
GNUnet provides a VPN, which can be used to share your Internet connection (yes, this may be dangerous, just as running a Tor exit node), or to provide access to services on your host (this should be less dangerous, as long as those services are secure).
For information on how to set up a VPN with GNUnet, see https://gnunet.org/en/use.html#vpn.
The GNU Name Service (GNS)
The GNU Name Service (GNS) is a fully decentralized alternative to the Domain Name System (DNS) that should not suffer the same major security flaws as the latter (see Wikipedia:Domain Name System#Security issues).
GNUnet GTK is a collection of graphical interfaces for the GNUnet framework. It ships the following GTK apps:
To install GNUnet GTK download theAUR package.
Currently several graphical user interfaces for chatting on the GNUnet network are being developed. One of these is Cadet GTK (GTK graphical user interface for chatting with GNUnet users.AUR), a mobile-friendly
Web User Interface
A Web interface for GNUnet exists and is available asAUR.
re:claimID is a decentralized Identity Provider (IdP) service built on top of the GNU Name System. It allows users to securely share personal information with websites using standardized protocols (OpenID Connect).
After having installed the extension it will be possible to add a new identity to the local re:claimID instance and add some attributes to it by visiting https://ui.reclaim/ (the link will not work without the extension installed).
For more information, please refer to the manual.
GNU Taler is a microtransaction and electronic payment system built on top of GNUnet. Differently than other distributed payment systems Taler is not based on a blockchain, but on blind signatures instead.
For more information please consult the official documentation. See also packages AUR, AUR, AUR, AUR and AUR.
GNUnet fails to publish files
A common mistake for who does not understand how the GNUnet services work is that of trying to publish files located in the home directory (or in its subdirectories). The problem is that the
gnunet system user (which runs the GNUnet service) has normally no access to the home directories of other users.
An easy solution is to create a shared directory, where only users that belong to the
gnunet group have write permissions, and use it to place the files that will be published. For instance,
/srv/filesharing/gnunet could be a good choice:
# install -dm775 -g gnunet -o gnunet /srv/filesharing/gnunet
Each user belonging to the
gnunet group can then create a link to it in their home directory,
$ ln -s /srv/filesharing/gnunet ~/Publishing
which can be dereferenced by
$ (cd ~/Publishing && gnunet-publish -k commons ostrom.pdf) && gnunet-fs -i
It is recommended for file-sharing that you increase GNUnet's bandwidth restrictions from the actually pretty low defaults. The example below sets the WAN and LAN limits to
$ gnunet-config -s ats -o WAN_QUOTA_IN -V unlimited $ gnunet-config -s ats -o WAN_QUOTA_OUT -V unlimited $ gnunet-config -s ats -o LAN_QUOTA_IN -V unlimited $ gnunet-config -s ats -o LAN_QUOTA_OUT -V unlimited
/var/lib/gnunet/ grows too big
GNUnet's cache is kept finite and cannot grow forever. However the quota reserved for it by default is not small (currently 5 GB). To reduce this number, you must assign your preferred value to the
QUOTA key in the
datastore section of
... [datastore] ... QUOTA = 2 GB ...
/var/lib/gnunet/ is left after uninstall
/var/lib/gnunet/ directory is the home directory of the
gnunet system user, which is left after uninstalling GNUnet. If you are sure that you are never going to use GNUnet ever again, launch:
# userdel -r gnunet # groupdel gnunetdns
The network is too static
By default GNUnet bootstraps itself using a
hostlist file downloaded from internet (plain
https) every time it connects to the network. If you want to instruct it to learn and memorize host lists provided by other peers you need to add the
-e option to the
OPTION key under
/etc/gnunet.conf. Further options are also available.
... [hostlist] ... # Options: # -p : provide a hostlist as a hostlist servers # -b : bootstrap using configured hostlist servers # -e : enable learning advertised hostlists # -a : advertise hostlist to other servers OPTIONS = -b -e -a -p ...
Tips and tricks
Launching the daemon as current user in a multi-user setup
After a fresh install the user configuration file is missing. In a multi-user setup this is almost only used (if needed) to start and stop the
gnunet.service user unit while the system daemon is running, hence it is generally enough to create a minimal configuration file containing only:
[arm] START_SYSTEM_SERVICES = NO START_USER_SERVICES = YES
NO, launching the daemon as current user while the system daemon is running will result in duplicate processes.
See The Multi-User Setup, in the manual for further insight.
The GNUnet peer can be started also from the current user without running the
gnunet system service. For a single-user setup make sure that
START_USER_SERVICES are set to
[arm] START_SYSTEM_SERVICES = YES START_USER_SERVICES = YES
For further information, please refer to the chapter on the single-user setup in the handbook.
Publishing updatable files
It is possible to publish "updatable" files (i.e., files for which you might want to release a different version in the future, advertising that it is the same file – just updated – and not a different one). To release an updatable file you need to create an ego and use it to sign the file. This is the only way to assure that a malicious party cannot supply counterfeited updates.
To create an ego the
gnunet-identity utility is available, for which the
gnunet.service user unit needs to be started (possibly along with the
gnunet.service system unit – see #Launching the daemon as current user in a multi-user setup). For instance, to create an ego named "caroline", start the
gnunet user unit and launch:
$ gnunet-identity -C caroline
gnunet-identity -D caroline.
Now that you have created an ego, you need to specify a string that identifies the current release of the file (the
-t option), and already now the string that will identify your planned next version (the
-N option) – you will have to remember the latter. Any content is possible for both strings.
$ gnunet-publish -P caroline -t 'diary version 1' -N 'diary version 2' -k 'diary' until-2020/my_diary.md
Publishing `/srv/filesharing/gnunet/until-2020/my_diary.md' done. URI is `gnunet://fs/chk/AF26...'. Namespace URI is `gnunet://fs/sks/V3TK.../diary version 1'.
When an update will be ready, you will have to use the same string that you had previously chosen for it ("diary version 2" in our example), possibly accompanying it with another name for a further update (if applicable):
$ gnunet-publish -P caroline -t 'diary version 2' -N 'diary version 3' -k 'diary' until-2021/my_diary.md
Publishing `/srv/filesharing/gnunet/until-2021/my_diary.md' done. URI is `gnunet://fs/chk/5Y7V...'. Namespace URI is `gnunet://fs/sks/V3TK.../diary version 2'.
If you decide that an update will be the last one, omit the
-N option (will not allow any future updates).
Note that an update with GNUnet will not make the old content unavailable, GNUnet merely allows the publisher to point users to more recent versions.
Launching and stopping GNUnet without systemd
GNUnet comes with an own daemon management system, the Automatic Restart Manager (limited to the GNUnet services).
To start the system services manually without systemd launch the
gnunet-arm utility as
$ sudo -u gnunet gnunet-arm -c /etc/gnunet.conf -s
To end the system services manually without systemd, launch:
$ sudo -u gnunet gnunet-arm -c /etc/gnunet.conf -e
To start the user services manually without systemd, launch the
gnunet-arm utility as current user:
$ gnunet-arm -c ~/.config/gnunet.conf -s
To end the user services manually without systemd, launch:
$ gnunet-arm -c ~/.config/gnunet.conf -e