{"id":10185,"date":"2021-06-22T13:00:40","date_gmt":"2021-06-22T11:00:40","guid":{"rendered":"https:\/\/www.credativ.de\/blog\/credativ-inside\/self-hosted-yubico-otp\/"},"modified":"2021-06-22T13:00:40","modified_gmt":"2021-06-22T11:00:40","slug":"self-hosted-yubico-otp","status":"publish","type":"post","link":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/","title":{"rendered":"Self-hosted Yubico OTP"},"content":{"rendered":"<p>In the preceding article, <a href=\"https:\/\/www.credativ.de\/blog\/howtos\/zwei-faktor-authentisierung-mit-yubico-otp\/\">Two-Factor Authentication with Yubico OTP<\/a>, we demonstrated how quickly existing services can be extended with two-factor authentication (2FA) using Yubico OTP with the help of the PAM module <code>pam_yubico<\/code>. The validation service used, the <a href=\"https:\/\/www.yubico.com\/support\/download\/yubicloud\/\">YubiCloud<\/a>, is provided by Yubico free of charge. <\/p>\n<p>However, the fact that you are bound to an external service provider is not to everyone&#8217;s liking: data protection concerns or doubts about the reliability of the cloud service lead to the question of whether the required services could not also be operated on your own systems. There may also be scenarios in which you cannot access external services. <\/p>\n<p>The good news is that there is also the option of hosting the services yourself!<\/p>\n<h1 id=\"komponenten\">Components<\/h1>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-10180 alignright\" src=\"https:\/\/www.credativ.de\/wp-content\/uploads\/2021\/06\/Yubi-key-security-300x169.jpg\" alt=\"\" width=\"300\" height=\"169\" srcset=\"https:\/\/www.credativ.de\/wp-content\/uploads\/2021\/06\/Yubi-key-security-300x169.jpg 300w, https:\/\/www.credativ.de\/wp-content\/uploads\/2021\/06\/Yubi-key-security-1024x576.jpg 1024w, https:\/\/www.credativ.de\/wp-content\/uploads\/2021\/06\/Yubi-key-security-768x432.jpg 768w, https:\/\/www.credativ.de\/wp-content\/uploads\/2021\/06\/Yubi-key-security-1536x864.jpg 1536w, https:\/\/www.credativ.de\/wp-content\/uploads\/2021\/06\/Yubi-key-security-600x338.jpg 600w, https:\/\/www.credativ.de\/wp-content\/uploads\/2021\/06\/Yubi-key-security-180x101.jpg 180w, https:\/\/www.credativ.de\/wp-content\/uploads\/2021\/06\/Yubi-key-security.jpg 1920w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>To be able to validate Yubico OTPs on your own system, two components are required: the <a href=\"https:\/\/github.com\/Yubico\/yubikey-val\">YubiKey OTP Validation Server<\/a> and the <a href=\"https:\/\/github.com\/Yubico\/python-pyhsm\">YubiKey Key Storage Module<\/a>. Yubico provides the necessary software both in <a href=\"https:\/\/github.com\/Yubico\/\">source code<\/a> and as ready-made binary packages in various Linux distributions. <\/p>\n<p>It should be noted that a large part of the documentation available online is still based on the old Key Storage Module, <a href=\"https:\/\/github.com\/Yubico\/yubikey-ksm\">YK-KSM<\/a>. The YK-KSM is implemented in PHP5 and is to be regarded as obsolete because it requires functions and libraries that are no longer included or available in current PHP versions. <\/p>\n<h2 id=\"validation-server---val\">Validation Server &#8211; VAL<\/h2>\n<p>The <em>Validation Server<\/em> implements the Yubico WSAPI for validating Yubico OTPs, which is also used in the YubiCloud. This is a PHP application that requires an RDBMS such as PostgreSQL<sup>\u00ae<\/sup> or MySQL in addition to the Apache web server to operate. <\/p>\n<p>The PAM module <code>pam_yubico<\/code> discussed in the previous articles can be configured by specifying a URL so that it uses a different <em>Validation Server<\/em>, in our case a local one, instead of the YubiCloud.<\/p>\n<p>If a client, for example the PAM module, sends a Yubico OTP to the validation service via the WSAP, the validation service forwards the OTP to the Key Storage Module and receives the decrypted OTP back from there. Based on the counter readings and timestamps, which are compared with the last values stored in the database, the VAL can then decide whether the OTP is valid or not. <\/p>\n<h2 id=\"key-storage-modul---ksm\">Key Storage Module &#8211; KSM<\/h2>\n<p>The <em>Key Storage Module<\/em> is used for the secure storage of the shared secrets of the YubiKeys used. The key used for encryption is either stored on a <a href=\"https:\/\/www.yubico.com\/products\/hardware-security-module\/\">hardware module<\/a> costing a good \u20ac650, or &#8211; as in this case &#8211; inexpensively in a text file. In contrast to the VAL, the KSM does not require a relational database, but instead uses the file system, by default the folder <code>\/var\/cache\/yubikey-ksm<\/code>, and stores the shared secrets there in encrypted form in so-called <a href=\"https:\/\/de.wikipedia.org\/wiki\/Authenticated_Encryption\">AEAD<\/a> files.  <\/p>\n<p>The KSM used here is implemented in Python and runs as an independent service, which by default listens on port <code>8002 TCP<\/code> for connections from <code>localhost<\/code> and offers a simple REST interface there.<\/p>\n<p>The <em>Validation Server<\/em> can use this REST interface to send OTPs to be checked to the <em>Key Storage Module<\/em>, which then uses the <em>Public ID<\/em> to read the corresponding shared secret from its memory in order to decrypt the OTP and return its content to the VAL.<\/p>\n<h1 id=\"installation\">Installation<\/h1>\n<p>Fortunately, there are ready-made packages for both the validation server and the key storage module in most Linux distributions. The following describes the installation and configuration of the services under Debian GNU\/Linux Buster. <\/p>\n<h2 id=\"key-storage-modul---ksm-1\">Key Storage Module &#8211; KSM<\/h2>\n<p>The KSM can be easily installed in Debian with the package <code>yhsm\u2212yubikey\u2212ksm<\/code>  installed:<\/p>\n<pre># apt-get install yhsm\u2212yubikey\u2212ksm<\/pre>\n<p>Before configuring the newly installed service, the so-called keyfile, which contains the key used to encrypt the key storage, must be created:<\/p>\n<pre># mkdir -p \/etc\/yubico\/yhsm\n# touch \/etc\/yubico\/yhsm\/keys.json\n# chown yhsm\u2212ksmsrv \/etc\/yubico\/yhsm\/keys.json\n# chmod 400 \/etc\/yubico\/yhsm\/keys.json<\/pre>\n<p>The keyfile can now be opened with any editor and filled with a key. As the file extension suggests, the keyfile is a JSON file. In the following example, the key, which is located in \u201cSlot\u201d <code>1<\/code>, is <code>000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f<\/code>.  <\/p>\n<pre>{\n  \"1\": \"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\"\n}<\/pre>\n<p><code>000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f<\/code> is the hexadecimal representation of a 32-byte (i.e. 256-bit) example key. For productive use, a reasonable key created from random data should of course be used. The program <code>openssl<\/code> can be used for this:  <\/p>\n<pre>$ openssl rand -hex 32<\/pre>\n<p>To configure the KSM, only a few parameters need to be adjusted in the file <code>\/etc\/default\/yhsm\u2212yubikey\u2212ksm<\/code>:<\/p>\n<pre>YHSM_KSM_ENABLE=\"true\"\nYHSM_KSM_DEVICE=\"\/etc\/yubico\/yhsm\/keys.json\"\nYHSM_KSM_KEYHANDLES=\"1\"<\/pre>\n<p>The parameter <code>YHSM_KSM_ENABLE=\"true\"<\/code> ensures that the KSM is started automatically when the system starts. Instead of the hardware device configured by default, the keyfile just created and the key with the ID <code>1<\/code> from it are used. <\/p>\n<p>Finally, the KSM is restarted with the changed configuration using <code>systemctl restart yhsm\u2212yubikey\u2212ksm<\/code>.<\/p>\n<h2 id=\"validation-server---val-1\">Validation Server &#8211; VAL<\/h2>\n<p>As already mentioned, the Validation Server is a web application written in PHP, the operation of which requires a web server and an RDBMS. While the package dependencies prescribe an Apache web server, you have the choice between MySQL, MariaDB and PostgreSQL<sup>\u00ae<\/sup> for the databases. According to the dependency order of the package, MySQL would be installed by <code>apt<\/code> here, but to give PostgreSQL<sup>\u00ae<\/sup> preference, it must be explicitly listed:  <\/p>\n<pre># apt-get install yubikey\u2212val postgresql php\u2212pgsql<\/pre>\n<p>The configuration of the Validation Server in <code>\/etc\/yubico\/val\/<\/code> is set by default to the Key Storage Module running locally on the same system, so no further intervention is necessary.<\/p>\n<p>So that the PAM module can authenticate itself later when making requests to the Validation Server, credentials in the form of an ID and a key must still be created:<\/p>\n<pre># ykval\u2212gen\u2212clients\n2,cOyFHRvltNYDjx74JE9jOBcdPhI=<\/pre>\n<p>This step corresponds to the registration in the YubiCloud described in the previous article. The output of the command consists of two parts: the ID, followed by a comma and the key in Base64 encoding. <\/p>\n<p>If the Validation Service is to be used from several machines, it is recommended to create separate credentials for each machine. To have several ID-key pairs created, <code>ykval-gen-clients<\/code> is simply called with the desired number: <\/p>\n<pre># ykval\u2212gen\u2212clients 5\n3,6WP1q1ohy92G\/BNLMNjpHpVeL1Q=\n4,InVj6Nbqc9FQN1EgtbsedtuYT9I=\n5,p\/R\/hHx6E3Kf3Qc+671O46laNec=\n6,\/FRX6YqioHSap+zoM+LkWp88TFU=\n7,XxEp4zoHSi9zTDSngvxnGiD4V1A=<\/pre>\n<p>To avoid losing track, you should note which credentials were used for which computer. Alternatively, <code>ykval-gen-clients<\/code> with the switch <code>--notes<\/code> allows you to create a note: <\/p>\n<pre># ykval-gen-clients --notes=OpenVPN\n8,rZKpqc5WcU4OB4Nv551+U3lj2tk=<\/pre>\n<p>The program <code>ykval-export-clients<\/code> outputs all credentials stored in the database, including notes, to the standard output:<\/p>\n<pre># ykval-export-clients\n1,1,1619686861,ua\/\/VH5rvFoxrFHGhLZBz\/RO3m0=,,,\n\u2026\n8,1,1619687606,pkodRX1F77Ck7bvS9MzpXE5IfxA=,,OpenVPN,<\/pre>\n<p>Here you can see that credentials with ID 1 were already created during the installation of the package. Of course, instead of creating your own ID, you can also read this from the database and use it to set up the PAM module. <\/p>\n<h2 id=\"pam\">PAM<\/h2>\n<p>As the last change to the system, the PAM module <code>pam_yubico<\/code>  must be installed and entered in the corresponding service configuration.<\/p>\n<pre># apt-get install libpam\u2212yubico<\/pre>\n<p>As in the previous articles, OpenVPN should once again benefit from 2FA with Yubico OTP. For this purpose, the file <code>\/etc\/pam.d\/openvpn<\/code> is created or adapted: <\/p>\n<pre>auth sufficient pam_yubico.so id=2 key=cOyFHRvltNYDjx74JE9jOBcdPhI= urllist=http:\/\/localhost\/wsapi\/2.0\/verify authfile=\/etc\/yubikey_mappings\naccount required pam_permit.so<\/pre>\n<p>The values specified in the above call of <code>ykval-gen-clients<\/code> or <code>ykval-export-clients<\/code> are used as values for <code>id<\/code> and <code>key<\/code>. The parameter <code>urllist<\/code> receives the URL of the WSAPI of the validation service, which in this case runs on the same computer. <\/p>\n<p>As with the use of the YubiCloud, a <code>authfile<\/code> must be specified again this time &#8211; a file that contains the mappings of user names to <em>Public IDs<\/em>. This is created later, after the keys have been generated. <\/p>\n<p>The configuration of the OpenVPN service is carried out as described in the article <a href=\"https:\/\/www.credativ.de\/blog\/howtos\/zwei-faktor-authentisierung-fuer-openssh-und-openvpn\/\">Two-Factor Authentication for OpenSSH and OpenVPN<\/a>. On the server side, the supplied OpenVPN-PAM plugin must be loaded in the configuration: <\/p>\n<pre>plugin \/usr\/lib\/openvpn\/openvpn-plugin-auth-pam.so openvpn<\/pre>\n<p>On the client side, only the option <code>auth-user-pass<\/code> is added to the existing configuration, so that the user is asked for a user name and password (here: OTP) when establishing a connection.<\/p>\n<h1 id=\"schl\u00fcsselverwaltung\">Key Management<\/h1>\n<p>So that YubiKeys can be used with your own validation service, they must be programmed with a new key, the shared secret. These keys are created in the KSM, read out from it and then written to the YubiKey. <\/p>\n<p>As the shared secret programmed on the YubiKey at the factory cannot be read out, it is of no use for a self-hosted validation service.<\/p>\n<h2 id=\"erzeugung-im-ksm\">Generation in the KSM<\/h2>\n<p>To generate a series of keys in the Key Storage Module, the command <code>yhsm-generate-keys<\/code>  is used:<\/p>\n<pre># yhsm-generate-keys -D \/etc\/yubico\/yhsm\/keys.json --key-handle 1 --start-public-id credtivccccc -c 10\noutput dir : \/var\/cache\/yubikey-ksm\/aeads\nkeys to generate : 10\nkey handles : {1: '1'}\nstart public_id : 13412510728192 (0xc32d7f00000)\nYHSM device : \/etc\/yubico\/yhsm\/keys.json\n\nGenerating 10 keys\n\nDone<\/pre>\n<p>The above command creates 10 (<code>-c<\/code>) keys, starting with the ID  <code>credtivccccc<\/code>  (<code>--start-public-id<\/code>) and uses the key with the ID  <code>1<\/code>  (<code>--key-handle<\/code>), which is in the file  <code>\/etc\/yubico\/yhsm\/keys.json<\/code>  (<code>-D<\/code>) for encryption. The keys are stored as described above under <code>\/var\/cache\/yubikey-ksm\/aeads<\/code>. <\/p>\n<p>The output gives a brief overview of the parameters used, the simple <em>Done<\/em> indicates the successful creation and storage of the credentials.<\/p>\n<p><strong>Caution:<\/strong> if the above command is called several times, existing keys with the same ID will be overwritten without prompting!<\/p>\n<p>With the help of the command <code>yhsm-decrypt-aead<\/code>, the keys just created can now be read out from the KSM:<\/p>\n<pre># yhsm-decrypt-aead --aes-key 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f --format yubikey-csv \/var\/cache\/yubikey-ksm\/aeads\/\n1,credtivccccf,47072c411963,1feff43b2d2b529c697d9db0849c9594,000000000000,,,,,\n2,credtivccccc,512a73c09e98,d6e07a6def46cee722be21b7c2f35aec,000000000000,,,,,\n3,credtivcccce,b491988426de,a72669341ab2a7d2acecec91c2fa0efb,000000000000,,,,,\n4,credtivcccci,fccc5e1dcfcf,b0b14a2454c6d2a54bd2351f09d19d6e,000000000000,,,,,\n5,credtivccccb,8a0b3916582f,a031f201920f6204a38b239836486bbf,000000000000,,,,,\n6,credtivccccj,b9dd85895291,e04d79d45ff80438c744f2a8deec4a15,000000000000,,,,,\n7,credtivccccg,a5213cab8e9c,f20acb5646de4282f21ef12b65c6a082,000000000000,,,,,\n8,credtivcccch,73e9c1fa06b9,4c9d121e432a2fbd14b4a5d96f3b9d8f,000000000000,,,,,\n9,credtivccccd,0695db026eb8,90779c79b363b7dbe54a9c3012e688e5,000000000000,,,,,\n10,credtivcccck,ddd42451acb3,f5803057ea519149041be830509b7b2a,000000000000,,,,,<\/pre>\n<p>The AES key created during the setup of the KSM is specified here as <code>--aes-key<\/code>; the argument <code>--format yubikey-csv<\/code> ensures that the credentials are output as comma-separated values instead of in raw format. The last argument specifies the storage location of the AEAD in the file system. <\/p>\n<h2 id=\"programmieren-des-yubikey\">Programming the YubiKey<\/h2>\n<p>A line in the above output of the command <code>yhsm-decrypt-aead<\/code>  contains the credentials for a YubiKey in several comma-separated fields: in addition to the serial number (field 1), these are the <em>Public ID<\/em> (field 2), the <em>Private ID<\/em> (field 3) and the actual <em>AES key<\/em> (field 4). All other fields are not used in our case. <\/p>\n<p>The entry in line 1 therefore contains the <em>Public ID<\/em> <code>credtivccccf<\/code> with the <em>Private UID<\/em> <code>47072c411963<\/code> and the <em>AES key<\/em> <code>1feff43b2d2b529c697d9db0849c9594<\/code>.<\/p>\n<p>These credentials can now be written to a YubiKey. The program <code>ykpersonalize<\/code> is a powerful command line tool for configuring YubiKeys and is located in the package <code>yubikey-personalization<\/code> on Debian. <\/p>\n<p>If there is already a configuration in slot 1 (<code>-1<\/code>) of the Yubikey that should not be overwritten, you can instead write to slot 2 using <code>-2<\/code>. The call <code>ykpersonalize -x<\/code> swaps the contents of slot 1 and slot 2 of a YubiKey. <\/p>\n<p>Unfortunately, the tool <code>ykpersonalize<\/code> uses different terms for the components of a credential: the <em>Public ID<\/em> becomes the <em>fixed part<\/em> and the <em>Private UID<\/em> becomes the <em>uid<\/em>. The following call writes the above credentials to slot 1 of a plugged-in YubiKey. <\/p>\n<pre>$ ykpersonalize -1 -o fixed=credtivccccf -o uid=47072c411963 -a 1feff43b2d2b529c697d9db0849c9594\nFirmware version 5.1.2 Touch level 1287 Program sequence 3\n\nConfiguration data to be written to key configuration 1:\n\nfixed: m:credtivccccf\nuid: 47072c411963\nkey: h:1feff43b2d2b529c697d9db0849c9594\nacc_code: h:000000000000\nticket_flags: APPEND_CR\nconfig_flags:\nextended_flags:\n\nCommit? (y\/n) [n]: <\/pre>\n<p>It should be noted that <em>fixed part<\/em> and <em>uid<\/em> are transferred as a KV pair using <code>-o<\/code>, while the <em>AES key<\/em> is transferred directly using <code>-a<\/code>.<\/p>\n<p>If the query <code>Commit?<\/code> is answered in the affirmative, the displayed configuration is written to the Yubikey and from then on, when the button is pressed, it outputs a Yubico OTP created with the new credentials.<\/p>\n<p>If you want to program several YubiKeys, the next of the generated credentials is simply used in further calls of <code>ykpersonalize<\/code> accordingly. All commands and tools used use files in CSV format or use stdin\/stdout; recurring processes can therefore be excellently automated by a bash script or similar. <\/p>\n<p>As an alternative to the approach described here, the <em>YubiKey Personalization Tool<\/em> from the package <code>yubikey-personalization-gui<\/code> offers the possibility to program several YubiKeys in a row. To do this, activate the option <em>Program Multiple YubiKeys<\/em> in the GUI under <em>Yubico OTP \u2192 Advanced<\/em>. In order to store the credentials of the YubiKeys programmed in this way in the KSM, the log file <code>configuration_log_hmac.csv<\/code> offered for saving after programming must first be adapted before the credentials contained therein can be imported into the KSM with the program <code>yhsm-import-keys<\/code>.  <\/p>\n<p>According to the man page, <code>yhsm-import-keys<\/code> expects a CSV file with the following structure:<\/p>\n<pre># ykksm 1\nseqno, public id, private uid, AES key,,,,\n\u2026<\/pre>\n<p>The log file of the <em>YubiKey Personalization Tool<\/em> already contains the fields <em>public id<\/em>, <em>private uid<\/em>, and <em>AES key<\/em> in the correct order as fields 4-6. The following awk script <code>log2ksm.awk<\/code> extracts these fields from the file, sets their line number as a <em>sequence number<\/em> in front of them, and outputs the entries line by line after the mandatory header <code># ykksm 1<\/code>:<\/p>\n<pre>#!\/usr\/bin\/awk -f\n\nBEGIN {\n  FS=\",\"\n  printf(\"# ykksm 1\\n\")\n}\n\n\/^Yubico OTP\/ {\n  printf(\"%d,%s,%s,%s,,,,\n\", NR, $4, $5, $6)\n}<\/pre>\n<p>The command to convert the file <code>configuration_log_hmac.csv<\/code> and save the result as <code>yubikey_secrets.csv<\/code> is:<\/p>\n<pre>$ .\/log2ksm.awk configuration_log_hmac.csv  &gt;  yubikey_secrets.csv<\/pre>\n<p>The generated file can then be copied to the machine where the KSM is running, and its entries can be imported into it with the following command:<\/p>\n<pre># yhsm-import-keys -D \/etc\/yubico\/yhsm\/keys.json --key-handle 1  &lt;  yubikey_secrets.csv\noutput dir : \/var\/cache\/yubikey-ksm\/aeads\nkey handles : {1: '1'}\nYHSM device : \/etc\/yubico\/yhsm\/keys.json\n\n\nDone<\/pre>\n<p>Here too, <em>Done<\/em> indicates that the credentials have been successfully imported.<\/p>\n<h2 id=\"pam-1\">PAM<\/h2>\n<p>So that PAM can map received <em>Public IDs<\/em> to user accounts during authentication, the above configured  <code>authfile<\/code>  under  <code>\/etc\/yubikey_mappings<\/code>  must still be created. This contains a username and its assigned YubiKey IDs per line, separated by colons. If the newly created YubiKey with the <em>Public ID<\/em> <code>credtivccccf<\/code> is to be used by user <code>bob<\/code>, the <code>authfile<\/code> must contain the following line:  <\/p>\n<pre>bob:credtivccccf<\/pre>\n<p>Mappings for further user accounts are configured accordingly in separate lines.<\/p>\n<p>As an alternative to using a <code>authfile<\/code>, the mappings can also be made using an LDAP directory service. A separate article will be dedicated to this variant. <\/p>\n<h1 id=\"demo\">Demo<\/h1>\n<p>If all steps have been carried out successfully up to this point, the OpenVPN client will ask for a username and password or the OTP when establishing a connection. While the username still has to be entered manually, a press of a button on the YubiKey is sufficient to enter the OTP, so that the connection can be established. Instead of the individual characters of the OTP, only asterisks are displayed here as well.  <\/p>\n<pre># openvpn client.conf\n...\nEnter Auth Username: bob\nEnter Auth Password: ********************************************\n...<\/pre>\n<h1 id=\"fazit\">Conclusion<\/h1>\n<p>The installation and operation of your own validation service and Key Storage Module is quite complex and involves some effort. The interaction of the components with each other is difficult to track (which makes troubleshooting difficult), and the available tools are sometimes not very intuitive or even inconsistent (which makes understanding difficult). <\/p>\n<p>However, those who do not shy away from the effort and are willing to delve deeper into the subject can ultimately enjoy the full comfort of Yubico OTP while still maintaining control over all components.<\/p>\n<h1 id=\"unterst\u00fctzung\">Support<\/h1>\n<p>If you require support with the configuration or use of two-factor authentication, our <a href=\"https:\/\/www.credativ.de\/en\/portfolio\/support\/open-source-support-center\/\">Open Source Support Center<\/a> is at your disposal &#8211; if desired, also 24 hours a day, 365 days a year.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the preceding article, Two-Factor Authentication with Yubico OTP, we demonstrated how quickly existing services can be extended with two-factor authentication (2FA) using Yubico OTP with the help of the PAM module pam_yubico. The validation service used, the YubiCloud, is provided by Yubico free of charge. However, the fact that you are bound to an [&hellip;]<\/p>\n","protected":false},"author":60,"featured_media":5908,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_improvement_type_select":"improve_an_existing","_thumb_yes_seoaic":false,"_frame_yes_seoaic":false,"seoaic_generate_description":"","seoaic_improve_instructions_prompt":"","seoaic_rollback_content_improvement":"","seoaic_idea_thumbnail_generator":"","thumbnail_generated":false,"thumbnail_generate_prompt":"","seoaic_article_description":"","seoaic_article_subtitles":[],"footnotes":""},"categories":[1885],"tags":[1709,1775,1759,1764,1755,1817,1818],"class_list":["post-10185","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-howtos-en","tag-2fa-en","tag-debian-en","tag-openssh-en","tag-openvpn-en","tag-otp-en","tag-yubico-otp-en","tag-yubikey-en"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.4 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Self-hosted Yubico OTP - credativ\u00ae<\/title>\n<meta name=\"description\" content=\"Discover the advantages of Yubikey OTP and learn how to host it on your own systems.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Self-hosted Yubico OTP\" \/>\n<meta property=\"og:description\" content=\"Discover the advantages of Yubikey OTP and learn how to host it on your own systems.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/\" \/>\n<meta property=\"og:site_name\" content=\"credativ\u00ae\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/credativDE\/\" \/>\n<meta property=\"article:published_time\" content=\"2021-06-22T11:00:40+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.credativ.de\/wp-content\/uploads\/2021\/06\/Yubico-OTP-selbst-gehostet-Header.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2500\" \/>\n\t<meta property=\"og:image:height\" content=\"300\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Jan Bolle\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@bollejansson\" \/>\n<meta name=\"twitter:site\" content=\"@credativde\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jan Bolle\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/\"},\"author\":{\"name\":\"Jan Bolle\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/#\\\/schema\\\/person\\\/f33560ea675ef6722c4459154b42606e\"},\"headline\":\"Self-hosted Yubico OTP\",\"datePublished\":\"2021-06-22T11:00:40+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/\"},\"wordCount\":2193,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.credativ.de\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/Yubico-OTP-selbst-gehostet-Header.jpg\",\"keywords\":[\"2FA\",\"Debian\",\"OpenSSH\",\"OpenVPN\",\"OTP\",\"Yubico OTP\",\"Yubikey\"],\"articleSection\":[\"HowTos\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/#respond\"]}],\"copyrightYear\":\"2021\",\"copyrightHolder\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/\",\"url\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/\",\"name\":\"Self-hosted Yubico OTP - credativ\u00ae\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.credativ.de\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/Yubico-OTP-selbst-gehostet-Header.jpg\",\"datePublished\":\"2021-06-22T11:00:40+00:00\",\"description\":\"Discover the advantages of Yubikey OTP and learn how to host it on your own systems.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.credativ.de\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/Yubico-OTP-selbst-gehostet-Header.jpg\",\"contentUrl\":\"https:\\\/\\\/www.credativ.de\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/Yubico-OTP-selbst-gehostet-Header.jpg\",\"width\":2500,\"height\":300,\"caption\":\"Yubico OTP Self-Hosted Header\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Self-hosted Yubico OTP\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/#website\",\"url\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/\",\"name\":\"credativ GmbH\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Organization\",\"Place\"],\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/#organization\",\"name\":\"credativ\u00ae\",\"url\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/\",\"logo\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/#local-main-organization-logo\"},\"image\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/#local-main-organization-logo\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/credativDE\\\/\",\"https:\\\/\\\/x.com\\\/credativde\",\"https:\\\/\\\/mastodon.social\\\/@credativde\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/credativ-gmbh\",\"https:\\\/\\\/www.instagram.com\\\/credativ\\\/\"],\"description\":\"Die credativ GmbH ist ein f\u00fchrendes, auf Open Source Software spezialisiertes IT-Dienstleistungs- und Beratungsunternehmen. Wir bieten umfassende und professionelle Services, von Beratung und Infrastruktur-Betrieb \u00fcber 24\\\/7 Support bis hin zu individuellen L\u00f6sungen und Schulungen. Unser Fokus liegt auf dem ganzheitlichen Management von gesch\u00e4ftskritischen Open-Source-Systemen, darunter Betriebssysteme (z.B. Linux), Datenbanken (z.B. PostgreSQL), Konfigurationsmanagement (z.B. Ansible, Puppet) und Virtualisierung. Als engagierter Teil der Open-Source-Community unterst\u00fctzen wir unsere Kunden dabei, die Vorteile freier Software sicher, stabil und effizient in ihrer IT-Umgebung zu nutzen.\",\"legalName\":\"credativ GmbH\",\"foundingDate\":\"2025-03-01\",\"duns\":\"316387060\",\"numberOfEmployees\":{\"@type\":\"QuantitativeValue\",\"minValue\":\"11\",\"maxValue\":\"50\"},\"address\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/#local-main-place-address\"},\"geo\":{\"@type\":\"GeoCoordinates\",\"latitude\":\"51.1732374\",\"longitude\":\"6.392010099999999\"},\"telephone\":[\"+4921619174200\",\"08002733284\"],\"contactPoint\":{\"@type\":\"ContactPoint\",\"telephone\":\"08002733284\",\"email\":\"vertrieb@credativ.de\"},\"openingHoursSpecification\":[{\"@type\":\"OpeningHoursSpecification\",\"dayOfWeek\":[\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\"],\"opens\":\"09:00\",\"closes\":\"17:00\"},{\"@type\":\"OpeningHoursSpecification\",\"dayOfWeek\":[\"Saturday\",\"Sunday\"],\"opens\":\"00:00\",\"closes\":\"00:00\"}],\"email\":\"info@credativ.de\",\"areaServed\":\"D-A-CH\",\"vatID\":\"DE452151696\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/#\\\/schema\\\/person\\\/f33560ea675ef6722c4459154b42606e\",\"name\":\"Jan Bolle\",\"description\":\"Jan arbeitet seit 2020 an Projekten des Support\u2013Teams und der Internen IT, nachdem er bereits sein Praktikum im Rahmen seines Informatikstudiums bei credativ absolvierte und auch seine Bachelorarbeit zum Thema Einmalpassw\u00f6rter, Zwei\u2013Faktor\u2013Authentisierung und OpenVPN bei credativ schrieb. Bereits zu Schulzeiten interessierte er sich f\u00fcr Freie Software, Netzwerke und Telekommunikation und richtete zusammen mit Mitsch\u00fclern ein Internetcaf\u00e9 ein, auf dessen Server und Clients Debian GNU\\\/Linux seinen Dienst verrichtete.\",\"sameAs\":[\"https:\\\/\\\/x.com\\\/bollejansson\"]},{\"@type\":\"PostalAddress\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/#local-main-place-address\",\"streetAddress\":\"Hennes-Weisweiler-Allee 23\",\"addressLocality\":\"M\u00f6nchengladbach\",\"postalCode\":\"41179\",\"addressRegion\":\"Deutschland\",\"addressCountry\":\"DE\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/self-hosted-yubico-otp\\\/#local-main-organization-logo\",\"url\":\"https:\\\/\\\/www.credativ.de\\\/wp-content\\\/uploads\\\/2025\\\/04\\\/credativ-logo-right.svg\",\"contentUrl\":\"https:\\\/\\\/www.credativ.de\\\/wp-content\\\/uploads\\\/2025\\\/04\\\/credativ-logo-right.svg\",\"caption\":\"credativ\u00ae\"}]}<\/script>\n<meta name=\"geo.placename\" content=\"M\u00f6nchengladbach\" \/>\n<meta name=\"geo.position\" content=\"51.1732374;6.392010099999999\" \/>\n<meta name=\"geo.region\" content=\"Germany\" \/>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Self-hosted Yubico OTP - credativ\u00ae","description":"Discover the advantages of Yubikey OTP and learn how to host it on your own systems.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/","og_locale":"en_US","og_type":"article","og_title":"Self-hosted Yubico OTP","og_description":"Discover the advantages of Yubikey OTP and learn how to host it on your own systems.","og_url":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/","og_site_name":"credativ\u00ae","article_publisher":"https:\/\/www.facebook.com\/credativDE\/","article_published_time":"2021-06-22T11:00:40+00:00","og_image":[{"width":2500,"height":300,"url":"https:\/\/www.credativ.de\/wp-content\/uploads\/2021\/06\/Yubico-OTP-selbst-gehostet-Header.jpg","type":"image\/jpeg"}],"author":"Jan Bolle","twitter_card":"summary_large_image","twitter_creator":"@bollejansson","twitter_site":"@credativde","twitter_misc":{"Written by":"Jan Bolle","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/#article","isPartOf":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/"},"author":{"name":"Jan Bolle","@id":"https:\/\/www.credativ.de\/en\/#\/schema\/person\/f33560ea675ef6722c4459154b42606e"},"headline":"Self-hosted Yubico OTP","datePublished":"2021-06-22T11:00:40+00:00","mainEntityOfPage":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/"},"wordCount":2193,"commentCount":0,"publisher":{"@id":"https:\/\/www.credativ.de\/en\/#organization"},"image":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/#primaryimage"},"thumbnailUrl":"https:\/\/www.credativ.de\/wp-content\/uploads\/2021\/06\/Yubico-OTP-selbst-gehostet-Header.jpg","keywords":["2FA","Debian","OpenSSH","OpenVPN","OTP","Yubico OTP","Yubikey"],"articleSection":["HowTos"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/#respond"]}],"copyrightYear":"2021","copyrightHolder":{"@id":"https:\/\/www.credativ.de\/#organization"}},{"@type":"WebPage","@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/","url":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/","name":"Self-hosted Yubico OTP - credativ\u00ae","isPartOf":{"@id":"https:\/\/www.credativ.de\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/#primaryimage"},"image":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/#primaryimage"},"thumbnailUrl":"https:\/\/www.credativ.de\/wp-content\/uploads\/2021\/06\/Yubico-OTP-selbst-gehostet-Header.jpg","datePublished":"2021-06-22T11:00:40+00:00","description":"Discover the advantages of Yubikey OTP and learn how to host it on your own systems.","breadcrumb":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/#primaryimage","url":"https:\/\/www.credativ.de\/wp-content\/uploads\/2021\/06\/Yubico-OTP-selbst-gehostet-Header.jpg","contentUrl":"https:\/\/www.credativ.de\/wp-content\/uploads\/2021\/06\/Yubico-OTP-selbst-gehostet-Header.jpg","width":2500,"height":300,"caption":"Yubico OTP Self-Hosted Header"},{"@type":"BreadcrumbList","@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.credativ.de\/en\/"},{"@type":"ListItem","position":2,"name":"Self-hosted Yubico OTP"}]},{"@type":"WebSite","@id":"https:\/\/www.credativ.de\/en\/#website","url":"https:\/\/www.credativ.de\/en\/","name":"credativ GmbH","description":"","publisher":{"@id":"https:\/\/www.credativ.de\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.credativ.de\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Organization","Place"],"@id":"https:\/\/www.credativ.de\/en\/#organization","name":"credativ\u00ae","url":"https:\/\/www.credativ.de\/en\/","logo":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/#local-main-organization-logo"},"image":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/#local-main-organization-logo"},"sameAs":["https:\/\/www.facebook.com\/credativDE\/","https:\/\/x.com\/credativde","https:\/\/mastodon.social\/@credativde","https:\/\/www.linkedin.com\/company\/credativ-gmbh","https:\/\/www.instagram.com\/credativ\/"],"description":"Die credativ GmbH ist ein f\u00fchrendes, auf Open Source Software spezialisiertes IT-Dienstleistungs- und Beratungsunternehmen. Wir bieten umfassende und professionelle Services, von Beratung und Infrastruktur-Betrieb \u00fcber 24\/7 Support bis hin zu individuellen L\u00f6sungen und Schulungen. Unser Fokus liegt auf dem ganzheitlichen Management von gesch\u00e4ftskritischen Open-Source-Systemen, darunter Betriebssysteme (z.B. Linux), Datenbanken (z.B. PostgreSQL), Konfigurationsmanagement (z.B. Ansible, Puppet) und Virtualisierung. Als engagierter Teil der Open-Source-Community unterst\u00fctzen wir unsere Kunden dabei, die Vorteile freier Software sicher, stabil und effizient in ihrer IT-Umgebung zu nutzen.","legalName":"credativ GmbH","foundingDate":"2025-03-01","duns":"316387060","numberOfEmployees":{"@type":"QuantitativeValue","minValue":"11","maxValue":"50"},"address":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/#local-main-place-address"},"geo":{"@type":"GeoCoordinates","latitude":"51.1732374","longitude":"6.392010099999999"},"telephone":["+4921619174200","08002733284"],"contactPoint":{"@type":"ContactPoint","telephone":"08002733284","email":"vertrieb@credativ.de"},"openingHoursSpecification":[{"@type":"OpeningHoursSpecification","dayOfWeek":["Monday","Tuesday","Wednesday","Thursday","Friday"],"opens":"09:00","closes":"17:00"},{"@type":"OpeningHoursSpecification","dayOfWeek":["Saturday","Sunday"],"opens":"00:00","closes":"00:00"}],"email":"info@credativ.de","areaServed":"D-A-CH","vatID":"DE452151696"},{"@type":"Person","@id":"https:\/\/www.credativ.de\/en\/#\/schema\/person\/f33560ea675ef6722c4459154b42606e","name":"Jan Bolle","description":"Jan arbeitet seit 2020 an Projekten des Support\u2013Teams und der Internen IT, nachdem er bereits sein Praktikum im Rahmen seines Informatikstudiums bei credativ absolvierte und auch seine Bachelorarbeit zum Thema Einmalpassw\u00f6rter, Zwei\u2013Faktor\u2013Authentisierung und OpenVPN bei credativ schrieb. Bereits zu Schulzeiten interessierte er sich f\u00fcr Freie Software, Netzwerke und Telekommunikation und richtete zusammen mit Mitsch\u00fclern ein Internetcaf\u00e9 ein, auf dessen Server und Clients Debian GNU\/Linux seinen Dienst verrichtete.","sameAs":["https:\/\/x.com\/bollejansson"]},{"@type":"PostalAddress","@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/#local-main-place-address","streetAddress":"Hennes-Weisweiler-Allee 23","addressLocality":"M\u00f6nchengladbach","postalCode":"41179","addressRegion":"Deutschland","addressCountry":"DE"},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/self-hosted-yubico-otp\/#local-main-organization-logo","url":"https:\/\/www.credativ.de\/wp-content\/uploads\/2025\/04\/credativ-logo-right.svg","contentUrl":"https:\/\/www.credativ.de\/wp-content\/uploads\/2025\/04\/credativ-logo-right.svg","caption":"credativ\u00ae"}]},"geo.placename":"M\u00f6nchengladbach","geo.position":{"lat":"51.1732374","long":"6.392010099999999"},"geo.region":"Germany"},"_links":{"self":[{"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/posts\/10185","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/users\/60"}],"replies":[{"embeddable":true,"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/comments?post=10185"}],"version-history":[{"count":0,"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/posts\/10185\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/media\/5908"}],"wp:attachment":[{"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/media?parent=10185"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/categories?post=10185"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/tags?post=10185"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}