{"id":17922494,"url":"https://github.com/gierens/yubipi","last_synced_at":"2026-02-09T21:05:46.242Z","repository":{"id":43584868,"uuid":"447776112","full_name":"gierens/yubipi","owner":"gierens","description":"Project for triggering a YubiKey from software and also remotely.","archived":false,"fork":false,"pushed_at":"2022-02-26T13:37:18.000Z","size":2305,"stargazers_count":4,"open_issues_count":12,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-02T04:09:09.136Z","etag":null,"topics":["api-server","automation","mfa","multi-factor-authentication","one-time-password","otp","python","raspberry-pi","script","yubikey","yubikey-trigger"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gierens.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-01-13T22:51:20.000Z","updated_at":"2025-03-28T22:49:21.000Z","dependencies_parsed_at":"2022-08-23T07:21:13.695Z","dependency_job_id":null,"html_url":"https://github.com/gierens/yubipi","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gierens%2Fyubipi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gierens%2Fyubipi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gierens%2Fyubipi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gierens%2Fyubipi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gierens","download_url":"https://codeload.github.com/gierens/yubipi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247804074,"owners_count":20998889,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-server","automation","mfa","multi-factor-authentication","one-time-password","otp","python","raspberry-pi","script","yubikey","yubikey-trigger"],"created_at":"2024-10-28T20:39:25.071Z","updated_at":"2026-02-09T21:05:46.183Z","avatar_url":"https://github.com/gierens.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# YubiPi\n\nYubiPi is project for triggering a YubiKey from software and providing the\nmeans to do so remotely. This takes the burden of having to bring it with \nyou and pressing the button manually from you, and enables you to easily\nautomate anything that requires a One-Time Password from the YubiKey.\n\n![YubiPi Demonstration](img/yubipi.gif)\n\n## Quick Start\n1. Build the triggering circuit exactly as descriped \n[below](#triggering-circuit).\n2. SSH into the Raspberry and go to the cloned repository.\n```bash\ncd yubipi\n```\n3. Execute the following commands. In case you need a bit more information or\nwant to alter the setup slightly, please refer to the more detailed guides\nbelow.\n```bash\nsudo pip3 install -r requirements.txt\nsudo ln -s \"$(pwd)/yubipi.py\" /usr/local/bin/yubipi\nsudo cp yubipi.sh /etc/default/yubipi\nTOKEN=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w ${1:-32} | head -n 1)\nsudo sed -i \"s/^TOKEN=.*$/TOKEN=${TOKEN}/g\" /etc/default/yubipi\nsudo cp yubipi.service /etc/systemd/system/\nsudo systemctl daemon-reload\nsudo systemctl start yubipi\nsudo apt update \u0026\u0026 sudo apt install nginx\nsudo systemctl start nginx\nsudo cp yubipi-nginx.conf /etc/nginx/sites-available/yubipi\nsudo ln -s /etc/nginx/sites-available/yubipi /etc/nginx/sites-enabled/yubipi\nsudo systemctl reload nginx\n```\n\n4. Now you should be able to reach the API server via HTTPS:\n```bash\ncurl -k https://127.0.0.1:5443/ -H \"X-Auth-Token: ${TOKEN}\"\n```\n\n## Hardware\n\n### Triggering Capacitive Touch Sensors\nYubiKeys use capacitive touch sensors. Those measure the capacitance of a\ncapacitor of which the contact plate is part of. The touch with you finger\ncauses a measurable change thus triggers the sensor.\n\nThere are multiple ways to replicate this. Touching the contact pad with a\nlarge conductive object or grounding the pad shortly could be realized with an\nactuator or a relay. Both those components however are a bit clunky and also\nrarely part of the electronic hobbyists assortment.\n\nA transistor-based solution seems much more elegant but has a catch.\nTransistors are capacitive components which means even in a cut-off state\nthey will pull some charge from the contact plate. This can easily disturb\nthe measurement process enough so that the touch sensor won't trigger when\nthe transistor is activated.\n\nThe circuit we are aiming for is this:\n\u003cimg src=\"img/yubipi_schem.png\" width=600px\u003e\n\nThe NPN transistor is switched with the Raspberry Pi's GPIO and the collector\nof it is used to pull the contact plate to ground. In this case the\ncollector-emitter or output capacitance of the transistor is key. It needs to\nbe very low so it does not pull too much charge in the cut-off state.\n\n### What you need\nUnfortunately the popular\n[BC337](https://www.futurlec.com/Datasheet/Transistor/BC337.pdf)\nhas an output capacitance of 15 pF. This is too much for triggering the\nYubiKey. A [C1815](https://www.futurlec.com/Datasheet/Transistor/C1815.pdf)\nwith only 2 pF should work just fine.\n\nAll in all you will be needing the following components to build the circuit:\n\n- A YubiKey with a capacitive touch sensor (like a YubiKey 5 NFC)\n- A Raspberry Pi with a matching free USB port (like a Raspberry Pi 3B v1.2)\n- A breadboard, a few wires, a little bit of tinfoil and tape\n- A transistor with a low output capacitance (like a C1815)\n- A 10 kOhm resistor and optionally a LED\n\n### Triggering Circuit\nThe following picture shows an example of how the circuit could be arranged on\na breadboard.\n\n![YubiPi Breadboard](img/yubipi_bb.png)\n\nNote that in case of a C1815 transistor the contact order is ECB (Emitter,\nCollector, Base).\n\nThe touch sensor plate of the YubiKey is connected to the transistors\ncollector. Make sure to have a large contact area between wire and the plate\nwith the tinfoil and some tape.\n\nFor good measure you might also want to ground the USB ports casing. Here you\ncan also use some tinfoil and tape.\n\n## Software\n\nAfter the hardware part is done, you can login into your Raspberry Pi to\ninstall the software. First clone this repository to an arbitrary location\nand enter the folder.\n\n### Installation\nThe Python dependencies are listed in `requirements.txt`, so you can install\nthem with:\n```bash\nsudo pip3 install -r requirements.txt\n```\nNow link the YubiPi script into a binary folder to make it available via the\n`PATH` variable.\n```bash\nsudo ln -s \"$(pwd)/yubipi.py\" /usr/local/bin/yubipi\n```\n\n### CLI Mode\nIf you connected the triggering circuit to GPIO 21 (pin 40) you should now be\nable to get an OTP with:\n```bash\nyubipi\n```\nIf you connected the trigger to different pin, you can specify this with the\n`-p/--pin` argument:\n```bash\nyubipi -p 40\n```\nYou can find the pinout for the Raspberry Pi [here](https://pinout.xyz).\n\nThe program tries to autodetect the YubiKey. In case multiple are connected\nyou will be prompted to choose one. To specify it from the start, especially\nin cases where the program is unable to identify the YubiKey from the device\nname, use the `-d/--device` argument:\n```bash\nyubipi -d /dev/input/event0\n```\nTo manually identify the YubiKey's input device you can use this command:\n```bash\nfor evdev in $(find /sys/class/input/event* -exec basename {} \\;);\n    do echo \"/dev/input/${evdev} : $(cat /sys/class/input/${evdev}/device/name)\";\ndone\n```\nFor more info on the command line interface check the help with help with\n`-h/--help`.\n\nAlso note that only one instance of the program can operate on one YubiKey at\na time.\n\n### API Mode\nTo start the API server use the `-s/--server` argument:\n```bash\nyubipi -s\n```\nEverything mentioned about setting the pin and input device applies in this\nmode as well.\n\nBy default the server will be started on localhost and port 5000. You can\nquery it for an OTP locally:\n```bash\ncurl http://127.0.0.1:5000/\n```\nIf you want it to listen on a different device and port use the `-H/--host`\nand `-P/--port`. For example if you want it to listen on any device on\nport 5050:\n```bash\nyubipi -s -H 0.0.0.0 -P 5050\n```\nIn this case you can also call the server on the local network.\n\nTo secure the API endpoint with token authentication you can specify tokes\nwith the `-t/--token` option:\n```bash\nyubipi -s -t secrettoken1 secrettoken2\n```\nThen you have to authenticate when doing a query with one of the given tokens:\n```bash\ncurl http://127.0.0.1:5000/ -H 'X-Auth-Token: secrettoken2'\n```\nNote that while the server is running you cannot run another instance of the\nprogram on the same YubiKey.\n\n### SystemD Service\nTo run the API server as SystemD service both a service and environment file\nare provided.\n\nFirst copy the environment file:\n```bash\nsudo cp yubipi.sh /etc/default/yubipi\n```\nand modify to your needs. You will definitely want to generate a new random\ntoken:\n```bash\nTOKEN=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w ${1:-32} | head -n 1)\nsudo sed -i \"s/^TOKEN=.*$/TOKEN=${TOKEN}/g\" /etc/default/yubipi\n```\nNow copy the service file:\n```bash\nsudo cp yubipi.service /etc/systemd/system/\n```\nReload the SystemD configuration:\n```bash\nsudo systemctl daemon-reload\n```\nNow you can start the service:\n```bash\nsudo systemctl start yubipi\n```\nYou should now be able to reach the API server again with CURL:\n```bash\ncurl http://127.0.0.1:5000/ -H \"X-Auth-Token: ${TOKEN}\"\n```\n\n### HTTPS\nFor TLS encryption with the Waitress WSGI server most often NGINX is used as a\nreverse proxy. First make sure NGINX is installed:\n```bash\nsudo apt update \u0026\u0026 sudo apt install nginx\n```\nMake sure the YubiPi service is up and running:\n```bash\nsudo systemctl start yubipi\n```\nMake sure NGINX starts:\n```bash\nsudo systemctl start nginx\n```\nNext copy the provided NGINX virtual host config:\n```bash\nsudo cp yubipi-nginx.conf /etc/nginx/sites-available/yubipi\n```\nAlter the configuration if necessary, for example to use your own root CA\ncertificate instead of the default self-signed one, or to configure\ndifferent ports.\n\nEnable the site by sym-linking the virtual host configuration file:\n```bash\nsudo ln -s /etc/nginx/sites-available/yubipi /etc/nginx/sites-enabled/yubipi\n```\nNow reload NGINX to apply the configuration:\n```bash\nsudo systemctl reload nginx\n```\nYou should now be able to reach the API server again with CURL but via HTTPS:\n```bash\ncurl -k https://127.0.0.1:5000/ -H \"X-Auth-Token: ${TOKEN}\"\n```\nNote the `-k` which we merely use to ignore the security warning because of the\nself-signed certificate. If you use a root CA certificate or your own CA this\nis not necessary. `${TOKEN}` is again the token configured in \n`/etc/default/yubipi`. Since the virtual host is configured to listen on all\ndevices, you should now also be able to reach the API server via HTTPS from\na different host on the network like your client machine.\n\n## License\nThis code is distributed under [GPLv3](LICENSE) license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgierens%2Fyubipi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgierens%2Fyubipi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgierens%2Fyubipi/lists"}